/* * if auditd isn't running, start it. Otherwise refresh. * First check to see if c2audit is loaded via the auditon() * system call, then check SMF state. */ static void start_auditd() { int audit_state; char *state; if (auditon(A_GETCOND, (caddr_t)&audit_state, sizeof (audit_state)) != 0) exit(1); if ((state = smf_get_state(AUDITD_FMRI)) == NULL) { display_smf_error(); exit(1); } if (strcmp(SCF_STATE_STRING_ONLINE, state) != 0) { if (smf_enable_instance(AUDITD_FMRI, 0) != 0) { display_smf_error(); free(state); exit(1); } } else { if (smf_refresh_instance(AUDITD_FMRI) != 0) { display_smf_error(); free(state); exit(1); } } free(state); }
/*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())); }
int isServiceEnabled( void ) { static const char * sInstanceName = "svc:/network/apocd/udp:default"; int isServiceEnabled = 0; char * theState = smf_get_state( sInstanceName ); if ( theState != 0 ) { if ( strcmp( theState, SCF_STATE_STRING_DISABLED ) != 0 ) { isServiceEnabled = 1; } free( ( void * )theState ); } return isServiceEnabled; }
static boolean_t is_iscsit_enabled(void) { char *state; state = smf_get_state(ISCSIT_FMRI); if (state != NULL) { if (strcmp(state, SCF_STATE_STRING_ONLINE) == 0) { free(state); return (B_TRUE); } free(state); } return (B_FALSE); }
gboolean ck_supports_activatable_consoles (void) { char *state = NULL; gboolean vt_enabled; state = smf_get_state ("svc:/system/vtdaemon:default"); if (state && g_str_equal (state, SCF_STATE_STRING_ONLINE)) { vt_enabled = TRUE; } else { vt_enabled = FALSE; } g_free (state); return vt_enabled; }
static boolean_t check_svc_up(const char *fmri, int wait_time) { int i; char *state; for (i = 1; i <= wait_time; i++) { state = smf_get_state(fmri); if (state == NULL) { syslog(LOG_ERR, "smf_get_state(%s) returned \"%s\"", fmri, scf_strerror(scf_error())); } else { if (strcmp(SCF_STATE_STRING_ONLINE, state) == 0) { free(state); return (B_TRUE); } free(state); } (void) sleep(1); } return (B_FALSE); }
void wait_till_to(char *fmri) { char *state; useconds_t max; useconds_t usecs; uint64_t *cp = NULL; scf_simple_prop_t *sp = NULL; max = DEFAULT_TIMEOUT; if (((sp = scf_simple_prop_get(NULL, fmri, "stop", SCF_PROPERTY_TIMEOUT)) != NULL) && ((cp = scf_simple_prop_next_count(sp)) != NULL) && (*cp != 0)) max = (*cp) * 1000000; /* convert to usecs */ if (sp != NULL) scf_simple_prop_free(sp); for (usecs = INIT_WAIT_USECS; max > 0; max -= usecs) { /* incremental wait */ usecs *= 2; usecs = (usecs > max) ? max : usecs; (void) usleep(usecs); /* Check state after the wait */ if ((state = smf_get_state(fmri)) != NULL) { if (strcmp(state, "disabled") == 0) return; } } (void) fprintf(stderr, gettext("Warning: delete %s timed out.\n"), fmri); }
/* Enables the location. */ static void nwamd_loc_activate(const char *object_name) { char *enabled; nlog(LOG_DEBUG, "nwamd_loc_activate: activating loc %s", object_name); /* * Find currently enabled location and change its state to disabled * if it is a manual location, or offline (if it is not). * Only manual locations reach disabled, since conditional and * system locations which are manually disabled simply revert to * their conditions for activation. */ if ((enabled = malloc(NWAM_MAX_NAME_LEN)) != NULL && nwamd_lookup_string_property(NET_LOC_FMRI, NET_LOC_PG, NET_LOC_SELECTED_PROP, enabled, NWAM_MAX_NAME_LEN) == 0) { /* Only change state if current != new */ if (strcmp(enabled, object_name) != 0) { boolean_t do_disable = B_FALSE; nwamd_object_t eobj = nwamd_object_find (NWAM_OBJECT_TYPE_LOC, enabled); if (eobj == NULL) { nlog(LOG_INFO, "nwamd_loc_activate: could not " "find old location %s", enabled); goto skip_disable; } /* * Disable if the old location was manual, since the * only way a manual location can deactivate is if * it is disabled. */ do_disable = (loc_get_activation_mode(eobj->nwamd_object_handle) == (int64_t)NWAM_ACTIVATION_MODE_MANUAL); nwamd_object_release(eobj); if (do_disable) { nlog(LOG_DEBUG, "nwamd_loc_activate: " "disable needed for old location %s", enabled); nwamd_object_set_state (NWAM_OBJECT_TYPE_LOC, enabled, NWAM_STATE_DISABLED, NWAM_AUX_STATE_MANUAL_DISABLE); } else { nlog(LOG_DEBUG, "nwamd_loc_activate: " "offline needed for old location %s", enabled); nwamd_object_set_state (NWAM_OBJECT_TYPE_LOC, enabled, NWAM_STATE_OFFLINE, NWAM_AUX_STATE_CONDITIONS_NOT_MET); } } } skip_disable: free(enabled); if (nwamd_set_string_property(NET_LOC_FMRI, NET_LOC_PG, NET_LOC_SELECTED_PROP, object_name) == 0) { char *state = smf_get_state(NET_LOC_FMRI); nlog(LOG_INFO, "nwamd_loc_activate: set %s/%s to %s; " "service is in %s state", NET_LOC_PG, NET_LOC_SELECTED_PROP, object_name, state == NULL ? "unknown" : state); free(state); (void) smf_restore_instance(NET_LOC_FMRI); if (smf_refresh_instance(NET_LOC_FMRI) == 0) { (void) pthread_mutex_lock(&active_loc_mutex); (void) strlcpy(active_loc, object_name, sizeof (active_loc)); (void) pthread_mutex_unlock(&active_loc_mutex); nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC, object_name, NWAM_STATE_ONLINE, NWAM_AUX_STATE_ACTIVE); } else { nlog(LOG_ERR, "nwamd_loc_activate: " "%s could not be refreshed", NET_LOC_FMRI); nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC, object_name, NWAM_STATE_MAINTENANCE, NWAM_AUX_STATE_METHOD_FAILED); } } }
static int is_correct_event(const char *fmri, const scf_propertygroup_t *pg, const boolean_t isrpc) { char *state = NULL; const char **proplist = all_props; int prop_cnt = ALL_PROPS_CNT; int i, ret = 0; if (scf_pg_get_name(pg, scratch_name, max_scf_name_size) < 0) { syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_name failed: %s\n", scf_strerror(scf_error())); return (-1); } /* * We care about enable, disable, and refresh since that's * when we activate, deactivate, or change firewall policy. * * - enable/disable -> change in "general" or "general_ovr" * - refresh/restart -> change in "restarter_actions" */ if (strcmp(scratch_name, SCF_PG_GENERAL) == 0 || strcmp(scratch_name, SCF_PG_GENERAL_OVR) == 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s", scratch_name); return (1); } if ((state = smf_get_state(fmri)) == NULL) { syslog(LOG_ERR | LOG_DAEMON, "smf_get_state failed for %s: " "%s\n", fmri, scf_strerror(scf_error())); return (-1); } syslog(LOG_DEBUG | LOG_DAEMON, "%s STATE: %s \n", fmri, state); if (strcmp(state, SCF_STATE_STRING_MAINT) == 0) { proplist = maint_props; prop_cnt = MAINT_PROPS_CNT; } /* * Only concerned with refresh, restart, and maint on|off actions. * RPC services are restarted whenever rpc/bind restarts so it's * an automatic valid event for RPC services. */ if (isrpc) { ret = 1; goto out; } else if (strcmp(scratch_name, SCF_PG_RESTARTER_ACTIONS) == 0) { for (i = 0; i < prop_cnt; i++) { if (pg_get_prop_value(pg, proplist[i], scratch_v) == 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s/%s", scratch_name, proplist[i]); ret = 1; goto out; } } } out: if (state) free(state); return (ret); }
int main(int argc, char *argv[]) { int c; /* options character */ int type = 0; /* type of accounting */ int modified = 0; /* have we modified any properties? */ acctconf_t ac; /* current configuration */ char *typestr = NULL; /* type of accounting argument string */ char *enabled = NULL; /* enabled resources string */ char *disabled = NULL; /* disabled resources string */ char *file = NULL; int Eflg = 0; int Dflg = 0; int rflg = 0; int sflg = 0; int xflg = 0; int optcnt = 0; int state; const char *fmri; /* FMRI for this instance */ int err = 0; setup_privs(); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); (void) setpname(argv[0]); for (; optind < argc; optind++) { while ((c = getopt(argc, argv, OPTS)) != (int)EOF) { switch (c) { case 'd': disabled = optarg; break; case 'e': enabled = optarg; break; case 'D': Dflg = 1; optcnt++; break; case 'E': Eflg = 1; optcnt++; break; case 'f': file = optarg; optcnt++; break; case 'r': rflg = 1; optcnt++; break; case 's': sflg = 1; optcnt++; break; case 'x': xflg = 1; optcnt++; break; case '?': default: usage(); } } /* * Permanently give up euid 0, egid 0 and privileges we * don't need for the specified options. */ if (!(file || sflg)) { if (setreuid(getuid(), getuid()) == -1 || setregid(getgid(), getgid()) == -1) die(gettext("setreuid()/setregid() failed")); (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_FILE_DAC_WRITE, NULL); } if (!(disabled || enabled || Dflg || Eflg || file || sflg || xflg)) (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL); if (optind < argc) { if (typestr != NULL) { warn(gettext("illegal argument -- %s\n"), argv[optind]); usage(); } else { typestr = argv[optind]; } } } if (typestr != NULL) { if (strcmp(typestr, "process") == 0 || strcmp(typestr, "proc") == 0) type |= AC_PROC; else if (strcmp(typestr, "task") == 0) type |= AC_TASK; else if (strcmp(typestr, "flow") == 0) type |= AC_FLOW; else if (strcmp(typestr, "net") == 0) type |= AC_NET; else { warn(gettext("unknown accounting type -- %s\n"), typestr); usage(); } } else type = AC_PROC | AC_TASK | AC_FLOW | AC_NET; /* * Drop the DL config privilege if we are not working with * net. */ if ((type & AC_NET) == 0) { (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_DL_CONFIG, NULL); } /* * check for invalid options */ if (optcnt > 1) usage(); /* * XXX For AC_NET, enabled/disabled should only be "basic" or * "extended" - need to check it here. */ if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg)) usage(); if ((file || xflg || Dflg || Eflg || enabled || disabled) && !typestr) { warn(gettext("accounting type must be specified\n")); usage(); } if (rflg) { printgroups(type); return (E_SUCCESS); } /* * If no arguments have been passed then just print out the current * state and exit. */ if (!enabled && !disabled && !file && !Eflg && !rflg && !Dflg && !sflg && !xflg) { aconf_print(stdout, type); return (E_SUCCESS); } /* Open the libdladm handle */ if (dladm_open(&dld_handle) != DLADM_STATUS_OK) die(gettext("failed to open dladm handle\n")); /* * smf(5) start method. The FMRI to operate on is retrieved from the * SMF_FMRI environment variable that the restarter provides. */ if (sflg) { if ((fmri = getenv("SMF_FMRI")) != NULL) { int ret = aconf_setup(fmri); dladm_close(dld_handle); return (ret); } die(gettext("-s option should only be invoked by smf(5)\n")); } assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW || type == AC_NET); if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID) die(gettext("%s accounting cannot be configured in " "non-global zones\n"), ac_type_name(type)); fmri = aconf_type2fmri(type); if (aconf_scf_init(fmri) == -1) die(gettext("cannot connect to repository for %s\n"), fmri); /* * Since the sys_acct the privilege allows use of acctctl() regardless * of the accounting type, we check the smf(5) authorizations granted * to the user to determine whether the user is allowed to change the * configuration for this particular accounting type. */ if (!aconf_have_smf_auths()) die(gettext("insufficient authorization to change %s extended " "accounting configuration\n"), ac_type_name(type)); if (xflg) { /* * Turn off the specified accounting and close its file */ /* * Stop net logging before turning it off so that the last * set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging network " "information, error %d\n"), errno); } } state = AC_OFF; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot disable %s accounting"), ac_type_name(type)); if (acctctl(type | AC_FILE_SET, NULL, 0) == -1) die(gettext("cannot close %s accounting file\n"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_FILE); modified++; } if (enabled || disabled) { char *tracked, *untracked; ac_res_t *buf; /* * Enable/disable resources */ if ((buf = malloc(AC_BUFSIZE)) == NULL) die(gettext("not enough memory\n")); (void) memset(buf, 0, AC_BUFSIZE); if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) { free(buf); die(gettext("cannot obtain list of resources\n")); } if (disabled) { /* * Stop net logging before turning it off so that the * last set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, strcmp(disabled, "basic") == 0 ? DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging " "network information, error %d\n"), errno); } } str2buf(buf, disabled, AC_OFF, type); } else if (enabled) { str2buf(buf, enabled, AC_ON, type); } (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) { free(buf); die(gettext("cannot enable/disable %s accounting " "resources\n"), ac_type_name(type)); } (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type); untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type); if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1) die(gettext("cannot update %s property\n"), AC_PROP_TRACKED); if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1) die(gettext("cannot update %s property\n"), AC_PROP_UNTRACKED); free(tracked); free(untracked); free(buf); modified++; } if (file) { /* * Open new accounting file */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (open_exacct_file(file, type) == -1) { dladm_close(dld_handle); exit(E_ERROR); } if (aconf_set_string(AC_PROP_FILE, file) == -1) die(gettext("cannot update %s property\n"), AC_PROP_FILE); state = AC_ON; if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot enable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } /* * Let's get network logging started. We do this after turning on * accounting and opening the file so that we can start writing * immediately. */ if (enabled && (type & AC_NET)) { /* * Default logging interval for AC_NET is * ACCTADM_NET_LOG_INTERVAL. */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_start_usagelog(dld_handle, strcmp(enabled, "basic") == 0 ? DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to start logging " "network information, error %d\n"), errno); } } if (Dflg) { /* * Disable accounting */ /* * Stop net logging before turning it off so that the last * set of logs can be written. */ if (type & AC_NET) { (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_stop_usagelog(dld_handle, DLADM_LOGTYPE_FLOW); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to stop logging " "network information, error %d\n"), errno); } } state = AC_OFF; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot disable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } if (Eflg) { /* * Enable accounting */ /* * Let's get network logging started. */ if (type & AC_NET) { /* * Default logging interval for AC_NET is * ACCTADM_NET_LOG_INTERVAL. */ (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); err = dladm_start_usagelog(dld_handle, DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_DL_CONFIG, NULL); if (err != DLADM_STATUS_OK) { die(gettext("failed to start logging " "network information, error %d\n"), errno); } } state = AC_ON; (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) die(gettext("cannot enable %s accounting"), ac_type_name(type)); (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) die(gettext("cannot update %s property\n"), AC_PROP_STATE); modified++; } (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL); if (modified) { char *smf_state; if (aconf_save() == -1) die(gettext("cannot save %s accounting " "configuration\n"), ac_type_name(type)); /* * Enable or disable the instance depending on the effective * configuration. If the effective configuration results in * extended accounting being 'on', the instance is enabled so * the configuration is applied at the next boot. */ smf_state = smf_get_state(fmri); aconf_init(&ac, type); if (ac.state == AC_ON || strcmp(ac.file, AC_STR_NONE) != 0 || strcmp(ac.tracked, AC_STR_NONE) != 0) { if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0) if (smf_enable_instance(fmri, 0) == -1) die(gettext("cannot enable %s\n"), fmri); } else { if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0) if (smf_disable_instance(fmri, 0) == -1) die(gettext("cannot disable %s\n"), fmri); } free(smf_state); } aconf_scf_fini(); dladm_close(dld_handle); return (E_SUCCESS); }
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); }