From 495b25a91a8f29aeec9e2965752a1fc9b9569583 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Tue, 8 Oct 2013 22:37:38 -0400 Subject: [PATCH] Add missing code to zfs_debug.{c,h} This is required to make Illumos 3962 merge. Signed-off-by: Richard Yao --- include/sys/zfs_debug.h | 33 +++++++++++++++++--- module/zfs/zfs_debug.c | 68 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/include/sys/zfs_debug.h b/include/sys/zfs_debug.h index 7632d7420c..41e8c08a15 100644 --- a/include/sys/zfs_debug.h +++ b/include/sys/zfs_debug.h @@ -20,11 +20,16 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #ifndef _SYS_ZFS_DEBUG_H #define _SYS_ZFS_DEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + #ifndef TRUE #define TRUE 1 #endif @@ -36,6 +41,7 @@ /* * ZFS debugging - Always enabled for user space builds. */ + #if !defined(ZFS_DEBUG) && !defined(_KERNEL) #define ZFS_DEBUG #endif @@ -75,9 +81,28 @@ extern int zfs_recover; #endif /* _KERNEL */ -void zfs_panic_recover(const char *fmt, ...); -#define zfs_dbgmsg(...) dprintf(__VA_ARGS__) -void zfs_dbgmsg_init(void); -void zfs_dbgmsg_fini(void); +extern void zfs_panic_recover(const char *fmt, ...); + +typedef struct zfs_dbgmsg { + list_node_t zdm_node; + time_t zdm_timestamp; + char zdm_msg[1]; /* variable length allocation */ +} zfs_dbgmsg_t; + +extern void zfs_dbgmsg_init(void); +extern void zfs_dbgmsg_fini(void); +#if defined(_KERNEL) && defined(__linux__) +#define zfs_dbgmsg(...) dprintf(__VA_ARGS__) +#else +extern void zfs_dbgmsg(const char *fmt, ...); +#endif + +#ifndef _KERNEL +extern int dprintf_find_string(const char *string); +#endif + +#ifdef __cplusplus +} +#endif #endif /* _SYS_ZFS_DEBUG_H */ diff --git a/module/zfs/zfs_debug.c b/module/zfs/zfs_debug.c index ad611ac91d..29423303fb 100644 --- a/module/zfs/zfs_debug.c +++ b/module/zfs/zfs_debug.c @@ -25,6 +25,13 @@ #include +#if !defined(_KERNEL) || !defined(__linux__) +list_t zfs_dbgmsgs; +int zfs_dbgmsg_size; +kmutex_t zfs_dbgmsgs_lock; +int zfs_dbgmsg_maxsize = 1<<20; /* 1MB */ +#endif + /* * Enable various debugging features. */ @@ -57,6 +64,12 @@ zfs_panic_recover(const char *fmt, ...) void zfs_dbgmsg_init(void) { +#if !defined(_KERNEL) || !defined(__linux__) + list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t), + offsetof(zfs_dbgmsg_t, zdm_node)); + mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL); +#endif + if (zfs_flags == 0) { #if defined(_KERNEL) zfs_flags = ZFS_DEBUG_DPRINTF; @@ -71,9 +84,64 @@ zfs_dbgmsg_init(void) void zfs_dbgmsg_fini(void) { +#if !defined(_KERNEL) || !defined(__linux__) + zfs_dbgmsg_t *zdm; + + while ((zdm = list_remove_head(&zfs_dbgmsgs)) != NULL) { + int size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); + kmem_free(zdm, size); + zfs_dbgmsg_size -= size; + } + mutex_destroy(&zfs_dbgmsgs_lock); + ASSERT0(zfs_dbgmsg_size); +#endif return; } +#if !defined(_KERNEL) || !defined(__linux__) +/* + * Print these messages by running: + * echo ::zfs_dbgmsg | mdb -k + * + * Monitor these messages by running: + * dtrace -q -n 'zfs-dbgmsg{printf("%s\n", stringof(arg0))}' + */ +void +zfs_dbgmsg(const char *fmt, ...) +{ + int size; + va_list adx; + zfs_dbgmsg_t *zdm; + + va_start(adx, fmt); + size = vsnprintf(NULL, 0, fmt, adx); + va_end(adx); + + /* + * There is one byte of string in sizeof (zfs_dbgmsg_t), used + * for the terminating null. + */ + zdm = kmem_alloc(sizeof (zfs_dbgmsg_t) + size, KM_SLEEP); + zdm->zdm_timestamp = gethrestime_sec(); + + va_start(adx, fmt); + (void) vsnprintf(zdm->zdm_msg, size + 1, fmt, adx); + va_end(adx); + + DTRACE_PROBE1(zfs__dbgmsg, char *, zdm->zdm_msg); + + mutex_enter(&zfs_dbgmsgs_lock); + list_insert_tail(&zfs_dbgmsgs, zdm); + zfs_dbgmsg_size += sizeof (zfs_dbgmsg_t) + size; + while (zfs_dbgmsg_size > zfs_dbgmsg_maxsize) { + zdm = list_remove_head(&zfs_dbgmsgs); + size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); + kmem_free(zdm, size); + zfs_dbgmsg_size -= size; + } + mutex_exit(&zfs_dbgmsgs_lock); +} +#endif #if defined(_KERNEL) module_param(zfs_flags, int, 0644);