aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zdb/zdb.c26
-rw-r--r--include/sys/zfs_debug.h1
-rw-r--r--man/man8/zdb.817
-rw-r--r--module/zfs/zfs_debug.c15
4 files changed, 52 insertions, 7 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 938df8227..6a36aa1ef 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2015, Intel Corporation.
*/
@@ -126,7 +126,7 @@ static void
usage(void)
{
(void) fprintf(stderr,
- "Usage: %s [-CumMdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
+ "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
"[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n"
" %s [-divPA] [-e -p path...] [-U config] dataset "
"[object...]\n"
@@ -187,12 +187,23 @@ usage(void)
(void) fprintf(stderr, " -I <number of inflight I/Os> -- "
"specify the maximum number of "
"checksumming I/Os [default is 200]\n");
+ (void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
+ "exiting\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");
exit(1);
}
+static void
+dump_debug_buffer(void)
+{
+ if (dump_opt['G']) {
+ (void) printf("\n");
+ zfs_dbgmsg_print("zdb");
+ }
+}
+
/*
* Called for usage errors that are discovered after a call to spa_open(),
* dmu_bonus_hold(), or pool_match(). abort() is called for other errors.
@@ -209,6 +220,8 @@ fatal(const char *fmt, ...)
va_end(ap);
(void) fprintf(stderr, "\n");
+ dump_debug_buffer();
+
exit(1);
}
@@ -3197,8 +3210,10 @@ dump_zpool(spa_t *spa)
if (dump_opt['h'])
dump_history(spa);
- if (rc != 0)
+ if (rc != 0) {
+ dump_debug_buffer();
exit(rc);
+ }
}
#define ZDB_FLAG_CHECKSUM 0x0001
@@ -3692,7 +3707,7 @@ main(int argc, char **argv)
spa_config_path = spa_config_path_env;
while ((c = getopt(argc, argv,
- "bcdhilmMI:suCDRSAFLXx:evp:t:U:PV")) != -1) {
+ "bcdhilmMI:suCDRSAFLXx:evp:t:U:PVG")) != -1) {
switch (c) {
case 'b':
case 'c':
@@ -3708,6 +3723,7 @@ main(int argc, char **argv)
case 'M':
case 'R':
case 'S':
+ case 'G':
dump_opt[c]++;
dump_all = 0;
break;
@@ -3939,6 +3955,8 @@ main(int argc, char **argv)
fuid_table_destroy();
sa_loaded = B_FALSE;
+ dump_debug_buffer();
+
libzfs_fini(g_zfs);
kernel_fini();
diff --git a/include/sys/zfs_debug.h b/include/sys/zfs_debug.h
index a2f61e5b2..b9b06a5ad 100644
--- a/include/sys/zfs_debug.h
+++ b/include/sys/zfs_debug.h
@@ -73,6 +73,7 @@ extern void zfs_dbgmsg_fini(void);
#ifndef _KERNEL
extern int dprintf_find_string(const char *string);
+extern void zfs_dbgmsg_print(const char *tag);
#endif
#ifdef __cplusplus
diff --git a/man/man8/zdb.8 b/man/man8/zdb.8
index efa1f41eb..271e512d5 100644
--- a/man/man8/zdb.8
+++ b/man/man8/zdb.8
@@ -11,15 +11,15 @@
.\"
.\"
.\" Copyright 2012, Richard Lowe.
-.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+.\" Copyright (c) 2012, 2016 by Delphix. All rights reserved.
.\"
-.TH "ZDB" "8" "February 15, 2012" "" ""
+.TH "ZDB" "8" "Feb 4, 2016" "" ""
.SH "NAME"
\fBzdb\fR - Display zpool debugging and consistency information
.SH "SYNOPSIS"
-\fBzdb\fR [-CumdibcsDvhLMXFPA] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
+\fBzdb\fR [-CumdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
[-U \fIcache\fR] [-I \fIinflight I/Os\fR] [-x \fIdumpdir\fR]
[\fIpoolname\fR [\fIobject\fR ...]]
@@ -400,6 +400,17 @@ transactions.
.sp
.ne 2
.na
+\fB-G\fR
+.ad
+.sp .6
+.RS 4n
+Dump the contents of the zfs_dbgmsg buffer before exiting zdb. zfs_dbgmsg is
+a buffer used by ZFS to dump advanced debug information.
+.RE
+
+.sp
+.ne 2
+.na
\fB-I \fIinflight I/Os\fR \fR
.ad
.sp .6
diff --git a/module/zfs/zfs_debug.c b/module/zfs/zfs_debug.c
index b553d21e4..76a3ad91c 100644
--- a/module/zfs/zfs_debug.c
+++ b/module/zfs/zfs_debug.c
@@ -228,6 +228,21 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
kmem_free(buf, size);
}
+
+#else
+
+void
+zfs_dbgmsg_print(const char *tag)
+{
+ zfs_dbgmsg_t *zdm;
+
+ (void) printf("ZFS_DBGMSG(%s):\n", tag);
+ mutex_enter(&zfs_dbgmsgs_lock);
+ for (zdm = list_head(&zfs_dbgmsgs); zdm;
+ zdm = list_next(&zfs_dbgmsgs, zdm))
+ (void) printf("%s\n", zdm->zdm_msg);
+ mutex_exit(&zfs_dbgmsgs_lock);
+}
#endif /* _KERNEL */
#ifdef _KERNEL