Exemplo n.º 1
0
/*ARGSUSED*/
static int
branch_dimm_cb(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	char *lbl, *p, *q;
	char cx[BUF_SIZE], cy[BUF_SIZE];
	nvlist_t *rsrc;
	int err;
	cmd_branch_t *branch = (cmd_branch_t *)arg;
	cmd_dimm_t *dimm;
	size_t nserids;
	char **serids;

	if (topo_node_resource(node, &rsrc, &err) < 0)
		return (TOPO_WALK_NEXT);	/* no label, try next */

	if ((nvlist_lookup_string(rsrc, FM_FMRI_MEM_UNUM, &lbl) != 0) ||
	    (nvlist_lookup_string_array(rsrc, FM_FMRI_MEM_SERIAL_ID,
	    &serids, &nserids) != 0)) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}

	/*
	 * Massage the unum of the candidate DIMM as follows:
	 * a) remove any trailing J number.  Use result for cmd_dimm_t.
	 * b) for branch membership purposes only, remove reference to
	 * a riser card (MR%d) if one exists.
	 */
	if ((p = strstr(lbl, "/J")) != NULL) {
		(void) strncpy(cx, lbl, p - lbl);
		cx[p - lbl] = '\0';
	} else {
		(void) strcpy(cx, lbl);
	}
	(void) strcpy(cy, cx);
	if ((p = strstr(cy, "/MR")) != NULL) {
		if ((q = strchr(p + 1, '/')) != NULL)
			(void) strcpy(p, q);
		else
			*p = '\0';
	}

	/*
	 * For benefit of Batoka-like platforms, start comparison with
	 * "CMP", so that any leading "MEM" or "CPU" makes no difference.
	 */

	p = strstr(branch->branch_unum, "CMP");
	q = strstr(cy, "CMP");

	if ((p != NULL) && (q != NULL) && strncmp(p, q, strlen(p)) == 0) {
		dimm = branch_dimm_create(br_hdl, cx, serids, nserids);
		if (dimm != NULL)
			cmd_branch_add_dimm(br_hdl, branch, dimm);
	}
	nvlist_free(rsrc);
	return (TOPO_WALK_NEXT);
}
Exemplo n.º 2
0
/*
 * Unpack a device path/nvlist pair to internal data list format.
 * Used to decode the nvlist format into the internal representation
 * when reading /etc/devices/devname_cache.
 * Note that the expiration counts are optional, for compatibility
 * with earlier instances of the cache.  If not present, the
 * expire counts are initialized to defaults.
 */
static int
sdev_ncache_unpack_nvlist(nvf_handle_t fd, nvlist_t *nvl, char *name)
{
	nvp_devname_t *np;
	char	**strs;
	int	*cnts;
	uint_t	nstrs, ncnts;
	int	rval, i;

	ASSERT(fd == sdevfd_handle);
	ASSERT(RW_WRITE_HELD(nvf_lock(fd)));

	/* name of the sublist must match what we created */
	if (strcmp(name, DP_DEVNAME_ID) != 0) {
		return (-1);
	}

	np = kmem_zalloc(sizeof (nvp_devname_t), KM_SLEEP);

	rval = nvlist_lookup_string_array(nvl,
	    DP_DEVNAME_NCACHE_ID, &strs, &nstrs);
	if (rval) {
		kmem_free(np, sizeof (nvp_devname_t));
		return (-1);
	}

	np->nvp_npaths = nstrs;
	np->nvp_paths = kmem_zalloc(nstrs * sizeof (char *), KM_SLEEP);
	for (i = 0; i < nstrs; i++) {
		np->nvp_paths[i] = i_ddi_strdup(strs[i], KM_SLEEP);
	}
	np->nvp_expirecnts = kmem_zalloc(nstrs * sizeof (int), KM_SLEEP);
	for (i = 0; i < nstrs; i++) {
		np->nvp_expirecnts[i] = sdev_nc_expirecnt;
	}

	rval = nvlist_lookup_int32_array(nvl,
	    DP_DEVNAME_NC_EXPIRECNT_ID, &cnts, &ncnts);
	if (rval == 0) {
		ASSERT(ncnts == nstrs);
		ncnts = min(ncnts, nstrs);
		for (i = 0; i < nstrs; i++) {
			np->nvp_expirecnts[i] = cnts[i];
		}
	}

	list_insert_tail(nvf_list(sdevfd_handle), np);

	return (0);
}
Exemplo n.º 3
0
static void
lst_print_array(nvlist_t *nvl, const char *key)
{
	int ret;
	uint_t i, count;
	char **vals;

	if ((ret = nvlist_lookup_string_array(nvl, key, &vals, &count)) != 0) {
		errx(1, "TEST FAILED failed to find key %s: %s\n", key,
		    strerror(ret));
	}

	(void) puts(key);
	for (i = 0; i < count; i++) {
		(void) printf("\t%d\t%s\n", i, vals[i]);
	}
}
Exemplo n.º 4
0
/*
 * Convert a device path/nvlist pair to an nvp_list_t
 * Used to parse the nvlist format when reading
 * /etc/devices/devname_cache
 */
static nvp_list_t *
sdev_nvl2nvp(nvlist_t *nvl, char *name)
{
	nvp_devname_t *np;
	char	**strs;
	int	*cnts;
	uint_t	nstrs, ncnts;
	int	rval, i;

	/* name of the sublist must match what we created */
	if (strcmp(name, DP_DEVNAME_ID) != 0) {
		return (NULL);
	}

	np = kmem_zalloc(sizeof (nvp_devname_t), KM_SLEEP);

	rval = nvlist_lookup_string_array(nvl,
	    DP_DEVNAME_NCACHE_ID, &strs, &nstrs);
	if (rval) {
		kmem_free(np, sizeof (nvp_devname_t));
		return (NULL);
	}

	np->nvp_npaths = nstrs;
	np->nvp_paths = kmem_zalloc(nstrs * sizeof (char *), KM_SLEEP);
	for (i = 0; i < nstrs; i++) {
		np->nvp_paths[i] = i_ddi_strdup(strs[i], KM_SLEEP);
	}
	np->nvp_expirecnts = kmem_zalloc(nstrs * sizeof (int), KM_SLEEP);
	for (i = 0; i < nstrs; i++) {
		np->nvp_expirecnts[i] = 4; /* XXX sdev_nc_expirecnt */
	}

	rval = nvlist_lookup_int32_array(nvl,
	    DP_DEVNAME_NC_EXPIRECNT_ID, &cnts, &ncnts);
	if (rval == 0) {
		ASSERT(ncnts == nstrs);
		ncnts = max(ncnts, nstrs);
		for (i = 0; i < nstrs; i++) {
			np->nvp_expirecnts[i] = cnts[i];
		}
	}

	return (NVPLIST(np));
}
Exemplo n.º 5
0
nvlist_t *
get_mem_fault_resource(fmd_hdl_t *hdl, nvlist_t *fru)
{
	char *sn;
	uint_t n;
	char **snarray;

	if (nvlist_lookup_string(fru, FM_FMRI_HC_SERIAL_ID, &sn) == 0)
		return (cmd_find_mem_rsc_by_sn(hdl, sn));

	/*
	 * T1 platform fru is in mem scheme
	 */
	if (nvlist_lookup_string_array(fru, FM_FMRI_MEM_SERIAL_ID,
	    &snarray, &n) == 0)
		return (cmd_find_mem_rsc_by_sn(hdl, snarray[0]));

	return (NULL);
}
Exemplo n.º 6
0
/*ARGSUSED*/
static int
find_dimm_sn_mem(topo_hdl_t *thp, tnode_t *node, void *arg)
{
	int err;
	uint_t n;
	nvlist_t *rsrc;
	char **sn;

	if (topo_node_resource(node, &rsrc, &err) < 0) {
		return (TOPO_WALK_NEXT);	/* no resource, try next */
	}
	if (nvlist_lookup_string_array(rsrc,
	    FM_FMRI_HC_SERIAL_ID, &sn, &n) != 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}
	if (strcmp(*sn, (char *)arg) != 0) {
		nvlist_free(rsrc);
		return (TOPO_WALK_NEXT);
	}
	(void) nvlist_dup(rsrc, &dimm_nvl, NV_UNIQUE_NAME);
	nvlist_free(rsrc);
	return (TOPO_WALK_TERMINATE);	/* if no space, give up */
}
Exemplo n.º 7
0
int
amd_rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl,
    nvlist_t *auth)
{
	uint64_t *csnumarr;
	char **csnamearr;
	uint_t ncs, ncsname;
	tnode_t *ranknode;
	nvlist_t *fmri, *pfmri = NULL;
	uint64_t dsz, rsz;
	int nerr = 0;
	int err;
	int i;

	if (nvlist_lookup_uint64_array(dimmnvl, "csnums", &csnumarr,
	    &ncs) != 0 || nvlist_lookup_string_array(dimmnvl, "csnames",
	    &csnamearr, &ncsname) != 0 || ncs != ncsname) {
		whinge(mod, &nerr, "amd_rank_create: "
		    "csnums/csnames extraction failed\n");
		return (nerr);
	}

	if (topo_node_resource(pnode, &pfmri, &err) < 0) {
		whinge(mod, &nerr, "amd_rank_create: parent fmri lookup "
		    "failed\n");
		return (nerr);
	}

	if (topo_node_range_create(mod, pnode, RANK_NODE_NAME, 0, ncs) < 0) {
		whinge(mod, &nerr, "amd_rank_create: range create failed\n");
		nvlist_free(pfmri);
		return (nerr);
	}

	if (topo_prop_get_uint64(pnode, PGNAME(DIMM), "size", &dsz,
	    &err) == 0) {
		rsz = dsz / ncs;
	} else {
		whinge(mod, &nerr, "amd_rank_create: parent dimm has no "
		    "size\n");
		return (nerr);
	}

	for (i = 0; i < ncs; i++) {
		if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, auth, &fmri) < 0) {
			whinge(mod, &nerr, "amd_rank_create: mkrsrc failed\n");
			continue;
		}

		if ((ranknode = topo_node_bind(mod, pnode, RANK_NODE_NAME, i,
		    fmri)) == NULL) {
			nvlist_free(fmri);
			whinge(mod, &nerr, "amd_rank_create: node bind "
			    "failed\n");
			continue;
		}

		nvlist_free(fmri);
		if (FM_AWARE_SMBIOS(mod))
			(void) topo_node_fru_set(ranknode, NULL, 0, &err);
		else
			(void) topo_node_fru_set(ranknode, pfmri, 0, &err);

		/*
		 * If a rank is faulted the asru is the associated
		 * chip-select, but if a page within a rank is faulted
		 * the asru is just that page.  Hence the dual preconstructed
		 * and computed ASRU.
		 */
		if (topo_method_register(mod, ranknode, rank_methods) < 0)
			whinge(mod, &nerr, "amd_rank_create: "
			    "topo_method_register failed");

		if (! is_xpv() && topo_method_register(mod, ranknode,
		    ntv_page_retire_methods) < 0)
			whinge(mod, &nerr, "amd_rank_create: "
			    "topo_method_register failed");

		(void) topo_node_asru_set(ranknode, cs_fmri[csnumarr[i]],
		    TOPO_ASRU_COMPUTE, &err);

		(void) topo_pgroup_create(ranknode, &rank_pgroup, &err);

		(void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "size",
		    TOPO_PROP_IMMUTABLE, rsz, &err);

		(void) topo_prop_set_string(ranknode, PGNAME(RANK), "csname",
		    TOPO_PROP_IMMUTABLE, csnamearr[i], &err);

		(void) topo_prop_set_uint64(ranknode, PGNAME(RANK), "csnum",
		    TOPO_PROP_IMMUTABLE, csnumarr[i], &err);
	}

	nvlist_free(pfmri);

	return (nerr);
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
0
/*
 * Actually processes events; returns a reply event
 */
static void
process_event(int cmd, int seq_num, nvlist_t *nvl, nvlist_t **ret)
{
	int i;
	int error;
	uint_t nvl_nrsrcs = 0;
	pid_t pid;
	uint32_t flag = (uint32_t)0;
	uint64_t pid64 = (uint64_t)0;
	size_t buflen = 0;
	size_t interval_size = 0;
	timespec_t *interval = NULL;
	nvlist_t *change_data = NULL;
	nvlist_t *event_data = NULL;
	rcm_info_t *info = NULL;
	char *modname = NULL;
	char *buf = NULL;
	char **rsrcnames = NULL;
	char **nvl_rsrcs = NULL;

	rcm_log_message(RCM_TRACE2, "servicing door command=%d\n", cmd);

	rcm_print_nvlist(nvl);

	/*
	 * Extract data from the door argument nvlist.  Not all arguments
	 * are needed; sanity checks are performed later.
	 */
	(void) nvlist_lookup_string_array(nvl, RCM_RSRCNAMES, &nvl_rsrcs,
	    &nvl_nrsrcs);
	(void) nvlist_lookup_string(nvl, RCM_CLIENT_MODNAME, &modname);
	(void) nvlist_lookup_uint64(nvl, RCM_CLIENT_ID, (uint64_t *)&pid64);
	pid = (pid_t)pid64;
	(void) nvlist_lookup_uint32(nvl, RCM_REQUEST_FLAG, (uint32_t *)&flag);
	(void) nvlist_lookup_byte_array(nvl, RCM_SUSPEND_INTERVAL,
	    (uchar_t **)&interval, &interval_size);
	(void) nvlist_lookup_byte_array(nvl, RCM_CHANGE_DATA, (uchar_t **)&buf,
	    &buflen);
	if (buf != NULL && buflen > 0) {
		(void) nvlist_unpack(buf, buflen, &change_data, 0);
		buf = NULL;
		buflen = 0;
	}
	(void) nvlist_lookup_byte_array(nvl, RCM_EVENT_DATA, (uchar_t **)&buf,
	    &buflen);
	if (buf != NULL && buflen > 0)
		(void) nvlist_unpack(buf, buflen, &event_data, 0);

	rsrcnames = s_calloc(nvl_nrsrcs + 1, sizeof (char *));
	for (i = 0; i < nvl_nrsrcs; i++) {
		rsrcnames[i] = nvl_rsrcs[i];
	}
	rsrcnames[nvl_nrsrcs] = NULL;

	/*
	 * Switch off the command being performed to do the appropriate
	 * sanity checks and dispatch the arguments to the appropriate
	 * implementation routine.
	 */
	switch (cmd) {
	case CMD_REGISTER:
		if ((modname == NULL) || (rsrcnames == NULL) ||
		    (rsrcnames[0] == NULL))
			goto faildata;
		error = add_resource_client(modname, rsrcnames[0], pid, flag,
		    &info);
		break;

	case CMD_UNREGISTER:
		if ((modname == NULL) || (rsrcnames == NULL) ||
		    (rsrcnames[0] == NULL))
			goto faildata;
		error = remove_resource_client(modname, rsrcnames[0], pid,
		    flag);
		break;

	case CMD_GETINFO:
		if ((rsrcnames == NULL) &&
		    ((flag & (RCM_DR_OPERATION | RCM_MOD_INFO)) == 0))
			goto faildata;
		if ((error = get_resource_info(rsrcnames, flag, seq_num, &info))
		    == EINVAL) {
			rcm_log_message(RCM_DEBUG,
			    "invalid argument in get info request\n");
			generate_reply_event(EINVAL, NULL, ret);
			return;
		}
		break;

	case CMD_SUSPEND:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) ||
		    (interval == NULL))
			goto faildata;
		error = process_resource_suspend(rsrcnames, pid, flag, seq_num,
		    interval, &info);
		break;

	case CMD_RESUME:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL))
			goto faildata;
		error = notify_resource_resume(rsrcnames, pid, flag, seq_num,
		    &info);
		break;

	case CMD_OFFLINE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL))
			goto faildata;
		error = process_resource_offline(rsrcnames, pid, flag, seq_num,
		    &info);
		break;

	case CMD_ONLINE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL))
			goto faildata;
		error = notify_resource_online(rsrcnames, pid, flag, seq_num,
		    &info);
		break;

	case CMD_REMOVE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL))
			goto faildata;
		error = notify_resource_remove(rsrcnames, pid, flag, seq_num,
		    &info);
		break;

	case CMD_EVENT:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) ||
		    (event_data == NULL))
			goto faildata;
		error = notify_resource_event(rsrcnames[0], pid, flag, seq_num,
		    event_data, &info);
		nvlist_free(event_data);
		break;

	case CMD_REQUEST_CHANGE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) ||
		    (change_data == NULL))
			goto faildata;
		error = request_capacity_change(rsrcnames[0], pid, flag,
		    seq_num, change_data, &info);
		nvlist_free(change_data);
		break;

	case CMD_NOTIFY_CHANGE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL) ||
		    (change_data == NULL))
			goto faildata;
		error = notify_capacity_change(rsrcnames[0], pid, flag, seq_num,
		    change_data, &info);
		nvlist_free(change_data);
		break;

	case CMD_GETSTATE:
		if ((rsrcnames == NULL) || (rsrcnames[0] == NULL))
			goto faildata;
		error = get_resource_state(rsrcnames[0], pid, &info);
		break;

	default:
		rcm_log_message(RCM_WARNING,
		    gettext("unknown door command: %d\n"), cmd);
		generate_reply_event(EFAULT, NULL, ret);
		(void) free(rsrcnames);
		return;
	}

	rcm_log_message(RCM_TRACE2, "finish processing event 0x%x\n", cmd);
	generate_reply_event(error, info, ret);
	(void) free(rsrcnames);
	return;

faildata:
	rcm_log_message(RCM_WARNING,
	    gettext("data error in door arguments for cmd 0x%x\n"), cmd);

	generate_reply_event(EFAULT, NULL, ret);
	(void) free(rsrcnames);
}
Exemplo n.º 10
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));
}
Exemplo n.º 11
0
cmd_dimm_t *
cmd_dimm_create(fmd_hdl_t *hdl, nvlist_t *asru)
{
	cmd_dimm_t *dimm;
	const char *unum;
	nvlist_t *fmri;
	size_t nserids = 0;
	char **serids = NULL;

	if (!fmd_nvl_fmri_present(hdl, asru)) {
		fmd_hdl_debug(hdl, "dimm_lookup: discarding old ereport\n");
		return (NULL);
	}

	if ((unum = cmd_fmri_get_unum(asru)) == NULL) {
		CMD_STAT_BUMP(bad_mem_asru);
		return (NULL);
	}

#ifdef sun4v
	if (nvlist_lookup_string_array(asru, FM_FMRI_HC_SERIAL_ID, &serids,
	    &nserids) != 0) {
		fmd_hdl_debug(hdl, "sun4v mem: FMRI does not"
		    " have serial_ids\n");
		CMD_STAT_BUMP(bad_mem_asru);
		return (NULL);
	}
#endif
	fmri = cmd_mem_fmri_create(unum, serids, nserids);
	if (fmd_nvl_fmri_expand(hdl, fmri) < 0) {
		CMD_STAT_BUMP(bad_mem_asru);
		nvlist_free(fmri);
		return (NULL);
	}

	fmd_hdl_debug(hdl, "dimm_create: creating new DIMM %s\n", unum);
	CMD_STAT_BUMP(dimm_creat);

	dimm = fmd_hdl_zalloc(hdl, sizeof (cmd_dimm_t), FMD_SLEEP);
	dimm->dimm_nodetype = CMD_NT_DIMM;
	dimm->dimm_version = CMD_DIMM_VERSION;

	cmd_bufname(dimm->dimm_bufname, sizeof (dimm->dimm_bufname), "dimm_%s",
	    unum);
	cmd_fmri_init(hdl, &dimm->dimm_asru, fmri, "dimm_asru_%s", unum);

	nvlist_free(fmri);

	(void) nvlist_lookup_string(dimm->dimm_asru_nvl, FM_FMRI_MEM_UNUM,
	    (char **)&dimm->dimm_unum);

	dimm_attach_to_bank(hdl, dimm);

	cmd_mem_retirestat_create(hdl, &dimm->dimm_retstat, dimm->dimm_unum, 0,
	    CMD_DIMM_STAT_PREFIX);

	cmd_list_append(&cmd.cmd_dimms, dimm);
	cmd_dimm_dirty(hdl, dimm);

	return (dimm);
}
Exemplo n.º 12
0
/*
 * Function:  it_config_setprop()
 *
 * Validate the provided property list and set the global properties
 * for iSCSI Target.  If errlist is not NULL, returns detailed
 * errors for each property that failed.  The format for errorlist
 * is key = property, value = error string.
 *
 * Parameters:
 *
 *    cfg		The current iSCSI configuration obtained from
 *			it_config_load()
 *    proplist		nvlist_t containing properties for this target.
 *    errlist		(optional)  nvlist_t of errors encountered when
 *                      validating the properties.
 *
 * Return Values:
 *    0			Success
 *    EINVAL		Invalid property
 *
 */
int
it_config_setprop(it_config_t *cfg, nvlist_t *proplist, nvlist_t **errlist)
{
	int		ret;
	nvlist_t	*errs = NULL;
	it_portal_t	*isns = NULL;
	it_portal_t	*pnext = NULL;
	it_portal_t	*newisnslist = NULL;
	char		**arr;
	uint32_t	count;
	uint32_t	newcount;
	nvlist_t	*cprops = NULL;
	char		*val = NULL;

	if (!cfg || !proplist) {
		return (EINVAL);
	}

	if (errlist) {
		(void) nvlist_alloc(&errs, 0, 0);
		*errlist = errs;
	}

	/*
	 * copy the existing properties, merge, then validate
	 * the merged properties before committing them.
	 */
	if (cfg->config_global_properties) {
		ret = nvlist_dup(cfg->config_global_properties, &cprops, 0);
	} else {
		ret = nvlist_alloc(&cprops, NV_UNIQUE_NAME, 0);
	}

	if (ret != 0) {
		return (ret);
	}

	ret = nvlist_merge(cprops, proplist, 0);
	if (ret != 0) {
		nvlist_free(cprops);
		return (ret);
	}

	/*
	 * base64 encode the radius secret, if it's changed.
	 */
	val = NULL;
	(void) nvlist_lookup_string(proplist, PROP_RADIUS_SECRET, &val);
	if (val) {
		char		bsecret[MAX_BASE64_LEN];

		ret = it_val_pass(PROP_RADIUS_SECRET, val, errs);

		if (ret == 0) {
			(void) memset(bsecret, 0, MAX_BASE64_LEN);

			ret = iscsi_binary_to_base64_str((uint8_t *)val,
			    strlen(val), bsecret, MAX_BASE64_LEN);

			if (ret == 0) {
				/* replace the value in the nvlist */
				ret = nvlist_add_string(cprops,
				    PROP_RADIUS_SECRET, bsecret);
			}
		}
	}

	if (ret != 0) {
		nvlist_free(cprops);
		return (ret);
	}

	/* see if we need to remove the radius server setting */
	val = NULL;
	(void) nvlist_lookup_string(cprops, PROP_RADIUS_SERVER, &val);
	if (val && (strcasecmp(val, "none") == 0)) {
		(void) nvlist_remove_all(cprops, PROP_RADIUS_SERVER);
	}

	/* and/or remove the alias */
	val = NULL;
	(void) nvlist_lookup_string(cprops, PROP_ALIAS, &val);
	if (val && (strcasecmp(val, "none") == 0)) {
		(void) nvlist_remove_all(cprops, PROP_ALIAS);
	}

	ret = it_validate_configprops(cprops, errs);
	if (ret != 0) {
		if (cprops) {
			nvlist_free(cprops);
		}
		return (ret);
	}

	/*
	 * Update iSNS server list, if exists in provided property list.
	 */
	ret = nvlist_lookup_string_array(proplist, PROP_ISNS_SERVER,
	    &arr, &count);

	if (ret == 0) {
		/* special case:  if "none", remove all defined */
		if (strcasecmp(arr[0], "none") != 0) {
			ret = it_array_to_portallist(arr, count,
			    ISNS_DEFAULT_SERVER_PORT, &newisnslist, &newcount);
		} else {
			newisnslist = NULL;
			newcount = 0;
			(void) nvlist_remove_all(cprops, PROP_ISNS_SERVER);
		}

		if (ret == 0) {
			isns = cfg->config_isns_svr_list;
			while (isns) {
				pnext = isns->portal_next;
				free(isns);
				isns = pnext;
			}

			cfg->config_isns_svr_list = newisnslist;
			cfg->config_isns_svr_count = newcount;

			/*
			 * Replace the array in the nvlist to ensure
			 * duplicates are properly removed & port numbers
			 * are added.
			 */
			if (newcount > 0) {
				int	i = 0;
				char	**newarray;

				newarray = malloc(sizeof (char *) * newcount);
				if (newarray == NULL) {
					ret = ENOMEM;
				} else {
					for (isns = newisnslist; isns != NULL;
					    isns = isns->portal_next) {
						(void) sockaddr_to_str(
						    &(isns->portal_addr),
						    &(newarray[i++]));
					}
					(void) nvlist_add_string_array(cprops,
					    PROP_ISNS_SERVER, newarray,
					    newcount);

					for (i = 0; i < newcount; i++) {
						if (newarray[i]) {
							free(newarray[i]);
						}
					}
					free(newarray);
				}
			}
		}
	} else if (ret == ENOENT) {
		/* not an error */
		ret = 0;
	}

	if (ret == 0) {
		/* replace the global properties list */
		nvlist_free(cfg->config_global_properties);
		cfg->config_global_properties = cprops;
	} else {
		if (cprops) {
			nvlist_free(cprops);
		}
	}

	if (ret == 0)
		free_empty_errlist(errlist);

	return (ret);
}
Exemplo n.º 13
0
/*
 * Goes through the config property list and validates
 * each entry.  If errs is non-NULL, will return explicit errors
 * for each property that fails validation.
 */
static int
it_validate_configprops(nvlist_t *nvl, nvlist_t *errs)
{
	int				errcnt = 0;
	nvpair_t			*nvp = NULL;
	data_type_t			nvtype;
	char				*name;
	char				*val;
	struct sockaddr_storage		sa;
	boolean_t			update_rad_server = B_FALSE;
	char				*rad_server;
	char				*auth = NULL;

	if (!nvl) {
		return (0);
	}

	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
		name = nvpair_name(nvp);
		nvtype = nvpair_type(nvp);

		if (!name) {
			continue;
		}

		val = NULL;

		/* prefetch string value as we mostly need it */
		if (nvtype == DATA_TYPE_STRING) {
			(void) nvpair_value_string(nvp, &val);
		}

		if (strcmp(name, PROP_ALIAS) == 0) {
			if (!val) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
			}
		} else if (strcmp(name, PROP_AUTH) == 0) {
			if (!val) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
				continue;
			}

			if ((strcmp(val, PA_AUTH_NONE) != 0) &&
			    (strcmp(val, PA_AUTH_CHAP) != 0) &&
			    (strcmp(val, PA_AUTH_RADIUS) != 0)) {
				PROPERR(errs, PROP_AUTH,
				    gettext("must be none, chap or radius"));
				errcnt++;
			}

			auth = val;

		} else if (strcmp(name, PROP_ISNS_ENABLED) == 0) {
			if (nvtype != DATA_TYPE_BOOLEAN_VALUE) {
				PROPERR(errs, name,
				    gettext("must be a boolean value"));
				errcnt++;
			}
		} else if (strcmp(name, PROP_ISNS_SERVER) == 0) {
			char		**arr = NULL;
			uint32_t	acount = 0;

			(void) nvlist_lookup_string_array(nvl, name,
			    &arr, &acount);

			while (acount > 0) {
				if (strcasecmp(arr[acount - 1], "none") == 0) {
					break;
				}
				if ((it_common_convert_sa(arr[acount - 1],
				    &sa, 0)) == NULL) {
					PROPERR(errs, arr[acount - 1],
					    gettext("invalid address"));
					errcnt++;
				}
				acount--;
			}

		} else if (strcmp(name, PROP_RADIUS_SECRET) == 0) {
			if (!val) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
				continue;
			}
		} else if (strcmp(name, PROP_RADIUS_SERVER) == 0) {
			struct sockaddr_storage		sa;
			if (!val) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
				continue;
			}

			if ((it_common_convert_sa(val, &sa,
			    DEFAULT_RADIUS_PORT)) == NULL) {
				PROPERR(errs, name,
				    gettext("invalid address"));
				errcnt++;
			} else {
				/*
				 * rewrite this property to ensure port
				 * number is added.
				 */

				if (sockaddr_to_str(&sa, &rad_server) == 0) {
					update_rad_server = B_TRUE;
				}
			}
		} else {
			/* unrecognized property */
			PROPERR(errs, name, gettext("unrecognized property"));
			errcnt++;
		}
	}

	/*
	 * If we successfully reformatted the radius server to add the port
	 * number then update the nvlist
	 */
	if (update_rad_server) {
		(void) nvlist_add_string(nvl, PROP_RADIUS_SERVER, rad_server);
		free(rad_server);
	}

	/*
	 * if auth = radius, ensure radius server & secret are set.
	 */
	if (auth) {
		if (strcmp(auth, PA_AUTH_RADIUS) == 0) {
			/* need server & secret for radius */
			if (!nvlist_exists(nvl, PROP_RADIUS_SERVER)) {
				PROPERR(errs, PROP_RADIUS_SERVER,
				    gettext("missing required property"));
				errcnt++;
			}
			if (!nvlist_exists(nvl, PROP_RADIUS_SECRET)) {
				PROPERR(errs, PROP_RADIUS_SECRET,
				    gettext("missing required property"));
				errcnt++;
			}
		}
	}

	if (errcnt) {
		return (EINVAL);
	}

	return (0);
}