MFV r267568:
4891 want zdb option to dump all metadata illumos/illumos-gate@df15e419cb MFC after: 2 weeks
This commit is contained in:
commit
6bab9dd0e4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268084
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user