Home | History | Annotate | Download | only in inc
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_LIBSCF_PRIV_H
     27 #define	_LIBSCF_PRIV_H
     28 
     29 
     30 #include <libscf.h>
     31 #include <unistd.h>
     32 
     33 #ifdef	__cplusplus
     34 extern "C" {
     35 #endif
     36 
     37 /*
     38  * NOTE
     39  *
     40  * The contents of this file are private to the implementation of Solaris
     41  * and are subject to change at any time without notice.
     42  */
     43 
     44 #define	SCF_PG_GENERAL_TYPE		SCF_GROUP_FRAMEWORK
     45 #define	SCF_PG_GENERAL_FLAGS		0
     46 
     47 #define	SCF_PG_GENERAL_OVR_TYPE		SCF_GROUP_FRAMEWORK
     48 #define	SCF_PG_GENERAL_OVR_FLAGS	SCF_PG_FLAG_NONPERSISTENT
     49 
     50 #define	SCF_PG_DEATHROW_TYPE		SCF_GROUP_FRAMEWORK
     51 #define	SCF_PG_DEATHROW_FLAGS		SCF_PG_FLAG_NONPERSISTENT
     52 
     53 #define	SCF_PG_OPTIONS_TYPE		SCF_GROUP_FRAMEWORK
     54 #define	SCF_PG_OPTIONS_FLAGS		0
     55 
     56 #define	SCF_PG_OPTIONS_OVR_TYPE		SCF_GROUP_FRAMEWORK
     57 #define	SCF_PG_OPTIONS_OVR_FLAGS	SCF_PG_FLAG_NONPERSISTENT
     58 
     59 #define	SCF_PG_RESTARTER_TYPE		SCF_GROUP_FRAMEWORK
     60 #define	SCF_PG_RESTARTER_FLAGS		SCF_PG_FLAG_NONPERSISTENT
     61 
     62 #define	SCF_PG_RESTARTER_ACTIONS_TYPE	SCF_GROUP_FRAMEWORK
     63 #define	SCF_PG_RESTARTER_ACTIONS_FLAGS	SCF_PG_FLAG_NONPERSISTENT
     64 
     65 #define	SCF_PROPERTY_CLEAR		((const char *)"maint_off")
     66 #define	SCF_PROPERTY_MAINTENANCE	((const char *)"maint_on")
     67 
     68 #define	SCF_PROPERTY_LOGFILE		((const char *)"logfile")
     69 #define	SCF_PROPERTY_ALT_LOGFILE	((const char *)"alt_logfile")
     70 
     71 #define	SCF_LEGACY_SERVICE		((const char *)"smf/legacy_run")
     72 
     73 #define	SCF_LEGACY_PROPERTY_NAME	((const char *)"name")
     74 #define	SCF_LEGACY_PROPERTY_INODE	((const char *)"inode")
     75 #define	SCF_LEGACY_PROPERTY_SUFFIX	((const char *)"suffix")
     76 
     77 #define	SCF_FMRI_TYPE_SVC		0x1
     78 #define	SCF_FMRI_TYPE_FILE		0x2
     79 
     80 /*
     81  * Strings for use in constructing FMRIs
     82  */
     83 #define	SCF_FMRI_SVC_PREFIX		"svc:"
     84 #define	SCF_FMRI_FILE_PREFIX		"file:"
     85 #define	SCF_FMRI_SCOPE_PREFIX		"//"
     86 #define	SCF_FMRI_LOCAL_SCOPE		"localhost"
     87 #define	SCF_FMRI_SCOPE_SUFFIX		"@localhost"
     88 #define	SCF_FMRI_SERVICE_PREFIX		"/"
     89 #define	SCF_FMRI_INSTANCE_PREFIX	":"
     90 #define	SCF_FMRI_PROPERTYGRP_PREFIX	"/:properties/"
     91 #define	SCF_FMRI_PROPERTY_PREFIX	"/"
     92 #define	SCF_FMRI_LEGACY_PREFIX		"lrc:"
     93 
     94 /*
     95  * sulogin Service FMRI
     96  */
     97 #define	SVC_SULOGIN_FMRI ((const char *)"svc:/system/sulogin")
     98 
     99 typedef struct scf_decoration_info {
    100 	const char *sdi_name;
    101 	scf_type_t sdi_type;
    102 	scf_value_t *sdi_value;		/* can be SCF_DECORATE_CLEAR */
    103 } scf_decoration_info_t;
    104 
    105 typedef int (*scf_decoration_func)(const scf_decoration_info_t *, void *);
    106 
    107 /*
    108  * calls a callback function for each decoration on the handle.  If the
    109  * callback returns 0, the iteration stops and returns 0.  If the callback
    110  * returns a non-zero value, the iteration continues.  After full completion,
    111  * 1 is returned.  On error, -1 is returned.
    112  */
    113 int _scf_handle_decorations(scf_handle_t *, scf_decoration_func *,
    114     scf_value_t *, void *);
    115 
    116 /*
    117  * wait for a change to the propertygroup -- may return early.
    118  * For now, only one of these can be outstanding at a time.
    119  *
    120  * The second argument is how long, in seconds, to wait for a response.
    121  *
    122  * Returns SCF_COMPLETE on timeout, -1 on error, and SCF_SUCCESS in every
    123  * other case.  You must call scf_pg_update() to see if the object has
    124  * actually changed.
    125  */
    126 int _scf_pg_wait(scf_propertygroup_t *, int);
    127 
    128 /*
    129  * set up notifications for changes to a class of property groups (by name
    130  * and type)
    131  *
    132  * Only one thread can be sleeping in _scf_notify_wait() -- others will
    133  * fail.  Deletions give an fmri in the output path.
    134  *
    135  * These do not survive unbind()->bind() -- in fact, that is currently the
    136  * only way to clear them.
    137  */
    138 int _scf_notify_add_pgname(scf_handle_t *, const char *);
    139 int _scf_notify_add_pgtype(scf_handle_t *, const char *);
    140 int _scf_notify_wait(scf_propertygroup_t *, char *, size_t);
    141 
    142 /*
    143  * Internal interfaces for snapshot creation:
    144  *	_scf_snapshot_take_new(), _scf_snapshot_take_new_named(), and
    145  *	_scf_snapshot_take_attach() create a set of snaplevels
    146  *	containing frozen versions of both the instance's property groups and
    147  *	its parent service's property groups. _scf_snapshot_take_new() and
    148  *	_scf_snapshot_take_new_named() create a new snapshot to which the
    149  *	new snaplevels are attached, while _scf_snapshot_take_attach()
    150  *	attaches the new snaplevels to a pre-existing snapshot.
    151  *
    152  *	_scf_snapshot_take_new_named() records the passed in names into the
    153  *	snaplevel instead of the instance and service name.  This creates
    154  *	an inconsistency, which should be resolved by using
    155  *	_scf_snapshot_attach() to attach the new snaplevels to a snapshot
    156  *	underneath the appropriate instance.  The first snapshot can
    157  *	then be deleted.
    158  *
    159  *	_scf_snapshot_attach(snap1, snap2) points snap2 at the snaplevels
    160  *	pointed to by snap1.  After a call to either
    161  *	_scf_snapshot_take_attach(snap1, snap2) or
    162  *	_scf_snapshot_attach(inst, snap), scf_snapshot_update() will be
    163  *	required for any open references to snap or snap2 to see the new
    164  *	snaplevels.
    165  *
    166  *	_scf_snapshot_delete() deletes the snapshot object.  While
    167  *	snaplevels, being only loosely connected to snapshots, stay
    168  *	around until they are no longer referenced, any references *through
    169  *	this snapshot object* will be invalidated.
    170  *
    171  * _scf_snapshot_take_new() can fail with at least _HANDLE_MISMATCH,
    172  * _CONNECTION_BROKEN, _INVALID_ARGUMENT, _NO_RESOURCES, _PERMISSION_DENIED,
    173  * _NOT_SET, _EXISTS.
    174  *
    175  * _scf_snapshot_take_new_named() can fail with at least _HANDLE_MISMATCH,
    176  * _CONNECTION_BROKEN, _INVALID_ARGUMENT, _NO_RESOURCES, _PERMISSION_DENIED,
    177  * _NOT_SET, _EXISTS.
    178  *
    179  * _scf_snapshot_take_attach() can fail with _CONNECTION_BROKEN, _NOT_SET,
    180  * _PERMISSION_DENIED, _NO_RESOURCES, _INVALID_ARGUMENT.
    181  *
    182  * _scf_snapshot_attach() can fail with _HANDLE_MISMATCH, _CONNECTION_BROKEN,
    183  * _NOT_SET, _NO_RESOURCES, _PERMISSION_DENIED.
    184  */
    185 int _scf_snapshot_take_new(scf_instance_t *, const char *, scf_snapshot_t *);
    186 int _scf_snapshot_take_new_named(scf_instance_t *,
    187     const char *, const char *, const char *, scf_snapshot_t *);
    188 int _scf_snapshot_take_attach(scf_instance_t *, scf_snapshot_t *);
    189 int _scf_snapshot_attach(scf_snapshot_t *, scf_snapshot_t *);
    190 int _scf_snapshot_delete(scf_snapshot_t *);
    191 
    192 /*
    193  * Destructively portions up the first argument into the different portions
    194  * of a svc: fmri, and returns pointers to the applicable portions.  Omitted
    195  * portions are set to NULL, except for the scope, which is set to the
    196  * default local scope if not specified.
    197  *
    198  * Parsing is attempted in the order of: svc:, file:. The identified type
    199  * of the service is returned in the second argument and may take a value
    200  * of: SCF_FMRI_TYPE_SVC or SCF_FMRI_TYPE_FILE.
    201  *
    202  * Note that some of the returned pointers (in particular the scope) may not
    203  * point into the passed buffer.
    204  */
    205 int scf_parse_fmri(char *, int *, const char **, const char **, const char **,
    206     const char **, const char **);
    207 
    208 int scf_parse_svc_fmri(char *, const char **, const char **, const char **,
    209     const char **, const char **);
    210 
    211 int scf_parse_file_fmri(char *fmri, const char **scope, const char **path);
    212 
    213 ssize_t scf_canonify_fmri(const char *, char *, size_t);
    214 
    215 int _smf_refresh_instance_i(scf_instance_t *);
    216 
    217 typedef struct scf_simple_handle {
    218 	scf_handle_t		*h;
    219 	scf_snapshot_t		*snap;
    220 	scf_instance_t		*inst;
    221 	scf_propertygroup_t	*running_pg;
    222 	scf_propertygroup_t	*editing_pg;
    223 } scf_simple_handle_t;
    224 
    225 void scf_simple_handle_destroy(scf_simple_handle_t *);
    226 scf_simple_handle_t *scf_general_pg_setup(const char *, const char *);
    227 scf_transaction_t *scf_transaction_setup(scf_simple_handle_t *);
    228 int scf_transaction_restart(scf_simple_handle_t *, scf_transaction_t *);
    229 int scf_read_count_property(scf_simple_handle_t *, char *, uint64_t *);
    230 int scf_set_count_property(scf_transaction_t *, char *, uint64_t, boolean_t);
    231 
    232 /*
    233  * Walks all the instances matching a given fmri list.  Each fmri in the array
    234  * can be one of the following:
    235  *
    236  * 	- Full instance name
    237  * 	- Full service name
    238  * 	- Full property group or property name
    239  * 	- Partial service or instance name
    240  * 	- A globbed pattern
    241  *
    242  * The matching rules for partial fmris are a slightly more complex.  We allow
    243  * for any substring anchored at the end of the instance or service name,
    244  * provided it begins with a complete element in the fmri.  For example, given
    245  * the fmri "svc:/system/filesystem/local:default", any of the following would
    246  * be acceptable matches: 'default', 'local', 'local:default',
    247  * 'filesystem/local'.  The following would not be acceptable:
    248  * 'system/filesystem', 'filesystem/loc', 'system/local'.  Possible flag values:
    249  *
    250  * 	SCF_WALK_MULTIPLE	Allow individual arguments to correspond to
    251  * 				multiple instances.
    252  *
    253  * 	SCF_WALK_LEGACY		Walk legacy services (indicated by a non-NULL
    254  * 				propery group).
    255  *
    256  * 	SCF_WALK_SERVICE	If the user specifies a service, pass the
    257  * 				service to the callback without iterating over
    258  * 				its instances.
    259  *
    260  * 	SCF_WALK_PROPERTY	Allow FMRIs which match property groups or
    261  * 				individual properties.  Incompatible with
    262  * 				SCF_WALK_LEGACY.
    263  *
    264  * 	SCF_WALK_NOINSTANCE	Walk only services.  Must be used in
    265  * 				conjunction with SCF_WALK_SERVICE.
    266  *
    267  * 	SCF_WALK_EXPLICIT	Walk only services if the match is exact
    268  *				else return instances. Must be used in
    269  *				conjunction with SCF_WALK_SERVICE.
    270  *
    271  * If no arguments are given, then all instances in the service graph are
    272  * walked.
    273  *
    274  * The second to last parameter is set to UU_EXIT_FATAL if one of the arguments
    275  * is an invalid FMRI or matches multiple FMRIs when SCF_WALK_MULTIPLE is not
    276  * set.
    277  *
    278  * The last parameter is a user-supplied error function that is called when
    279  * reporting invalid arguments.
    280  */
    281 
    282 #define	SCF_WALK_MULTIPLE	0x01
    283 #define	SCF_WALK_LEGACY		0x02
    284 #define	SCF_WALK_SERVICE	0x04
    285 #define	SCF_WALK_PROPERTY	0x08
    286 #define	SCF_WALK_NOINSTANCE	0x10
    287 #define	SCF_WALK_EXPLICIT	0x20
    288 
    289 /*
    290  * The default locations of the repository dbs
    291  */
    292 #define	REPOSITORY_DB		"/etc/svc/repository.db"
    293 #define	NONPERSIST_DB		"/etc/svc/volatile/svc_nonpersist.db"
    294 #define	FAST_REPOSITORY_DB	"/etc/svc/volatile/fast_repository.db"
    295 
    296 
    297 typedef struct scf_walkinfo {
    298 	const char		*fmri;
    299 	scf_scope_t		*scope;
    300 	scf_service_t		*svc;
    301 	scf_instance_t		*inst;
    302 	scf_propertygroup_t	*pg;
    303 	scf_property_t		*prop;
    304 	int			count;	/* svcprop special */
    305 } scf_walkinfo_t;
    306 
    307 typedef int (*scf_walk_callback)(void *, scf_walkinfo_t *);
    308 
    309 scf_error_t scf_walk_fmri(scf_handle_t *, int, char **, int,
    310     scf_walk_callback, void *, int *, void (*)(const char *, ...));
    311 
    312 /*
    313  * Requests a backup of the repository with a particular name, which
    314  * can be any alphabetic string.  Only privileged users can do this.
    315  *
    316  * Can fail with:
    317  *	_NOT_BOUND, _CONNECTION_BROKEN, _PERMISSION_DENIED, _INVALID_ARGUMENT,
    318  *	_INTERNAL (path too long, or the backup failed for an odd reason),
    319  *	_BACKEND_READONLY (filesystem is still read-only)
    320  */
    321 int _scf_request_backup(scf_handle_t *, const char *);
    322 
    323 /*
    324  * Repository switch client
    325  */
    326 int _scf_repository_switch(scf_handle_t *, int);
    327 
    328 /*
    329  * Determines whether a property group requires authorization to read; this
    330  * does not in any way reflect whether the caller has that authorization.
    331  * To determine that, the caller must attempt to read the value of one of the
    332  * group's properties.
    333  *
    334  * Can fail with:
    335  *	_NOT_BOUND, _CONNECTION_BROKEN, _INVALID_ARGUMENT, _INTERNAL,
    336  *	_NO_RESOURCES, _CONSTRAINT_VIOLATED, _DELETED.
    337  */
    338 int _scf_pg_is_read_protected(const scf_propertygroup_t *, boolean_t *);
    339 
    340 /*
    341  * Sets annotation data for SMF audit logging.  Once this function has been
    342  * set, the next audit record will be preceded by an ADT_smf_annotation
    343  * with the information provided in this function.  This function is used
    344  * to mark operations which comprise multiple primitive operations such as
    345  * svccfg import.
    346  */
    347 int _scf_set_annotation(scf_handle_t *h, const char *operation,
    348     const char *file);
    349 
    350 /*
    351  * scf_pattern_t
    352  */
    353 typedef struct scf_pattern {
    354 	enum	{
    355 		PATTERN_INVALID,	/* Uninitialized state */
    356 		PATTERN_EXACT,
    357 		PATTERN_GLOB,
    358 		PATTERN_PARTIAL
    359 	} sp_type;
    360 	char			*sp_arg;	/* Original argument */
    361 	struct scf_match	*sp_matches;	/* List of matches */
    362 	int			sp_matchcount;	/* # of matches */
    363 } scf_pattern_t;
    364 
    365 int scf_cmp_pattern(char *, scf_pattern_t *);
    366 
    367 int gen_filenms_from_fmri(const char *, const char *, char *, char *);
    368 
    369 /*
    370  * Interfaces for bulk access to SMF-stored configuration.
    371  *
    372  * Each scf_propvec_t represents a single property to be read (with
    373  * scf_read_propvec) or written (with scf_write_propvec).
    374  *
    375  * The fields of a scf_propvec_t have the following meanings:
    376  *
    377  *   pv_prop - the name of the property
    378  *   pv_desc - a description string (optional; to be consumed by the caller)
    379  *   pv_type - the type of the property
    380  *   pv_ptr  - where to store the data read, or a pointer to the data to
    381  *             be written
    382  *   pv_aux  - additional data influencing the interpretation of pv_ptr
    383  *
    384  * The meaning of pv_ptr and pv_aux depends on the type of property.  For:
    385  *
    386  *   boolean - if pv_aux is 0, pv_ptr is a pointer to a boolean_t
    387  *             if pv_aux is non-0, pv_ptr is a pointer to a uint64_t,
    388  *             where pv_aux indicates the bit holding the truth value.
    389  *   count   - pv_ptr is a pointer to a uint64_t; pv_aux is unused
    390  *   integer - pv_ptr is a pointer to an int64_t; pv_aux is unused
    391  *   time    - pv_ptr is a pointer to an scf_time_t; pv_aux is unused
    392  *   opaque  - pv_ptr is a pointer to an scf_opaque_t; pv_aux is unused
    393  *   strings - (scf_read_propvec) pv_ptr is a pointer to a char *
    394  *             (scf_write_propvec) pv_ptr is a pointer to an array of char
    395  *             (both) pv_aux is unused
    396  */
    397 typedef struct {
    398 	void	*so_addr;
    399 	size_t	so_size;
    400 } scf_opaque_t;
    401 
    402 typedef struct {
    403 	const char	*pv_prop;
    404 	const char	*pv_desc;
    405 	scf_type_t	pv_type;
    406 	void		*pv_ptr;
    407 	uint64_t	pv_aux;
    408 } scf_propvec_t;
    409 
    410 void scf_clean_propvec(scf_propvec_t *);
    411 int scf_read_propvec(const char *, const char *, boolean_t, scf_propvec_t *,
    412     scf_propvec_t **);
    413 int scf_write_propvec(const char *, const char *, scf_propvec_t *,
    414     scf_propvec_t **);
    415 
    416 scf_tmpl_errors_t *_scf_create_errors(const char *, int);
    417 int _scf_tmpl_add_error(scf_tmpl_errors_t *errs, scf_tmpl_error_type_t type,
    418     const char *pg_name, const char *prop_name,
    419     const char *ev1, const char *ev2, const char *actual,
    420     const char *tmpl_fmri, const char *tmpl_pg_name, const char *tmpl_pg_type,
    421     const char *tmpl_prop_name, const char *tmpl_prop_type);
    422 int _scf_tmpl_error_set_prefix(scf_tmpl_errors_t *, const char *);
    423 
    424 /*
    425  * Templates definitions
    426  */
    427 
    428 /*
    429  * For CARDINALITY_VIOLATION and RANGE_VIOLATION, te_ev1 holds
    430  * the min value and te_ev2 holds the max value
    431  *
    432  * For MISSING_PG te_ev1 should hold the expected pg_name and
    433  * expected2 holds the expected pg_type.
    434  *
    435  * For SCF_TERR_PG_PATTERN_CONFLICT and SCF_TERR_GENERAL_REDEFINE te_ev1 is
    436  * the FMRI holding the conflicting pg_pattern.  te_ev2 is the name of the
    437  * conflicting pg_pattern, and actual is the type of the conflicting
    438  * pg_pattern.
    439  *
    440  * SCF_TERR_PROP_PATTERN_CONFLICT te_ev1 is the FMRI holding the
    441  * conflicting prop_pattern.  te_ev2 is the name of the conflicting
    442  * prop_pattern, and actual is the type of the conflicting prop_pattern.
    443  *
    444  * For SCF_TERR_INCLUDE_VALUES te_ev1 is the type specified for the
    445  * include_values element.
    446  *
    447  * For all other errors, te_ev1 should hold the expected value and
    448  * te_ev2 is ignored
    449  *
    450  * te_actual holds the current value of the property
    451  */
    452 
    453 struct scf_tmpl_error {
    454 	scf_tmpl_errors_t		*te_errs;
    455 	scf_tmpl_error_type_t		te_type;
    456 	const char			*te_pg_name;
    457 	const char			*te_prop_name;
    458 	const char			*te_ev1;
    459 	const char			*te_ev2;
    460 	const char			*te_actual;
    461 	const char			*te_tmpl_fmri;
    462 	const char			*te_tmpl_pg_name;
    463 	const char			*te_tmpl_pg_type;
    464 	const char			*te_tmpl_prop_name;
    465 	const char			*te_tmpl_prop_type;
    466 };
    467 
    468 /*
    469  * The pg_pattern element has two optional attributes that play a part in
    470  * selecting the appropriate prefix for the name of the pg_pattern property
    471  * group. The two attributes are name and type.  The appropriate prefix
    472  * encodes the presence are absence of these attributes.
    473  *
    474  *	SCF_PG_TM_PG_PATTERN_PREFIX	neither attribute
    475  *	SCF_PG_TM_PG_PATTERN_N_PREFIX	name only
    476  *	SCF_PG_TM_PG_PATTERN_T_PREFIX	type only
    477  *	SCF_PG_TM_PG_PATTERN_NT_PREFIX	both name and type
    478  */
    479 #define	SCF_PG_TM_PG_PAT_BASE		"tm_pgpat"
    480 #define	SCF_PG_TM_PG_PATTERN_PREFIX	((const char *)SCF_PG_TM_PG_PAT_BASE \
    481 	"_")
    482 #define	SCF_PG_TM_PG_PATTERN_N_PREFIX	((const char *)SCF_PG_TM_PG_PAT_BASE \
    483 	"n_")
    484 #define	SCF_PG_TM_PG_PATTERN_T_PREFIX	((const char *)SCF_PG_TM_PG_PAT_BASE \
    485 	"t_")
    486 #define	SCF_PG_TM_PG_PATTERN_NT_PREFIX	((const char *)SCF_PG_TM_PG_PAT_BASE \
    487 	"nt_")
    488 #define	SCF_PG_TM_PROP_PATTERN_PREFIX	((const char *)"tm_proppat_")
    489 
    490 /*
    491  * Pad character to use when encoding strings for property names.
    492  */
    493 #define	SCF_ENCODE32_PAD		('-')
    494 
    495 /*
    496  * Functions for base 32 encoding/decoding
    497  */
    498 int scf_decode32(const char *, size_t, char *, size_t, size_t *, char);
    499 int scf_encode32(const char *, size_t, char *, size_t, size_t *, char);
    500 
    501 /*
    502  * handy functions
    503  */
    504 /*
    505  * _scf_sanitize_locale
    506  * Make sure a locale string has only alpha-numeric or '_' characters
    507  */
    508 void _scf_sanitize_locale(char *);
    509 
    510 /*
    511  * _scf_read_tmpl_prop_type_as_string()
    512  * Handy function to get template property type as a string
    513  */
    514 char *_scf_read_tmpl_prop_type_as_string(const scf_prop_tmpl_t *);
    515 /*
    516  * _scf_read_single_astring_from_pg()
    517  * Given a property group (pg) and a property name (pn), this function
    518  * retrives an astring value from pg/pn.
    519  */
    520 char *_scf_read_single_astring_from_pg(scf_propertygroup_t *, const char *);
    521 
    522 /*
    523  * scf_instance_delete_prop()
    524  * Given instance, property group, and property, delete the property.
    525  */
    526 int
    527 scf_instance_delete_prop(scf_instance_t *, const char *, const char *);
    528 
    529 /*
    530  * Functions to extract boot config information from FMRI_BOOT_CONFIG
    531  */
    532 void scf_get_boot_config(uint8_t *);
    533 void scf_get_boot_config_ovr(uint8_t *);
    534 int scf_is_fastboot_default(void);
    535 
    536 /*
    537  * Set value of "config_ovr/fastreboot_default".
    538  */
    539 int scf_fastreboot_default_set_transient(boolean_t);
    540 
    541 /*
    542  * scf_is_compatible_type()
    543  * Return true if the second type is the same type, or a subtype of the
    544  * first.
    545  */
    546 int scf_is_compatible_type(scf_type_t, scf_type_t);
    547 
    548 #ifdef	__cplusplus
    549 }
    550 #endif
    551 
    552 #endif	/* _LIBSCF_PRIV_H */
    553