]>
git.proxmox.com Git - mirror_spl-debian.git/blob - cmd/spl.c
1 /*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://github.com/behlendorf/spl/>.
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * You should have received a copy of the GNU General Public License along
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 *****************************************************************************
24 * Solaris Porting Layer (SPL) User Space Interface.
25 \*****************************************************************************/
33 #include <sys/types.h>
35 #include "../include/spl-ctl.h"
37 static int spl_debug_mask
= ~0;
38 static int spl_debug_subsystem
= ~0;
40 /* all strings nul-terminated; only the struct and hdr need to be freed */
42 struct spl_debug_header
*hdr
;
49 cmp_rec(const void *p1
, const void *p2
)
51 struct dbg_line
*d1
= *(struct dbg_line
**)p1
;
52 struct dbg_line
*d2
= *(struct dbg_line
**)p2
;
54 if (d1
->hdr
->ph_sec
< d2
->hdr
->ph_sec
)
57 if (d1
->hdr
->ph_sec
== d2
->hdr
->ph_sec
&&
58 d1
->hdr
->ph_usec
< d2
->hdr
->ph_usec
)
61 if (d1
->hdr
->ph_sec
== d2
->hdr
->ph_sec
&&
62 d1
->hdr
->ph_usec
== d2
->hdr
->ph_usec
)
69 print_rec(struct dbg_line
**linev
, int used
, FILE *out
)
73 for (i
= 0; i
< used
; i
++) {
74 struct dbg_line
*line
= linev
[i
];
75 struct spl_debug_header
*hdr
= line
->hdr
;
77 fprintf(out
, "%08x:%08x:%u:%u.%06llu:%u:%u:%u:(%s:%u:%s()) %s",
78 hdr
->ph_subsys
, hdr
->ph_mask
, hdr
->ph_cpu_id
,
79 hdr
->ph_sec
, (unsigned long long)hdr
->ph_usec
,
80 hdr
->ph_stack
, hdr
->ph_pid
, hdr
->ph_stack
, line
->file
,
81 hdr
->ph_line_num
, line
->fn
, line
->text
);
90 add_rec(struct dbg_line
*line
, struct dbg_line
***linevp
, int *lenp
, int used
)
92 struct dbg_line
**linev
= *linevp
;
95 int nlen
= *lenp
+ 512;
96 int nsize
= nlen
* sizeof(struct dbg_line
*);
98 linev
= *linevp
? realloc(*linevp
, nsize
) : malloc(nsize
);
109 parse_buffer(FILE *in
, FILE *out
)
111 struct dbg_line
*line
;
112 struct spl_debug_header
*hdr
;
114 unsigned long dropped
= 0, kept
= 0;
115 struct dbg_line
**linev
= NULL
;
116 const int phl
= sizeof(hdr
->ph_len
);
117 const int phf
= sizeof(hdr
->ph_flags
);
118 int rc
, linev_len
= 0;
121 rc
= fread(buf
, phl
+ phf
, 1, in
);
126 if (hdr
->ph_len
== 0)
128 if (hdr
->ph_len
> 4094) {
129 fprintf(stderr
, "unexpected large record: %d bytes. "
130 "aborting.\n", hdr
->ph_len
);
134 rc
= fread(buf
+ phl
+ phf
, 1, hdr
->ph_len
- phl
- phf
, in
);
139 (!(spl_debug_subsystem
& hdr
->ph_subsys
) ||
140 (!(spl_debug_mask
& hdr
->ph_mask
)))) {
145 line
= malloc(sizeof(*line
));
147 fprintf(stderr
, "malloc failed; printing accumulated "
148 "records and exiting.\n");
152 line
->hdr
= malloc(hdr
->ph_len
+ 1);
153 if (line
->hdr
== NULL
) {
155 fprintf(stderr
, "malloc failed; printing accumulated "
156 "records and exiting.\n");
160 p
= (void *)line
->hdr
;
161 memcpy(line
->hdr
, buf
, hdr
->ph_len
);
162 p
[hdr
->ph_len
] = '\0';
166 p
+= strlen(line
->file
) + 1;
168 p
+= strlen(line
->fn
) + 1;
171 if (!add_rec(line
, &linev
, &linev_len
, kept
)) {
172 fprintf(stderr
, "malloc failed; printing accumulated "
173 "records and exiting.\n");
180 qsort(linev
, kept
, sizeof(struct dbg_line
*), cmp_rec
);
181 print_rec(linev
, kept
, out
);
184 printf("Debug log: %lu lines, %lu kept, %lu dropped.\n",
185 dropped
+ kept
, kept
, dropped
);
190 main(int argc
, char *argv
[])
193 FILE *in
, *out
= stdout
;
196 if (argc
> 3 || argc
< 2) {
197 fprintf(stderr
, "usage: %s <input> [output]\n", argv
[0]);
201 #ifdef __USE_LARGEFILE64
205 fdin
= open(argv
[1], O_RDONLY
| o_lf
);
207 fprintf(stderr
, "open(%s) failed: %s\n", argv
[1],
211 in
= fdopen(fdin
, "r");
213 fprintf(stderr
, "fopen(%s) failed: %s\n", argv
[1],
219 fdout
= open(argv
[2], O_CREAT
| O_TRUNC
| O_WRONLY
| o_lf
, 0600);
221 fprintf(stderr
, "open(%s) failed: %s\n", argv
[2],
226 out
= fdopen(fdout
, "w");
228 fprintf(stderr
, "fopen(%s) failed: %s\n", argv
[2],
236 rc
= parse_buffer(in
, out
);