1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * This file and its contents are supplied under the terms of the
4 * Common Development and Distribution License ("CDDL"), version 1.0.
5 * You may only use this file in accordance with the terms of version
6 * 1.0 of the CDDL.
7 *
8 * A full copy of the text of the CDDL should have accompanied this
9 * source. A copy of the CDDL is also available via the Internet at
10 * https://opensource.org/license/CDDL-1.0.
11 */
12 /*
13 * Copyright (c) 2025 by Lawrence Livermore National Security, LLC.
14 */
15 /*
16 * This file contains zfs_dbgmsg() specific functions that are not OS or
17 * userspace specific.
18 */
19 #if !defined(_KERNEL)
20 #include <string.h>
21 #endif
22
23 #include <sys/zfs_context.h>
24 #include <sys/zfs_debug.h>
25 #include <sys/nvpair.h>
26
27 /*
28 * Given a multi-line string, print out one of the lines and return a pointer
29 * to the next line. Lines are demarcated by '\n'. Note: this modifies the
30 * input string (buf[]).
31 *
32 * This function is meant to be used in a loop like:
33 * while (buf != NULL)
34 * buf = kernel_print_one_line(buf);
35 *
36 * This function is useful for printing large, multi-line text buffers.
37 *
38 * Returns the pointer to the beginning of the next line in buf[], or NULL
39 * if it's the last line, or nothing more to print.
40 */
41 static char *
zfs_dbgmsg_one_line(char * buf)42 zfs_dbgmsg_one_line(char *buf)
43 {
44 char *nl;
45 if (!buf)
46 return (NULL);
47
48 nl = strchr(buf, '\n');
49 if (nl == NULL) {
50 __zfs_dbgmsg(buf);
51 return (NULL); /* done */
52 }
53 *nl = '\0';
54 __zfs_dbgmsg(buf);
55
56 return (nl + 1);
57 }
58
59 /*
60 * Dump an nvlist tree to dbgmsg.
61 *
62 * This is the zfs_dbgmsg version of userspace's dump_nvlist() from libnvpair.
63 */
64 void
__zfs_dbgmsg_nvlist(nvlist_t * nv)65 __zfs_dbgmsg_nvlist(nvlist_t *nv)
66 {
67 int len;
68 char *buf;
69
70 len = nvlist_snprintf(NULL, 0, nv, 4);
71 len++; /* Add null terminator */
72
73 buf = vmem_alloc(len, KM_SLEEP);
74 if (buf == NULL)
75 return;
76
77 (void) nvlist_snprintf(buf, len, nv, 4);
78
79 while (buf != NULL)
80 buf = zfs_dbgmsg_one_line(buf);
81
82 vmem_free(buf, len);
83 }
84
85 #ifdef _KERNEL
86 EXPORT_SYMBOL(__zfs_dbgmsg_nvlist);
87 #endif
88