/* * Enable processor set plugin. */ int pool_pset_enable(void) { int error; nvlist_t *props; ASSERT(pool_lock_held()); ASSERT(INGLOBALZONE(curproc)); /* * Can't enable pools if there are existing cpu partitions. */ mutex_enter(&cpu_lock); if (cp_numparts > 1) { mutex_exit(&cpu_lock); return (EEXIST); } /* * We want to switch things such that everything that was tagged with * the special ALL_ZONES token now is explicitly visible to all zones: * first add individual zones to the visibility list then remove the * special "ALL_ZONES" token. There must only be the default pset * (PS_NONE) active if pools are being enabled, so we only need to * deal with it. * * We want to make pool_pset_enabled() start returning B_TRUE before * we call any of the visibility update functions. */ global_zone->zone_psetid = PS_NONE; /* * We need to explicitly handle the global zone since * zone_pset_set() won't modify it. */ pool_pset_visibility_add(PS_NONE, global_zone); /* * A NULL argument means the ALL_ZONES token. */ pool_pset_visibility_remove(PS_NONE, NULL); error = zone_walk(pool_pset_zone_pset_set, (void *)PS_NONE); ASSERT(error == 0); /* * It is safe to drop cpu_lock here. We're still * holding pool_lock so no new cpu partitions can * be created while we're here. */ mutex_exit(&cpu_lock); (void) nvlist_alloc(&pool_pset_default->pset_props, NV_UNIQUE_NAME, KM_SLEEP); props = pool_pset_default->pset_props; (void) nvlist_add_string(props, "pset.name", "pset_default"); (void) nvlist_add_string(props, "pset.comment", ""); (void) nvlist_add_int64(props, "pset.sys_id", PS_NONE); (void) nvlist_add_string(props, "pset.units", "population"); (void) nvlist_add_byte(props, "pset.default", 1); (void) nvlist_add_uint64(props, "pset.max", 65536); (void) nvlist_add_uint64(props, "pset.min", 1); pool_pset_mod = pool_cpu_mod = gethrtime(); return (0); }
/* * Create new processor set and give it a temporary name. */ int pool_pset_create(psetid_t *id) { char pset_name[40]; pool_pset_t *pset; psetid_t psetid; int err; ASSERT(pool_lock_held()); if ((err = cpupart_create(&psetid)) != 0) return (err); pset = kmem_alloc(sizeof (pool_pset_t), KM_SLEEP); pset->pset_id = *id = psetid; pset->pset_npools = 0; (void) nvlist_alloc(&pset->pset_props, NV_UNIQUE_NAME, KM_SLEEP); (void) nvlist_add_int64(pset->pset_props, "pset.sys_id", psetid); (void) nvlist_add_byte(pset->pset_props, "pset.default", 0); pool_pset_mod = gethrtime(); (void) snprintf(pset_name, sizeof (pset_name), "pset_%lld", pool_pset_mod); (void) nvlist_add_string(pset->pset_props, "pset.name", pset_name); list_insert_tail(&pool_pset_list, pset); return (0); }
void fnvlist_add_int64(nvlist_t *nvl, const char *name, int64_t val) { VERIFY0(nvlist_add_int64(nvl, name, val)); }
static void set_prop(topo_hdl_t *thp, tnode_t *node, nvlist_t *fmri, struct prop_args *pp) { int ret, err = 0; topo_type_t type; nvlist_t *nvl, *f = NULL; char *end; if (pp->prop == NULL || pp->type == NULL || pp->value == NULL) return; if ((type = str2type(pp->type)) == TOPO_TYPE_INVALID) { (void) fprintf(stderr, "%s: invalid property type %s for %s\n", g_pname, pp->type, pp->prop); return; } if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { (void) fprintf(stderr, "%s: nvlist allocation failed for " "%s=%s:%s\n", g_pname, pp->prop, pp->type, pp->value); return; } ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pp->prop); ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type); if (ret != 0) { (void) fprintf(stderr, "%s: invalid property type %s for %s\n", g_pname, pp->type, pp->prop); nvlist_free(nvl); return; } errno = 0; switch (type) { case TOPO_TYPE_INT32: { int32_t val; val = strtol(pp->value, &end, 0); if (errno == ERANGE) { ret = -1; break; } ret = nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, val); break; } case TOPO_TYPE_UINT32: { uint32_t val; val = strtoul(pp->value, &end, 0); if (errno == ERANGE) { ret = -1; break; } ret = nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, val); break; } case TOPO_TYPE_INT64: { int64_t val; val = strtoll(pp->value, &end, 0); if (errno == ERANGE) { ret = -1; break; } ret = nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, val); break; } case TOPO_TYPE_UINT64: { uint64_t val; val = strtoull(pp->value, &end, 0); if (errno == ERANGE) { ret = -1; break; } ret = nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, val); break; } case TOPO_TYPE_STRING: { ret = nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, pp->value); break; } case TOPO_TYPE_FMRI: { if ((ret = topo_fmri_str2nvl(thp, pp->value, &f, &err)) < 0) break; if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, f)) != 0) err = ETOPO_PROP_NVL; break; } default: ret = -1; } if (ret != 0) { (void) fprintf(stderr, "%s: unable to set property value for " "%s: %s\n", g_pname, pp->prop, topo_strerror(err)); nvlist_free(nvl); return; } if (node != NULL) { if (topo_prop_setprop(node, pp->group, nvl, TOPO_PROP_MUTABLE, f, &ret) < 0) { (void) fprintf(stderr, "%s: unable to set property " "value for " "%s=%s:%s: %s\n", g_pname, pp->prop, pp->type, pp->value, topo_strerror(ret)); nvlist_free(nvl); nvlist_free(f); return; } } else { if (topo_fmri_setprop(thp, fmri, pp->group, nvl, TOPO_PROP_MUTABLE, f, &ret) < 0) { (void) fprintf(stderr, "%s: unable to set property " "value for " "%s=%s:%s: %s\n", g_pname, pp->prop, pp->type, pp->value, topo_strerror(ret)); nvlist_free(nvl); nvlist_free(f); return; } } nvlist_free(nvl); /* * Now, get the property back for printing */ if (node != NULL) { if (topo_prop_getprop(node, pp->group, pp->prop, f, &nvl, &err) < 0) { (void) fprintf(stderr, "%s: failed to get %s.%s: %s\n", g_pname, pp->group, pp->prop, topo_strerror(err)); nvlist_free(f); return; } } else { if (topo_fmri_getprop(thp, fmri, pp->group, pp->prop, f, &nvl, &err) < 0) { (void) fprintf(stderr, "%s: failed to get %s.%s: %s\n", g_pname, pp->group, pp->prop, topo_strerror(err)); nvlist_free(f); return; } } print_pgroup(thp, node, pp->group, NULL, NULL, 0); print_prop_nameval(thp, node, nvl); nvlist_free(nvl); nvlist_free(f); }
static int topo_prop_set(tnode_t *node, const char *pgname, const char *pname, topo_type_t type, int flag, void *val, int nelems, int *err) { int ret; topo_hdl_t *thp = node->tn_hdl; nvlist_t *nvl; if (topo_hdl_nvalloc(thp, &nvl, NV_UNIQUE_NAME) < 0) { *err = ETOPO_PROP_NVL; return (-1); } ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pname); ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type); switch (type) { case TOPO_TYPE_INT32: ret |= nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, *(int32_t *)val); break; case TOPO_TYPE_UINT32: ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, *(uint32_t *)val); break; case TOPO_TYPE_INT64: ret |= nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, *(int64_t *)val); break; case TOPO_TYPE_UINT64: ret |= nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, *(uint64_t *)val); break; case TOPO_TYPE_DOUBLE: ret |= nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, *(double *)val); break; case TOPO_TYPE_STRING: ret |= nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, (char *)val); break; case TOPO_TYPE_FMRI: ret |= nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, (nvlist_t *)val); break; case TOPO_TYPE_INT32_ARRAY: ret |= nvlist_add_int32_array(nvl, TOPO_PROP_VAL_VAL, (int32_t *)val, nelems); break; case TOPO_TYPE_UINT32_ARRAY: ret |= nvlist_add_uint32_array(nvl, TOPO_PROP_VAL_VAL, (uint32_t *)val, nelems); break; case TOPO_TYPE_INT64_ARRAY: ret |= nvlist_add_int64_array(nvl, TOPO_PROP_VAL_VAL, (int64_t *)val, nelems); break; case TOPO_TYPE_UINT64_ARRAY: ret |= nvlist_add_uint64_array(nvl, TOPO_PROP_VAL_VAL, (uint64_t *)val, nelems); break; case TOPO_TYPE_STRING_ARRAY: ret |= nvlist_add_string_array(nvl, TOPO_PROP_VAL_VAL, (char **)val, nelems); break; case TOPO_TYPE_FMRI_ARRAY: ret |= nvlist_add_nvlist_array(nvl, TOPO_PROP_VAL_VAL, (nvlist_t **)val, nelems); break; default: *err = ETOPO_PROP_TYPE; return (-1); } if (ret != 0) { nvlist_free(nvl); if (ret == ENOMEM) { *err = ETOPO_PROP_NOMEM; return (-1); } else { *err = ETOPO_PROP_NVL; return (-1); } } if (topo_prop_setprop(node, pgname, nvl, flag, nvl, err) != 0) { nvlist_free(nvl); return (-1); /* err set */ } nvlist_free(nvl); return (ret); }
/* * Take a snapshot of the current state of processor sets and CPUs, * pack it in the exacct format, and attach it to specified exacct record. */ int pool_pset_pack(ea_object_t *eo_system) { ea_object_t *eo_pset, *eo_cpu; cpupart_t *cpupart; psetid_t mypsetid; pool_pset_t *pset; nvlist_t *nvl; size_t bufsz; cpu_t *cpu; char *buf; int ncpu; ASSERT(pool_lock_held()); mutex_enter(&cpu_lock); mypsetid = zone_pset_get(curproc->p_zone); for (pset = list_head(&pool_pset_list); pset; pset = list_next(&pool_pset_list, pset)) { psetid_t psetid = pset->pset_id; if (!INGLOBALZONE(curproc) && mypsetid != psetid) continue; cpupart = cpupart_find(psetid); ASSERT(cpupart != NULL); eo_pset = ea_alloc_group(EXT_GROUP | EXC_LOCAL | EXD_GROUP_PSET); (void) ea_attach_item(eo_pset, &psetid, sizeof (id_t), EXC_LOCAL | EXD_PSET_PSETID | EXT_UINT32); /* * Pack info for all CPUs in this processor set. */ ncpu = 0; cpu = cpu_list; do { if (cpu->cpu_part != cpupart) /* not our pset */ continue; ncpu++; eo_cpu = ea_alloc_group(EXT_GROUP | EXC_LOCAL | EXD_GROUP_CPU); (void) ea_attach_item(eo_cpu, &cpu->cpu_id, sizeof (processorid_t), EXC_LOCAL | EXD_CPU_CPUID | EXT_UINT32); if (cpu->cpu_props == NULL) { (void) nvlist_alloc(&cpu->cpu_props, NV_UNIQUE_NAME, KM_SLEEP); (void) nvlist_add_string(cpu->cpu_props, "cpu.comment", ""); } (void) nvlist_dup(cpu->cpu_props, &nvl, KM_SLEEP); (void) nvlist_add_int64(nvl, "cpu.sys_id", cpu->cpu_id); (void) nvlist_add_string(nvl, "cpu.status", (char *)cpu_get_state_str(cpu)); buf = NULL; bufsz = 0; (void) nvlist_pack(nvl, &buf, &bufsz, NV_ENCODE_NATIVE, 0); (void) ea_attach_item(eo_cpu, buf, bufsz, EXC_LOCAL | EXD_CPU_PROP | EXT_RAW); (void) nvlist_free(nvl); kmem_free(buf, bufsz); (void) ea_attach_to_group(eo_pset, eo_cpu); } while ((cpu = cpu->cpu_next) != cpu_list); (void) nvlist_dup(pset->pset_props, &nvl, KM_SLEEP); (void) nvlist_add_uint64(nvl, "pset.size", ncpu); (void) nvlist_add_uint64(nvl, "pset.load", (uint64_t)PSET_LOAD(cpupart->cp_hp_avenrun[0])); buf = NULL; bufsz = 0; (void) nvlist_pack(nvl, &buf, &bufsz, NV_ENCODE_NATIVE, 0); (void) ea_attach_item(eo_pset, buf, bufsz, EXC_LOCAL | EXD_PSET_PROP | EXT_RAW); (void) nvlist_free(nvl); kmem_free(buf, bufsz); (void) ea_attach_to_group(eo_system, eo_pset); } mutex_exit(&cpu_lock); return (0); }
/*ARGSUSED*/ static int sw_fmri_create(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { nvlist_t *args, *fmri = NULL, *obj = NULL, *site = NULL, *ctxt = NULL; topo_mod_errno_t moderr; int err = 0; char *obj_path, *obj_root; nvlist_t *obj_pkg; char *site_token, *site_module, *site_file, *site_func; int64_t site_line; char *ctxt_origin, *ctxt_execname, *ctxt_zone; int64_t ctxt_pid, ctxt_ctid; char **ctxt_stack; uint_t ctxt_stackdepth; if (version > TOPO_METH_FMRI_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args) != 0) return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); if (nvlist_lookup_string(args, "obj_path", &obj_path) != 0) return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); err |= sw_get_optl_string(args, "obj_root", &obj_root); err |= sw_get_optl_nvlist(args, "obj-pkg", &obj_pkg); err |= sw_get_optl_string(args, "site_token", &site_token); err |= sw_get_optl_string(args, "site_module", &site_module); err |= sw_get_optl_string(args, "site_file", &site_file); err |= sw_get_optl_string(args, "site_func", &site_func); err |= sw_get_optl_int64(args, "site_line", &site_line); err |= sw_get_optl_string(args, "ctxt_origin", &ctxt_origin); err |= sw_get_optl_string(args, "ctxt_execname", &ctxt_execname); err |= sw_get_optl_string(args, "ctxt_zone", &ctxt_zone); err |= sw_get_optl_int64(args, "ctxt_pid", &ctxt_pid); err |= sw_get_optl_int64(args, "ctxt_ctid", &ctxt_ctid); if (nvlist_lookup_string_array(args, "stack", &ctxt_stack, &ctxt_stackdepth) != 0) { if (errno == ENOENT) ctxt_stack = NULL; else err++; } if (err) (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0 || topo_mod_nvalloc(mod, &obj, NV_UNIQUE_NAME) != 0) { moderr = EMOD_NOMEM; goto out; } /* * Add standard FMRI members 'version' and 'scheme'. */ err |= nvlist_add_uint8(fmri, FM_VERSION, FM_SW_SCHEME_VERSION); err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW); /* * Build up the 'object' nvlist. */ err |= nvlist_add_string(obj, FM_FMRI_SW_OBJ_PATH, obj_path); err |= sw_add_optl_string(obj, FM_FMRI_SW_OBJ_ROOT, obj_root); if (obj_pkg) err |= nvlist_add_nvlist(obj, FM_FMRI_SW_OBJ_PKG, obj_pkg); /* * Add 'object' to the fmri. */ if (err == 0) err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_OBJ, obj); if (err) { moderr = EMOD_NOMEM; goto out; } /* * Do we have anything for a 'site' nvlist? */ if (site_token == NULL && site_module == NULL && site_file == NULL && site_func == NULL && site_line == -1) goto context; /* * Allocate and build 'site' nvlist. */ if (topo_mod_nvalloc(mod, &site, NV_UNIQUE_NAME) != 0) { moderr = EMOD_NOMEM; goto out; } err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_TOKEN, site_token); err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_MODULE, site_module); err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FILE, site_file); err |= sw_add_optl_string(site, FM_FMRI_SW_SITE_FUNC, site_func); if ((site_token || site_module || site_file || site_func) && site_line != -1) err |= nvlist_add_int64(site, FM_FMRI_SW_SITE_LINE, site_line); /* * Add 'site' to the fmri. */ if (err == 0) err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_SITE, site); if (err) { moderr = EMOD_NOMEM; goto out; } context: /* * Do we have anything for a 'context' nvlist? */ if (ctxt_origin || ctxt_execname || ctxt_zone || ctxt_pid != -1 || ctxt_ctid != -1 || ctxt_stack != NULL) goto out; /* * Allocate and build 'context' nvlist. */ if (topo_mod_nvalloc(mod, &ctxt, NV_UNIQUE_NAME) != 0) { moderr = EMOD_NOMEM; goto out; } err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ORIGIN, ctxt_origin); err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_EXECNAME, ctxt_execname); err |= sw_add_optl_string(ctxt, FM_FMRI_SW_CTXT_ZONE, ctxt_zone); if (ctxt_pid != -1) err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_PID, ctxt_pid); if (ctxt_ctid != -1) err |= nvlist_add_int64(ctxt, FM_FMRI_SW_CTXT_CTID, ctxt_ctid); if (ctxt_stack != NULL) err |= nvlist_add_string_array(ctxt, FM_FMRI_SW_CTXT_STACK, ctxt_stack, ctxt_stackdepth); /* * Add 'context' to the fmri. */ if (err == 0) err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_CTXT, ctxt); moderr = err ? EMOD_NOMEM : 0; out: if (moderr == 0) *out = fmri; if (moderr != 0 && fmri) nvlist_free(fmri); if (obj) nvlist_free(obj); if (site) nvlist_free(site); if (ctxt) nvlist_free(ctxt); return (moderr == 0 ? 0 : topo_mod_seterrno(mod, moderr)); }
/*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); } }