static scf_propertygroup_t * add_property_group_to_instance(scf_handle_t *handle, scf_instance_t *instance, const char *pg_name, const char *pg_type) { scf_propertygroup_t *pg; pg = scf_pg_create(handle); if (pg == NULL) { KSSL_DEBUG("scf_pg_create failed: %s\n", scf_strerror(scf_error())); (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (NULL); } if (scf_instance_add_pg(instance, pg_name, pg_type, 0, pg) != 0) { KSSL_DEBUG("ERROR: scf_instance_add_pg failed: %s\n", scf_strerror(scf_error())); if (scf_error() == SCF_ERROR_EXISTS) (void) fprintf(stderr, gettext( "Error: another process is modifying this instance." " Exiting.\n")); else (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); scf_pg_destroy(pg); return (NULL); } else { KSSL_DEBUG("property group created\n"); } return (pg); }
static void repository_notify_setup(scf_handle_t *h) { for (;;) { if (_scf_notify_add_pgtype(h, SCF_GROUP_FRAMEWORK) == SCF_SUCCESS) break; switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: repository_rebind(h); break; case SCF_ERROR_NO_RESOURCES: (void) sleep(1); break; default: syslog(LOG_ERR | LOG_DAEMON, "Abort: Couldn't set up repository notification " "for pg type %s: %s\n", SCF_GROUP_FRAMEWORK, scf_strerror(scf_error())); abort(); } } }
/* * retrieve_inetd_hash retrieves inetd's configuration file hash from the * repository. On success, hash is modified to point to the hash string and * SCF_ERROR_NONE is returned. Otherwise, the scf_error value is returned. * The space for the hash string is obtained using malloc(3C) and should be * freed by the caller. */ scf_error_t retrieve_inetd_hash(char **hash) { scf_simple_prop_t *sp; char *hashstr, *s; scf_error_t scf_err; if ((sp = scf_simple_prop_get(NULL, INETD_INSTANCE_FMRI, HASH_PG, HASH_PROP)) == NULL) return (scf_error()); if ((hashstr = scf_simple_prop_next_astring(sp)) == NULL) { scf_err = scf_error(); scf_simple_prop_free(sp); return (scf_err); } if ((s = strdup(hashstr)) == NULL) { scf_simple_prop_free(sp); return (SCF_ERROR_NO_MEMORY); } *hash = s; scf_simple_prop_free(sp); return (SCF_ERROR_NONE); }
static void delete_prop(const scf_instance_t *inst, const char *pg, const char *prop) { scf_transaction_t *tx; scf_transaction_entry_t *ent; scf_propertygroup_t *gpg; scf_property_t *eprop; int ret; if ((gpg = scf_pg_create(h)) == NULL || (eprop = scf_property_create(h)) == NULL || (tx = scf_transaction_create(h)) == NULL || (ent = scf_entry_create(h)) == NULL) scfdie(); if (scf_instance_get_pg(inst, pg, gpg) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); uu_die(gettext("Error: \"%s\" property group missing.\n"), pg); } do { if (scf_transaction_start(tx, gpg) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } if (scf_transaction_property_delete(tx, ent, prop) != SCF_SUCCESS) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); uu_die( gettext("Error: \"%s\" property does not exist.\n"), prop); } ret = scf_transaction_commit(tx); if (ret < 0) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } if (ret == 0) { scf_transaction_reset(tx); if (scf_pg_update(gpg) == -1) scfdie(); } } while (ret == 0); (void) scf_entry_destroy(ent); scf_transaction_destroy(tx); scf_property_destroy(eprop); scf_pg_destroy(gpg); }
/* * Determine whether a given instance is a RPC service. Repository and * libscf errors are treated as if the service isn't an RPC service, * returning B_FALSE to indicate validation failure. */ static boolean_t service_is_rpc(const scf_instance_t *inst) { scf_snapshot_t *lsnap = NULL; uint8_t isrpc; if (scf_instance_get_snapshot(inst, SCF_SNAPSHOT_RUNNING, snap) != 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Could not get running snapshot, using editing value\n"); } else { lsnap = snap; } if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_INETD, scratch_pg) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); return (B_FALSE); } if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_FW_CONTEXT, scratch_pg) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); } return (B_FALSE); } } if (pg_get_prop_value(scratch_pg, SCF_PROPERTY_ISRPC, scratch_v) == -1) return (B_FALSE); if (scf_value_get_boolean(scratch_v, &isrpc) == -1) { syslog(LOG_ERR | LOG_DAEMON, "scf_value_get_boolean failed: " "%s\n", scf_strerror(scf_error())); return (B_FALSE); } if (isrpc) return (B_TRUE); else return (B_FALSE); }
/* * Get FMRI for the named process. */ isc_result_t ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { scf_handle_t *h = NULL; int namelen; char *instance; REQUIRE(ins_name != NULL && *ins_name == NULL); if ((h = scf_handle_create(SCF_VERSION)) == NULL) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_handle_create() failed: %s", scf_strerror(scf_error())); return (ISC_R_FAILURE); } if (scf_handle_bind(h) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_handle_bind() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); return (ISC_R_FAILURE); } if ((namelen = scf_myname(h, NULL, 0)) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_myname() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); return (ISC_R_FAILURE); } if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { UNEXPECTED_ERROR(__FILE__, __LINE__, "ns_smf_get_instance memory " "allocation failed: %s", isc_result_totext(ISC_R_NOMEMORY)); scf_handle_destroy(h); return (ISC_R_FAILURE); } if (scf_myname(h, instance, namelen + 1) == -1) { if (debug) UNEXPECTED_ERROR(__FILE__, __LINE__, "scf_myname() failed: %s", scf_strerror(scf_error())); scf_handle_destroy(h); isc_mem_free(mctx, instance); return (ISC_R_FAILURE); } scf_handle_destroy(h); *ins_name = instance; return (ISC_R_SUCCESS); }
/* * smb_smf_scf_log_error(msg) * Logs error messages from scf API's */ static void smb_smf_scf_log_error(char *msg) { if (!msg) { syslog(LOG_ERR, " SMBC SMF problem: %s\n", scf_strerror(scf_error())); } else { /*LINTED E_SEC_PRINTF_E_VAR_FMT*/ syslog(LOG_ERR, msg, scf_strerror(scf_error())); } }
static int add_new_property(scf_handle_t *handle, const char *prop_name, scf_type_t type, const char *val, scf_transaction_t *tx) { scf_value_t *value = NULL; scf_transaction_entry_t *entry = NULL; int status = FAILURE; entry = scf_entry_create(handle); if (entry == NULL) { KSSL_DEBUG("scf_entry_create failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_entry_create succeeded\n"); value = scf_value_create(handle); if (value == NULL) { goto out; } KSSL_DEBUG("scf_value_create succeeded\n"); if (scf_transaction_property_new(tx, entry, prop_name, type) != 0) { goto out; } KSSL_DEBUG("scf_transaction_property_new succeeded\n"); if (scf_value_set_from_string(value, type, val) != 0) { goto out; } KSSL_DEBUG("scf_value_set_from_string \'%s\' succeeded\n", val); if (scf_entry_add_value(entry, value) != 0) { KSSL_DEBUG( "scf_entry_add_value failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_entry_add_value succeeded\n"); status = SUCCESS; out: if (status != SUCCESS) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
/* * Inputs: * lpg is the property group to look up * lprop is the property within that group to look up * Outputs: * answer is a pointer to the property value * Returns: * 0 on success * -1 on failure * If successful, the property value is retured in *answer. * Otherwise, *answer is undefined, and it is up to the caller to decide * how to handle that case. */ int lookup_boolean_property(const char *lpg, const char *lprop, boolean_t *answer) { int result = -1; scf_resources_t res; uint8_t prop_val; if (get_property_value(lpg, lprop, &res) != 0) { /* * an error was already logged by get_property_value, * and it released any resources assigned to res before * returning. */ return (result); } if (scf_value_get_boolean(res.sr_val, &prop_val) != 0) { syslog(LOG_ERR, "scf_value_get_boolean() failed: %s", scf_strerror(scf_error())); goto cleanup; } *answer = (boolean_t)prop_val; dprintf("lookup_boolean_property(%s, %s) returns %s", lpg, lprop, *answer ? "TRUE" : "FALSE"); result = 0; cleanup: release_scf_resources(&res); return (result); }
/*ARGSUSED*/ JNIEXPORT void JNICALL Java_com_sun_dhcpmgr_bridge_Bridge_startup( JNIEnv *env, jobject obj) { char *s; int ret; /* * We first get the current state of the server according to * svc.startd; if it's "disabled", we can just enable it. * In any other case, we want to send a refresh so that * dependencies are re-evaluated, which will be the case if the * service was marked enabled by the profile, yet the * config file didn't exist to allow it to run. */ if ((s = smf_get_state(DHCP_SERVER_INST)) != NULL) { if (strcmp(SCF_STATE_STRING_DISABLED, s) == 0) ret = smf_enable_instance(DHCP_SERVER_INST, 0); else ret = smf_refresh_instance(DHCP_SERVER_INST); free(s); if (ret == 0) return; } /* Something wasn't right, return exception with error from smf */ throw_bridge_exception(env, scf_strerror(scf_error())); }
/* * Inputs: * lpg is the property group to look up * lprop is the property within that group to look up * Outputs: * answer is a pointer to the property value * Returns: * 0 on success * -1 on failure * If successful, the property value is retured in *answer. * Otherwise, *answer is undefined, and it is up to the caller to decide * how to handle that case. */ int lookup_count_property(const char *lpg, const char *lprop, uint64_t *answer) { int result = -1; scf_resources_t res; if (get_property_value(lpg, lprop, &res) != 0) { /* * an error was already logged by get_property_value, * and it released any resources assigned to res before * returning. */ return (result); } if (scf_value_get_count(res.sr_val, answer) != 0) { syslog(LOG_ERR, "scf_value_get_count() failed: %s", scf_strerror(scf_error())); goto cleanup; } dprintf("lookup_count_property(%s, %s) returns %lld", lpg, lprop, *answer); result = 0; cleanup: release_scf_resources(&res); return (result); }
/* * Return a snapshot for the supplied instance and snapshot name. */ static scf_snapshot_t * get_snapshot(const scf_instance_t *inst, const char *snapshot) { scf_snapshot_t *snap = scf_snapshot_create(hndl); if (snap == NULL) scfdie(); if (scf_instance_get_snapshot(inst, snapshot, snap) == -1) { switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: die(gettext("Invalid snapshot name.\n")); /* NOTREACHED */ case SCF_ERROR_NOT_FOUND: if (sflag == 0) { scf_snapshot_destroy(snap); snap = NULL; } else die(gettext("No such snapshot.\n")); break; default: scfdie(); } } return (snap); }
/* * Sets string property in current pg */ int smb_smf_set_string_property(smb_scfhandle_t *handle, char *propname, char *valstr) { int ret = SMBC_SMF_OK; scf_value_t *value = NULL; scf_transaction_entry_t *entry = NULL; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } /* * properties must be set in transactions and don't take * effect until the transaction has been ended/committed. */ value = scf_value_create(handle->scf_handle); entry = scf_entry_create(handle->scf_handle); if (value != NULL && entry != NULL) { if (scf_transaction_property_change(handle->scf_trans, entry, propname, SCF_TYPE_ASTRING) == 0 || scf_transaction_property_new(handle->scf_trans, entry, propname, SCF_TYPE_ASTRING) == 0) { if (scf_value_set_astring(value, valstr) == 0) { if (scf_entry_add_value(entry, value) != 0) { ret = SMBC_SMF_SYSTEM_ERR; scf_value_destroy(value); } /* the value is in the transaction */ value = NULL; } else { /* value couldn't be constructed */ ret = SMBC_SMF_SYSTEM_ERR; } /* the entry is in the transaction */ entry = NULL; } else { ret = SMBC_SMF_SYSTEM_ERR; } } else { ret = SMBC_SMF_SYSTEM_ERR; } if (ret == SMBC_SMF_SYSTEM_ERR) { switch (scf_error()) { case SCF_ERROR_PERMISSION_DENIED: ret = SMBC_SMF_NO_PERMISSION; break; } } /* * cleanup if there were any errors that didn't leave these * values where they would be cleaned up later. */ if (value != NULL) scf_value_destroy(value); if (entry != NULL) scf_entry_destroy(entry); return (ret); }
/* * Start transaction on current pg in handle. * The pg could be service or instance level. * Must be called after pg handle is obtained * from create or get. */ int smb_smf_start_transaction(smb_scfhandle_t *handle) { int ret = SMBD_SMF_OK; if (!handle || (!handle->scf_pg)) return (SMBD_SMF_SYSTEM_ERR); /* * lookup the property group and create it if it doesn't already * exist. */ if (handle->scf_state == SCH_STATE_INIT) { if (ret == SMBD_SMF_OK) { handle->scf_trans = scf_transaction_create(handle->scf_handle); if (handle->scf_trans != NULL) { if (scf_transaction_start(handle->scf_trans, handle->scf_pg) != 0) { ret = SMBD_SMF_SYSTEM_ERR; scf_transaction_destroy( handle->scf_trans); handle->scf_trans = NULL; } } else { ret = SMBD_SMF_SYSTEM_ERR; } } } if (ret == SMBD_SMF_SYSTEM_ERR && scf_error() == SCF_ERROR_PERMISSION_DENIED) ret = SMBD_SMF_NO_PERMISSION; return (ret); }
static int set_svc_enable_cb(void *data, scf_walkinfo_t *wip) { uint8_t desired = *(uint8_t *)data; const char *instname = wip->fmri; if (desired) { if (smf_enable_instance(instname, 0) == 0) return (0); } else { if (smf_disable_instance(instname, 0) == 0) return (0); } switch (scf_error()) { case SCF_ERROR_INVALID_ARGUMENT: uu_die(gettext("Error: \"%s\" is not a valid service " "instance.\n"), instname); break; case SCF_ERROR_NOT_FOUND: uu_die(gettext("Error: Service instance \"%s\" not found.\n"), instname); break; default: scfdie(); } return (0); }
/* * smb_smf_scf_log_error(msg) * Logs error messages from scf API's */ static void smb_smf_scf_log_error(char *msg) { if (msg == NULL) msg = "SMBD SMF problem"; syslog(LOG_ERR, " %s: %s", msg, scf_strerror(scf_error())); }
targ_scf_t * mgmt_handle_init(void) { targ_scf_t *h; h = calloc(1, sizeof (targ_scf_t)); if (h == NULL) return (NULL); h->t_handle = scf_handle_create(SCF_VERSION); if (h->t_handle != NULL) { if (scf_handle_bind(h->t_handle) == 0) { h->t_scope = scf_scope_create(h->t_handle); h->t_service = scf_service_create(h->t_handle); h->t_pg = scf_pg_create(h->t_handle); h->t_instance = scf_instance_create(h->t_handle); if (scf_handle_get_scope(h->t_handle, SCF_SCOPE_LOCAL, h->t_scope) == 0) { if (scf_scope_get_service(h->t_scope, SA_TARGET_SVC_NAME, h->t_service) != 0) goto error; } else { syslog(LOG_ERR, "Got local scope which is wrong\n"); goto error; } } else goto error; } else { free(h); h = NULL; syslog(LOG_ERR, "iscsitgt could not access SMF repository: %s\n", scf_strerror(scf_error())); } return (h); error: mgmt_handle_fini(h); free(h); syslog(LOG_ERR, "iscsitgt SMF initialization problem: %s\n", scf_strerror(scf_error())); return (NULL); }
/*ARGSUSED*/ JNIEXPORT void JNICALL Java_com_sun_dhcpmgr_bridge_Bridge_shutdown( JNIEnv *env, jobject obj) { if (smf_disable_instance(DHCP_SERVER_INST, 0) != 0) { throw_bridge_exception(env, scf_strerror(scf_error())); } }
static void * scf_exception(const char *err, const char *value) { int scferr = scf_error(); const char *scfstrerr = scf_strerror(scferr); PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value); PyErr_SetObject(scf_exc, obj); return (NULL); }
/* * smb_smf_delete_instance_pgroup(handle, pgroup) * * remove the property group from the current instance. * but only if it actually exists. */ int smb_smf_delete_instance_pgroup(smb_scfhandle_t *handle, char *pgroup) { int ret = SMBC_SMF_OK; int err; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } /* * only create a handle if it doesn't exist. It is ok to exist * since the pg handle will be set as a side effect. */ if (handle->scf_pg == NULL) { handle->scf_pg = scf_pg_create(handle->scf_handle); } /* * only delete if it does exist. */ if (scf_instance_get_pg(handle->scf_instance, pgroup, handle->scf_pg) == 0) { /* does exist so delete it */ if (scf_pg_delete(handle->scf_pg) != 0) { ret = SMBC_SMF_SYSTEM_ERR; err = scf_error(); if (err != SCF_ERROR_NONE) { smb_smf_scf_log_error("SMF delpg " "problem: %s\n"); } } } else { err = scf_error(); if (err != SCF_ERROR_NONE) smb_smf_scf_log_error("SMF getpg problem: %s\n"); ret = SMBC_SMF_SYSTEM_ERR; } if (ret == SMBC_SMF_SYSTEM_ERR && scf_error() == SCF_ERROR_PERMISSION_DENIED) { ret = SMBC_SMF_NO_PERMISSION; } return (ret); }
/* * Reads the value of the enabled property from the named property group * of the given instance. * If an error occurs, the SCF error code is returned. The possible errors are: * - SCF_ERROR_INVALID_ARGUMENT: The enabled property is not a boolean. * - SCF_ERROR_NONE: No value exists for the enabled property. * - SCF_ERROR_CONNECTION_BROKEN: Repository connection broken. * - SCF_ERROR_NOT_FOUND: The property wasn't found. * - SCF_ERROR_NO_MEMORY: allocation failure. * Else 0 is returned and 'enabled' set appropriately. */ static scf_error_t read_enable_prop(const char *fmri, boolean_t *enabled, const char *pg) { scf_simple_prop_t *sp; uint8_t *u8p; if ((sp = scf_simple_prop_get(rep_handle, fmri, pg, SCF_PROPERTY_ENABLED)) == NULL) return (scf_error()); if ((u8p = scf_simple_prop_next_boolean(sp)) == NULL) { scf_simple_prop_free(sp); return (scf_error()); } *enabled = (*u8p != 0); scf_simple_prop_free(sp); return (0); }
int main() { if (daemonize_self() == 1) return (1); max_scf_fmri_size = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1; max_scf_name_size = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; assert(max_scf_fmri_size > 0); assert(max_scf_name_size > 0); if ((h = scf_handle_create(SCF_VERSION)) == NULL) { syslog(LOG_ERR | LOG_DAEMON, "scf_handle_create failed: %s\n", scf_strerror(scf_error())); return (1); } repository_rebind(h); scratch_fmri = umem_alloc(max_scf_fmri_size, UMEM_DEFAULT); scratch_name = umem_alloc(max_scf_name_size, UMEM_DEFAULT); if (scratch_fmri == NULL || scratch_name == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Out of memory"); return (1); } inst = scf_instance_create(h); snap = scf_snapshot_create(h); scratch_pg = scf_pg_create(h); scratch_prop = scf_property_create(h); scratch_v = scf_value_create(h); if (inst == NULL || snap == NULL || scratch_pg == NULL || scratch_prop == NULL || scratch_v == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Initialization failed: %s\n", scf_strerror(scf_error())); return (1); } return (repository_event_wait()); }
/* * Returns an allocated instance_cfg_t representation of an instance's * configuration read from the repository. If the configuration is invalid, a * repository error occurred, or a memory allocation occurred returns NULL, * else returns a pointer to the allocated instance_cfg_t. */ instance_cfg_t * read_instance_cfg(const char *fmri) { uint_t retries; inetd_prop_t *bprops; inetd_prop_t *mprops[NUM_METHODS]; instance_cfg_t *ret = NULL; scf_error_t err; debug_msg("Entering read_instance_cfg"); if ((ret = calloc(1, sizeof (instance_cfg_t))) == NULL) return (NULL); for (retries = 0; retries <= REP_OP_RETRIES; retries++) { if (make_handle_bound(rep_handle) == -1) { err = scf_error(); goto read_error; } if (read_inst_props(fmri, &bprops, mprops, &err) == 0) break; if (err != SCF_ERROR_CONNECTION_BROKEN) goto read_error; (void) scf_handle_unbind(rep_handle); } if (retries > REP_OP_RETRIES) goto read_error; /* * Switch off validation of the start method's exec string, since * during boot the filesystem it resides on may not have been * mounted yet, which would result in a false validation failure. * We'll catch any real errors when the start method is first run * in passes_basic_exec_checks(). */ bprops[PT_EXEC_INDEX].ip_error = IVE_UNSET; if ((!valid_inst_props(fmri, bprops, mprops, &ret->basic)) || (populate_defaults(bprops, ret->basic) != 0) || (create_method_infos(fmri, mprops, ret->methods) != 0)) { destroy_instance_cfg(ret); ret = NULL; } destroy_inst_props(bprops, mprops); return (ret); read_error: error_msg(gettext( "Failed to read the configuration of instance %s: %s"), fmri, scf_strerror(err)); free(ret); return (NULL); }
static int get_notify_prefs(fmd_hdl_t *hdl, nvlist_t *ev_nvl, nvlist_t ***pref_nvl, uint_t *nprefs) { nvlist_t *top_nvl, **np_nvlarr, *mech_nvl; nvlist_t **tmparr; int ret, i; uint_t nelem, nslelem; if ((ret = smf_notify_get_params(&top_nvl, ev_nvl)) != SCF_SUCCESS) { ret = scf_error(); if (ret != SCF_ERROR_NOT_FOUND) { fmd_hdl_debug(hdl, "Error looking up notification " "preferences (%s)", scf_strerror(ret)); return (ret); } return (ret); } if (nvlist_lookup_nvlist_array(top_nvl, SCF_NOTIFY_PARAMS, &np_nvlarr, &nelem) != 0) { fmd_hdl_debug(hdl, "Malformed preference nvlist\n"); ret = SCF_ERROR_INVALID_ARGUMENT; goto pref_done; } tmparr = fmd_hdl_alloc(hdl, nelem * sizeof (nvlist_t *), FMD_SLEEP); nslelem = 0; for (i = 0; i < nelem; i++) { if (nvlist_lookup_nvlist(np_nvlarr[i], "syslog", &mech_nvl) == 0) tmparr[nslelem++] = fmd_nvl_dup(hdl, mech_nvl, FMD_SLEEP); } if (nslelem != 0) { size_t sz = nslelem * sizeof (nvlist_t *); *pref_nvl = fmd_hdl_zalloc(hdl, sz, FMD_SLEEP); *nprefs = nslelem; bcopy(tmparr, *pref_nvl, sz); ret = 0; } else { *pref_nvl = NULL; *nprefs = 0; ret = SCF_ERROR_NOT_FOUND; } fmd_hdl_free(hdl, tmparr, nelem * sizeof (nvlist_t *)); pref_done: nvlist_free(top_nvl); return (ret); }
/* * Returns a pointer to an allocated method context for the specified method * of the specified instance if it could retrieve it. Else, if there were * errors retrieving it, NULL is returned and the pointer referenced by * 'errstr' is set to point at an appropriate error string. */ struct method_context * read_method_context(const char *inst_fmri, const char *method, const char *path) { scf_instance_t *scf_inst = NULL; struct method_context *ret; uint_t retries; mc_error_t *tmperr; char *fail; fail = gettext("Failed to retrieve method context for the %s method of " "instance %s : %s"); for (retries = 0; retries <= REP_OP_RETRIES; retries++) { if (make_handle_bound(rep_handle) == -1) goto inst_failure; if (((scf_inst = scf_instance_create(rep_handle)) != NULL) && (scf_handle_decode_fmri(rep_handle, inst_fmri, NULL, NULL, scf_inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == 0)) break; if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) { scf_instance_destroy(scf_inst); goto inst_failure; } (void) scf_instance_destroy(scf_inst); scf_inst = NULL; (void) scf_handle_unbind(rep_handle); } if (retries > REP_OP_RETRIES) goto inst_failure; if ((tmperr = restarter_get_method_context( RESTARTER_METHOD_CONTEXT_VERSION, scf_inst, NULL, method, path, &ret)) != NULL) { ret = NULL; error_msg(fail, method, inst_fmri, tmperr->msg); restarter_mc_error_destroy(tmperr); } scf_instance_destroy(scf_inst); return (ret); inst_failure: /* * We can rely on this string not becoming invalid * since we don't call bind_textdomain_codeset() or * setlocale(3C) after initialization. */ error_msg(fail, method, inst_fmri, gettext("failed to get instance from repository")); return (NULL); }
/* * Reads the enabled value for the given instance FMRI. The read value * is based on a merge of the 'standard' enabled property, and the temporary * override one; the merge involves using the latter properties value if * present, else resporting to the formers. If an error occurs -1 is returned, * else 0 is returned and 'enabled' set approriately. */ int read_enable_merged(const char *fmri, boolean_t *enabled) { uint_t retries; debug_msg("Entering read_enabled_prop: inst: %s", fmri); for (retries = 0; retries <= REP_OP_RETRIES; retries++) { if (make_handle_bound(rep_handle) == -1) goto gen_fail; switch (read_enable_prop(fmri, enabled, SCF_PG_GENERAL_OVR)) { case 0: debug_msg("read %d from override", *enabled); return (0); case SCF_ERROR_CONNECTION_BROKEN: break; case SCF_ERROR_NOT_FOUND: case SCF_ERROR_NONE: case SCF_ERROR_INVALID_ARGUMENT: switch (read_enable_prop(fmri, enabled, SCF_PG_GENERAL)) { case 0: debug_msg("read %d from non_override", *enabled); return (0); case SCF_ERROR_CONNECTION_BROKEN: break; case SCF_ERROR_NOT_FOUND: case SCF_ERROR_NONE: case SCF_ERROR_INVALID_ARGUMENT: error_msg(gettext("Missing %s property/value " "for instance %s"), SCF_PROPERTY_ENABLED, fmri); return (-1); default: goto gen_fail; } break; default: goto gen_fail; } (void) scf_handle_unbind(rep_handle); continue; } gen_fail: error_msg(gettext("Failed to read the %s property of instance %s: %s"), SCF_PROPERTY_ENABLED, fmri, scf_strerror(scf_error())); return (-1); }
/* * This function starts a transaction with name of a property group * and name of its property. If the property group does not exist * this function will create an empty property group. */ Boolean_t mgmt_transaction_start(targ_scf_t *h, char *pg, char *prop) { Boolean_t ret = True; h->t_trans = scf_transaction_create(h->t_handle); if (h->t_trans != NULL) { if ((create_pg(h, pg, prop) == False) || (scf_transaction_start(h->t_trans, h->t_pg) != 0)) { scf_transaction_destroy(h->t_trans); h->t_trans = NULL; ret = False; syslog(LOG_ERR, "transaction_start start: %s\n", scf_strerror(scf_error())); } } else { syslog(LOG_ERR, "transaction_start create: %s\n", scf_strerror(scf_error())); ret = False; } return (ret); }
static void * get_smf_prop(const char *var, char type, void *def_val) { scf_simple_prop_t *prop; void *val; char *me = "get_smf_prop"; prop = scf_simple_prop_get(NULL, NULL, "config", var); if (prop) { switch (type) { case 'b': val = scf_simple_prop_next_boolean(prop); if (val != NULL) (void) memcpy(def_val, val, sizeof (uint8_t)); break; case 'i': val = scf_simple_prop_next_integer(prop); if (val != NULL) (void) memcpy(def_val, val, sizeof (int64_t)); break; } scf_simple_prop_free(prop); } if (prop == NULL || val == NULL) { char vs[64]; switch (type) { case 'b': if (*(uint8_t *)def_val) (void) strcpy(vs, "yes"); else (void) strcpy(vs, "no"); break; case 'i': (void) sprintf(vs, "%lld", *(int64_t *)def_val); break; } _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_ALERT) (me, "no value for config/%s (%s). " "Using default \"%s\"\n", var, scf_strerror(scf_error()), vs); } return (def_val); }
static int pg_get_prop_value(const scf_propertygroup_t *pg, const char *pname, scf_value_t *v) { if (pg == NULL || pname == NULL || v == NULL) return (-1); if (scf_pg_get_property(pg, pname, scratch_prop) == -1 || scf_property_get_value(scratch_prop, v) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_property failed for %s: %s\n", pname, scf_strerror(scf_error())); } return (-1); } return (0); }
/* * Refresh the value of debug property under the property group "config" * for network/inetd service. */ void refresh_debug_flag(void) { scf_simple_prop_t *sprop; uint8_t *tmp_bool; if ((sprop = scf_simple_prop_get(rep_handle, INETD_INSTANCE_FMRI, PG_NAME_APPLICATION_CONFIG, PR_NAME_DEBUG_FLAG)) == NULL) { error_msg(gettext("Unable to read %s property from %s property " "group. scf_simple_prop_get() failed: %s"), PR_NAME_DEBUG_FLAG, PG_NAME_APPLICATION_CONFIG, scf_strerror(scf_error())); return; } else if ((tmp_bool = scf_simple_prop_next_boolean(sprop)) == NULL) { error_msg(gettext("Unable to read %s property for %s service. " "scf_simple_prop_next_boolean() failed: %s"), PR_NAME_DEBUG_FLAG, INETD_INSTANCE_FMRI, scf_strerror(scf_error())); } else { debug_enabled = ((*tmp_bool == 0) ? B_FALSE : B_TRUE); } scf_simple_prop_free(sprop); }