summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorBrian Behlendorf <behlendorf1@llnl.gov>2020-07-30 01:12:12 -0500
committerJason King <jason.king@joyent.com>2020-08-11 21:23:17 -0500
commit0ac8993002ee179cc3289243a0fc956ee0db04da (patch)
treea022bb414cfd4f6e41c2efe02b5f0eede12f3807 /usr/src/lib
parent0904e7ecf266ebe6844dfc4b178441dc8d81296b (diff)
downloadillumos-joyent-0ac8993002ee179cc3289243a0fc956ee0db04da.tar.gz
13013 Port OpenZFS zpool label clear improvements
13012 zpool_read_label semantics should match OpenZFS Portions contributed by: Jason King <jason.king@joyent.com> Reviewed by: Matt Ahrens <mahrens@delphix.com> Reviewed by: Tim Chase <tim@chase2k.com> Reviewed by: Tony Hutter <hutter2@llnl.gov> Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libzfs/common/libzfs_import.c49
-rw-r--r--usr/src/lib/libzutil/common/zutil_import.c11
2 files changed, 51 insertions, 9 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_import.c b/usr/src/lib/libzfs/common/libzfs_import.c
index 706f08e6ec..dc15aca0c0 100644
--- a/usr/src/lib/libzfs/common/libzfs_import.c
+++ b/usr/src/lib/libzfs/common/libzfs_import.c
@@ -169,23 +169,66 @@ zpool_clear_label(int fd)
int l;
vdev_label_t *label;
uint64_t size;
+ int labels_cleared = 0;
if (fstat64(fd, &statbuf) == -1)
return (0);
+
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
if ((label = calloc(sizeof (vdev_label_t), 1)) == NULL)
return (-1);
for (l = 0; l < VDEV_LABELS; l++) {
- if (pwrite64(fd, label, sizeof (vdev_label_t),
+ uint64_t state, guid;
+ nvlist_t *config;
+
+ if (pread64(fd, label, sizeof (vdev_label_t),
label_offset(size, l)) != sizeof (vdev_label_t)) {
- free(label);
- return (-1);
+ continue;
+ }
+
+ if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
+ sizeof (label->vl_vdev_phys.vp_nvlist), &config, 0) != 0) {
+ continue;
+ }
+
+ /* Skip labels which do not have a valid guid. */
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
+ &guid) != 0 || guid == 0) {
+ nvlist_free(config);
+ continue;
+ }
+
+ /* Skip labels which are not in a known valid state. */
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
+ &state) != 0 || state > POOL_STATE_L2CACHE) {
+ nvlist_free(config);
+ continue;
+ }
+
+ nvlist_free(config);
+
+ /*
+ * A valid label was found, overwrite this label's nvlist
+ * and uberblocks with zeros on disk. This is done to prevent
+ * system utilities, like blkid, from incorrectly detecting a
+ * partial label. The leading pad space is left untouched.
+ */
+ memset(label, 0, sizeof (vdev_label_t));
+ size_t label_size = sizeof (vdev_label_t) - (2 * VDEV_PAD_SIZE);
+
+ if (pwrite64(fd, label, label_size, label_offset(size, l) +
+ (2 * VDEV_PAD_SIZE)) == label_size) {
+ labels_cleared++;
}
}
free(label);
+
+ if (labels_cleared == 0)
+ return (-1);
+
return (0);
}
diff --git a/usr/src/lib/libzutil/common/zutil_import.c b/usr/src/lib/libzutil/common/zutil_import.c
index 961247c5c0..b4e6ccc0ca 100644
--- a/usr/src/lib/libzutil/common/zutil_import.c
+++ b/usr/src/lib/libzutil/common/zutil_import.c
@@ -25,6 +25,7 @@
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright 2015 RackTop Systems.
* Copyright (c) 2016, Intel Corporation.
+ * Copyright 2020 Joyent, Inc.
*/
/*
@@ -913,8 +914,11 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
*config = NULL;
+ if (num_labels != NULL)
+ *num_labels = 0;
+
if (fstat64(fd, &statbuf) == -1)
- return (-1);
+ return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
@@ -968,11 +972,6 @@ zpool_read_label(int fd, nvlist_t **config, int *num_labels)
free(label);
*config = expected_config;
- if (count == 0) {
- errno = ENOENT;
- return (-1);
- }
-
return (0);
}