summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2016-04-09 19:57:01 +0300
committerMatthew Ahrens <mahrens@delphix.com>2017-01-13 10:20:46 -0800
commit64723e361134b2a2c45341334174f9d34002f8d0 (patch)
treedee4623487bb271e0e83497bb4a6f79ad18cad42
parent105686550ee9cbf5d033166a8a2a5a763667d436 (diff)
downloadillumos-joyent-64723e361134b2a2c45341334174f9d34002f8d0.tar.gz
6866 zdb -l should return non-zero if it fails to find any label
Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed by: John Kennedy <john.kennedy@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/cmd/zdb/zdb.c85
-rw-r--r--usr/src/man/man1m/zdb.1m16
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zdb/zdb_001_neg.ksh4
3 files changed, 61 insertions, 44 deletions
diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c
index bd9c5c2408..ecf63568ab 100644
--- a/usr/src/cmd/zdb/zdb.c
+++ b/usr/src/cmd/zdb/zdb.c
@@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
+ * Copyright 2016 Nexenta Systems, Inc.
*/
#include <stdio.h>
@@ -119,7 +120,7 @@ static void
usage(void)
{
(void) fprintf(stderr,
- "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
+ "Usage: %s [-CmMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
"[-U config] [-I inflight I/Os] [-x dumpdir] [-o var=value] "
"poolname [object...]\n"
" %s [-divPA] [-e -p path...] [-U config] dataset "
@@ -129,7 +130,7 @@ usage(void)
" %s -R [-A] [-e [-p path...]] poolname "
"vdev:offset:size[:flags]\n"
" %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
- " %s -l [-uA] device\n"
+ " %s -l [-Aqu] device\n"
" %s -C [-A] [-U config]\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
@@ -140,7 +141,6 @@ usage(void)
(void) fprintf(stderr, " If object numbers are specified, only "
"those objects are dumped\n\n");
(void) fprintf(stderr, " Options to control amount of output:\n");
- (void) fprintf(stderr, " -u uberblock\n");
(void) fprintf(stderr, " -d dataset(s)\n");
(void) fprintf(stderr, " -i intent logs\n");
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
@@ -154,7 +154,7 @@ usage(void)
(void) fprintf(stderr, " -D dedup statistics\n");
(void) fprintf(stderr, " -S simulate dedup to measure effect\n");
(void) fprintf(stderr, " -v verbose (applies to all others)\n");
- (void) fprintf(stderr, " -l dump label contents\n");
+ (void) fprintf(stderr, " -l read label contents\n");
(void) fprintf(stderr, " -L disable leak tracking (do not "
"load spacemaps)\n");
(void) fprintf(stderr, " -R read and display block from a "
@@ -185,6 +185,8 @@ usage(void)
"exiting\n");
(void) fprintf(stderr, " -o <variable>=<value> set global "
"variable to an unsigned 32-bit integer value\n");
+ (void) fprintf(stderr, " -q don't print label contents\n");
+ (void) fprintf(stderr, " -u uberblock\n");
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
@@ -2139,45 +2141,48 @@ dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift)
}
}
-static void
+static int
dump_label(const char *dev)
{
int fd;
vdev_label_t label;
- char *path, *buf = label.vl_vdev_phys.vp_nvlist;
+ char path[MAXPATHLEN];
+ char *buf = label.vl_vdev_phys.vp_nvlist;
size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
struct stat64 statbuf;
uint64_t psize, ashift;
- int len = strlen(dev) + 1;
-
- if (strncmp(dev, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) {
- len++;
- path = malloc(len);
- (void) snprintf(path, len, "%s%s", ZFS_RDISK_ROOTD,
- dev + strlen(ZFS_DISK_ROOTD));
- } else {
- path = strdup(dev);
- }
+ boolean_t label_found = B_FALSE;
+
+ (void) strlcpy(path, dev, sizeof (path));
+ if (dev[0] == '/') {
+ if (strncmp(dev, ZFS_DISK_ROOTD,
+ strlen(ZFS_DISK_ROOTD)) == 0) {
+ (void) snprintf(path, sizeof (path), "%s%s",
+ ZFS_RDISK_ROOTD, dev + strlen(ZFS_DISK_ROOTD));
+ }
+ } else if (stat64(path, &statbuf) != 0) {
+ char *s;
- if ((fd = open64(path, O_RDONLY)) < 0) {
- (void) printf("cannot open '%s': %s\n", path, strerror(errno));
- free(path);
- exit(1);
+ (void) snprintf(path, sizeof (path), "%s%s", ZFS_RDISK_ROOTD,
+ dev);
+ if ((s = strrchr(dev, 's')) == NULL || !isdigit(*(s + 1)))
+ (void) strlcat(path, "s0", sizeof (path));
}
- if (fstat64(fd, &statbuf) != 0) {
+ if (stat64(path, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", path,
strerror(errno));
- free(path);
- (void) close(fd);
exit(1);
}
if (S_ISBLK(statbuf.st_mode)) {
(void) printf("cannot use '%s': character device required\n",
path);
- free(path);
- (void) close(fd);
+ exit(1);
+ }
+
+ if ((fd = open64(path, O_RDONLY)) < 0) {
+ (void) printf("cannot open '%s': %s\n", path, strerror(errno));
exit(1);
}
@@ -2187,36 +2192,43 @@ dump_label(const char *dev)
for (int l = 0; l < VDEV_LABELS; l++) {
nvlist_t *config = NULL;
- (void) printf("--------------------------------------------\n");
- (void) printf("LABEL %d\n", l);
- (void) printf("--------------------------------------------\n");
+ if (!dump_opt['q']) {
+ (void) printf("------------------------------------\n");
+ (void) printf("LABEL %d\n", l);
+ (void) printf("------------------------------------\n");
+ }
if (pread64(fd, &label, sizeof (label),
vdev_label_offset(psize, l, 0)) != sizeof (label)) {
- (void) printf("failed to read label %d\n", l);
+ if (!dump_opt['q'])
+ (void) printf("failed to read label %d\n", l);
continue;
}
if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
- (void) printf("failed to unpack label %d\n", l);
+ if (!dump_opt['q'])
+ (void) printf("failed to unpack label %d\n", l);
ashift = SPA_MINBLOCKSHIFT;
} else {
nvlist_t *vdev_tree = NULL;
- dump_nvlist(config, 4);
+ if (!dump_opt['q'])
+ dump_nvlist(config, 4);
if ((nvlist_lookup_nvlist(config,
ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) ||
(nvlist_lookup_uint64(vdev_tree,
ZPOOL_CONFIG_ASHIFT, &ashift) != 0))
ashift = SPA_MINBLOCKSHIFT;
nvlist_free(config);
+ label_found = B_TRUE;
}
if (dump_opt['u'])
dump_label_uberblocks(&label, ashift);
}
- free(path);
(void) close(fd);
+
+ return (label_found ? 0 : 2);
}
static uint64_t dataset_feature_count[SPA_FEATURES];
@@ -3587,7 +3599,7 @@ main(int argc, char **argv)
spa_config_path = spa_config_path_env;
while ((c = getopt(argc, argv,
- "bcdhilmMI:suCDRSAFLXx:evp:t:U:PGo:")) != -1) {
+ "bcdhilmMI:suCDRSAFLXx:evp:t:U:PGo:q")) != -1) {
switch (c) {
case 'b':
case 'c':
@@ -3613,6 +3625,7 @@ main(int argc, char **argv)
case 'X':
case 'e':
case 'P':
+ case 'q':
dump_opt[c]++;
break;
case 'I':
@@ -3720,10 +3733,8 @@ main(int argc, char **argv)
usage();
}
- if (dump_opt['l']) {
- dump_label(argv[0]);
- return (0);
- }
+ if (dump_opt['l'])
+ return (dump_label(argv[0]));
if (dump_opt['X'] || dump_opt['F'])
rewind = ZPOOL_DO_REWIND |
diff --git a/usr/src/man/man1m/zdb.1m b/usr/src/man/man1m/zdb.1m
index ed74d510d0..eaa615a3fc 100644
--- a/usr/src/man/man1m/zdb.1m
+++ b/usr/src/man/man1m/zdb.1m
@@ -12,14 +12,15 @@
.\"
.\" Copyright 2012, Richard Lowe.
.\" Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+.\" Copyright 2016 Nexenta Systems, Inc.
.\"
-.TH "ZDB" "1M" "Feb 4, 2016" "" ""
+.TH "ZDB" "1M" "April 9, 2016"
.SH "NAME"
\fBzdb\fR - Display zpool debugging and consistency information
.SH "SYNOPSIS"
-\fBzdb\fR [-CumdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
+\fBzdb\fR [-CmdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
[-U \fIcache\fR] [-I \fIinflight I/Os\fR] [-x \fIdumpdir\fR]
[-o \fIvar\fR=\fIvalue\fR] ... [\fIpoolname\fR [\fIobject\fR ...]]
@@ -39,7 +40,7 @@
\fBzdb\fR -S [-AP] [-e [-p \fIpath\fR...]] [-U \fIcache\fR] \fIpoolname\fR
.P
-\fBzdb\fR -l [-uA] \fIdevice\fR
+\fBzdb\fR -l [-Aqu] \fIdevice\fR
.P
\fBzdb\fR -C [-A] [-U \fIcache\fR]
@@ -176,8 +177,13 @@ transaction type.
.ad
.sp .6
.RS 4n
-Display the vdev labels from the specified device. If the \fB-u\fR option is
-also specified, also display the uberblocks on this device.
+Read the vdev labels from the specified device. \fBzdb -l\fR will return 0 if
+valid label was found, 1 if error occured, and 2 if no valid labels were found.
+.P
+If the \fB-u\fR option is also specified, also display the uberblocks on this
+device.
+.P
+If the \fB-q\fR option is also specified, don't print the labels.
.RE
.sp
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zdb/zdb_001_neg.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zdb/zdb_001_neg.ksh
index 8205ec3104..9776447097 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zdb/zdb_001_neg.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zdb/zdb_001_neg.ksh
@@ -56,8 +56,8 @@ set -A args "create" "add" "destroy" "import fakepool" \
"add mirror fakepool" "add raidz fakepool" \
"add raidz1 fakepool" "add raidz2 fakepool" \
"setvprop" "blah blah" "-%" "--?" "-*" "-=" \
- "-a" "-f" "-g" "-h" "-j" "-k" "-m" "-n" "-o" "-p" "-p /tmp" \
- "-q" "-r" "-t" "-w" "-x" "-y" "-z" \
+ "-a" "-f" "-g" "-h" "-j" "-k" "-m" "-n" "-o" "-p" \
+ "-p /tmp" "-r" "-t" "-w" "-x" "-y" "-z" \
"-D" "-E" "-G" "-H" "-I" "-J" "-K" "-M" \
"-N" "-Q" "-R" "-S" "-T" "-V" "-W" "-Y" "-Z"