mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Illumos 4891 - want zdb option to dump all metadata
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> We'd like a way for zdb to dump metadata in a machine-readable format, so that we can bring that back from a customer site for in-house diagnosis. Think of it as a crash dump for zpools, which can be used for post-mortem analysis of a malfunctioning pool References: https://www.illumos.org/issues/4891 https://github.com/illumos/illumos-gate/commit/df15e41 Porting notes: - [cmd/zdb/zdb.c] -a5778eazdb: Introduce -V for verbatim import - In main() getopt 'opt' variable removed and the code was brought back in line with illumos. - [lib/libzpool/kernel.c] -1e33ac1Fix Solaris thread dependency by using pthreads -f0e324fUpdate utsname support -4d58b69Fix vn_open/vn_rdwr error handling - In vn_open() allocate 'dumppath' on heap instead of stack - Properly handle 'dump_fd == -1' error path - Free 'realpath' after added vn_dumpdir_code block Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
committed by
Brian Behlendorf
parent
f3c9dca093
commit
9867e8be2a
+33
-2
@@ -29,6 +29,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/spa.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -50,6 +51,9 @@ char hw_serial[HW_HOSTID_LEN];
|
||||
struct utsname hw_utsname;
|
||||
vmem_t *zio_arena = NULL;
|
||||
|
||||
/* If set, all blocks read will be copied to the specified directory. */
|
||||
char *vn_dumpdir = NULL;
|
||||
|
||||
/* this only exists to have its address taken */
|
||||
struct proc p0;
|
||||
|
||||
@@ -588,6 +592,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 = 0;
|
||||
char *realpath;
|
||||
@@ -655,13 +660,31 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
|
||||
* FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
|
||||
*/
|
||||
fd = open64(realpath, flags - FREAD, mode);
|
||||
free(realpath);
|
||||
err = errno;
|
||||
|
||||
if (flags & FCREAT)
|
||||
(void) umask(old_umask);
|
||||
|
||||
if (vn_dumpdir != NULL) {
|
||||
char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
(void) snprintf(dumppath, MAXPATHLEN,
|
||||
"%s/%s", vn_dumpdir, basename(realpath));
|
||||
dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
|
||||
umem_free(dumppath, MAXPATHLEN);
|
||||
if (dump_fd == -1) {
|
||||
err = errno;
|
||||
free(realpath);
|
||||
close(fd);
|
||||
return (err);
|
||||
}
|
||||
} else {
|
||||
dump_fd = -1;
|
||||
}
|
||||
|
||||
free(realpath);
|
||||
|
||||
if (fd == -1)
|
||||
return (errno);
|
||||
return (err);
|
||||
|
||||
if (fstat64_blk(fd, &st) == -1) {
|
||||
err = errno;
|
||||
@@ -676,6 +699,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);
|
||||
}
|
||||
@@ -708,6 +732,11 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
|
||||
|
||||
if (uio == UIO_READ) {
|
||||
rc = pread64(vp->v_fd, addr, len, offset);
|
||||
if (vp->v_dump_fd != -1) {
|
||||
int status =
|
||||
pwrite64(vp->v_dump_fd, addr, rc, offset);
|
||||
ASSERT(status != -1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* To simulate partial disk writes, we split writes into two
|
||||
@@ -750,6 +779,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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user