Example #1
0
static void __dump_nvlist_array(nvpair_t *pair, int indent)
{
	nvlist_t **out;
	uint_t nout;
	uint_t i;
	int ret;

	ret = nvpair_value_nvlist_array(pair, &out, &nout);
	ASSERT0(ret);

	fprintf(stderr, " items=%u\n", nout);

	for (i = 0; i < nout; i++) {
		fprintf(stderr, "%*s%u:\n", indent, "", i);
		__dump(out[i], indent + INDENT);
	}
}
Example #2
0
/*
 * nvlist_print - Prints elements in an event buffer
 */
static
void
nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
{
	int i;
	char *name;
	uint_t nelem;
	nvpair_t *nvp;

	if (nvl == NULL)
		return;

	indent(fp, depth);
	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));

	nvp = nvlist_next_nvpair(nvl, NULL);

	while (nvp) {
		data_type_t type = nvpair_type(nvp);

		indent(fp, depth);
		name = nvpair_name(nvp);
		(void) fprintf(fp, "\t%s =", name);
		nelem = 0;
		switch (type) {
		case DATA_TYPE_BOOLEAN: {
			(void) fprintf(fp, " 1");
			break;
		}
		case DATA_TYPE_BOOLEAN_VALUE: {
			boolean_t val;
			(void) nvpair_value_boolean_value(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_BYTE: {
			uchar_t val;
			(void) nvpair_value_byte(nvp, &val);
			(void) fprintf(fp, " 0x%2.2x", val);
			break;
		}
		case DATA_TYPE_INT8: {
			int8_t val;
			(void) nvpair_value_int8(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT8: {
			uint8_t val;
			(void) nvpair_value_uint8(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT16: {
			int16_t val;
			(void) nvpair_value_int16(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT16: {
			uint16_t val;
			(void) nvpair_value_uint16(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT32: {
			int32_t val;
			(void) nvpair_value_int32(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT32: {
			uint32_t val;
			(void) nvpair_value_uint32(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT64: {
			int64_t val;
			(void) nvpair_value_int64(nvp, &val);
			(void) fprintf(fp, " %lld", (longlong_t)val);
			break;
		}
		case DATA_TYPE_UINT64: {
			uint64_t val;
			(void) nvpair_value_uint64(nvp, &val);
			(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
			break;
		}
		case DATA_TYPE_DOUBLE: {
			double val;
			(void) nvpair_value_double(nvp, &val);
			(void) fprintf(fp, " 0x%llf", val);
			break;
		}
		case DATA_TYPE_STRING: {
			char *val;
			(void) nvpair_value_string(nvp, &val);
			(void) fprintf(fp, " %s", val);
			break;
		}
		case DATA_TYPE_BOOLEAN_ARRAY: {
			boolean_t *val;
			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_BYTE_ARRAY: {
			uchar_t *val;
			(void) nvpair_value_byte_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%2.2x", val[i]);
			break;
		}
		case DATA_TYPE_INT8_ARRAY: {
			int8_t *val;
			(void) nvpair_value_int8_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT8_ARRAY: {
			uint8_t *val;
			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT16_ARRAY: {
			int16_t *val;
			(void) nvpair_value_int16_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT16_ARRAY: {
			uint16_t *val;
			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;
			(void) nvpair_value_int32_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;
			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;
			(void) nvpair_value_int64_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %lld", (longlong_t)val[i]);
			break;
		}
		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;
			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%llx",
				    (u_longlong_t)val[i]);
			break;
		}
		case DATA_TYPE_STRING_ARRAY: {
			char **val;
			(void) nvpair_value_string_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %s", val[i]);
			break;
		}
		case DATA_TYPE_HRTIME: {
			hrtime_t val;
			(void) nvpair_value_hrtime(nvp, &val);
			(void) fprintf(fp, " 0x%llx", val);
			break;
		}
		case DATA_TYPE_NVLIST: {
			nvlist_t *val;
			(void) nvpair_value_nvlist(nvp, &val);
			(void) fprintf(fp, " (embedded nvlist)\n");
			nvlist_print_with_indent(fp, val, depth + 1);
			indent(fp, depth + 1);
			(void) fprintf(fp, "(end %s)\n", name);
			break;
		}
		case DATA_TYPE_NVLIST_ARRAY: {
			nvlist_t **val;
			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
			(void) fprintf(fp, " (array of embedded nvlists)\n");
			for (i = 0; i < nelem; i++) {
				indent(fp, depth + 1);
				(void) fprintf(fp,
				    "(start %s[%d])\n", name, i);
				nvlist_print_with_indent(fp, val[i], depth + 1);
				indent(fp, depth + 1);
				(void) fprintf(fp, "(end %s[%d])\n", name, i);
			}
			break;
		}
		default:
			(void) fprintf(fp, " unknown data type (%d)", type);
			break;
		}
		(void) fprintf(fp, "\n");
		nvp = nvlist_next_nvpair(nvl, nvp);
	}
}
Example #3
0
/*
 * Copy in a packed nvlist from the user and create a request set out of it.
 * If successful, return 0 and store a pointer to the set we've created. Returns
 * error code on error.
 */
int
kcpc_copyin_set(kcpc_set_t **inset, void *ubuf, size_t len)
{
	kcpc_set_t	*set;
	int		i;
	int		j;
	char		*packbuf;

	nvlist_t	*nvl;
	nvpair_t	*nvp = NULL;

	nvlist_t	*attrs;
	nvpair_t	*nvp_attr;
	kcpc_attr_t	*attrp;

	nvlist_t	**reqlist;
	uint_t		nreqs;
	uint64_t	uint64;
	uint32_t	uint32;
	uint32_t	setflags = (uint32_t)-1;
	char		*string;
	char		*name;

	if (len < CPC_MIN_PACKSIZE || len > CPC_MAX_PACKSIZE)
		return (EINVAL);

	packbuf = kmem_alloc(len, KM_SLEEP);

	if (copyin(ubuf, packbuf, len) == -1) {
		kmem_free(packbuf, len);
		return (EFAULT);
	}

	if (nvlist_unpack(packbuf, len, &nvl, KM_SLEEP) != 0) {
		kmem_free(packbuf, len);
		return (EINVAL);
	}

	/*
	 * The nvlist has been unpacked so there is no need for the packed
	 * representation from this point on.
	 */
	kmem_free(packbuf, len);

	i = 0;
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
		switch (nvpair_type(nvp)) {
		case DATA_TYPE_UINT32:
			if (strcmp(nvpair_name(nvp), "flags") != 0 ||
			    nvpair_value_uint32(nvp, &setflags) != 0) {
				nvlist_free(nvl);
				return (EINVAL);
			}
			break;
		case DATA_TYPE_NVLIST_ARRAY:
			if (strcmp(nvpair_name(nvp), "reqs") != 0 ||
			    nvpair_value_nvlist_array(nvp, &reqlist,
			    &nreqs) != 0) {
				nvlist_free(nvl);
				return (EINVAL);
			}
			break;
		default:
			nvlist_free(nvl);
			return (EINVAL);
		}
		i++;
	}

	/*
	 * There should be two members in the top-level nvlist:
	 * an array of nvlists consisting of the requests, and flags.
	 * Anything else is an invalid set.
	 */
	if (i != 2) {
		nvlist_free(nvl);
		return (EINVAL);
	}

	if (nreqs > CPC_MAX_NREQS) {
		nvlist_free(nvl);
		return (EINVAL);
	}

	/*
	 * The requests are now stored in the nvlist array at reqlist.
	 * Note that the use of kmem_zalloc() to alloc the kcpc_set_t means
	 * we don't need to call the init routines for ks_lock and ks_condv.
	 */
	set = kmem_zalloc(sizeof (kcpc_set_t), KM_SLEEP);
	set->ks_req = (kcpc_request_t *)kmem_zalloc(sizeof (kcpc_request_t) *
	    nreqs, KM_SLEEP);
	set->ks_nreqs = nreqs;
	/*
	 * If the nvlist didn't contain a flags member, setflags was initialized
	 * with an illegal value and this set will fail sanity checks later on.
	 */
	set->ks_flags = setflags;
	/*
	 * Initialize bind/unbind set synchronization.
	 */
	set->ks_state &= ~KCPC_SET_BOUND;

	/*
	 * Build the set up one request at a time, always keeping it self-
	 * consistent so we can give it to kcpc_free_set() if we need to back
	 * out and return and error.
	 */
	for (i = 0; i < nreqs; i++) {
		nvp = NULL;
		set->ks_req[i].kr_picnum = -1;
		while ((nvp = nvlist_next_nvpair(reqlist[i], nvp)) != NULL) {
			name = nvpair_name(nvp);
			switch (nvpair_type(nvp)) {
			case DATA_TYPE_UINT32:
				if (nvpair_value_uint32(nvp, &uint32) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_flags") == 0)
					set->ks_req[i].kr_flags = uint32;
				if (strcmp(name, "cr_index") == 0)
					set->ks_req[i].kr_index = uint32;
				break;
			case DATA_TYPE_UINT64:
				if (nvpair_value_uint64(nvp, &uint64) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_preset") == 0)
					set->ks_req[i].kr_preset = uint64;
				break;
			case DATA_TYPE_STRING:
				if (nvpair_value_string(nvp, &string) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_event") == 0)
					(void) strncpy(set->ks_req[i].kr_event,
					    string, CPC_MAX_EVENT_LEN);
				break;
			case DATA_TYPE_NVLIST:
				if (strcmp(name, "cr_attr") != 0)
					goto inval;
				if (nvpair_value_nvlist(nvp, &attrs) == EINVAL)
					goto inval;
				nvp_attr = NULL;
				/*
				 * If the picnum has been specified as an
				 * attribute, consume that attribute here and
				 * remove it from the list of attributes.
				 */
				if (nvlist_lookup_uint64(attrs, "picnum",
				    &uint64) == 0) {
					if (nvlist_remove(attrs, "picnum",
					    DATA_TYPE_UINT64) != 0)
						panic("nvlist %p faulty",
						    (void *)attrs);
					set->ks_req[i].kr_picnum = uint64;
				}

				if ((set->ks_req[i].kr_nattrs =
				    kcpc_nvlist_npairs(attrs)) == 0)
					break;

				if (set->ks_req[i].kr_nattrs > CPC_MAX_ATTRS)
					goto inval;

				set->ks_req[i].kr_attr =
				    kmem_alloc(set->ks_req[i].kr_nattrs *
				    sizeof (kcpc_attr_t), KM_SLEEP);
				j = 0;

				while ((nvp_attr = nvlist_next_nvpair(attrs,
				    nvp_attr)) != NULL) {
					attrp = &set->ks_req[i].kr_attr[j];

					if (nvpair_type(nvp_attr) !=
					    DATA_TYPE_UINT64)
						goto inval;

					(void) strncpy(attrp->ka_name,
					    nvpair_name(nvp_attr),
					    CPC_MAX_ATTR_LEN);

					if (nvpair_value_uint64(nvp_attr,
					    &(attrp->ka_val)) == EINVAL)
						goto inval;
					j++;
				}
				ASSERT(j == set->ks_req[i].kr_nattrs);
			default:
				break;
			}
		}
	}

	nvlist_free(nvl);
	*inset = set;
	return (0);

inval:
	nvlist_free(nvl);
	kcpc_free_set(set);
	return (EINVAL);
}
Example #4
0
/*
 * Dump a JSON-formatted representation of an nvlist to the provided FILE *.
 * This routine does not output any new-lines or additional whitespace other
 * than that contained in strings, nor does it call fflush(3C).
 */
int
bunyan_nvlist_print_json(FILE *fp, nvlist_t *nvl)
{
	nvpair_t *curr;
	boolean_t first = B_TRUE;

	FPRINTF(fp, "{");

	for (curr = nvlist_next_nvpair(nvl, NULL); curr;
	    curr = nvlist_next_nvpair(nvl, curr)) {
		data_type_t type = nvpair_type(curr);

		if (!first)
			FPRINTF(fp, ",");
		else
			first = B_FALSE;

		if (bunyan_nvlist_print_json_string(fp,
		    nvpair_name(curr)) == -1) {
			return (-1);
		}
		FPRINTF(fp, ":");

		switch (type) {
		case DATA_TYPE_STRING: {
			char *string = fnvpair_value_string(curr);
			if (bunyan_nvlist_print_json_string(fp, string) == -1)
				return (-1);
			break;
		}

		case DATA_TYPE_BOOLEAN: {
			FPRINTF(fp, "true");
			break;
		}

		case DATA_TYPE_BOOLEAN_VALUE: {
			FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) ==
			    B_TRUE ? "true" : "false");
			break;
		}

		case DATA_TYPE_BYTE: {
			FPRINTF(fp, "%hhu", fnvpair_value_byte(curr));
			break;
		}

		case DATA_TYPE_INT8: {
			FPRINTF(fp, "%hhd", fnvpair_value_int8(curr));
			break;
		}

		case DATA_TYPE_UINT8: {
			FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr));
			break;
		}

		case DATA_TYPE_INT16: {
			FPRINTF(fp, "%hd", fnvpair_value_int16(curr));
			break;
		}

		case DATA_TYPE_UINT16: {
			FPRINTF(fp, "%hu", fnvpair_value_uint16(curr));
			break;
		}

		case DATA_TYPE_INT32: {
			FPRINTF(fp, "%d", fnvpair_value_int32(curr));
			break;
		}

		case DATA_TYPE_UINT32: {
			FPRINTF(fp, "%u", fnvpair_value_uint32(curr));
			break;
		}

		case DATA_TYPE_INT64: {
			FPRINTF(fp, "%lld",
			    (long long)fnvpair_value_int64(curr));
			break;
		}

		case DATA_TYPE_UINT64: {
			FPRINTF(fp, "%llu",
			    (unsigned long long)fnvpair_value_uint64(curr));
			break;
		}

		case DATA_TYPE_HRTIME: {
			hrtime_t val;
			VERIFY0(nvpair_value_hrtime(curr, &val));
			FPRINTF(fp, "%llu", (unsigned long long)val);
			break;
		}

		case DATA_TYPE_DOUBLE: {
			double val;
			VERIFY0(nvpair_value_double(curr, &val));
			FPRINTF(fp, "%f", val);
			break;
		}

		case DATA_TYPE_NVLIST: {
			if (nvlist_print_json(fp,
			    fnvpair_value_nvlist(curr)) == -1)
				return (-1);
			break;
		}

		case DATA_TYPE_STRING_ARRAY: {
			char **val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				if (bunyan_nvlist_print_json_string(fp,
				    val[i]) == -1) {
					return (-1);
				}
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_NVLIST_ARRAY: {
			nvlist_t **val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				if (nvlist_print_json(fp, val[i]) == -1)
					return (-1);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_BOOLEAN_ARRAY: {
			boolean_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, val[i] == B_TRUE ?
				    "true" : "false");
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_BYTE_ARRAY: {
			uchar_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%hhu", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_UINT8_ARRAY: {
			uint8_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%hhu", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_INT8_ARRAY: {
			int8_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%hd", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_UINT16_ARRAY: {
			uint16_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%hu", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_INT16_ARRAY: {
			int16_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%hhd", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%u", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%d", val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%llu",
				    (unsigned long long)val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;
			uint_t valsz, i;
			VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
			FPRINTF(fp, "[");
			for (i = 0; i < valsz; i++) {
				if (i > 0)
					FPRINTF(fp, ",");
				FPRINTF(fp, "%lld", (long long)val[i]);
			}
			FPRINTF(fp, "]");
			break;
		}

		case DATA_TYPE_UNKNOWN:
			return (-1);
		}
	}

	FPRINTF(fp, "}");
	return (0);
}