From 5f023415af5aa5803be6fbd6e2760782f4a6ad53 Mon Sep 17 00:00:00 2001 From: delphij Date: Tue, 1 Jul 2014 08:20:34 +0000 Subject: MFV r267568: 4891 want zdb option to dump all metadata illumos/illumos-gate@df15e419cb7359ba56ddddab9045e438d89e7cbc MFC after: 2 weeks --- .../opensolaris/lib/libzpool/common/kernel.c | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'cddl/contrib/opensolaris/lib/libzpool/common/kernel.c') 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 #include #include +#include #include #include #include @@ -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)); } -- cgit v1.1