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