summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-07-15 05:28:58 +0000
committerdelphij <delphij@FreeBSD.org>2014-07-15 05:28:58 +0000
commitbfdd43f2b55bab822f028f6f948a2c3ea6d51401 (patch)
tree03a4aca1ecbc67bae4cfa138bb2b1cf1ce123d42 /cddl
parent66efdb2ba0fef5a0c32e712f8e3cc06b09ab9cdc (diff)
downloadFreeBSD-src-bfdd43f2b55bab822f028f6f948a2c3ea6d51401.zip
FreeBSD-src-bfdd43f2b55bab822f028f6f948a2c3ea6d51401.tar.gz
MFC r268084: MFV r267568:
4891 want zdb option to dump all metadata
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.813
-rw-r--r--cddl/contrib/opensolaris/cmd/zdb/zdb.c17
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/kernel.c24
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h2
4 files changed, 49 insertions, 7 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.8 b/cddl/contrib/opensolaris/cmd/zdb/zdb.8
index e59f370..41b99ac 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.8
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.8
@@ -14,12 +14,12 @@
.\"
.\" Copyright 2012, Richard Lowe.
.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
-.\" Copyright (c) 2012 by Delphix. All rights reserved.
+.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved.
.\" All Rights Reserved.
.\"
.\" $FreeBSD$
.\"
-.Dd March 20, 2014
+.Dd July 1, 2014
.Dt ZDB 8
.Os
.Sh NAME
@@ -32,6 +32,7 @@
.Op Fl t Ar txg
.Op Fl U Ar cache
.Op Fl M Ar inflight I/Os
+.Op Fl x Ar dumpdir
.Ar poolname
.Op Ar object ...
.Nm
@@ -217,6 +218,14 @@ Operate on an exported pool, not present in
The
.Fl p
flag specifies the path under which devices are to be searched.
+.It Fl x Ar dumpdir
+All blocks accessed will be copied to files in the specified directory.
+The blocks will be placed in sparse files whose name is the same as
+that of the file or device read. zdb can be then run on the generated files.
+Note that the
+.Fl bbc
+flags are sufficient to access (and thus copy)
+all metadata on the pool.
.It Fl F
Attempt to make an unreadable pool readable by trying progressively older
transactions.
diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
index 5974878..038cc28 100644
--- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c
+++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c
@@ -112,7 +112,7 @@ usage(void)
{
(void) fprintf(stderr,
"Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
- "[-U config] [-M inflight I/Os] poolname [object...]\n"
+ "[-U config] [-M inflight I/Os] [-x dumpdir] poolname [object...]\n"
" %s [-divPA] [-e -p path...] [-U config] dataset "
"[object...]\n"
" %s -m [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
@@ -150,7 +150,7 @@ usage(void)
(void) fprintf(stderr, " -R read and display block from a "
"device\n\n");
(void) fprintf(stderr, " Below options are intended for use "
- "with other options (except -l):\n");
+ "with other options:\n");
(void) fprintf(stderr, " -A ignore assertions (-A), enable "
"panic recovery (-AA) or both (-AAA)\n");
(void) fprintf(stderr, " -F attempt automatic rewind within "
@@ -163,11 +163,14 @@ usage(void)
"has altroot/not in a cachefile\n");
(void) fprintf(stderr, " -p <path> -- use one or more with "
"-e to specify path to vdev dir\n");
- (void) fprintf(stderr, " -P print numbers in parseable form\n");
+ (void) fprintf(stderr, " -x <dumpdir> -- "
+ "dump all read blocks into specified directory\n");
+ (void) fprintf(stderr, " -P print numbers in parseable form\n");
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
"searching for uberblocks\n");
(void) fprintf(stderr, " -M <number of inflight I/Os> -- "
- "specify the maximum number of checksumming I/Os [default is 200]");
+ "specify the maximum number of "
+ "checksumming I/Os [default is 200]\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");
@@ -3355,7 +3358,8 @@ main(int argc, char **argv)
dprintf_setup(&argc, argv);
- while ((c = getopt(argc, argv, "bcdhilmM:suCDRSAFLXevp:t:U:P")) != -1) {
+ while ((c = getopt(argc, argv,
+ "bcdhilmM:suCDRSAFLXx:evp:t:U:P")) != -1) {
switch (c) {
case 'b':
case 'c':
@@ -3408,6 +3412,9 @@ main(int argc, char **argv)
}
searchdirs[nsearch++] = optarg;
break;
+ case 'x':
+ vn_dumpdir = optarg;
+ break;
case 't':
max_txg = strtoull(optarg, NULL, 0);
if (max_txg < TXG_INITIAL) {
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
index 2b174f9..c61c5c2 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
+#include <libgen.h>
#include <sys/spa.h>
#include <sys/stat.h>
#include <sys/processor.h>
@@ -52,6 +53,9 @@ char hw_serial[HW_HOSTID_LEN];
kmutex_t cpu_lock;
#endif
+/* If set, all blocks read will be copied to the specified directory. */
+char *vn_dumpdir = NULL;
+
struct utsname utsname = {
"userland", "libzpool", "1", "1", "na"
};
@@ -415,6 +419,7 @@ int
vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
{
int fd;
+ int dump_fd;
vnode_t *vp;
int old_umask;
char realpath[MAXPATHLEN];
@@ -463,6 +468,17 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
if (flags & FCREAT)
(void) umask(old_umask);
+ if (vn_dumpdir != NULL) {
+ char dumppath[MAXPATHLEN];
+ (void) snprintf(dumppath, sizeof (dumppath),
+ "%s/%s", vn_dumpdir, basename(realpath));
+ dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
+ if (dump_fd == -1)
+ return (errno);
+ } else {
+ dump_fd = -1;
+ }
+
if (fd == -1)
return (errno);
@@ -478,6 +494,7 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
vp->v_fd = fd;
vp->v_size = st.st_size;
vp->v_path = spa_strdup(path);
+ vp->v_dump_fd = dump_fd;
return (0);
}
@@ -510,6 +527,11 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
if (uio == UIO_READ) {
iolen = pread64(vp->v_fd, addr, len, offset);
+ if (vp->v_dump_fd != -1) {
+ int status =
+ pwrite64(vp->v_dump_fd, addr, iolen, offset);
+ ASSERT(status != -1);
+ }
} else {
/*
* To simulate partial disk writes, we split writes into two
@@ -536,6 +558,8 @@ void
vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
{
close(vp->v_fd);
+ if (vp->v_dump_fd != -1)
+ close(vp->v_dump_fd);
spa_strfree(vp->v_path);
umem_free(vp, sizeof (vnode_t));
}
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
index cc8285d..03027c3 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
@@ -424,8 +424,10 @@ typedef struct vnode {
uint64_t v_size;
int v_fd;
char *v_path;
+ int v_dump_fd;
} vnode_t;
+extern char *vn_dumpdir;
#define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */
typedef struct xoptattr {
OpenPOWER on IntegriCloud