xref: /freebsd/sys/contrib/openzfs/module/zfs/zfs_debug_common.c (revision 071ab5a1f3cbfd29c8fbec27f7e619418adaf074)
1*071ab5a1SMartin Matuska // SPDX-License-Identifier: CDDL-1.0
2*071ab5a1SMartin Matuska /*
3*071ab5a1SMartin Matuska  * CDDL HEADER START
4*071ab5a1SMartin Matuska  *
5*071ab5a1SMartin Matuska  * The contents of this file are subject to the terms of the
6*071ab5a1SMartin Matuska  * Common Development and Distribution License (the "License").
7*071ab5a1SMartin Matuska  * You may not use this file except in compliance with the License.
8*071ab5a1SMartin Matuska  *
9*071ab5a1SMartin Matuska  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*071ab5a1SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
11*071ab5a1SMartin Matuska  * See the License for the specific language governing permissions
12*071ab5a1SMartin Matuska  * and limitations under the License.
13*071ab5a1SMartin Matuska  *
14*071ab5a1SMartin Matuska  * When distributing Covered Code, include this CDDL HEADER in each
15*071ab5a1SMartin Matuska  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*071ab5a1SMartin Matuska  * If applicable, add the following below this CDDL HEADER, with the
17*071ab5a1SMartin Matuska  * fields enclosed by brackets "[]" replaced with your own identifying
18*071ab5a1SMartin Matuska  * information: Portions Copyright [yyyy] [name of copyright owner]
19*071ab5a1SMartin Matuska  *
20*071ab5a1SMartin Matuska  * CDDL HEADER END
21*071ab5a1SMartin Matuska  */
22*071ab5a1SMartin Matuska /*
23*071ab5a1SMartin Matuska  * Copyright (c) 2025 by Lawrence Livermore National Security, LLC.
24*071ab5a1SMartin Matuska  */
25*071ab5a1SMartin Matuska /*
26*071ab5a1SMartin Matuska  * This file contains zfs_dbgmsg() specific functions that are not OS or
27*071ab5a1SMartin Matuska  * userspace specific.
28*071ab5a1SMartin Matuska  */
29*071ab5a1SMartin Matuska #if !defined(_KERNEL)
30*071ab5a1SMartin Matuska #include <string.h>
31*071ab5a1SMartin Matuska #endif
32*071ab5a1SMartin Matuska 
33*071ab5a1SMartin Matuska #include <sys/zfs_context.h>
34*071ab5a1SMartin Matuska #include <sys/zfs_debug.h>
35*071ab5a1SMartin Matuska #include <sys/nvpair.h>
36*071ab5a1SMartin Matuska 
37*071ab5a1SMartin Matuska /*
38*071ab5a1SMartin Matuska  * Given a multi-line string, print out one of the lines and return a pointer
39*071ab5a1SMartin Matuska  * to the next line. Lines are demarcated by '\n'.  Note: this modifies the
40*071ab5a1SMartin Matuska  * input string (buf[]).
41*071ab5a1SMartin Matuska  *
42*071ab5a1SMartin Matuska  * This function is meant to be used in a loop like:
43*071ab5a1SMartin Matuska  * 	while (buf != NULL)
44*071ab5a1SMartin Matuska  * 		buf = kernel_print_one_line(buf);
45*071ab5a1SMartin Matuska  *
46*071ab5a1SMartin Matuska  * This function is useful for printing large, multi-line text buffers.
47*071ab5a1SMartin Matuska  *
48*071ab5a1SMartin Matuska  * Returns the pointer to the beginning of the next line in buf[], or NULL
49*071ab5a1SMartin Matuska  * if it's the last line, or nothing more to print.
50*071ab5a1SMartin Matuska  */
51*071ab5a1SMartin Matuska static char *
zfs_dbgmsg_one_line(char * buf)52*071ab5a1SMartin Matuska zfs_dbgmsg_one_line(char *buf)
53*071ab5a1SMartin Matuska {
54*071ab5a1SMartin Matuska 	char *nl;
55*071ab5a1SMartin Matuska 	if (!buf)
56*071ab5a1SMartin Matuska 		return (NULL);
57*071ab5a1SMartin Matuska 
58*071ab5a1SMartin Matuska 	nl = strchr(buf, '\n');
59*071ab5a1SMartin Matuska 	if (nl == NULL) {
60*071ab5a1SMartin Matuska 		__zfs_dbgmsg(buf);
61*071ab5a1SMartin Matuska 		return (NULL); /* done */
62*071ab5a1SMartin Matuska 	}
63*071ab5a1SMartin Matuska 	*nl = '\0';
64*071ab5a1SMartin Matuska 	__zfs_dbgmsg(buf);
65*071ab5a1SMartin Matuska 
66*071ab5a1SMartin Matuska 	return (nl + 1);
67*071ab5a1SMartin Matuska }
68*071ab5a1SMartin Matuska 
69*071ab5a1SMartin Matuska /*
70*071ab5a1SMartin Matuska  * Dump an nvlist tree to dbgmsg.
71*071ab5a1SMartin Matuska  *
72*071ab5a1SMartin Matuska  * This is the zfs_dbgmsg version of userspace's dump_nvlist() from libnvpair.
73*071ab5a1SMartin Matuska  */
74*071ab5a1SMartin Matuska void
__zfs_dbgmsg_nvlist(nvlist_t * nv)75*071ab5a1SMartin Matuska __zfs_dbgmsg_nvlist(nvlist_t *nv)
76*071ab5a1SMartin Matuska {
77*071ab5a1SMartin Matuska 	int len;
78*071ab5a1SMartin Matuska 	char *buf;
79*071ab5a1SMartin Matuska 
80*071ab5a1SMartin Matuska 	len = nvlist_snprintf(NULL, 0, nv, 4);
81*071ab5a1SMartin Matuska 	len++; /* Add null terminator */
82*071ab5a1SMartin Matuska 
83*071ab5a1SMartin Matuska 	buf = vmem_alloc(len, KM_SLEEP);
84*071ab5a1SMartin Matuska 	if (buf == NULL)
85*071ab5a1SMartin Matuska 		return;
86*071ab5a1SMartin Matuska 
87*071ab5a1SMartin Matuska 	(void) nvlist_snprintf(buf, len, nv, 4);
88*071ab5a1SMartin Matuska 
89*071ab5a1SMartin Matuska 	while (buf != NULL)
90*071ab5a1SMartin Matuska 		buf = zfs_dbgmsg_one_line(buf);
91*071ab5a1SMartin Matuska 
92*071ab5a1SMartin Matuska 	vmem_free(buf, len);
93*071ab5a1SMartin Matuska }
94*071ab5a1SMartin Matuska 
95*071ab5a1SMartin Matuska #ifdef _KERNEL
96*071ab5a1SMartin Matuska EXPORT_SYMBOL(__zfs_dbgmsg_nvlist);
97*071ab5a1SMartin Matuska #endif
98