4891 want zdb option to dump all metadata

Reviewed by: Sonu Pillai <sonu.pillai@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Garrett D'Amore <garrett@damore.org>

illumos/illumos-gate@df15e419cb
This commit is contained in:
delphij 2014-06-17 07:51:55 +00:00
parent 50a9e47c91
commit 1202381781
4 changed files with 54 additions and 7 deletions

View File

@ -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, " -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");
@ -3325,7 +3328,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':
@ -3378,6 +3382,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) {

View File

@ -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>
@ -51,6 +52,9 @@ char hw_serial[HW_HOSTID_LEN];
kmutex_t cpu_lock;
vmem_t *zio_arena = NULL;
/* If set, all blocks read will be copied to the specified directory. */
char *vn_dumpdir = NULL;
struct utsname utsname = {
"userland", "libzpool", "1", "1", "na"
};
@ -394,6 +398,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];
@ -442,6 +447,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);
@ -457,6 +473,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);
}
@ -489,6 +506,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
@ -515,6 +537,8 @@ void
vn_close(vnode_t *vp)
{
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));
}

View File

@ -389,8 +389,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 {

View File

@ -11,7 +11,7 @@
.\"
.\"
.\" Copyright 2012, Richard Lowe.
.\" Copyright (c) 2012 by Delphix. All rights reserved.
.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved.
.\"
.TH "ZDB" "1M" "March 6, 2014" "" ""
@ -20,8 +20,8 @@
.SH "SYNOPSIS"
\fBzdb\fR [-CumdibcsDvhLXFPA] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
[-U \fIcache\fR] [-M \fIinflight I/Os\fR] [\fIpoolname\fR
[\fIobject\fR ...]]
[-U \fIcache\fR] [-M \fIinflight I/Os\fR] [-x \fIdumpdir\fR]
[\fIpoolname\fR [\fIobject\fR ...]]
.P
\fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] [-U \fIcache\fR]
@ -352,6 +352,20 @@ Operate on an exported pool, not present in \fB/etc/zfs/zpool.cache\fR. The
\fB-p\fR flag specifies the path under which devices are to be searched.
.RE
.sp
.ne 2
.na
\fB-x\fR \fIdumpdir\fR
.ad
.sp .6
.RS 4n
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 \fB-bbc\fR flags are sufficient to access (and thus copy)
all metadata on the pool.
.RE
.sp
.ne 2
.na