git: e097436cb2bc - main - libsa: Make the nvlist implementation more self-contained

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Fri, 20 May 2022 14:36:34 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=e097436cb2bc42e74d1dc2bf188c4491eeff3ec0

commit e097436cb2bc42e74d1dc2bf188c4491eeff3ec0
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-05-20 14:17:35 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-05-20 14:35:19 +0000

    libsa: Make the nvlist implementation more self-contained
    
    Move declarations into a new nvlist.h rather than putting everything in
    libzfs.h.  This makes this nvlist code easier to reuse elsewhere.  In
    particular, the nvlist implementation in sys/contrib/libnv does not
    provide XDR encoding, but this is needed when reading from or writing to
    ZFS pools.
    
    Also:
    - Remove references to boolean_t.  It has to be a 32-bit int here, so
      just reference the underlying type.
    - Add includes needed when compiling the nvlist code outside of stand/.
    
    No functional change intended.
    
    Reviewed by:    tsoome
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D35255
---
 stand/libsa/zfs/libzfs.h    | 103 +---------------------------
 stand/libsa/zfs/nvlist.c    |  22 +++---
 stand/libsa/zfs/nvlist.h    | 164 ++++++++++++++++++++++++++++++++++++++++++++
 sys/cddl/boot/zfs/zfsimpl.h |  34 ---------
 4 files changed, 180 insertions(+), 143 deletions(-)

diff --git a/stand/libsa/zfs/libzfs.h b/stand/libsa/zfs/libzfs.h
index 27fde493670c..e8676c0d53b8 100644
--- a/stand/libsa/zfs/libzfs.h
+++ b/stand/libsa/zfs/libzfs.h
@@ -35,6 +35,8 @@
 #include <crypto/intake.h>
 #endif
 
+#include "nvlist.h"
+
 #define	ZFS_MAXNAMELEN	256
 
 /*
@@ -46,107 +48,6 @@ struct zfs_devdesc {
 	uint64_t	root_guid;
 };
 
-/* nvp implementation version */
-#define	NV_VERSION		0
-
-/* nvlist persistent unique name flags, stored in nvl_nvflags */
-#define	NV_UNIQUE_NAME		0x1
-#define	NV_UNIQUE_NAME_TYPE	0x2
-
-#define	NV_ALIGN4(x)		(((x) + 3) & ~3)
-#define	NV_ALIGN(x)		(((x) + 7) & ~7)
-
-/*
- * nvlist header.
- * nvlist has 4 bytes header followed by version and flags, then nvpairs
- * and the list is terminated by double zero.
- */
-typedef struct {
-	char nvh_encoding;
-	char nvh_endian;
-	char nvh_reserved1;
-	char nvh_reserved2;
-} nvs_header_t;
-
-typedef struct {
-	nvs_header_t nv_header;
-	size_t nv_asize;
-	size_t nv_size;
-	uint8_t *nv_data;
-	uint8_t *nv_idx;
-} nvlist_t;
-
-/*
- * nvpair header.
- * nvpair has encoded and decoded size
- * name string (size and data)
- * data type and number of elements
- * data
- */
-typedef struct {
-	unsigned encoded_size;
-	unsigned decoded_size;
-} nvp_header_t;
-
-/*
- * nvlist stream head.
- */
-typedef struct {
-	unsigned nvl_version;
-	unsigned nvl_nvflag;
-	nvp_header_t nvl_pair;
-} nvs_data_t;
-
-typedef struct {
-	unsigned nv_size;
-	uint8_t nv_data[];	/* NV_ALIGN4(string) */
-} nv_string_t;
-
-typedef struct {
-	unsigned nv_type;	/* data_type_t */
-	unsigned nv_nelem;	/* number of elements */
-	uint8_t nv_data[];	/* data stream */
-} nv_pair_data_t;
-
-nvlist_t *nvlist_create(int);
-void nvlist_destroy(nvlist_t *);
-nvlist_t *nvlist_import(const char *, size_t);
-int nvlist_export(nvlist_t *);
-int nvlist_remove(nvlist_t *, const char *, data_type_t);
-int nvpair_type_from_name(const char *);
-nvp_header_t *nvpair_find(nvlist_t *, const char *);
-void nvpair_print(nvp_header_t *, unsigned int);
-void nvlist_print(const nvlist_t *, unsigned int);
-char *nvstring_get(nv_string_t *);
-int nvlist_find(const nvlist_t *, const char *, data_type_t,
-    int *, void *, int *);
-nvp_header_t *nvlist_next_nvpair(nvlist_t *, nvp_header_t *);
-
-int nvlist_add_boolean_value(nvlist_t *, const char *, boolean_t);
-int nvlist_add_byte(nvlist_t *, const char *, uint8_t);
-int nvlist_add_int8(nvlist_t *, const char *, int8_t);
-int nvlist_add_uint8(nvlist_t *, const char *, uint8_t);
-int nvlist_add_int16(nvlist_t *, const char *, int16_t);
-int nvlist_add_uint16(nvlist_t *, const char *, uint16_t);
-int nvlist_add_int32(nvlist_t *, const char *, int32_t);
-int nvlist_add_uint32(nvlist_t *, const char *, uint32_t);
-int nvlist_add_int64(nvlist_t *, const char *, int64_t);
-int nvlist_add_uint64(nvlist_t *, const char *, uint64_t);
-int nvlist_add_string(nvlist_t *, const char *, const char *);
-int nvlist_add_boolean_array(nvlist_t *, const char *, boolean_t *, uint32_t);
-int nvlist_add_byte_array(nvlist_t *, const char *, uint8_t *, uint32_t);
-int nvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint32_t);
-int nvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint32_t);
-int nvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint32_t);
-int nvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint32_t);
-int nvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint32_t);
-int nvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint32_t);
-int nvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint32_t);
-int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint32_t);
-int nvlist_add_string_array(nvlist_t *, const char *, char * const *, uint32_t);
-int nvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *);
-int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint32_t);
-
 int	zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
 		     const char **path);
 char	*zfs_fmtdev(void *vdev);
diff --git a/stand/libsa/zfs/nvlist.c b/stand/libsa/zfs/nvlist.c
index 84a0edafe182..e5e0abecb274 100644
--- a/stand/libsa/zfs/nvlist.c
+++ b/stand/libsa/zfs/nvlist.c
@@ -26,13 +26,20 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <stand.h>
-#include <stdbool.h>
+#include <sys/param.h>
 #include <sys/endian.h>
 #include <sys/stdint.h>
-#include <sys/param.h>
-#include <zfsimpl.h>
-#include "libzfs.h"
+#ifdef _STANDALONE
+#include <stand.h>
+#else
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "nvlist.h"
 
 enum xdr_op {
 	XDR_OP_ENCODE = 1,
@@ -1342,7 +1349,7 @@ nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
 }
 
 int
-nvlist_add_boolean_value(nvlist_t *nvl, const char *name, boolean_t value)
+nvlist_add_boolean_value(nvlist_t *nvl, const char *name, int value)
 {
 	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_VALUE, 1,
 	    &value));
@@ -1409,8 +1416,7 @@ nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
 }
 
 int
-nvlist_add_boolean_array(nvlist_t *nvl, const char *name,
-    boolean_t *a, uint32_t n)
+nvlist_add_boolean_array(nvlist_t *nvl, const char *name, int *a, uint32_t n)
 {
 	return (nvlist_add_common(nvl, name, DATA_TYPE_BOOLEAN_ARRAY, n, a));
 }
diff --git a/stand/libsa/zfs/nvlist.h b/stand/libsa/zfs/nvlist.h
new file mode 100644
index 000000000000..9dab53d006c2
--- /dev/null
+++ b/stand/libsa/zfs/nvlist.h
@@ -0,0 +1,164 @@
+/*-
+ * Copyright 2020 Toomas Soome <tsoome@me.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BOOT_NVLIST_H_
+#define	_BOOT_NVLIST_H_
+
+typedef enum {
+	DATA_TYPE_UNKNOWN = 0,
+	DATA_TYPE_BOOLEAN,
+	DATA_TYPE_BYTE,
+	DATA_TYPE_INT16,
+	DATA_TYPE_UINT16,
+	DATA_TYPE_INT32,
+	DATA_TYPE_UINT32,
+	DATA_TYPE_INT64,
+	DATA_TYPE_UINT64,
+	DATA_TYPE_STRING,
+	DATA_TYPE_BYTE_ARRAY,
+	DATA_TYPE_INT16_ARRAY,
+	DATA_TYPE_UINT16_ARRAY,
+	DATA_TYPE_INT32_ARRAY,
+	DATA_TYPE_UINT32_ARRAY,
+	DATA_TYPE_INT64_ARRAY,
+	DATA_TYPE_UINT64_ARRAY,
+	DATA_TYPE_STRING_ARRAY,
+	DATA_TYPE_HRTIME,
+	DATA_TYPE_NVLIST,
+	DATA_TYPE_NVLIST_ARRAY,
+	DATA_TYPE_BOOLEAN_VALUE,
+	DATA_TYPE_INT8,
+	DATA_TYPE_UINT8,
+	DATA_TYPE_BOOLEAN_ARRAY,
+	DATA_TYPE_INT8_ARRAY,
+	DATA_TYPE_UINT8_ARRAY
+} data_type_t;
+
+/* nvp implementation version */
+#define	NV_VERSION		0
+
+/* nvlist pack encoding */
+#define	NV_ENCODE_NATIVE	0
+#define	NV_ENCODE_XDR		1
+
+/* nvlist persistent unique name flags, stored in nvl_nvflags */
+#define	NV_UNIQUE_NAME		0x1
+#define	NV_UNIQUE_NAME_TYPE	0x2
+
+#define	NV_ALIGN4(x)		(((x) + 3) & ~3)
+#define	NV_ALIGN(x)		(((x) + 7) & ~7)
+
+/*
+ * nvlist header.
+ * nvlist has 4 bytes header followed by version and flags, then nvpairs
+ * and the list is terminated by double zero.
+ */
+typedef struct {
+	char nvh_encoding;
+	char nvh_endian;
+	char nvh_reserved1;
+	char nvh_reserved2;
+} nvs_header_t;
+
+typedef struct {
+	nvs_header_t nv_header;
+	size_t nv_asize;
+	size_t nv_size;
+	uint8_t *nv_data;
+	uint8_t *nv_idx;
+} nvlist_t;
+
+/*
+ * nvpair header.
+ * nvpair has encoded and decoded size
+ * name string (size and data)
+ * data type and number of elements
+ * data
+ */
+typedef struct {
+	unsigned encoded_size;
+	unsigned decoded_size;
+} nvp_header_t;
+
+/*
+ * nvlist stream head.
+ */
+typedef struct {
+	unsigned nvl_version;
+	unsigned nvl_nvflag;
+	nvp_header_t nvl_pair;
+} nvs_data_t;
+
+typedef struct {
+	unsigned nv_size;
+	uint8_t nv_data[];	/* NV_ALIGN4(string) */
+} nv_string_t;
+
+typedef struct {
+	unsigned nv_type;	/* data_type_t */
+	unsigned nv_nelem;	/* number of elements */
+	uint8_t nv_data[];	/* data stream */
+} nv_pair_data_t;
+
+nvlist_t *nvlist_create(int);
+void nvlist_destroy(nvlist_t *);
+nvlist_t *nvlist_import(const char *, size_t);
+int nvlist_export(nvlist_t *);
+int nvlist_remove(nvlist_t *, const char *, data_type_t);
+int nvpair_type_from_name(const char *);
+nvp_header_t *nvpair_find(nvlist_t *, const char *);
+void nvpair_print(nvp_header_t *, unsigned int);
+void nvlist_print(const nvlist_t *, unsigned int);
+char *nvstring_get(nv_string_t *);
+int nvlist_find(const nvlist_t *, const char *, data_type_t,
+    int *, void *, int *);
+nvp_header_t *nvlist_next_nvpair(nvlist_t *, nvp_header_t *);
+
+int nvlist_add_boolean_value(nvlist_t *, const char *, int);
+int nvlist_add_byte(nvlist_t *, const char *, uint8_t);
+int nvlist_add_int8(nvlist_t *, const char *, int8_t);
+int nvlist_add_uint8(nvlist_t *, const char *, uint8_t);
+int nvlist_add_int16(nvlist_t *, const char *, int16_t);
+int nvlist_add_uint16(nvlist_t *, const char *, uint16_t);
+int nvlist_add_int32(nvlist_t *, const char *, int32_t);
+int nvlist_add_uint32(nvlist_t *, const char *, uint32_t);
+int nvlist_add_int64(nvlist_t *, const char *, int64_t);
+int nvlist_add_uint64(nvlist_t *, const char *, uint64_t);
+int nvlist_add_string(nvlist_t *, const char *, const char *);
+int nvlist_add_boolean_array(nvlist_t *, const char *, int *, uint32_t);
+int nvlist_add_byte_array(nvlist_t *, const char *, uint8_t *, uint32_t);
+int nvlist_add_int8_array(nvlist_t *, const char *, int8_t *, uint32_t);
+int nvlist_add_uint8_array(nvlist_t *, const char *, uint8_t *, uint32_t);
+int nvlist_add_int16_array(nvlist_t *, const char *, int16_t *, uint32_t);
+int nvlist_add_uint16_array(nvlist_t *, const char *, uint16_t *, uint32_t);
+int nvlist_add_int32_array(nvlist_t *, const char *, int32_t *, uint32_t);
+int nvlist_add_uint32_array(nvlist_t *, const char *, uint32_t *, uint32_t);
+int nvlist_add_int64_array(nvlist_t *, const char *, int64_t *, uint32_t);
+int nvlist_add_uint64_array(nvlist_t *, const char *, uint64_t *, uint32_t);
+int nvlist_add_string_array(nvlist_t *, const char *, char * const *, uint32_t);
+int nvlist_add_nvlist(nvlist_t *, const char *, nvlist_t *);
+int nvlist_add_nvlist_array(nvlist_t *, const char *, nvlist_t **, uint32_t);
+
+#endif /* !_BOOT_NVLIST_H_ */
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 0adcd8e1bbab..46f42bc0386d 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -671,40 +671,6 @@ enum zio_zstd_levels {
 #define	ZIO_COMPRESS_ON_VALUE	ZIO_COMPRESS_LZJB
 #define	ZIO_COMPRESS_DEFAULT	ZIO_COMPRESS_OFF
 
-/* nvlist pack encoding */
-#define	NV_ENCODE_NATIVE	0
-#define	NV_ENCODE_XDR		1
-
-typedef enum {
-	DATA_TYPE_UNKNOWN = 0,
-	DATA_TYPE_BOOLEAN,
-	DATA_TYPE_BYTE,
-	DATA_TYPE_INT16,
-	DATA_TYPE_UINT16,
-	DATA_TYPE_INT32,
-	DATA_TYPE_UINT32,
-	DATA_TYPE_INT64,
-	DATA_TYPE_UINT64,
-	DATA_TYPE_STRING,
-	DATA_TYPE_BYTE_ARRAY,
-	DATA_TYPE_INT16_ARRAY,
-	DATA_TYPE_UINT16_ARRAY,
-	DATA_TYPE_INT32_ARRAY,
-	DATA_TYPE_UINT32_ARRAY,
-	DATA_TYPE_INT64_ARRAY,
-	DATA_TYPE_UINT64_ARRAY,
-	DATA_TYPE_STRING_ARRAY,
-	DATA_TYPE_HRTIME,
-	DATA_TYPE_NVLIST,
-	DATA_TYPE_NVLIST_ARRAY,
-	DATA_TYPE_BOOLEAN_VALUE,
-	DATA_TYPE_INT8,
-	DATA_TYPE_UINT8,
-	DATA_TYPE_BOOLEAN_ARRAY,
-	DATA_TYPE_INT8_ARRAY,
-	DATA_TYPE_UINT8_ARRAY
-} data_type_t;
-
 /*
  * On-disk version number.
  */