NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/58212: cgdconfig(8): Add zfs verification method
>Number: 58212
>Category: bin
>Synopsis: cgdconfig(8): Add zfs verification method
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Apr 28 20:15:00 +0000 2024
>Originator: Malte Dehling
>Release: NetBSD 10.0, -current
>Organization:
>Environment:
NetBSD 10.0 (GENERIC) #4: Wed Apr 24 12:21:26 PDT 2024
mdehling@nb-base-dev:/scratch/obj/sys/arch/amd64/compile/GENERIC amd64
>Description:
I would like to propose the attached patch to add a zfs verification
method to the cgdconfig(8) program. With such a method, it will be
possible to use cgd devices as vdevs in a zpool without an intermediate
gpt.
The verification method used here is the same as in fstyp(8): read the
first vdev label (256k at offset 0) and see if vdev_label->vl_vdev_phys
(112k-40b at offset 16k) describes a valid nvlist structure with existing
zpool name property.
>How-To-Repeat:
>Fix:
Make it possible to use cgd devices as vdevs in a zpool without an
intermediate gpt.
---
.../amd64/ramdisks/ramdisk-cgdroot/Makefile | 3 ++
.../amd64/ramdisks/ramdisk-cgdroot/list.zfs | 3 ++
rescue/Makefile | 4 ++
rescue/list.zfs | 3 ++
sbin/cgdconfig/Makefile | 18 +++++++
sbin/cgdconfig/cgdconfig.8 | 2 +
sbin/cgdconfig/cgdconfig.c | 53 +++++++++++++++++++
sbin/cgdconfig/params.c | 9 ++++
sbin/cgdconfig/params.h | 1 +
9 files changed, 96 insertions(+)
create mode 100644 distrib/amd64/ramdisks/ramdisk-cgdroot/list.zfs
create mode 100644 rescue/list.zfs
diff --git a/distrib/amd64/ramdisks/ramdisk-cgdroot/Makefile
b/distrib/amd64/ramdisks/ramdisk-cgdroot/Makefile
index 7be7a009f28..75b07c6ebf0 100644
--- a/distrib/amd64/ramdisks/ramdisk-cgdroot/Makefile
+++ b/distrib/amd64/ramdisks/ramdisk-cgdroot/Makefile
@@ -9,6 +9,9 @@ SMALLPROG_INET6=1
.include "${.CURDIR}/../common/Makefile.ramdisk"
LISTS+= ${DISTRIBDIR}/common/list.cgdroot
+.if ${MKZFS} != "no"
+LISTS+= ${.CURDIR}/list.zfs
+.endif
MTREECONF+= ${DISTRIBDIR}/common/mtree.cgdroot
.if ${USE_INET6} != "no"
diff --git a/distrib/amd64/ramdisks/ramdisk-cgdroot/list.zfs
b/distrib/amd64/ramdisks/ramdisk-cgdroot/list.zfs
new file mode 100644
index 00000000000..8247065d020
--- /dev/null
+++ b/distrib/amd64/ramdisks/ramdisk-cgdroot/list.zfs
@@ -0,0 +1,3 @@
+# $NetBSD$
+
+LIBS -lnvpair
diff --git a/rescue/Makefile b/rescue/Makefile
index 459e8a7135a..6ed6c178f3f 100644
--- a/rescue/Makefile
+++ b/rescue/Makefile
@@ -42,6 +42,10 @@ LISTS+= ${.CURDIR}/list.${f}
LISTS+= ${.CURDIR}/list.inet6
.endif
+.if ${MKZFS} != "no"
+LISTS+= ${.CURDIR}/list.zfs
+.endif
+
LISTS+= ${.CURDIR}/list.crypto
CRUNCHENV+= MKKERBEROS=no # for ssh
diff --git a/rescue/list.zfs b/rescue/list.zfs
new file mode 100644
index 00000000000..02bf8bc362c
--- /dev/null
+++ b/rescue/list.zfs
@@ -0,0 +1,3 @@
+# $NetBSD$
+
+LIBS -lnvpair
diff --git a/sbin/cgdconfig/Makefile b/sbin/cgdconfig/Makefile
index fec75b4e375..bf1be8109e3 100644
--- a/sbin/cgdconfig/Makefile
+++ b/sbin/cgdconfig/Makefile
@@ -29,4 +29,22 @@ ARGON2_NO_THREADS=1
.include "${NETBSDSRCDIR}/external/apache2/argon2/lib/libargon2/Makefile.inc"
.endif
+.if ${MKZFS} != "no"
+DPADD+= ${LIBNVPAIR}
+LDADD+= -lnvpair
+CPPFLAGS+= -DHAVE_ZFS
+
+OSNET=${NETBSDSRCDIR}/external/cddl/osnet
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/include
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/sys
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/head
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/lib/libzpool/common
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/uts/common
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/uts/common/fs/zfs
+CPPFLAGS.cgdconfig.c+= -I${OSNET}/dist/lib/libnvpair
+
+COPTS.cgdconfig.c+= -Wno-unknown-pragmas
+COPTS.cgdconfig.c+= -Wno-strict-prototypes
+.endif
+
.include <bsd.prog.mk>
diff --git a/sbin/cgdconfig/cgdconfig.8 b/sbin/cgdconfig/cgdconfig.8
index 2b0da2cb732..e48ccde02c5 100644
--- a/sbin/cgdconfig/cgdconfig.8
+++ b/sbin/cgdconfig/cgdconfig.8
@@ -270,6 +270,8 @@ scan for a valid Master Boot Record.
scan for a valid GUID partition table.
.It ffs
scan for a valid FFS file system.
+.It zfs
+scan for a valid ZFS vdev label (if compiled with MKZFS).
.It re-enter
prompt for passphrase twice, and ensure entered passphrases are
identical.
diff --git a/sbin/cgdconfig/cgdconfig.c b/sbin/cgdconfig/cgdconfig.c
index 9a634ef37e2..4baccb1d68f 100644
--- a/sbin/cgdconfig/cgdconfig.c
+++ b/sbin/cgdconfig/cgdconfig.c
@@ -73,6 +73,11 @@ __RCSID("$NetBSD: cgdconfig.c,v 1.61 2022/11/17
06:40:38 chs Exp $");
#include <ufs/ffs/fs.h>
+#ifdef HAVE_ZFS
+#include <libnvpair.h>
+#include <sys/vdev_impl.h>
+#endif
+
#include "params.h"
#include "pkcs5_pbkdf2.h"
#include "utils.h"
@@ -170,6 +175,9 @@ static int verify_ffs(int);
static int verify_reenter(struct params *);
static int verify_mbr(int);
static int verify_gpt(int);
+#ifdef HAVE_ZFS
+static int verify_zfs(int);
+#endif
__dead static void usage(void);
@@ -1024,6 +1032,10 @@ verify(struct params *p, int fd)
return verify_mbr(fd);
case VERIFY_GPT:
return verify_gpt(fd);
+#ifdef HAVE_ZFS
+ case VERIFY_ZFS:
+ return verify_zfs(fd);
+#endif
default:
warnx("unimplemented verification method");
return -1;
@@ -1182,6 +1194,47 @@ verify_gpt(int fd)
return ret;
}
+#ifdef HAVE_ZFS
+static int
+verify_zfs(int fd)
+{
+ vdev_label_t *vdev_label;
+ vdev_phys_t *vdev_phys;
+ nvlist_t *config = NULL;
+ ssize_t ret;
+
+ /*
+ * Read the first ZFS vdev label located at offset 0.
+ */
+ vdev_label = emalloc(sizeof *vdev_label);
+ ret = prog_pread(fd, vdev_label, sizeof(*vdev_label), 0);
+ if (ret < 0) {
+ warn("pread");
+ ret = 1;
+ goto bail;
+ } else if ((size_t)ret < sizeof(*vdev_label)) {
+ warnx("pread: incomplete block");
+ ret = 1;
+ goto bail;
+ };
+
+ ret = 0;
+
+ vdev_phys = &(vdev_label->vl_vdev_phys);
+ if ((nvlist_unpack(vdev_phys->vp_nvlist,
+ sizeof(vdev_phys->vp_nvlist), &config, 0)) != 0 ||
+ !nvlist_exists(config, "name"))
+ {
+ ret = 1;
+ };
+
+ nvlist_free(config);
+ bail:
+ free(vdev_label);
+ return ret;
+}
+#endif
+
static off_t sblock_try[] = SBLOCKSEARCH;
static int
diff --git a/sbin/cgdconfig/params.c b/sbin/cgdconfig/params.c
index 91af02c21cc..5da25ec0595 100644
--- a/sbin/cgdconfig/params.c
+++ b/sbin/cgdconfig/params.c
@@ -287,6 +287,10 @@ params_verify_method(string_t *in)
p->verify_method = VERIFY_MBR;
if (!strcmp("gpt", vm))
p->verify_method = VERIFY_GPT;
+#ifdef HAVE_ZFS
+ if (!strcmp("zfs", vm))
+ p->verify_method = VERIFY_ZFS;
+#endif
string_free(in);
@@ -1065,6 +1069,11 @@ params_fput(struct params *p, FILE *f)
case VERIFY_GPT:
print_kvpair_cstr(f, ts, "verify_method", "gpt");
break;
+#ifdef HAVE_ZFS
+ case VERIFY_ZFS:
+ print_kvpair_cstr(f, ts, "verify_method", "zfs");
+ break;
+#endif
default:
warnx("unsupported verify_method (%d)", p->verify_method);
return -1;
diff --git a/sbin/cgdconfig/params.h b/sbin/cgdconfig/params.h
index fb79a0deb80..ef49dde6aba 100644
--- a/sbin/cgdconfig/params.h
+++ b/sbin/cgdconfig/params.h
@@ -81,6 +81,7 @@ struct params {
#define VERIFY_REENTER 0x4
#define VERIFY_MBR 0x5
#define VERIFY_GPT 0x6
+#define VERIFY_ZFS 0x7
/* shared key derivation methods */
--
Malte Dehling
Home |
Main Index |
Thread Index |
Old Index