zfs_debug.c revision 268079
1219089Spjd/* 2219089Spjd * CDDL HEADER START 3219089Spjd * 4219089Spjd * The contents of this file are subject to the terms of the 5219089Spjd * Common Development and Distribution License (the "License"). 6219089Spjd * You may not use this file except in compliance with the License. 7219089Spjd * 8219089Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9219089Spjd * or http://www.opensolaris.org/os/licensing. 10219089Spjd * See the License for the specific language governing permissions 11219089Spjd * and limitations under the License. 12219089Spjd * 13219089Spjd * When distributing Covered Code, include this CDDL HEADER in each 14219089Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15219089Spjd * If applicable, add the following below this CDDL HEADER, with the 16219089Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17219089Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18219089Spjd * 19219089Spjd * CDDL HEADER END 20219089Spjd */ 21219089Spjd/* 22219089Spjd * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23254112Sdelphij * Copyright (c) 2013 by Delphix. All rights reserved. 24219089Spjd */ 25219089Spjd 26219089Spjd#include <sys/zfs_context.h> 27219089Spjd 28219089Spjdlist_t zfs_dbgmsgs; 29219089Spjdint zfs_dbgmsg_size; 30219089Spjdkmutex_t zfs_dbgmsgs_lock; 31268079Sdelphijint zfs_dbgmsg_maxsize = 4<<20; /* 4MB */ 32219089Spjd 33219089Spjdvoid 34219089Spjdzfs_dbgmsg_init(void) 35219089Spjd{ 36219089Spjd list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t), 37219089Spjd offsetof(zfs_dbgmsg_t, zdm_node)); 38219089Spjd mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL); 39219089Spjd} 40219089Spjd 41219089Spjdvoid 42219089Spjdzfs_dbgmsg_fini(void) 43219089Spjd{ 44219089Spjd zfs_dbgmsg_t *zdm; 45219089Spjd 46219089Spjd while ((zdm = list_remove_head(&zfs_dbgmsgs)) != NULL) { 47219089Spjd int size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); 48219089Spjd kmem_free(zdm, size); 49219089Spjd zfs_dbgmsg_size -= size; 50219089Spjd } 51219089Spjd mutex_destroy(&zfs_dbgmsgs_lock); 52240415Smm ASSERT0(zfs_dbgmsg_size); 53219089Spjd} 54219089Spjd 55219089Spjd/* 56219089Spjd * Print these messages by running: 57240415Smm * echo ::zfs_dbgmsg | mdb -k 58219089Spjd * 59219089Spjd * Monitor these messages by running: 60219089Spjd * dtrace -q -n 'zfs-dbgmsg{printf("%s\n", stringof(arg0))}' 61219089Spjd */ 62219089Spjdvoid 63219089Spjdzfs_dbgmsg(const char *fmt, ...) 64219089Spjd{ 65219089Spjd int size; 66219089Spjd va_list adx; 67219089Spjd zfs_dbgmsg_t *zdm; 68219089Spjd 69219089Spjd va_start(adx, fmt); 70219089Spjd size = vsnprintf(NULL, 0, fmt, adx); 71219089Spjd va_end(adx); 72219089Spjd 73219089Spjd /* 74219089Spjd * There is one byte of string in sizeof (zfs_dbgmsg_t), used 75219089Spjd * for the terminating null. 76219089Spjd */ 77219089Spjd zdm = kmem_alloc(sizeof (zfs_dbgmsg_t) + size, KM_SLEEP); 78219089Spjd zdm->zdm_timestamp = gethrestime_sec(); 79219089Spjd 80219089Spjd va_start(adx, fmt); 81219089Spjd (void) vsnprintf(zdm->zdm_msg, size + 1, fmt, adx); 82219089Spjd va_end(adx); 83219089Spjd 84219089Spjd DTRACE_PROBE1(zfs__dbgmsg, char *, zdm->zdm_msg); 85219089Spjd 86219089Spjd mutex_enter(&zfs_dbgmsgs_lock); 87219089Spjd list_insert_tail(&zfs_dbgmsgs, zdm); 88219089Spjd zfs_dbgmsg_size += sizeof (zfs_dbgmsg_t) + size; 89219089Spjd while (zfs_dbgmsg_size > zfs_dbgmsg_maxsize) { 90219089Spjd zdm = list_remove_head(&zfs_dbgmsgs); 91219089Spjd size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); 92219089Spjd kmem_free(zdm, size); 93219089Spjd zfs_dbgmsg_size -= size; 94219089Spjd } 95219089Spjd mutex_exit(&zfs_dbgmsgs_lock); 96219089Spjd} 97254112Sdelphij 98254112Sdelphijvoid 99254112Sdelphijzfs_dbgmsg_print(const char *tag) 100254112Sdelphij{ 101254112Sdelphij zfs_dbgmsg_t *zdm; 102254112Sdelphij 103254112Sdelphij (void) printf("ZFS_DBGMSG(%s):\n", tag); 104254112Sdelphij mutex_enter(&zfs_dbgmsgs_lock); 105254112Sdelphij for (zdm = list_head(&zfs_dbgmsgs); zdm; 106254112Sdelphij zdm = list_next(&zfs_dbgmsgs, zdm)) 107254112Sdelphij (void) printf("%s\n", zdm->zdm_msg); 108254112Sdelphij mutex_exit(&zfs_dbgmsgs_lock); 109254112Sdelphij} 110