diff options
Diffstat (limited to 'module/zfs/zfs_debug.c')
-rw-r--r-- | module/zfs/zfs_debug.c | 132 |
1 files changed, 49 insertions, 83 deletions
diff --git a/module/zfs/zfs_debug.c b/module/zfs/zfs_debug.c index ca79893c9..b5f93fd9b 100644 --- a/module/zfs/zfs_debug.c +++ b/module/zfs/zfs_debug.c @@ -24,13 +24,17 @@ */ #include <sys/zfs_context.h> -#include <sys/kstat.h> -list_t zfs_dbgmsgs; +typedef struct zfs_dbgmsg { + procfs_list_node_t zdm_node; + time_t zdm_timestamp; + int zdm_size; + char zdm_msg[1]; /* variable length allocation */ +} zfs_dbgmsg_t; + +procfs_list_t zfs_dbgmsgs; int zfs_dbgmsg_size = 0; -kmutex_t zfs_dbgmsgs_lock; int zfs_dbgmsg_maxsize = 4<<20; /* 4MB */ -kstat_t *zfs_dbgmsg_kstat; /* * Internal ZFS debug messages are enabled by default. @@ -47,123 +51,71 @@ kstat_t *zfs_dbgmsg_kstat; int zfs_dbgmsg_enable = 1; static int -zfs_dbgmsg_headers(char *buf, size_t size) +zfs_dbgmsg_show_header(struct seq_file *f) { - (void) snprintf(buf, size, "%-12s %-8s\n", "timestamp", "message"); - + seq_printf(f, "%-12s %-8s\n", "timestamp", "message"); return (0); } static int -zfs_dbgmsg_data(char *buf, size_t size, void *data) +zfs_dbgmsg_show(struct seq_file *f, void *p) { - zfs_dbgmsg_t *zdm = (zfs_dbgmsg_t *)data; - - (void) snprintf(buf, size, "%-12llu %-s\n", + zfs_dbgmsg_t *zdm = (zfs_dbgmsg_t *)p; + seq_printf(f, "%-12llu %-s\n", (u_longlong_t)zdm->zdm_timestamp, zdm->zdm_msg); - return (0); } -static void * -zfs_dbgmsg_addr(kstat_t *ksp, loff_t n) -{ - zfs_dbgmsg_t *zdm = (zfs_dbgmsg_t *)ksp->ks_private; - - ASSERT(MUTEX_HELD(&zfs_dbgmsgs_lock)); - - if (n == 0) - ksp->ks_private = list_head(&zfs_dbgmsgs); - else if (zdm) - ksp->ks_private = list_next(&zfs_dbgmsgs, zdm); - - return (ksp->ks_private); -} - static void zfs_dbgmsg_purge(int max_size) { - zfs_dbgmsg_t *zdm; - int size; - - ASSERT(MUTEX_HELD(&zfs_dbgmsgs_lock)); - while (zfs_dbgmsg_size > max_size) { - zdm = list_remove_head(&zfs_dbgmsgs); + zfs_dbgmsg_t *zdm = list_remove_head(&zfs_dbgmsgs.pl_list); if (zdm == NULL) return; - size = zdm->zdm_size; + int size = zdm->zdm_size; kmem_free(zdm, size); zfs_dbgmsg_size -= size; } } static int -zfs_dbgmsg_update(kstat_t *ksp, int rw) +zfs_dbgmsg_clear(procfs_list_t *procfs_list) { - if (rw == KSTAT_WRITE) - zfs_dbgmsg_purge(0); - + mutex_enter(&zfs_dbgmsgs.pl_lock); + zfs_dbgmsg_purge(0); + mutex_exit(&zfs_dbgmsgs.pl_lock); return (0); } void zfs_dbgmsg_init(void) { - list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t), + procfs_list_install("zfs", + "dbgmsg", + &zfs_dbgmsgs, + zfs_dbgmsg_show, + zfs_dbgmsg_show_header, + zfs_dbgmsg_clear, offsetof(zfs_dbgmsg_t, zdm_node)); - mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL); - - zfs_dbgmsg_kstat = kstat_create("zfs", 0, "dbgmsg", "misc", - KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL); - if (zfs_dbgmsg_kstat) { - zfs_dbgmsg_kstat->ks_lock = &zfs_dbgmsgs_lock; - zfs_dbgmsg_kstat->ks_ndata = UINT32_MAX; - zfs_dbgmsg_kstat->ks_private = NULL; - zfs_dbgmsg_kstat->ks_update = zfs_dbgmsg_update; - kstat_set_raw_ops(zfs_dbgmsg_kstat, zfs_dbgmsg_headers, - zfs_dbgmsg_data, zfs_dbgmsg_addr); - kstat_install(zfs_dbgmsg_kstat); - } } void zfs_dbgmsg_fini(void) { - if (zfs_dbgmsg_kstat) - kstat_delete(zfs_dbgmsg_kstat); + procfs_list_uninstall(&zfs_dbgmsgs); + zfs_dbgmsg_purge(0); + /* * TODO - decide how to make this permanent */ #ifdef _KERNEL - mutex_enter(&zfs_dbgmsgs_lock); - zfs_dbgmsg_purge(0); - mutex_exit(&zfs_dbgmsgs_lock); - mutex_destroy(&zfs_dbgmsgs_lock); + procfs_list_destroy(&zfs_dbgmsgs); #endif } void -__zfs_dbgmsg(char *buf) -{ - zfs_dbgmsg_t *zdm; - int size; - - size = sizeof (zfs_dbgmsg_t) + strlen(buf); - zdm = kmem_zalloc(size, KM_SLEEP); - zdm->zdm_size = size; - zdm->zdm_timestamp = gethrestime_sec(); - strcpy(zdm->zdm_msg, buf); - - mutex_enter(&zfs_dbgmsgs_lock); - list_insert_tail(&zfs_dbgmsgs, zdm); - zfs_dbgmsg_size += size; - zfs_dbgmsg_purge(MAX(zfs_dbgmsg_maxsize, 0)); - mutex_exit(&zfs_dbgmsgs_lock); -} - -void __set_error(const char *file, const char *func, int line, int err) { /* @@ -176,6 +128,22 @@ __set_error(const char *file, const char *func, int line, int err) } #ifdef _KERNEL +static void +__zfs_dbgmsg(char *buf) +{ + int size = sizeof (zfs_dbgmsg_t) + strlen(buf); + zfs_dbgmsg_t *zdm = kmem_zalloc(size, KM_SLEEP); + zdm->zdm_size = size; + zdm->zdm_timestamp = gethrestime_sec(); + strcpy(zdm->zdm_msg, buf); + + mutex_enter(&zfs_dbgmsgs.pl_lock); + procfs_list_add(&zfs_dbgmsgs, zdm); + zfs_dbgmsg_size += size; + zfs_dbgmsg_purge(MAX(zfs_dbgmsg_maxsize, 0)); + mutex_exit(&zfs_dbgmsgs.pl_lock); +} + void __dprintf(const char *file, const char *func, int line, const char *fmt, ...) { @@ -244,14 +212,12 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...) 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)) + mutex_enter(&zfs_dbgmsgs.pl_lock); + for (zfs_dbgmsg_t *zdm = list_head(&zfs_dbgmsgs.pl_list); zdm != NULL; + zdm = list_next(&zfs_dbgmsgs.pl_list, zdm)) (void) printf("%s\n", zdm->zdm_msg); - mutex_exit(&zfs_dbgmsgs_lock); + mutex_exit(&zfs_dbgmsgs.pl_lock); } #endif /* _KERNEL */ |