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