--- old/usr/src/cmd/fm/fmdump/common/asru.c	Wed Jan 30 07:34:39 2013
+++ new/usr/src/cmd/fm/fmdump/common/asru.c	Wed Jan 30 07:34:39 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <fmdump.h>
@@ -144,5 +145,8 @@
 (fmd_log_rec_f *)asru_pretty
 }, {
 NULL, NULL
+}, {
+NULL,
+(fmd_log_rec_f *)fmdump_print_json
 } }
 };
--- old/usr/src/cmd/fm/fmdump/common/error.c	Wed Jan 30 07:34:39 2013
+++ new/usr/src/cmd/fm/fmdump/common/error.c	Wed Jan 30 07:34:39 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <fmdump.h>
@@ -111,5 +112,8 @@
 (fmd_log_rec_f *)err_pretty
 }, {
 NULL, NULL
+}, {
+NULL,
+(fmd_log_rec_f *)fmdump_print_json
 } }
 };
--- old/usr/src/cmd/fm/fmdump/common/fault.c	Wed Jan 30 07:34:39 2013
+++ new/usr/src/cmd/fm/fmdump/common/fault.c	Wed Jan 30 07:34:39 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <fmdump.h>
@@ -285,5 +286,8 @@
 }, {
 NULL,
 (fmd_log_rec_f *)flt_msg
+}, {
+NULL,
+(fmd_log_rec_f *)fmdump_print_json
 } }
 };
--- old/usr/src/cmd/fm/fmdump/common/fmdump.c	Wed Jan 30 07:34:39 2013
+++ new/usr/src/cmd/fm/fmdump/common/fmdump.c	Wed Jan 30 07:34:39 2013
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <alloca.h>
@@ -193,7 +194,8 @@
 	"\t-m  display human-readable messages (only for fault logs)\n"
 	"\t-v  set verbose mode: display additional event detail\n"
 	"\t-V  set very verbose mode: display complete event contents\n"
-	"\t-p  Used with -V: apply some output prettification\n    "
+	"\t-p  Used with -V: apply some output prettification\n"
+	"\t-j  Used with -V: emit JSON-formatted output\n    "
     "Selection filters:\n"
 	"\t-c  select events that match the specified class\n"
 	"\t-t  select events that occurred after the specified time\n"
@@ -1027,7 +1029,7 @@
 static int
 aggregate(char **ifiles, int n_ifiles, int opt_f,
     fmd_log_filter_t *fv, uint_t fc,
-    int opt_v, int opt_V, int opt_p)
+    int opt_v, int opt_V, int opt_p, int opt_j)
 {
 	struct fmdump_pipeline *pipeline, *pl;
 	struct fmdump_srlzer srlzer;
@@ -1074,7 +1076,8 @@
 	}
 
 	if (opt_V)
-		fmt = opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2;
+		fmt = opt_p ? FMDUMP_PRETTY : opt_j ? FMDUMP_JSON :
+		    FMDUMP_VERB2;
 	else if (opt_v)
 		fmt = FMDUMP_VERB1;
 	else
@@ -1152,7 +1155,7 @@
 main(int argc, char *argv[])
 {
 	int opt_a = 0, opt_e = 0, opt_f = 0, opt_H = 0, opt_m = 0, opt_p = 0;
-	int opt_u = 0, opt_v = 0, opt_V = 0;
+	int opt_u = 0, opt_v = 0, opt_V = 0, opt_j = 0;
 	int opt_i = 0, opt_I = 0;
 	int opt_A = 0;
 	char **ifiles = NULL;
@@ -1187,7 +1190,7 @@
 
 	while (optind < argc) {
 		while ((c =
-		    getopt(argc, argv, "Aac:efHiImn:O:pR:t:T:u:vV")) != EOF) {
+		    getopt(argc, argv, "Aac:efHiIjmn:O:pR:t:T:u:vV")) != EOF) {
 			switch (c) {
 			case 'A':
 				opt_A++;
@@ -1221,6 +1224,11 @@
 					return (usage(stderr));
 				opt_I++;
 				break;
+			case 'j':
+				if (opt_p)
+					return (usage(stderr));
+				opt_j++;
+				break;
 			case 'm':
 				opt_m++;
 				break;
@@ -1229,6 +1237,8 @@
 				iflags |= FMD_LOG_XITER_OFFS;
 				break;
 			case 'p':
+				if (opt_j)
+					return (usage(stderr));
 				opt_p++;
 				break;
 			case 'R':
@@ -1309,7 +1319,7 @@
 
 		rc = aggregate(ifiles, n_ifiles, opt_f,
 		    allfv, allfc,
-		    opt_v, opt_V, opt_p);
+		    opt_v, opt_V, opt_p, opt_j);
 
 		cleanup(ifiles, n_ifiles);
 		return (rc);
@@ -1400,7 +1410,8 @@
 
 	if (opt_V) {
 		arg.da_fmt =
-		    &ops->do_formats[opt_p ? FMDUMP_PRETTY : FMDUMP_VERB2];
+		    &ops->do_formats[opt_p ? FMDUMP_PRETTY :
+		    opt_j ? FMDUMP_JSON : FMDUMP_VERB2];
 		iflags |= FMD_LOG_XITER_REFS;
 	} else if (opt_v) {
 		arg.da_fmt = &ops->do_formats[FMDUMP_VERB1];
--- old/usr/src/cmd/fm/fmdump/common/fmdump.h	Wed Jan 30 07:34:40 2013
+++ new/usr/src/cmd/fm/fmdump/common/fmdump.h	Wed Jan 30 07:34:40 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #ifndef	_FMDUMP_H
@@ -53,6 +54,7 @@
 	FMDUMP_VERB2,
 	FMDUMP_PRETTY,
 	FMDUMP_MSG,
+	FMDUMP_JSON,
 	FMDUMP_NFMTS
 };
 
@@ -101,6 +103,8 @@
 extern int fmdump_render_nvlist(nvlist_prtctl_t, void *, nvlist_t *,
     const char *, nvlist_t *);
 
+extern int fmdump_print_json(fmd_log_t *, const fmd_log_record_t *, FILE *);
+
 #ifdef	__cplusplus
 }
 #endif
--- old/usr/src/cmd/fm/fmdump/common/info.c	Wed Jan 30 07:34:40 2013
+++ new/usr/src/cmd/fm/fmdump/common/info.c	Wed Jan 30 07:34:40 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <fmdump.h>
@@ -114,5 +115,8 @@
 (fmd_log_rec_f *)info_pretty
 }, {
 NULL, NULL
+}, {
+NULL,
+(fmd_log_rec_f *)fmdump_print_json
 } }
 };
--- old/usr/src/cmd/fm/fmdump/common/nvlrender.c	Wed Jan 30 07:34:40 2013
+++ new/usr/src/cmd/fm/fmdump/common/nvlrender.c	Wed Jan 30 07:34:40 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 /*
@@ -71,4 +72,20 @@
 	topo_hdl_strfree(thp, fmristr);
 
 	return (1);
+}
+
+/*
+ * Thin wrapper around libnvpair's inbuilt JSON routine.  Simply dumps the
+ * entire log record nvlist without any reformatting.
+ */
+
+/*ARGSUSED*/
+int
+fmdump_print_json(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp)
+{
+	if (nvlist_print_json(fp, rp->rec_nvl) == 0 || fprintf(fp, "\n") < 0 ||
+	    fflush(fp) != 0)
+		return (-1);
+
+	return (0);
 }
--- old/usr/src/lib/libnvpair/Makefile.com	Wed Jan 30 07:34:40 2013
+++ new/usr/src/lib/libnvpair/Makefile.com	Wed Jan 30 07:34:40 2013
@@ -23,6 +23,7 @@
 # Use is subject to license terms.
 #
 # Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright (c) 2013, Joyent, Inc. All rights reserved.
 #
 
 LIBRARY=	libnvpair.a
@@ -32,7 +33,8 @@
 		nvpair_alloc_system.o \
 		nvpair_alloc_fixed.o \
 		nvpair.o \
-		fnvpair.o
+		fnvpair.o \
+		nvpair_json.o
 
 include ../../Makefile.lib
 include ../../Makefile.rootfs
@@ -39,6 +41,7 @@
 
 SRCS=		../libnvpair.c \
 		../nvpair_alloc_system.c \
+		../nvpair_json.c \
 		$(SRC)/common/nvpair/nvpair_alloc_fixed.c \
 		$(SRC)/common/nvpair/nvpair.c \
 		$(SRC)/common/nvpair/fnvpair.c
@@ -54,7 +57,13 @@
 
 # turn off warning caused by lint bug: not understanding SCNi8 "hhi"
 LINTFLAGS +=	-erroff=E_BAD_FORMAT_STR2
+LINTFLAGS +=	-erroff=E_INVALID_TOKEN_IN_DEFINE_MACRO
+LINTFLAGS +=	-erroff=E_RET_INT_IMPLICITLY
+LINTFLAGS +=	-erroff=E_FUNC_USED_VAR_ARG2
 LINTFLAGS64 +=	-erroff=E_BAD_FORMAT_STR2
+LINTFLAGS64 +=	-erroff=E_INVALID_TOKEN_IN_DEFINE_MACRO
+LINTFLAGS64 +=	-erroff=E_RET_INT_IMPLICITLY
+LINTFLAGS64 +=	-erroff=E_FUNC_USED_VAR_ARG2
 
 CERRWARN +=	-_gcc=-Wno-type-limits
 CERRWARN +=	-_gcc=-Wno-parentheses
--- old/usr/src/lib/libnvpair/libnvpair.h	Wed Jan 30 07:34:40 2013
+++ new/usr/src/lib/libnvpair/libnvpair.h	Wed Jan 30 07:34:40 2013
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #ifndef	_LIBNVPAIR_H
@@ -46,6 +47,7 @@
     char **);
 
 extern void nvlist_print(FILE *, nvlist_t *);
+extern int nvlist_print_json(FILE *, nvlist_t *);
 extern void dump_nvlist(nvlist_t *, int);
 
 /*
--- old/usr/src/lib/libnvpair/mapfile-vers	Wed Jan 30 07:34:40 2013
+++ new/usr/src/lib/libnvpair/mapfile-vers	Wed Jan 30 07:34:40 2013
@@ -21,6 +21,7 @@
 #
 # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
 # Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright (c) 2013, Joyent, Inc. All rights reserved.
 #
 
 #
@@ -243,6 +244,7 @@
 	nvlist_add_hrtime;
 	nvlist_lookup_hrtime;
 	nvlist_print;
+	nvlist_print_json;
 	nvlist_prt;
 	nvlist_prtctl_alloc;
 	nvlist_prtctl_free;
--- /dev/null	Wed Jan 30 07:34:40 2013
+++ new/usr/src/lib/libnvpair/nvpair_json.c	Wed Jan 30 07:34:40 2013
@@ -0,0 +1,400 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+/*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <wchar.h>
+#include <sys/debug.h>
+
+#include "libnvpair.h"
+
+#define	FPRINTF(fp, ...)				\
+	do {						\
+		if (fprintf(fp, __VA_ARGS__) < 0)	\
+			return (-1);			\
+	} while (0)
+
+/*
+ * When formatting a string for JSON output we must escape certain characters,
+ * as described in RFC4627.  This applies to both member names and
+ * DATA_TYPE_STRING values.
+ *
+ * This function will only operate correctly if the following conditions are
+ * met:
+ *
+ *       1. The input String is encoded in the current locale.
+ *
+ *       2. The current locale includes the Basic Multilingual Plane (plane 0)
+ *          as defined in the Unicode standard.
+ *
+ * The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all
+ * representable Unicode characters included in their escaped numeric form.
+ */
+static int
+nvlist_print_json_string(FILE *fp, const char *input)
+{
+	mbstate_t mbr;
+	wchar_t c;
+	size_t sz;
+
+	bzero(&mbr, sizeof (mbr));
+
+	FPRINTF(fp, "\"");
+	while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
+		switch (c) {
+		case '"':
+			FPRINTF(fp, "\\\"");
+			break;
+		case '\n':
+			FPRINTF(fp, "\\n");
+			break;
+		case '\r':
+			FPRINTF(fp, "\\r");
+			break;
+		case '\\':
+			FPRINTF(fp, "\\\\");
+			break;
+		case '\f':
+			FPRINTF(fp, "\\f");
+			break;
+		case '\t':
+			FPRINTF(fp, "\\t");
+			break;
+		case '\b':
+			FPRINTF(fp, "\\b");
+			break;
+		default:
+			if ((c >= 0x00 && c <= 0x1f) ||
+			    (c > 0x7f && c <= 0xffff)) {
+				/*
+				 * Render both Control Characters and Unicode
+				 * characters in the Basic Multilingual Plane
+				 * as JSON-escaped multibyte characters.
+				 */
+				FPRINTF(fp, "\\u%04x", 0xffff & c);
+			} else if (c >= 0x20 && c <= 0x7f) {
+				/*
+				 * Render other 7-bit ASCII characters directly
+				 * and drop other, unrepresentable characters.
+				 */
+				FPRINTF(fp, "%c", 0xff & c);
+			}
+			break;
+		}
+		input += sz;
+	}
+
+	if (sz == (size_t)-1 || sz == (size_t)-2) {
+		/*
+		 * We last read an invalid multibyte character sequence,
+		 * so return an error.
+		 */
+		return (-1);
+	}
+
+	FPRINTF(fp, "\"");
+	return (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
+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 (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 (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", fnvpair_value_int64(curr));
+			break;
+		}
+
+		case DATA_TYPE_UINT64: {
+			FPRINTF(fp, "%llu", fnvpair_value_uint64(curr));
+			break;
+		}
+
+		case DATA_TYPE_HRTIME: {
+			hrtime_t val;
+			VERIFY0(nvpair_value_hrtime(curr, &val));
+			FPRINTF(fp, "%llu", 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 (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", 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", val[i]);
+			}
+			FPRINTF(fp, "]");
+			break;
+		}
+
+		case DATA_TYPE_UNKNOWN:
+			return (-1);
+		}
+	}
+
+	FPRINTF(fp, "}");
+	return (0);
+}
