int32_t fnvlist_lookup_int32(nvlist_t *nvl, const char *name) { int32_t rv; VERIFY0(nvlist_lookup_int32(nvl, name, &rv)); return (rv); }
static void print_fmri_pgroup(topo_hdl_t *thp, const char *pgn, nvlist_t *nvl) { char *dstab = NULL, *nstab = NULL; int32_t version = -1; nvlist_t *pnvl; nvpair_t *pnvp; (void) nvlist_lookup_string(nvl, TOPO_PROP_GROUP_NSTAB, &nstab); (void) nvlist_lookup_string(nvl, TOPO_PROP_GROUP_DSTAB, &dstab); (void) nvlist_lookup_int32(nvl, TOPO_PROP_GROUP_VERSION, &version); print_pgroup(thp, NULL, pgn, dstab, nstab, version); for (pnvp = nvlist_next_nvpair(nvl, NULL); pnvp != NULL; pnvp = nvlist_next_nvpair(nvl, pnvp)) { /* * Print property group and property name-value pair */ if (strcmp(TOPO_PROP_VAL, nvpair_name(pnvp)) == 0 && nvpair_type(pnvp) == DATA_TYPE_NVLIST) { (void) nvpair_value_nvlist(pnvp, &pnvl); print_prop_nameval(thp, NULL, pnvl); } } }
/* * Top level function for event service */ void event_service(void **data, size_t *datalen) { int cmd; int lerrno; int seq_num; nvlist_t *nvl; nvlist_t *ret; rcm_log_message(RCM_TRACE1, "received door operation\n"); /* Decode the data from the door into an unpacked nvlist */ if (data == NULL || datalen == NULL) { rcm_log_message(RCM_ERROR, "received null door argument\n"); return; } if (lerrno = nvlist_unpack(*data, *datalen, &nvl, 0)) { rcm_log_message(RCM_ERROR, "received bad door argument, %s\n", strerror(lerrno)); return; } /* Do nothing if the door is just being knocked on */ if (errno = nvlist_lookup_int32(nvl, RCM_CMD, &cmd)) { rcm_log_message(RCM_ERROR, "bad door argument (nvlist_lookup=%s)\n", strerror(errno)); nvlist_free(nvl); return; } if (cmd == CMD_KNOCK) { rcm_log_message(RCM_TRACE1, "door event was just a knock\n"); nvlist_free(nvl); *data = NULL; *datalen = 0; return; } /* * Go increment thread count. Before daemon is fully initialized, * the event processing blocks inside this function. */ seq_num = rcmd_thr_incr(cmd); process_event(cmd, seq_num, nvl, &ret); nvlist_free(nvl); assert(ret != NULL); /* * Decrement thread count */ rcmd_thr_decr(); out: *data = ret; *datalen = 0; }
static int32_t fma_cap_cpu_info(cpu_tbl_t *ci) { nvlist_t **cpus, *nvl; uint_t ncpu, i; fmd_agent_hdl_t *hdl; char *ven; int32_t family, model; if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) return (-1); if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) { fmd_agent_close(hdl); return (-1); } fmd_agent_close(hdl); if (cpus == NULL) return (-1); /* * There is no mixed CPU type on x86 systems, it's ok to * just pick the first one */ nvl = cpus[0]; if (nvlist_lookup_string(nvl, FM_PHYSCPU_INFO_VENDOR_ID, &ven) != 0 || nvlist_lookup_int32(nvl, FM_PHYSCPU_INFO_FAMILY, &family) != 0 || nvlist_lookup_int32(nvl, FM_PHYSCPU_INFO_MODEL, &model) != 0) { for (i = 0; i < ncpu; i++) nvlist_free(cpus[i]); umem_free(cpus, sizeof (nvlist_t *) * ncpu); return (-1); } (void) snprintf(ci->vendor, X86_VENDOR_STRLEN, "%s", ven); ci->family = family; ci->model = model; for (i = 0; i < ncpu; i++) nvlist_free(cpus[i]); umem_free(cpus, sizeof (nvlist_t *) * ncpu); return (0); }
static int update_stat32(nvlist_t *stats, char *attr, uint32_t value) { int32_t currval; if (nvlist_lookup_int32(stats, attr, &currval) == 0) { value += currval; } return (nvlist_add_uint32(stats, attr, value)); }
int ct_pr_status_get_svc_ctid(ct_stathdl_t stathdl, ctid_t *ctid) { struct ctlib_status_info *info = stathdl; if (info->status.ctst_type != CTT_PROCESS) return (EINVAL); if (info->nvl == NULL) return (ENOENT); return (nvlist_lookup_int32(info->nvl, CTPS_SVC_CTID, (int32_t *)ctid)); }
int ct_pr_event_get_exitstatus(ct_evthdl_t evthdl, int *exitstatus) { struct ctlib_event_info *info = evthdl; if (info->event.ctev_cttype != CTT_PROCESS) return (EINVAL); if (info->event.ctev_type != CT_PR_EV_EXIT) return (EINVAL); if (info->nvl == NULL) return (ENOENT); return (nvlist_lookup_int32(info->nvl, CTPE_EXITSTATUS, exitstatus)); }
/* * cmd_changestate() * * Implements the door command to initate a state change operation. * * NOTE: requires 'modify' authorization. */ static int cmd_changestate(nvlist_t *args, nvlist_t **resultsp) { hp_node_t root = NULL; nvlist_t *results = NULL; char *path, *connection; ucred_t *uc = NULL; uint_t flags; int rv, state, old_state, status; dprintf("cmd_changestate:\n"); /* Get arguments */ if ((nvlist_lookup_string(args, HPD_PATH, &path) != 0) || (nvlist_lookup_string(args, HPD_CONNECTION, &connection) != 0) || (nvlist_lookup_int32(args, HPD_STATE, &state) != 0)) { dprintf("cmd_changestate: invalid arguments.\n"); return (EINVAL); } if (nvlist_lookup_uint32(args, HPD_FLAGS, (uint32_t *)&flags) != 0) flags = 0; /* Get caller's credentials */ if (door_ucred(&uc) != 0) { log_err("Cannot get door credentials (%s)\n", strerror(errno)); return (EACCES); } /* Check authorization */ if (check_auth(uc, HP_MODIFY_AUTH) != 0) { dprintf("cmd_changestate: access denied.\n"); audit_changestate(uc, HP_MODIFY_AUTH, path, connection, state, -1, ADT_FAIL_VALUE_AUTH); ucred_free(uc); return (EACCES); } /* Perform the state change operation */ status = changestate(path, connection, state, flags, &old_state, &root); dprintf("cmd_changestate: changestate() == %d\n", status); /* Audit the operation */ audit_changestate(uc, HP_MODIFY_AUTH, path, connection, state, old_state, status); /* Caller's credentials no longer needed */ ucred_free(uc); /* * Pack the results into an nvlist if there is an error snapshot. * * If any error occurs while packing the results, the original * error code from changestate() above is still returned. */ if (root != NULL) { char *buf = NULL; size_t len = 0; dprintf("cmd_changestate: results nvlist required.\n"); /* Pack and discard the error snapshot */ rv = hp_pack(root, &buf, &len); hp_fini(root); if (rv != 0) { dprintf("cmd_changestate: hp_pack() failed (%s).\n", strerror(rv)); return (status); } /* Allocate nvlist for results */ if (nvlist_alloc(&results, NV_UNIQUE_NAME_TYPE, 0) != 0) { dprintf("cmd_changestate: nvlist_alloc() failed.\n"); free(buf); return (status); } /* Add the results into the nvlist */ if ((nvlist_add_int32(results, HPD_STATUS, status) != 0) || (nvlist_add_byte_array(results, HPD_INFO, (uchar_t *)buf, len) != 0)) { dprintf("cmd_changestate: nvlist add failed.\n"); nvlist_free(results); free(buf); return (status); } *resultsp = results; } return (status); }
/*ARGSUSED*/ static void door_server(void *cookie, char *argp, size_t sz, door_desc_t *dp, uint_t ndesc) { nvlist_t *args = NULL; nvlist_t *results = NULL; hp_cmd_t cmd; int rv; dprintf("Door call: cookie=%p, argp=%p, sz=%d\n", cookie, (void *)argp, sz); /* Special case to free a results buffer */ if (sz == sizeof (uint64_t)) { free_buffer(*(uint64_t *)(uintptr_t)argp); (void) door_return(NULL, 0, NULL, 0); return; } /* Unpack the arguments nvlist */ if (nvlist_unpack(argp, sz, &args, 0) != 0) { log_err("Cannot unpack door arguments.\n"); rv = EINVAL; goto fail; } /* Extract the requested command */ if (nvlist_lookup_int32(args, HPD_CMD, (int32_t *)&cmd) != 0) { log_err("Cannot decode door command.\n"); rv = EINVAL; goto fail; } /* Implement the command */ switch (cmd) { case HP_CMD_GETINFO: rv = cmd_getinfo(args, &results); break; case HP_CMD_CHANGESTATE: rv = cmd_changestate(args, &results); break; case HP_CMD_SETPRIVATE: case HP_CMD_GETPRIVATE: rv = cmd_private(cmd, args, &results); break; default: rv = EINVAL; break; } /* The arguments nvlist is no longer needed */ nvlist_free(args); args = NULL; /* * If an nvlist was constructed for the results, * then pack the results nvlist and return it. */ if (results != NULL) { uint64_t seqnum; char *buf = NULL; size_t len = 0; /* Add a sequence number to the results */ seqnum = get_seqnum(); if (nvlist_add_uint64(results, HPD_SEQNUM, seqnum) != 0) { log_err("Cannot add sequence number.\n"); rv = EFAULT; goto fail; } /* Pack the results nvlist */ if (nvlist_pack(results, &buf, &len, NV_ENCODE_NATIVE, 0) != 0) { log_err("Cannot pack door results.\n"); rv = EFAULT; goto fail; } /* Link results buffer into list */ add_buffer(seqnum, buf); /* The results nvlist is no longer needed */ nvlist_free(results); /* Return the results */ (void) door_return(buf, len, NULL, 0); return; } /* Return result code (when no nvlist) */ (void) door_return((char *)&rv, sizeof (int), NULL, 0); return; fail: log_err("Door call failed (%s)\n", strerror(rv)); nvlist_free(args); nvlist_free(results); (void) door_return((char *)&rv, sizeof (int), NULL, 0); }
/* ARGSUSED */ int x86pi_check_comp(topo_mod_t *mod) { int rv; int fd; int32_t legacy; nvlist_t *nvl = NULL; fm_ioc_data_t fid; char *ibuf = NULL, *obuf = NULL; size_t insz = 0, outsz = 0; char *f = "x86pi_check_comp"; smbios_hdl_t *shp; shp = topo_mod_smbios(mod); if (shp == NULL) return (X86PI_NONE); /* open /dev/fm */ fd = open("/dev/fm", O_RDONLY); if (fd < 0) { topo_mod_dprintf(mod, "%s: failed to open /dev/fm.\n", f); return (X86PI_NONE); } /* set up buffers and ioctl data structure */ outsz = FM_IOC_MAXBUFSZ; obuf = topo_mod_alloc(mod, outsz); if (obuf == NULL) { perror("umem_alloc"); return (X86PI_NONE); } fid.fid_version = 1; fid.fid_insz = insz; fid.fid_inbuf = ibuf; fid.fid_outsz = outsz; fid.fid_outbuf = obuf; /* send the ioctl to /dev/fm to retrieve legacy variable */ rv = ioctl(fd, FM_IOC_GENTOPO_LEGACY, &fid); if (rv < 0) { topo_mod_dprintf(mod, "%s: ioctl to /dev/fm failed", f); perror("fm_ioctl"); (void) close(fd); return (X86PI_NONE); } (void) close(fd); (void) nvlist_unpack(fid.fid_outbuf, fid.fid_outsz, &nvl, 0); (void) nvlist_lookup_int32(nvl, FM_GENTOPO_LEGACY, &legacy); nvlist_free(nvl); topo_mod_free(mod, obuf, outsz); if (legacy == 1) { /* legacy kernel variable set; will do the same */ return (X86PI_NONE); } /* legacy kernel variable not set; generic topo enum */ return (X86PI_FULL); }
/* * Helper function for ipmgmt_setaddr_handler(). * It converts the nvlist_t, `nvl', to aobjmap node `nodep'. */ static int i_ipmgmt_nvl2aobjnode(nvlist_t *nvl, ipmgmt_aobjmap_t *nodep) { char *aobjname = NULL, *ifname = NULL; int32_t lnum; nvlist_t *nvladdr; struct sockaddr_storage addr; uint_t n; sa_family_t af = AF_UNSPEC; ipadm_addr_type_t addrtype = IPADM_ADDR_NONE; int err = 0; /* * Retrieve all the information needed to build '*nodep' from * nvlist_t nvl. */ if ((err = nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME, &aobjname)) != 0 || (err = nvlist_lookup_string(nvl, IPADM_NVP_IFNAME, &ifname)) != 0 || (err = nvlist_lookup_int32(nvl, IPADM_NVP_LIFNUM, &lnum)) != 0) { return (err); } if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR)) { af = AF_INET; addrtype = IPADM_ADDR_STATIC; } else if (nvlist_exists(nvl, IPADM_NVP_DHCP)) { af = AF_INET; addrtype = IPADM_ADDR_DHCP; } else if (nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) { af = AF_INET6; addrtype = IPADM_ADDR_STATIC; } else if (nvlist_lookup_nvlist(nvl, IPADM_NVP_INTFID, &nvladdr) == 0) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr; uint8_t *addr6; uint32_t plen; af = AF_INET6; addrtype = IPADM_ADDR_IPV6_ADDRCONF; if (nvlist_lookup_uint32(nvladdr, IPADM_NVP_PREFIXLEN, &plen) != 0) return (EINVAL); if (plen != 0) { if (nvlist_lookup_uint8_array(nvladdr, IPADM_NVP_IPNUMADDR, &addr6, &n) != 0) return (EINVAL); bcopy(addr6, &sin6->sin6_addr, n); } else { bzero(&sin6->sin6_addr, sizeof (sin6->sin6_addr)); } } /* * populate the `*nodep' with retrieved values. */ (void) strlcpy(nodep->am_ifname, ifname, sizeof (nodep->am_ifname)); (void) strlcpy(nodep->am_aobjname, aobjname, sizeof (nodep->am_aobjname)); nodep->am_lnum = lnum; nodep->am_family = af; nodep->am_atype = addrtype; if (addrtype == IPADM_ADDR_IPV6_ADDRCONF) { nodep->am_linklocal = B_TRUE; nodep->am_ifid = addr; } nodep->am_next = NULL; /* * Do not store logical interface number in persistent store as it * takes different value on reboot. So remove it from `nvl'. */ if (nvlist_exists(nvl, IPADM_NVP_LIFNUM)) (void) nvlist_remove(nvl, IPADM_NVP_LIFNUM, DATA_TYPE_INT32); return (0); }
static int prop_getval(tnode_t *node, const char *pgname, const char *pname, void *val, topo_type_t type, uint_t *nelems, int *err) { int i, j, ret = 0; topo_hdl_t *thp = node->tn_hdl; topo_propval_t *pv; topo_node_lock(node); if ((pv = prop_get(node, pgname, pname, NULL, err)) == NULL) return (get_properror(node, err, *err)); if (pv->tp_type != type) return (get_properror(node, err, ETOPO_PROP_TYPE)); switch (type) { case TOPO_TYPE_INT32: ret = nvlist_lookup_int32(pv->tp_val, TOPO_PROP_VAL_VAL, (int32_t *)val); break; case TOPO_TYPE_UINT32: ret = nvlist_lookup_uint32(pv->tp_val, TOPO_PROP_VAL_VAL, (uint32_t *)val); break; case TOPO_TYPE_INT64: ret = nvlist_lookup_int64(pv->tp_val, TOPO_PROP_VAL_VAL, (int64_t *)val); break; case TOPO_TYPE_UINT64: ret = nvlist_lookup_uint64(pv->tp_val, TOPO_PROP_VAL_VAL, (uint64_t *)val); break; case TOPO_TYPE_DOUBLE: ret = nvlist_lookup_double(pv->tp_val, TOPO_PROP_VAL_VAL, (double *)val); break; case TOPO_TYPE_STRING: { char *str; ret = nvlist_lookup_string(pv->tp_val, TOPO_PROP_VAL_VAL, &str); if (ret == 0) { char *s2; if ((s2 = topo_hdl_strdup(thp, str)) == NULL) ret = -1; else *(char **)val = s2; } break; } case TOPO_TYPE_FMRI: { nvlist_t *nvl; ret = nvlist_lookup_nvlist(pv->tp_val, TOPO_PROP_VAL_VAL, &nvl); if (ret == 0) ret = topo_hdl_nvdup(thp, nvl, (nvlist_t **)val); break; } case TOPO_TYPE_INT32_ARRAY: { int32_t *a1, *a2; if ((ret = nvlist_lookup_int32_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (int32_t) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) a1[i] = a2[i]; *(int32_t **)val = a1; break; } case TOPO_TYPE_UINT32_ARRAY: { uint32_t *a1, *a2; if ((ret = nvlist_lookup_uint32_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (uint32_t) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) a1[i] = a2[i]; *(uint32_t **)val = a1; break; } case TOPO_TYPE_INT64_ARRAY: { int64_t *a1, *a2; if ((ret = nvlist_lookup_int64_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (int64_t) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) a1[i] = a2[i]; *(int64_t **)val = a1; break; } case TOPO_TYPE_UINT64_ARRAY: { uint64_t *a1, *a2; if ((ret = nvlist_lookup_uint64_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (uint64_t) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) a1[i] = a2[i]; *(uint64_t **)val = a1; break; } case TOPO_TYPE_STRING_ARRAY: { char **a1, **a2; if ((ret = nvlist_lookup_string_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (char *) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) { if ((a1[i] = topo_hdl_strdup(thp, a2[i])) == NULL) { for (j = 0; j < i; ++j) topo_hdl_free(thp, a1[j], sizeof (char *)); topo_hdl_free(thp, a1, sizeof (char *) * *nelems); break; } } *(char ***)val = a1; break; } case TOPO_TYPE_FMRI_ARRAY: { nvlist_t **a1, **a2; if ((ret = nvlist_lookup_nvlist_array(pv->tp_val, TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) break; if ((a1 = topo_hdl_alloc(thp, sizeof (nvlist_t *) * *nelems)) == NULL) { ret = ETOPO_NOMEM; break; } for (i = 0; i < *nelems; ++i) { if (topo_hdl_nvdup(thp, a2[i], &a1[i]) < 0) { for (j = 0; j < i; ++j) nvlist_free(a1[j]); topo_hdl_free(thp, a1, sizeof (nvlist_t *) * *nelems); break; } } *(nvlist_t ***)val = a1; break; } default: ret = ETOPO_PROP_NOENT; } if (ret != 0) if (ret == ENOENT) return (get_properror(node, err, ETOPO_PROP_NOENT)); else if (ret < ETOPO_UNKNOWN) return (get_properror(node, err, ETOPO_PROP_NVL)); else return (get_properror(node, err, ret)); topo_node_unlock(node); return (0); }
/* * pset_validate_remove() * Check to see if the requested cpu removal would be acceptable. * Returns RCM_FAILURE if not. */ static int pset_validate_remove(nvlist_t *nvl, char **errorp) { int error = RCM_SUCCESS; int32_t old_total, new_total, removed_total; processorid_t *removed_list = NULL; /* list terminated by (-1). */ processorid_t *old_cpu_list = NULL, *new_cpu_list = NULL; int i, j; pool_conf_t *conf; pool_value_t *pvals[] = { NULL, NULL }; pool_resource_t **res = NULL; uint_t nelem; const char *generic_error = gettext("POOL: Error processing request\n"); if ((conf = pool_conf_alloc()) == NULL) return (RCM_FAILURE); if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) < 0) { rcm_log_message(RCM_TRACE1, "POOL: failed to parse config file: '%s'\n", pool_dynamic_location()); pool_conf_free(conf); return (RCM_SUCCESS); } if ((error = nvlist_lookup_int32(nvl, "old_total", &old_total)) != 0) { (void) pool_conf_close(conf); pool_conf_free(conf); rcm_log_message(RCM_ERROR, gettext("POOL: unable to find 'old_total' in nvlist: %s\n"), strerror(error)); *errorp = strdup(generic_error); return (RCM_FAILURE); } if ((error = nvlist_lookup_int32(nvl, "new_total", &new_total)) != 0) { (void) pool_conf_close(conf); pool_conf_free(conf); rcm_log_message(RCM_ERROR, gettext("POOL: unable to find 'new_total' in nvlist: %s\n"), strerror(error)); *errorp = strdup(generic_error); return (RCM_FAILURE); } if (new_total >= old_total) { (void) pool_conf_close(conf); pool_conf_free(conf); /* * This doesn't look like a cpu removal. */ rcm_log_message(RCM_TRACE1, gettext("POOL: 'old_total' (%d) is less than 'new_total' " "(%d)\n"), old_total, new_total); return (RCM_SUCCESS); } if ((removed_list = malloc((old_total - new_total + 1) * sizeof (int))) == NULL) { rcm_log_message(RCM_ERROR, gettext("POOL: malloc failed: %s\n"), strerror(errno)); error = RCM_FAILURE; goto out; } if ((error = nvlist_lookup_int32_array(nvl, "old_cpu_list", &old_cpu_list, &nelem)) != 0) { rcm_log_message(RCM_ERROR, gettext("POOL: 'old_cpu_list' not found in nvlist: %s\n"), strerror(error)); error = RCM_FAILURE; goto out; } if ((int32_t)nelem != old_total) { rcm_log_message(RCM_ERROR, gettext("POOL: 'old_cpu_list' size mismatch: %1$d vs " "%2$d\n"), nelem, old_total); error = RCM_FAILURE; goto out; } if ((error = nvlist_lookup_int32_array(nvl, "new_cpu_list", &new_cpu_list, &nelem)) != 0) { rcm_log_message(RCM_ERROR, gettext("POOL: 'new_cpu_list' not found in nvlist: %s\n"), strerror(error)); error = RCM_FAILURE; goto out; } if (nelem != new_total) { rcm_log_message(RCM_ERROR, gettext("POOL: 'new_cpu_list' size mismatch: %1$d vs " "%2$d\n"), nelem, new_total); error = RCM_FAILURE; goto out; } for (i = 0, removed_total = 0; i < old_total; i++) { for (j = 0; j < new_total; j++) if (old_cpu_list[i] == new_cpu_list[j]) break; if (j == new_total) /* not found in new_cpu_list */ removed_list[removed_total++] = old_cpu_list[i]; } removed_list[removed_total] = -1; if (removed_total != (old_total - new_total)) { rcm_log_message(RCM_ERROR, gettext("POOL: error finding removed cpu list\n")); error = RCM_FAILURE; goto out; } if ((pvals[0] = pool_value_alloc()) == NULL) { rcm_log_message(RCM_ERROR, gettext("POOL: pool_value_alloc" " failed: %s\n"), strerror(errno)); error = RCM_FAILURE; goto out; } /* * Look for resources with "'type' = 'pset'" */ (void) pool_value_set_name(pvals[0], "type"); (void) pool_value_set_string(pvals[0], "pset"); if ((res = pool_query_resources(conf, &nelem, pvals)) == NULL) { rcm_log_message(RCM_ERROR, gettext("POOL: No psets found in configuration\n")); pool_value_free(pvals[0]); error = RCM_FAILURE; goto out; } pool_value_free(pvals[0]); for (i = 0; res[i] != NULL; i++) /* * Ask each pset if removing these cpus would cause it to go * below it's minimum value. */ if (pool_check_pset(conf, res[i], removed_list, errorp) < 0) { error = RCM_FAILURE; break; } free(res); out: if (removed_list) free(removed_list); if (conf) { (void) pool_conf_close(conf); pool_conf_free(conf); } /* * Set the error string if not already set. */ if (error != RCM_SUCCESS && *errorp == NULL) *errorp = strdup(generic_error); return (error); }
/*ARGSUSED*/ uint_t fmevt_pp_smf(char *classes[FMEVT_FANOUT_MAX], nvlist_t *attr[FMEVT_FANOUT_MAX], const char *ruleset, const nvlist_t *detector, nvlist_t *rawattr, const struct fmevt_ppargs *eap) { int32_t transition, from, to; const char *fromstr, *tostr; char *svcname, *rsn, *rsnl; nvlist_t *myattr; nvlist_t *fmri; uint32_t ver; if (!fmd_prop_get_int32(fmevt_hdl, "inbound_postprocess_smf")) return (0); if (rawattr == NULL || strcmp(eap->pp_rawclass, "state-transition") != 0 || nvlist_lookup_string(rawattr, "fmri", &svcname) != 0 || nvlist_lookup_int32(rawattr, "transition", &transition) != 0 || nvlist_lookup_string(rawattr, "reason-short", &rsn) != 0 || nvlist_lookup_string(rawattr, "reason-long", &rsnl) != 0 || nvlist_lookup_uint32(rawattr, "reason-version", &ver) != 0) return (0); from = transition >> 16; to = transition & 0xffff; fromstr = smf_state_to_string(from); tostr = smf_state_to_string(to); if (fromstr == NULL || tostr == NULL) return (0); if (strcmp(eap->pp_rawsubclass, tostr) != 0) return (0); if ((fmri = shortfmri_to_fmri(fmevt_hdl, svcname)) == NULL) return (0); if (snprintf(classes[0], FMEVT_MAX_CLASS, "%s.%s.%s.%s", FM_IREPORT_CLASS, "os.smf", eap->pp_rawclass, eap->pp_rawsubclass) >= FMEVT_MAX_CLASS - 1) return (0); if ((myattr = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP)) == NULL) return (0); if (nvlist_add_nvlist(myattr, "svc", fmri) != 0 || nvlist_add_string(myattr, "svc-string", svcname) != 0 || nvlist_add_string(myattr, "from-state", fromstr) != 0 || nvlist_add_string(myattr, "to-state", tostr) != 0 || nvlist_add_uint32(myattr, "reason-version", ver) != 0 || nvlist_add_string(myattr, "reason-short", rsn) != 0 || nvlist_add_string(myattr, "reason-long", rsnl) != 0) { nvlist_free(fmri); nvlist_free(myattr); return (0); } attr[0] = myattr; nvlist_free(fmri); return (1); }
/* ARGSUSED */ static int ipgpc_modify_action(ipp_action_id_t aid, nvlist_t **nvlpp, ipp_flags_t flags) { nvlist_t *nvlp; int rc = 0; uint8_t config_type; uint32_t stat; char *name; int32_t filter_instance; ipgpc_filter_t *filter; ipgpc_class_t *aclass; nvlp = *nvlpp; *nvlpp = NULL; /* nvlist should be NULL when this returns */ if ((rc = nvlist_lookup_byte(nvlp, IPP_CONFIG_TYPE, &config_type)) != 0) { nvlist_free(nvlp); ipgpc0dbg(("ipgpc_modify_action: invalid configuration type")); return (EINVAL); } switch (config_type) { case IPP_SET: /* set an action parameter */ if ((rc = nvlist_lookup_uint32(nvlp, IPP_ACTION_STATS_ENABLE, &stat)) != 0) { nvlist_free(nvlp); ipgpc0dbg(("ipgpc_modify_action: invalid IPP_SET " \ "parameter")); return (EINVAL); } else { ipgpc_gather_stats = (boolean_t)stat; } break; case CLASSIFIER_ADD_FILTER: /* add a filter */ filter = kmem_zalloc(sizeof (ipgpc_filter_t), KM_SLEEP); if ((rc = ipgpc_parse_filter(filter, nvlp)) != 0) { ipgpc0dbg(("ipgpc_modify_action: invalid filter")); ipgpc_filter_destructor(filter); kmem_free(filter, sizeof (ipgpc_filter_t)); break; } /* parse class name */ if ((rc = nvlist_lookup_string(nvlp, CLASSIFIER_CLASS_NAME, &name)) != 0) { ipgpc0dbg(("ipgpc_modify_action: class name missing")); ipgpc_filter_destructor(filter); kmem_free(filter, sizeof (ipgpc_filter_t)); break; } rc = ipgpc_addfilter(filter, name, flags); if (rc != 0) { ipgpc_filter_destructor(filter); } kmem_free(filter, sizeof (ipgpc_filter_t)); break; case CLASSIFIER_ADD_CLASS: /* add a class */ aclass = kmem_zalloc(sizeof (ipgpc_class_t), KM_SLEEP); if ((rc = ipgpc_parse_class(aclass, nvlp)) != 0) { ipgpc0dbg(("ipgpc_modify_action: invalid class")); kmem_free(aclass, sizeof (ipgpc_class_t)); break; } rc = ipgpc_addclass(aclass, flags); kmem_free(aclass, sizeof (ipgpc_class_t)); break; case CLASSIFIER_REMOVE_FILTER: /* remove a filter */ /* parse filter name */ if ((rc = nvlist_lookup_string(nvlp, CLASSIFIER_FILTER_NAME, &name)) != 0) { ipgpc0dbg(("ipgpc_modify_action: filtername missing")); break; } /* parse optional filter_instance */ if (nvlist_lookup_int32(nvlp, IPGPC_FILTER_INSTANCE, &filter_instance) != 0) { filter_instance = -1; } rc = ipgpc_removefilter(name, filter_instance, flags); break; case CLASSIFIER_REMOVE_CLASS: /* remove a class */ /* parse class name */ if ((rc = nvlist_lookup_string(nvlp, CLASSIFIER_CLASS_NAME, &name)) != 0) { ipgpc0dbg(("ipgpc_modify_action: class name missing")); break; } rc = ipgpc_removeclass(name, flags); break; case CLASSIFIER_MODIFY_FILTER: /* modify a filter */ rc = ipgpc_modifyfilter(&nvlp, flags); break; case CLASSIFIER_MODIFY_CLASS: /* modify a class */ rc = ipgpc_modifyclass(&nvlp, flags); break; default: /* invalid config type */ nvlist_free(nvlp); ipgpc0dbg(("ipgpc_modify_action:invalid configuration type %u", config_type)); return (EINVAL); } nvlist_free(nvlp); /* free the list */ return (rc); /* nvlist is passed back NULL */ }
static int create_strand(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth, uint16_t chip_smbiosid) { tnode_t *strand; int32_t strandid, cpuid; int err, perr, nerr = 0; nvlist_t *fmri; char *serial = NULL; char *part = NULL; char *rev = NULL; if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_STRAND_ID, &strandid)) != 0) { whinge(mod, NULL, "create_strand: lookup strand_id failed: " "%s\n", strerror(err)); return (-1); } if ((strand = topo_node_lookup(pnode, STRAND_NODE_NAME, strandid)) != NULL) { whinge(mod, NULL, "create_strand: duplicate tuple found\n"); return (-1); } if ((strand = create_node(mod, pnode, auth, STRAND_NODE_NAME, strandid, chip_smbiosid)) == NULL) return (-1); /* * Inherit FRU from core node, in native use cpu scheme ASRU, * in xpv, use hc scheme ASRU. */ (void) topo_node_fru_set(strand, NULL, 0, &perr); /* * From the inherited FRU, extract the Serial * number(if SMBIOS donates) and set it in the ASRU */ if (FM_AWARE_SMBIOS(mod)) { char *val = NULL; if (topo_prop_get_fmri(strand, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, &fmri, &err) != 0) whinge(mod, NULL, "create_strand: topo_prop_get_fmri failed\n"); if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &val) != 0) whinge(mod, NULL, "create_strand: nvlist_lookup_string failed: \n"); else serial = topo_mod_strdup(mod, val); nvlist_free(fmri); } if (is_xpv()) { if (topo_node_resource(strand, &fmri, &err) == -1) { whinge(mod, &nerr, "create_strand: " "topo_node_resource failed\n"); } else { if (FM_AWARE_SMBIOS(mod)) (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); (void) topo_node_asru_set(strand, fmri, 0, &err); nvlist_free(fmri); } } else { if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { whinge(mod, &nerr, "create_strand: lookup cpuid " "failed\n"); } else { if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0)) != NULL) { (void) topo_node_asru_set(strand, fmri, 0, &err); nvlist_free(fmri); } else { whinge(mod, &nerr, "create_strand: " "cpu_fmri_create() failed\n"); } } } if (topo_method_register(mod, strand, strands_retire_methods) < 0) whinge(mod, &nerr, "create_strand: " "topo_method_register failed\n"); (void) topo_pgroup_create(strand, &strand_pgroup, &err); nerr -= add_nvlist_longprops(mod, strand, cpu, PGNAME(STRAND), NULL, STRAND_CHIP_ID, STRAND_PROCNODE_ID, STRAND_CORE_ID, STRAND_CPU_ID, NULL); if (FM_AWARE_SMBIOS(mod)) { (void) topo_node_label_set(strand, NULL, &perr); if (topo_node_resource(strand, &fmri, &perr) != 0) { whinge(mod, &nerr, "create_strand: " "topo_node_resource failed\n"); perr = 0; } perr += nvlist_lookup_string(fmri, FM_FMRI_HC_PART, &part); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_REVISION, &rev); if (perr != 0) { whinge(mod, NULL, "create_strand: nvlist_lookup_string failed\n"); perr = 0; } perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr); perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr); perr += topo_prop_set_string(strand, PGNAME(STRAND), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr); if (perr != 0) whinge(mod, NULL, "create_strand: topo_prop_set_string" "failed\n"); nvlist_free(fmri); topo_mod_strfree(mod, serial); } return (err == 0 && nerr == 0 ? 0 : -1); }
static int create_core(topo_mod_t *mod, tnode_t *pnode, nvlist_t *cpu, nvlist_t *auth, uint16_t chip_smbiosid) { tnode_t *core; int32_t coreid, cpuid; int err, perr, nerr = 0; nvlist_t *fmri; char *serial = NULL; char *part = NULL; char *rev = NULL; if ((err = nvlist_lookup_int32(cpu, FM_PHYSCPU_INFO_CORE_ID, &coreid)) != 0) { whinge(mod, NULL, "create_core: lookup core_id failed: %s\n", strerror(err)); return (-1); } if ((core = topo_node_lookup(pnode, CORE_NODE_NAME, coreid)) == NULL) { if ((core = create_node(mod, pnode, auth, CORE_NODE_NAME, coreid, chip_smbiosid)) == NULL) return (-1); /* * Inherit FRU from the chip node, for native, we use hc * scheme ASRU for the core node. */ (void) topo_node_fru_set(core, NULL, 0, &perr); /* * From the inherited FRU, extract the Serial * number if SMBIOS donates and set it in the ASRU */ if (FM_AWARE_SMBIOS(mod)) { char *val = NULL; if (topo_node_resource(core, &fmri, &err) != 0) whinge(mod, NULL, "create_core: topo_prop_get_fmri failed\n"); if (nvlist_lookup_string(fmri, FM_FMRI_HC_SERIAL_ID, &val) != 0) whinge(mod, NULL, "create_core:" "nvlist_lookup_string failed\n"); else serial = topo_mod_strdup(mod, val); nvlist_free(fmri); } if (is_xpv()) { if (topo_node_resource(core, &fmri, &err) == -1) { whinge(mod, &nerr, "create_core: " "topo_node_resource failed\n"); } else { if (FM_AWARE_SMBIOS(mod)) (void) nvlist_add_string(fmri, FM_FMRI_HC_SERIAL_ID, serial); (void) topo_node_asru_set(core, fmri, 0, &err); nvlist_free(fmri); } } if (topo_method_register(mod, core, strands_retire_methods) < 0) whinge(mod, &nerr, "create_core: " "topo_method_register failed\n"); (void) topo_pgroup_create(core, &core_pgroup, &err); nerr -= add_nvlist_longprops(mod, core, cpu, PGNAME(CORE), NULL, CORE_CHIP_ID, CORE_PROCNODE_ID, NULL); if (topo_node_range_create(mod, core, STRAND_NODE_NAME, 0, 255) != 0) return (-1); } if (!is_xpv()) { /* * In native mode, we're in favor of cpu scheme ASRU for * printing reason. More work needs to be done to support * multi-strand cpu: the ASRU will be a list of cpuid then. */ if (nvlist_lookup_int32(cpu, STRAND_CPU_ID, &cpuid) != 0) { whinge(mod, &nerr, "create_core: lookup cpuid " "failed\n"); } else { if ((fmri = cpu_fmri_create(mod, cpuid, serial, 0)) != NULL) { (void) topo_node_asru_set(core, fmri, 0, &err); nvlist_free(fmri); } else { whinge(mod, &nerr, "create_core: " "cpu_fmri_create() failed\n"); } } } if (FM_AWARE_SMBIOS(mod)) { (void) topo_node_label_set(core, NULL, &perr); if (topo_node_resource(core, &fmri, &perr) != 0) { whinge(mod, &nerr, "create_core: " "topo_node_resource failed\n"); perr = 0; } perr += nvlist_lookup_string(fmri, FM_FMRI_HC_PART, &part); perr += nvlist_lookup_string(fmri, FM_FMRI_HC_REVISION, &rev); if (perr != 0) { whinge(mod, NULL, "create_core: nvlist_lookup_string failed\n"); perr = 0; } perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_SERIAL_ID, TOPO_PROP_IMMUTABLE, serial, &perr); perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_PART, TOPO_PROP_IMMUTABLE, part, &perr); perr += topo_prop_set_string(core, PGNAME(CORE), FM_FMRI_HC_REVISION, TOPO_PROP_IMMUTABLE, rev, &perr); if (perr != 0) whinge(mod, NULL, "create_core: topo_prop_set_string" "failed\n"); nvlist_free(fmri); topo_mod_strfree(mod, serial); } err = create_strand(mod, core, cpu, auth, chip_smbiosid); return (err == 0 && nerr == 0 ? 0 : -1); }
/*ARGSUSED3*/ static nvlist_t * fmevt_detector(nvlist_t *attr, char *ruleset, int user, int priv, fmev_pri_t pri) { char buf[FMEV_MAX_RULESET_LEN + 1]; char *ns, *subsys; nvlist_t *obj, *dtcr, *site, *ctxt; char *execname = NULL; int32_t i32; int64_t i64; int err = 0; char *str; (void) strncpy(buf, ruleset, sizeof (buf)); if (!fmevt_rs_burst(NULL, buf, &ns, &subsys, B_FALSE)) return (NULL); obj = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP); dtcr = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP); site = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP); ctxt = fmd_nvl_alloc(fmevt_hdl, FMD_SLEEP); if (obj == NULL || dtcr == NULL || site == NULL || ctxt == NULL) { err++; goto done; } /* * Build up 'object' nvlist. */ if (nvlist_lookup_string(attr, "__fmev_execname", &execname) == 0) err += nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, execname); /* * Build up 'site' nvlist. We should have source file and line * number and, if the producer was compiled with C99, function name. */ if (nvlist_lookup_string(attr, "__fmev_file", &str) == 0) { err += nvlist_add_string(site, FM_FMRI_SW_SITE_FILE, str); (void) nvlist_remove(attr, "__fmev_file", DATA_TYPE_STRING); } if (nvlist_lookup_string(attr, "__fmev_func", &str) == 0) { err += nvlist_add_string(site, FM_FMRI_SW_SITE_FUNC, str); (void) nvlist_remove(attr, "__fmev_func", DATA_TYPE_STRING); } if (nvlist_lookup_int64(attr, "__fmev_line", &i64) == 0) { err += nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, i64); (void) nvlist_remove(attr, "__fmev_line", DATA_TYPE_INT64); } /* * Build up 'context' nvlist. We do not include contract id at * this time. */ err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN, user ? "userland" : "kernel"); if (execname) { err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME, execname); (void) nvlist_remove(attr, "__fmev_execname", DATA_TYPE_STRING); } if (nvlist_lookup_int32(attr, "__fmev_pid", &i32) == 0) { err += nvlist_add_int32(ctxt, FM_FMRI_SW_CTXT_PID, i32); (void) nvlist_remove(attr, "__fmev_pid", DATA_TYPE_INT32); } if (!isglobalzone) err += nvlist_add_string(ctxt, FM_FMRI_SW_CTXT_ZONE, zonename); /* Put it all together */ err += nvlist_add_uint8(dtcr, FM_VERSION, SW_SCHEME_VERSION0); err += nvlist_add_string(dtcr, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW); err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_OBJ, obj); err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_SITE, site); err += nvlist_add_nvlist(dtcr, FM_FMRI_SW_CTXT, ctxt); done: nvlist_free(obj); nvlist_free(site); nvlist_free(ctxt); if (err == 0) { return (dtcr); } else { nvlist_free(dtcr); return (NULL); } }