void mgmt_handle_fini(targ_scf_t *h) { if (h != NULL) { int unbind = 0; if (h->t_scope != NULL) { unbind = 1; scf_scope_destroy(h->t_scope); h->t_scope = NULL; } if (h->t_instance != NULL) { scf_instance_destroy(h->t_instance); h->t_instance = NULL; } if (h->t_service != NULL) { scf_service_destroy(h->t_service); h->t_service = NULL; } if (h->t_pg != NULL) { scf_pg_destroy(h->t_pg); h->t_pg = NULL; } if (h->t_handle != NULL) { if (unbind) (void) scf_handle_unbind(h->t_handle); scf_handle_destroy(h->t_handle); h->t_handle = NULL; } free(h); h = NULL; } }
/* * smb_smf_scf_fini(handle) * * must be called when done. Called with the handle allocated in * smb_smf_scf_init(), it cleans up the state and frees any SCF resources * still in use. */ void smb_smf_scf_fini(smb_scfhandle_t *handle) { if (handle != NULL) { int unbind = 0; scf_iter_destroy(handle->scf_pg_iter); handle->scf_pg_iter = NULL; scf_iter_destroy(handle->scf_inst_iter); handle->scf_inst_iter = NULL; unbind = 1; scf_scope_destroy(handle->scf_scope); handle->scf_scope = NULL; scf_instance_destroy(handle->scf_instance); handle->scf_instance = NULL; scf_service_destroy(handle->scf_service); handle->scf_service = NULL; scf_pg_destroy(handle->scf_pg); handle->scf_pg = NULL; handle->scf_state = SCH_STATE_UNINIT; if (unbind) (void) scf_handle_unbind(handle->scf_handle); scf_handle_destroy(handle->scf_handle); handle->scf_handle = NULL; free(handle); } }
/* * 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); }
/* * Inputs: * res is a pointer to the scf_resources_t to be released. */ static void release_scf_resources(scf_resources_t *res) { scf_value_destroy(res->sr_val); scf_property_destroy(res->sr_prop); scf_pg_destroy(res->sr_pg); scf_snapshot_destroy(res->sr_snap); scf_instance_destroy(res->sr_inst); (void) scf_handle_unbind(res->sr_handle); scf_handle_destroy(res->sr_handle); }
/* * 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); }
void config_fini(void) { if (rep_handle == NULL) return; if (proto_info_pool != NULL) { uu_list_pool_destroy(proto_info_pool); proto_info_pool = NULL; } (void) scf_handle_unbind(rep_handle); scf_handle_destroy(rep_handle); rep_handle = NULL; }
void fs_smf_fini(fs_smfhandle_t *handle) { if (handle != NULL) { scf_scope_destroy(handle->fs_scope); scf_instance_destroy(handle->fs_instance); scf_service_destroy(handle->fs_service); scf_pg_destroy(handle->fs_pg); scf_property_destroy(handle->fs_property); scf_value_destroy(handle->fs_value); if (handle->fs_handle != NULL) { scf_handle_unbind(handle->fs_handle); scf_handle_destroy(handle->fs_handle); } free(handle); } }
static void repository_rebind(scf_handle_t *hndl) { int c = 0; (void) scf_handle_unbind(hndl); while ((scf_handle_bind(hndl)) != 0) { if (c > MAX_RETRY) { syslog(LOG_ERR | LOG_DAEMON, "Repository access " "unavailable. Couldn't bind handle: %s\n", scf_strerror(scf_error())); syslog(LOG_ERR | LOG_DAEMON, "Service specific" "IPfilter configuration may not be updated " "properly\n"); exit(1); } else { c++; } (void) sleep(1); } }
static int create_service(const char *instance_name, const char *kssl_entry, const char *command, const char *username, char *inaddr_any_name) { int status = FAILURE; scf_scope_t *scope; scf_service_t *svc; scf_handle_t *handle; boolean_t errflag = B_TRUE; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) { KSSL_DEBUG("scf_handle_create failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_create succeeded\n"); if (scf_handle_bind(handle) == -1) { KSSL_DEBUG("scf_handle_bind failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_bind succeeded\n"); if ((scope = scf_scope_create(handle)) == NULL) { KSSL_DEBUG("scf_scope_create failed: %s\n", scf_strerror(scf_error())); goto out2; } KSSL_DEBUG("scf_scope_create succeeded\n"); if ((svc = scf_service_create(handle)) == NULL) { KSSL_DEBUG("scf_service_create failed: %s\n", scf_strerror(scf_error())); goto out3; } KSSL_DEBUG("scf_service_create succeeded\n"); if (scf_handle_decode_fmri(handle, SERVICE_NAME, NULL, svc, NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0) { KSSL_DEBUG("scf_handle_decode_fmri failed: %s\n", scf_strerror(scf_error())); if (scf_error() == SCF_ERROR_NOT_FOUND) { (void) fprintf(stderr, gettext( "service %s not found in the repository." " Exiting.\n"), SERVICE_NAME); errflag = B_FALSE; } goto out4; } status = create_instance(handle, svc, instance_name, kssl_entry, command, username, inaddr_any_name); out4: scf_service_destroy(svc); out3: scf_scope_destroy(scope); out2: (void) scf_handle_unbind(handle); out1: if (handle != NULL) scf_handle_destroy(handle); if (status != SUCCESS && status != INSTANCE_OTHER_EXISTS && status != INSTANCE_ANY_EXISTS && errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
int delete_instance(const char *instance_name) { int status = FAILURE; char *buf; boolean_t errflag = B_FALSE; ssize_t max_fmri_len; scf_scope_t *scope; scf_service_t *svc; scf_handle_t *handle; scf_instance_t *instance; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_create failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_create succeeded\n"); if (scf_handle_bind(handle) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_bind failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_bind succeeded\n"); if ((scope = scf_scope_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_scope_create failed: %s\n", scf_strerror(scf_error())); goto out2; } KSSL_DEBUG("scf_scope_create succeeded\n"); if ((svc = scf_service_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_service_create failed: %s\n", scf_strerror(scf_error())); goto out3; } KSSL_DEBUG("scf_service_create succeeded\n"); if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_get_scope failed: %s\n", scf_strerror(scf_error())); goto out4; } KSSL_DEBUG("scf_handle_get_scope succeeded\n"); if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum != SCF_ERROR_NOT_FOUND) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } goto out4; } else { KSSL_DEBUG("scf_scope_get_service succeeded\n"); } instance = scf_instance_create(handle); if (instance == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_instance_create failed: %s\n", scf_strerror(scf_error())); goto out4; } if (scf_service_get_instance(svc, instance_name, instance) != 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum == SCF_ERROR_NOT_FOUND) { status = SUCCESS; } else { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } scf_instance_destroy(instance); goto out4; } max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((buf = malloc(max_fmri_len + 1)) == NULL) goto out4; if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { char *state; KSSL_DEBUG("instance_fmri=%s\n", buf); state = smf_get_state(buf); if (state) KSSL_DEBUG("state=%s\n", state); if (state && strcmp(state, "online") == 0) { if (smf_disable_instance(buf, 0) != 0) { errflag = B_TRUE; KSSL_DEBUG( "smf_disable_instance failed: %s\n", scf_strerror(scf_error())); } else { /* * Wait for some time till timeout to avoid * a race with scf_instance_delete() below. */ wait_till_to(buf); } } } if (scf_instance_delete(instance) != 0) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_instance_delete failed: %s\n", scf_strerror(scf_error())); goto out4; } else { KSSL_DEBUG("deleted %s\n", instance_name); } status = SUCCESS; out4: scf_service_destroy(svc); out3: scf_scope_destroy(scope); out2: (void) scf_handle_unbind(handle); out1: if (handle != NULL) scf_handle_destroy(handle); if (errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
int main(int argc, char *argv[]) { int opt; uint_t lflag, eflag, dflag, pflag, mflag, Mflag; uint8_t enable; scf_error_t serr; int exit_status = 0; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); if ((h = scf_handle_create(SCF_VERSION)) == NULL) scfdie(); if (scf_handle_bind(h) == -1) uu_die(gettext("Error: Couldn't bind to svc.configd.\n")); if (argc == 1) { list_services(); goto out; } lflag = eflag = dflag = pflag = mflag = Mflag = 0; while ((opt = getopt(argc, argv, "ledpMm?")) != -1) { switch (opt) { case 'l': lflag = 1; break; case 'e': eflag = 1; break; case 'd': dflag = 1; break; case 'p': pflag = 1; break; case 'M': Mflag = 1; break; case 'm': mflag = 1; break; case '?': if (optopt == '?') { usage(B_TRUE); goto out; } else { usage(B_FALSE); } default: usage(B_FALSE); } } /* * All options are mutually exclusive, and we must have an option * if we reached here. */ if (lflag + eflag + dflag + pflag + mflag + Mflag != 1) usage(B_FALSE); argv += optind; argc -= optind; if ((pflag == 0) && (argc == 0)) usage(B_FALSE); serr = 0; if (lflag) { serr = scf_walk_fmri(h, argc, argv, 0, list_props_cb, NULL, &exit_status, uu_warn); } else if (dflag) { enable = 0; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (eflag) { enable = 1; serr = scf_walk_fmri(h, argc, argv, 0, set_svc_enable_cb, &enable, &exit_status, uu_warn); } else if (mflag) { arglist_t args; char **cpp = argv; uint_t fmri_args = 0; /* count number of fmri arguments */ while ((fmri_args < argc) && (strchr(*cpp, '=') == NULL)) { fmri_args++; cpp++; } /* if no x=y args or no fmri, show usage */ if ((fmri_args == argc) || (fmri_args == 0)) usage(B_FALSE); /* setup args for modify_inst_props_cb */ args.argc = argc - fmri_args; args.argv = argv + fmri_args; serr = scf_walk_fmri(h, fmri_args, argv, 0, modify_inst_props_cb, &args, &exit_status, uu_warn); } else if (Mflag) { modify_defaults(argc, argv); } else if (pflag) { /* ensure there's no trailing garbage */ if (argc != 0) usage(B_FALSE); list_defaults(); } if (serr != 0) { uu_warn(gettext("failed to iterate over instances: %s"), scf_strerror(serr)); exit(UU_EXIT_FATAL); } out: (void) scf_handle_unbind(h); scf_handle_destroy(h); return (exit_status); }