FreeBSD ZFS
The Zettabyte File System
|
00001 /* 00002 * CDDL HEADER START 00003 * 00004 * The contents of this file are subject to the terms of the 00005 * Common Development and Distribution License (the "License"). 00006 * You may not use this file except in compliance with the License. 00007 * 00008 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 00009 * or http://www.opensolaris.org/os/licensing. 00010 * See the License for the specific language governing permissions 00011 * and limitations under the License. 00012 * 00013 * When distributing Covered Code, include this CDDL HEADER in each 00014 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 00015 * If applicable, add the following below this CDDL HEADER, with the 00016 * fields enclosed by brackets "[]" replaced with your own identifying 00017 * information: Portions Copyright [yyyy] [name of copyright owner] 00018 * 00019 * CDDL HEADER END 00020 */ 00021 /* 00022 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 00023 * Copyright (c) 2012 by Delphix. All rights reserved. 00024 */ 00025 00026 #include <sys/zfs_context.h> 00027 00028 list_t zfs_dbgmsgs; 00029 int zfs_dbgmsg_size; 00030 kmutex_t zfs_dbgmsgs_lock; 00031 int zfs_dbgmsg_maxsize = 1<<20; /* 1MB */ 00032 00033 void 00034 zfs_dbgmsg_init(void) 00035 { 00036 list_create(&zfs_dbgmsgs, sizeof (zfs_dbgmsg_t), 00037 offsetof(zfs_dbgmsg_t, zdm_node)); 00038 mutex_init(&zfs_dbgmsgs_lock, NULL, MUTEX_DEFAULT, NULL); 00039 } 00040 00041 void 00042 zfs_dbgmsg_fini(void) 00043 { 00044 zfs_dbgmsg_t *zdm; 00045 00046 while ((zdm = list_remove_head(&zfs_dbgmsgs)) != NULL) { 00047 int size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); 00048 kmem_free(zdm, size); 00049 zfs_dbgmsg_size -= size; 00050 } 00051 mutex_destroy(&zfs_dbgmsgs_lock); 00052 ASSERT0(zfs_dbgmsg_size); 00053 } 00054 00062 void 00063 zfs_dbgmsg(const char *fmt, ...) 00064 { 00065 int size; 00066 va_list adx; 00067 zfs_dbgmsg_t *zdm; 00068 00069 va_start(adx, fmt); 00070 size = vsnprintf(NULL, 0, fmt, adx); 00071 va_end(adx); 00072 00073 /* 00074 * There is one byte of string in sizeof (zfs_dbgmsg_t), used 00075 * for the terminating null. 00076 */ 00077 zdm = kmem_alloc(sizeof (zfs_dbgmsg_t) + size, KM_SLEEP); 00078 zdm->zdm_timestamp = gethrestime_sec(); 00079 00080 va_start(adx, fmt); 00081 (void) vsnprintf(zdm->zdm_msg, size + 1, fmt, adx); 00082 va_end(adx); 00083 00084 DTRACE_PROBE1(zfs__dbgmsg, char *, zdm->zdm_msg); 00085 00086 mutex_enter(&zfs_dbgmsgs_lock); 00087 list_insert_tail(&zfs_dbgmsgs, zdm); 00088 zfs_dbgmsg_size += sizeof (zfs_dbgmsg_t) + size; 00089 while (zfs_dbgmsg_size > zfs_dbgmsg_maxsize) { 00090 zdm = list_remove_head(&zfs_dbgmsgs); 00091 size = sizeof (zfs_dbgmsg_t) + strlen(zdm->zdm_msg); 00092 kmem_free(zdm, size); 00093 zfs_dbgmsg_size -= size; 00094 } 00095 mutex_exit(&zfs_dbgmsgs_lock); 00096 }