Page MenuHomeFreeBSD

D11920.diff
No OneTemporary

D11920.diff

Index: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
===================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -772,6 +772,7 @@
* Label manipulation.
*/
extern int zpool_read_label(int, nvlist_t **);
+extern int zpool_read_all_labels(int, nvlist_t **);
extern int zpool_clear_label(int);
/* is this zvol valid for use as a dump device? */
Index: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
===================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
@@ -914,6 +914,65 @@
return (0);
}
+/*
+ * Given a file descriptor, read the label information and return an nvlist
+ * describing the configuration, if there is one.
+ * returns the number of valid labels found
+ */
+int
+zpool_read_all_labels(int fd, nvlist_t **config)
+{
+ struct stat64 statbuf;
+ int l;
+ vdev_label_t *label;
+ uint64_t state, txg, size;
+ int nlabels = 0;
+
+ *config = NULL;
+
+ if (fstat64(fd, &statbuf) == -1)
+ return (0);
+ size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
+
+ if ((label = malloc(sizeof (vdev_label_t))) == NULL)
+ return (0);
+
+ for (l = 0; l < VDEV_LABELS; l++) {
+ nvlist_t *temp = NULL;
+
+ /* TODO: use aio_read so we can read al 4 labels in parallel */
+ if (pread64(fd, label, sizeof (vdev_label_t),
+ label_offset(size, l)) != sizeof (vdev_label_t))
+ continue;
+
+ if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
+ sizeof (label->vl_vdev_phys.vp_nvlist), &temp, 0) != 0)
+ continue;
+
+ if (nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_STATE,
+ &state) != 0 || state > POOL_STATE_L2CACHE) {
+ nvlist_free(temp);
+ temp = NULL;
+ continue;
+ }
+
+ if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
+ (nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_TXG,
+ &txg) != 0 || txg == 0)) {
+ nvlist_free(temp);
+ temp = NULL;
+ continue;
+ }
+ if (temp)
+ *config = temp;
+
+ nlabels++;
+ }
+
+ free(label);
+ return (nlabels);
+}
+
typedef struct rdsk_node {
char *rn_name;
int rn_dfd;
Index: head/cddl/usr.sbin/zfsd/zfsd_event.cc
===================================================================
--- head/cddl/usr.sbin/zfsd/zfsd_event.cc
+++ head/cddl/usr.sbin/zfsd/zfsd_event.cc
@@ -36,6 +36,7 @@
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/fs/zfs.h>
+#include <sys/vdev_impl.h>
#include <syslog.h>
@@ -93,6 +94,7 @@
pool_state_t poolState;
char *poolName;
boolean_t b_inuse;
+ int nlabels;
inUse = false;
degraded = false;
@@ -105,8 +107,16 @@
if (poolName != NULL)
free(poolName);
- if (zpool_read_label(devFd, &devLabel) != 0
- || devLabel == NULL)
+ nlabels = zpool_read_all_labels(devFd, &devLabel);
+ /*
+ * If we find a disk with fewer than the maximum number of
+ * labels, it might be the whole disk of a partitioned disk
+ * where ZFS resides on a partition. In that case, we should do
+ * nothing and wait for the partition to appear. Or, the disk
+ * might be damaged. In that case, zfsd should do nothing and
+ * wait for the sysadmin to decide.
+ */
+ if (nlabels != VDEV_LABELS || devLabel == NULL)
return (NULL);
try {

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 11, 8:51 AM (19 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15752262
Default Alt Text
D11920.diff (3 KB)

Event Timeline