/* * 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); } }
void load_fini(void) { scf_iter_destroy(load_propiter); load_propiter = NULL; scf_iter_destroy(load_valiter); load_valiter = NULL; scf_value_destroy(load_val); load_val = NULL; scf_property_destroy(load_prop); load_prop = NULL; free(loadbuf); loadbuf = NULL; }
conerr_t smfu_get_property(char *fmri, char *pgname, char *propname, char *value, size_t n) { conerr_t err = ce_ok; scf_handle_t *scfhandle = handle_create(); scf_service_t *service = scf_service_create(scfhandle); scf_instance_t *instance = scf_instance_create(scfhandle); scf_propertygroup_t *pg = scf_pg_create(scfhandle); scf_property_t *prop = scf_property_create(scfhandle); scf_iter_t *iter = scf_iter_create(scfhandle); scf_value_t *val = scf_value_create(scfhandle); if (scfhandle == NULL || service == NULL || instance == NULL || pg == NULL || prop == NULL || iter == NULL || val == NULL) { err = ce_nomem; goto out; } if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance, NULL, NULL, 0) != SCF_SUCCESS) { rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } if (scf_instance_get_pg(instance, pgname, pg) != 0 || scf_pg_get_property(pg, propname, prop) != 0 || scf_iter_property_values(iter, prop) != 0) { rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } if (scf_iter_next_value(iter, val) > 0 && scf_value_get_as_string(val, value, n) == -1) { rad_log(RL_ERROR, "couldn't get property value: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } out: scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_iter_destroy(iter); scf_instance_destroy(instance); scf_service_destroy(service); scf_handle_destroy(scfhandle); return (err); }
Boolean_t mgmt_param_save2scf(tgt_node_t *node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pgname[64]; tgt_node_t *n = NULL; h = mgmt_handle_init(); if (h == NULL) return (False); snprintf(pgname, sizeof (pgname), "param_%s_%d", target_name, lun); (void) pthread_mutex_lock(&scf_param_mutex); if (mgmt_transaction_start(h, pgname, "parameter") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (mgmt_transaction_start(h, pgname, "parameter") == True) { for (n = node->x_child; n; n = n->x_sibling) { if (n->x_child == NULL) { /* now n is node of basic property */ new_property(h, n); } } new_property(h, node->x_attr); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } (void) pthread_mutex_unlock(&scf_param_mutex); return (True); error: (void) pthread_mutex_unlock(&scf_param_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (False); }
/* * display_prop() all of the properties in the given property group. Force * types to true so identification will be displayed. */ static void display_pg(scf_propertygroup_t *pg) { scf_property_t *prop; scf_iter_t *iter; int ret; types = 1; /* Always display types for whole propertygroups. */ if ((prop = scf_property_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (scf_iter_pg_properties(iter, pg) == -1) scfdie(); while ((ret = scf_iter_next_property(iter, prop)) == 1) display_prop(pg, prop); if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_property_destroy(prop); }
/* * mgmt_get_param() get parameter of a specific LUN from scf * Args: * node - the node which parameters will be stored in mem * target_name - the local target name * lun - the LUN number * See also : mgmt_param_save2scf() */ Boolean_t mgmt_get_param(tgt_node_t **node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pname[64]; char pgname[64]; char valuebuf[MAXPATHLEN]; tgt_node_t *n; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); snprintf(pgname, sizeof (pgname), "param_%s_%d", target_name, lun); (void) pthread_mutex_lock(&scf_param_mutex); if (scf_service_get_pg(h->t_service, pgname, h->t_pg) == -1) { goto error; } *node = tgt_node_alloc(XML_ELEMENT_PARAMS, String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } status = True; error: (void) pthread_mutex_unlock(&scf_param_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }
/* * mgmt_config_save2scf() saves main configuration to scf * See also : mgmt_get_main_config() */ Boolean_t mgmt_config_save2scf() { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pgname[64]; char passcode[32]; unsigned int outlen; tgt_node_t *n = NULL; tgt_node_t *pn = NULL; tgt_node_t *tn = NULL; scf_transaction_t *tx = NULL; secret_list_t *sl_head; secret_list_t *sl_tail; h = mgmt_handle_init(); if (h == NULL) return (False); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); (void) pthread_mutex_lock(&scf_conf_mutex); if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (mgmt_transaction_start(h, "passwords", "application") == True) { scf_pg_delete(h->t_pg); mgmt_transaction_end(h); } if (scf_iter_service_pgs_typed(iter, h->t_service, "configuration") == -1) { goto error; } tx = scf_transaction_create(h->t_handle); while (scf_iter_next_pg(iter, h->t_pg) > 0) { scf_transaction_start(tx, h->t_pg); scf_pg_delete(h->t_pg); scf_transaction_commit(tx); } scf_transaction_reset(tx); scf_transaction_destroy(tx); sl_head = (secret_list_t *)calloc(1, sizeof (secret_list_t)); sl_tail = sl_head; if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) { for (n = main_config->x_child; n; n = n->x_sibling) { if (strcmp(n->x_name, XML_ELEMENT_CHAPSECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = strdup("main"); sl_tail->secret = strdup(n->x_value); continue; } /* so does the radius server secret */ if (strcmp(n->x_name, XML_ELEMENT_RAD_SECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = strdup("radius"); sl_tail->secret = strdup(n->x_value); continue; } if (n->x_child == NULL) { new_property(h, n); } } new_property(h, main_config->x_attr); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } /* now update target/initiator/tpgt information */ for (n = main_config->x_child; n; n = n->x_sibling) { if (n->x_child == NULL) continue; snprintf(pgname, sizeof (pgname), "%s_%s", n->x_name, n->x_value); if (mgmt_transaction_start(h, pgname, "configuration") == True) { for (pn = n->x_child; pn; pn = pn->x_sibling) { if (strcmp(pn->x_name, XML_ELEMENT_CHAPSECRET) == 0) { sl_tail->next = (secret_list_t *) calloc(1, sizeof (secret_list_t)); sl_tail = sl_tail->next; sl_tail->name = (char *) calloc(1, strlen(n->x_value) + 3); snprintf(sl_tail->name, strlen(n->x_value) + 3, "I_%s", n->x_value); sl_tail->secret = strdup(pn->x_value); continue; } if (pn->x_child == NULL) { /* normal property */ new_property(h, pn); } else { /* pn -> xxx-list */ new_value_list(h, pn); } tn = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, tn); tgt_node_free(tn); tn = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, tn); tgt_node_free(tn); } mgmt_transaction_end(h); } } if (mgmt_transaction_start(h, "passwords", "application") == True) { while (sl_head != NULL) { /* Here we use sl_tail as a temporari var */ sl_tail = sl_head->next; if (sl_head->name) { /* max length of encoded passwd is 24B */ sasl_encode64(sl_head->secret, strlen(sl_head->secret), passcode, sizeof (passcode), &outlen); n = tgt_node_alloc(sl_head->name, String, passcode); new_property(h, n); tgt_node_free(n); } if (sl_head->name) free(sl_head->name); if (sl_head->secret) free(sl_head->secret); free(sl_head); sl_head = sl_tail; } n = tgt_node_alloc(ISCSI_READ_AUTHNAME, String, ISCSI_AUTH_READ); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String, ISCSI_AUTH_VALUE); new_property(h, n); tgt_node_free(n); n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String, ISCSI_AUTH_MODIFY); new_property(h, n); tgt_node_free(n); mgmt_transaction_end(h); } if (smf_refresh_instance(SA_TARGET_SVC_INSTANCE_FMRI) != 0) goto error; (void) pthread_mutex_unlock(&scf_conf_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); return (True); error: (void) pthread_mutex_unlock(&scf_conf_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (False); }
/* * mgmt_get_main_config() loads main configuration * from scf into a node tree. * Main configuration includes: admin/target/tpgt/initiator info. * admin info is stored in "iscsitgt" property group * target info is stored in "target_<name>" property group * initiator info is stored in "initiator_<name>" property group * tpgt info is stored in "tpgt_<number>" property group */ Boolean_t mgmt_get_main_config(tgt_node_t **node) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; scf_iter_t *iter_v = NULL; scf_iter_t *iter_pv = NULL; char pname[32]; char valuebuf[MAXPATHLEN]; char passcode[32]; unsigned int outlen; tgt_node_t *n; tgt_node_t *pn; tgt_node_t *vn; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); (void) pthread_mutex_lock(&scf_conf_mutex); /* Basic Information is stored in iscsitgt pg */ if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == -1) { goto error; } *node = NULL; *node = tgt_node_alloc("main_config", String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } /* * targets/initiators/tpgt information is * stored as type "configuration" in scf * each target's param is stored as type "parameter" */ if (scf_iter_service_pgs_typed(iter, h->t_service, "configuration") == -1) { goto error; } while (scf_iter_next_pg(iter, h->t_pg) > 0) { char *iname; scf_pg_get_name(h->t_pg, pname, sizeof (pname)); iname = strchr(pname, '_'); if (iname == NULL) { /* the pg found here is not a tgt/initiator/tpgt */ continue; } *iname = '\0'; iname++; /* * now pname is "target" or "initiator" or "tpgt" * meanwhile iname is the actual name of the item */ n = tgt_node_alloc(pname, String, iname); if (n == NULL) goto error; iter_v = scf_iter_create(h->t_handle); if (scf_iter_pg_properties(iter_v, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter_v, prop) > 0) { /* there may be many values in one property */ char *vname; scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; vname = strstr(pname, "-list"); if (vname == NULL) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); pn = tgt_node_alloc(pname, String, valuebuf); if (pn == NULL) goto error; tgt_node_add(n, pn); } else { pn = tgt_node_alloc(pname, String, NULL); if (pn == NULL) goto error; tgt_node_add(n, pn); *vname = '\0'; iter_pv = scf_iter_create(h->t_handle); scf_iter_property_values(iter_pv, prop); while (scf_iter_next_value(iter_pv, value) > 0) { scf_value_get_as_string(value, valuebuf, MAXPATHLEN); vn = tgt_node_alloc(pname, String, valuebuf); if (vn == NULL) goto error; tgt_node_add(pn, vn); } scf_iter_destroy(iter_pv); iter_pv = NULL; } } tgt_node_add(*node, n); scf_iter_destroy(iter_v); iter_v = NULL; } /* chap-secrets are stored in "passwords" pgroup as "application" */ if (scf_service_get_pg(h->t_service, "passwords", h->t_pg) == 0) { if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; /* max length of decoded passwd is 16B */ sasl_decode64(valuebuf, strlen(valuebuf), passcode, sizeof (passcode), &outlen); if (strcmp(pname, "radius") == 0) { pn = tgt_node_alloc(XML_ELEMENT_RAD_SECRET, String, passcode); tgt_node_add(*node, pn); } else if (strcmp(pname, "main") == 0) { pn = tgt_node_alloc(XML_ELEMENT_CHAPSECRET, String, passcode); tgt_node_add(*node, pn); } else { /* find corresponding initiator */ n = NULL; while (n = tgt_node_next_child(*node, XML_ELEMENT_INIT, n)) { if (strcmp(pname + 2, n->x_value) != 0) continue; pn = tgt_node_alloc( XML_ELEMENT_CHAPSECRET, String, passcode); tgt_node_add(n, pn); } } } } status = True; error: if ((status != True) && (*node != NULL)) tgt_node_free(*node); (void) pthread_mutex_unlock(&scf_conf_mutex); if (iter_pv != NULL) scf_iter_destroy(iter_pv); if (iter_v != NULL) scf_iter_destroy(iter_v); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }
/* * Entity (service or instance): If there are -p options, * display_{pg,prop}() the named property groups and/or properties. Otherwise * display_pg() all property groups. */ static void process_ent(scf_entityp_t ent) { scf_snapshot_t *snap = NULL; scf_propertygroup_t *pg; scf_property_t *prop; scf_iter_t *iter; svcprop_prop_node_t *spn; int ret, err; if (uu_list_numnodes(prop_list) == 0) { if (quiet) return; if ((pg = scf_pg_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (cflag || Cflag || ent.type != ENT_INSTANCE) { if (scf_iter_entity_pgs(iter, ent) == -1) scfdie(); } else { if (snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, snap) == -1) scfdie(); if (snap) scf_snapshot_destroy(snap); } while ((ret = scf_iter_next_pg(iter, pg)) == 1) display_pg(pg); if (ret == -1) scfdie(); /* * In normal usage, i.e. against the running snapshot, * we must iterate over the current non-persistent * pg's. */ if (sflag == 0 && snap != NULL) { scf_iter_reset(iter); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, NULL) == -1) scfdie(); while ((ret = scf_iter_next_pg(iter, pg)) == 1) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if (flags & SCF_PG_FLAG_NONPERSISTENT) display_pg(pg); } } if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_pg_destroy(pg); return; } if ((pg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (ent.type == ENT_INSTANCE && snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (ent.type == ENT_INSTANCE) { if (Cflag) ret = scf_instance_get_pg(ent.u.inst, spn->spn_comp1, pg); else ret = scf_instance_get_pg_composed(ent.u.inst, snap, spn->spn_comp1, pg); err = scf_error(); /* * If we didn't find it in the specified snapshot, use * the current values if the pg is nonpersistent. */ if (ret == -1 && !Cflag &&snap != NULL && err == SCF_ERROR_NOT_FOUND) { ret = scf_instance_get_pg_composed( ent.u.inst, NULL, spn->spn_comp1, pg); if (ret == 0) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if ((flags & SCF_PG_FLAG_NONPERSISTENT) == 0) { ret = -1; } } } } else { /* * If we are displaying properties for a service, * treat it as though it were a composed, current * lookup. (implicit cflag) However, if a snapshot * was specified, fail. */ if (sflag) die(gettext("Only instances have " "snapshots.\n")); ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); err = scf_error(); } if (ret == -1) { if (err != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property group " "`%s' for %s `%s'.\n"), spn->spn_comp1, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (spn->spn_comp2 == NULL) { if (!quiet) display_pg(pg); continue; } if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); /* FMRI syntax knowledge */ uu_warn(gettext("Couldn't find property " "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (!quiet) display_prop(pg, prop); } scf_property_destroy(prop); scf_pg_destroy(pg); if (snap) scf_snapshot_destroy(snap); }
/* * Display a property's values on a line. If types is true, prepend * identification (the FMRI if fmris is true, pg/prop otherwise) and the type * of the property. */ static void display_prop(scf_propertygroup_t *pg, scf_property_t *prop) { scf_value_t *val; scf_iter_t *iter; int ret, first, err; const char * const permission_denied_emsg = gettext("Permission denied.\n"); if (types) { scf_type_t ty; char *buf; size_t buf_sz; if (fmris) { buf_sz = max_scf_fmri_length + 1; buf = safe_malloc(buf_sz); if (scf_property_to_fmri(prop, buf, buf_sz) == -1) scfdie(); (void) fputs(buf, stdout); free(buf); } else { buf_sz = max_scf_name_length + 1; buf = safe_malloc(buf_sz); if (scf_pg_get_name(pg, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); (void) putchar('/'); if (scf_property_get_name(prop, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); free(buf); } (void) putchar(' '); if (scf_property_type(prop, &ty) == -1) scfdie(); (void) fputs(scf_type_to_string(ty), stdout); (void) putchar(' '); } if ((iter = scf_iter_create(hndl)) == NULL || (val = scf_value_create(hndl)) == NULL) scfdie(); if (scf_iter_property_values(iter, prop) == -1) scfdie(); first = 1; while ((ret = scf_iter_next_value(iter, val)) == 1) { if (first) first = 0; else (void) putchar(' '); print_value(val); } if (ret == -1) { err = scf_error(); if (err == SCF_ERROR_PERMISSION_DENIED) { if (uu_list_numnodes(prop_list) > 0) die(permission_denied_emsg); } else { scfdie(); } } (void) putchar('\n'); scf_iter_destroy(iter); (void) scf_value_destroy(val); }
void read_scf_proto_cfg(const char *proto, scf_cfg_t *cfg) { scf_handle_t *handle = NULL; scf_scope_t *sc = NULL; scf_service_t *svc = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *value_iter = NULL; uint64_t val; char *str; size_t slen; int i; handle = scf_handle_create(SCF_VERSION); sc = scf_scope_create(handle); svc = scf_service_create(handle); pg = scf_pg_create(handle); prop = scf_property_create(handle); value = scf_value_create(handle); value_iter = scf_iter_create(handle); if (handle == NULL || sc == NULL || svc == NULL || pg == NULL || prop == NULL || value == NULL || value_iter == NULL) { DMSG(D_OP, "%s: unable to create smf(5) handles.", proto); goto done; } if (scf_handle_bind(handle) != 0) { DMSG(D_OP, "%s: unable to bind smf(5) handle: %s", proto, scf_strerror(scf_error())); goto done; } if (scf_handle_decode_fmri(handle, fmri, sc, svc, NULL, NULL, NULL, 0) != 0) { DMSG(D_OP, "%s: unable to decode fmri '%s': %s", fmri, scf_strerror(scf_error())); goto done; } if (scf_service_get_pg(svc, proto, pg) != 0 && scf_error() != SCF_ERROR_NOT_FOUND) { DMSG(D_OP, "%s: unable to read '%s' property group: %s", proto, proto, scf_strerror(scf_error())); goto done; } for (i = 0; cfg[i].name != NULL; i++) { scf_cfg_t *c = &cfg[i]; if (scf_pg_get_property(pg, c->name, prop) != 0) { if (scf_error() != SCF_ERROR_NOT_FOUND) DMSG(D_OP, "%s: unable to read %s/%s from " "smf: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (scf_property_is_type(prop, c->type) != 0) { scf_type_t type; if (scf_error() != SCF_ERROR_TYPE_MISMATCH) { DMSG(D_OP, "%s: unable to validate " "type of '%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (scf_property_type(prop, &type) != 0) { DMSG(D_OP, "%s: unable to obtain " "type of '%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } DMSG(D_OP, "%s: property '%s/%s' has an unexpected " "type:\n" " expected type: %s\n" " actual type: %s\n", proto, proto, c->name, scf_type_to_string(c->type), scf_type_to_string(type)); continue; } if (scf_property_get_value(prop, value) != 0) { if (scf_error() != SCF_ERROR_NOT_SET) DMSG(D_OP, "%s: unable to get value of " "'%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } switch (c->type) { case SCF_TYPE_COUNT: if (scf_value_get_count(value, &val) != 0) { DMSG(D_OP, "%s: unable to read value of " "'%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (val > c->max) { DMSG(D_OP, "%s: value of '%s/%s' smf property " "(%'llu) is out of range (0 - %'zu).", proto, proto, c->name, val, c->max); continue; } *((uint32_t *)c->val) = (uint32_t)val; break; case SCF_TYPE_ASTRING: { char **valp = (char **)c->val; ssize_t len; slen = c->max + 1; if ((str = malloc(slen)) == NULL) { /* XXX message */ continue; } if ((len = scf_value_get_astring(value, str, slen)) >= slen) DMSG(D_OP, "%s: length of '%s/%s' " "(%'zd bytes) exceeds maximum " "allowable length (%zu bytes). The string" " will be truncated.", proto, proto, c->name, len, c->max); free(*valp); *valp = str; break; } default: VERIFY(0); } } done: scf_iter_destroy(value_iter); scf_value_destroy(value); scf_property_destroy(prop); scf_pg_destroy(pg); scf_service_destroy(svc); scf_scope_destroy(sc); scf_handle_destroy(handle); }
/* * mgmt_get_param() get parameter of a specific LUN from scf * Args: * node - the node which parameters will be stored in mem * target_name - the local target name * lun - the LUN number * See also : mgmt_param_save2scf() */ Boolean_t mgmt_get_param(tgt_node_t **node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char *pname = NULL; char *expgname = NULL; char *pgname = NULL; char *valuebuf = NULL; ssize_t max_name_len; ssize_t expg_max_name_len; ssize_t max_value_len; tgt_node_t *n; Boolean_t status = False; /* Set NULL as default output value */ *node = NULL; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); if ((alloc_scf_name(&max_name_len, (void *)&pname) == NULL) || (alloc_scf_name(&max_name_len, (void *)&pgname) == NULL) || (alloc_scf_value(&max_value_len, (void *)&valuebuf) == NULL)) { goto error; } /* * Allocate memory for an "expanded" (or "decoded") Property Group * name. */ expg_max_name_len = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) * PG_FACTOR + 1; if ((expgname = malloc(expg_max_name_len)) == NULL) { goto error; } (void) snprintf(pgname, max_name_len, "param_%s_%d", target_name, lun); pgname_encode(pgname, expgname, max_name_len); (void) pthread_mutex_lock(&scf_param_mutex); if (scf_service_get_pg(h->t_service, expgname, h->t_pg) == -1) { goto error; } *node = tgt_node_alloc(XML_ELEMENT_PARAMS, String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { (void) scf_property_get_value(prop, value); (void) scf_value_get_as_string(value, valuebuf, max_value_len); (void) scf_property_get_name(prop, pname, max_name_len); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } status = True; error: (void) pthread_mutex_unlock(&scf_param_mutex); free(valuebuf); free(expgname); free(pgname); free(pname); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }