xref: /titanic_53/usr/src/cmd/zdb/zdb_il.c (revision fa9e4066f08beec538e775443c5be79dd423fcab)
1*fa9e4066Sahrens /*
2*fa9e4066Sahrens  * CDDL HEADER START
3*fa9e4066Sahrens  *
4*fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5*fa9e4066Sahrens  * Common Development and Distribution License, Version 1.0 only
6*fa9e4066Sahrens  * (the "License").  You may not use this file except in compliance
7*fa9e4066Sahrens  * with the License.
8*fa9e4066Sahrens  *
9*fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
11*fa9e4066Sahrens  * See the License for the specific language governing permissions
12*fa9e4066Sahrens  * and limitations under the License.
13*fa9e4066Sahrens  *
14*fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15*fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17*fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18*fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19*fa9e4066Sahrens  *
20*fa9e4066Sahrens  * CDDL HEADER END
21*fa9e4066Sahrens  */
22*fa9e4066Sahrens /*
23*fa9e4066Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*fa9e4066Sahrens  * Use is subject to license terms.
25*fa9e4066Sahrens  */
26*fa9e4066Sahrens 
27*fa9e4066Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*fa9e4066Sahrens 
29*fa9e4066Sahrens /*
30*fa9e4066Sahrens  * Print intent log header and statistics.
31*fa9e4066Sahrens  */
32*fa9e4066Sahrens 
33*fa9e4066Sahrens #include <stdio.h>
34*fa9e4066Sahrens #include <stdlib.h>
35*fa9e4066Sahrens #include <ctype.h>
36*fa9e4066Sahrens #include <sys/zfs_context.h>
37*fa9e4066Sahrens #include <sys/spa.h>
38*fa9e4066Sahrens #include <sys/dmu.h>
39*fa9e4066Sahrens #include <sys/stat.h>
40*fa9e4066Sahrens #include <sys/resource.h>
41*fa9e4066Sahrens #include <sys/zil.h>
42*fa9e4066Sahrens #include <sys/zil_impl.h>
43*fa9e4066Sahrens 
44*fa9e4066Sahrens extern uint8_t dump_opt[256];
45*fa9e4066Sahrens 
46*fa9e4066Sahrens static void
47*fa9e4066Sahrens print_log_bp(blkptr_t *bp, const char *prefix)
48*fa9e4066Sahrens {
49*fa9e4066Sahrens 	char blkbuf[200];
50*fa9e4066Sahrens 
51*fa9e4066Sahrens 	sprintf_blkptr(blkbuf, bp);
52*fa9e4066Sahrens 	(void) printf("%s%s\n", prefix, blkbuf);
53*fa9e4066Sahrens }
54*fa9e4066Sahrens 
55*fa9e4066Sahrens /* ARGSUSED */
56*fa9e4066Sahrens static void
57*fa9e4066Sahrens zil_prt_rec_create(zilog_t *zilog, int txtype, lr_create_t *lr)
58*fa9e4066Sahrens {
59*fa9e4066Sahrens 	time_t crtime = lr->lr_crtime[0];
60*fa9e4066Sahrens 	char *name = (char *)(lr + 1);
61*fa9e4066Sahrens 	char *link = name + strlen(name) + 1;
62*fa9e4066Sahrens 
63*fa9e4066Sahrens 	if (txtype == TX_SYMLINK)
64*fa9e4066Sahrens 		(void) printf("\t\t\t%s -> %s\n", name, link);
65*fa9e4066Sahrens 	else
66*fa9e4066Sahrens 		(void) printf("\t\t\t%s\n", name);
67*fa9e4066Sahrens 
68*fa9e4066Sahrens 	(void) printf("\t\t\t%s", ctime(&crtime));
69*fa9e4066Sahrens 	(void) printf("\t\t\tdoid %llu, foid %llu, mode %llo\n",
70*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_foid,
71*fa9e4066Sahrens 	    (longlong_t)lr->lr_mode);
72*fa9e4066Sahrens 	(void) printf("\t\t\tuid %llu, gid %llu, gen %llu, rdev 0x%llx\n",
73*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_uid, (u_longlong_t)lr->lr_gid,
74*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_gen, (u_longlong_t)lr->lr_rdev);
75*fa9e4066Sahrens }
76*fa9e4066Sahrens 
77*fa9e4066Sahrens /* ARGSUSED */
78*fa9e4066Sahrens static void
79*fa9e4066Sahrens zil_prt_rec_remove(zilog_t *zilog, int txtype, lr_remove_t *lr)
80*fa9e4066Sahrens {
81*fa9e4066Sahrens 	(void) printf("\t\t\tdoid %llu, name %s\n",
82*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_doid, (char *)(lr + 1));
83*fa9e4066Sahrens }
84*fa9e4066Sahrens 
85*fa9e4066Sahrens /* ARGSUSED */
86*fa9e4066Sahrens static void
87*fa9e4066Sahrens zil_prt_rec_link(zilog_t *zilog, int txtype, lr_link_t *lr)
88*fa9e4066Sahrens {
89*fa9e4066Sahrens 	(void) printf("\t\t\tdoid %llu, link_obj %llu, name %s\n",
90*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_doid, (u_longlong_t)lr->lr_link_obj,
91*fa9e4066Sahrens 	    (char *)(lr + 1));
92*fa9e4066Sahrens }
93*fa9e4066Sahrens 
94*fa9e4066Sahrens /* ARGSUSED */
95*fa9e4066Sahrens static void
96*fa9e4066Sahrens zil_prt_rec_rename(zilog_t *zilog, int txtype, lr_rename_t *lr)
97*fa9e4066Sahrens {
98*fa9e4066Sahrens 	char *snm = (char *)(lr + 1);
99*fa9e4066Sahrens 	char *tnm = snm + strlen(snm) + 1;
100*fa9e4066Sahrens 
101*fa9e4066Sahrens 	(void) printf("\t\t\tsdoid %llu, tdoid %llu\n",
102*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_sdoid, (u_longlong_t)lr->lr_tdoid);
103*fa9e4066Sahrens 	(void) printf("\t\t\tsrc %s tgt %s\n", snm, tnm);
104*fa9e4066Sahrens }
105*fa9e4066Sahrens 
106*fa9e4066Sahrens /* ARGSUSED */
107*fa9e4066Sahrens static void
108*fa9e4066Sahrens zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
109*fa9e4066Sahrens {
110*fa9e4066Sahrens 	char *data, *dlimit;
111*fa9e4066Sahrens 	blkptr_t *bp = &lr->lr_blkptr;
112*fa9e4066Sahrens 	char buf[SPA_MAXBLOCKSIZE];
113*fa9e4066Sahrens 	int verbose = MAX(dump_opt['d'], dump_opt['i']);
114*fa9e4066Sahrens 	int error;
115*fa9e4066Sahrens 
116*fa9e4066Sahrens 	(void) printf("\t\t\tfoid %llu, offset 0x%llx,"
117*fa9e4066Sahrens 	    " length 0x%llx, blkoff 0x%llx\n",
118*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_foid, (longlong_t)lr->lr_offset,
119*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_length, (u_longlong_t)lr->lr_blkoff);
120*fa9e4066Sahrens 
121*fa9e4066Sahrens 	if (verbose < 5)
122*fa9e4066Sahrens 		return;
123*fa9e4066Sahrens 
124*fa9e4066Sahrens 	if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
125*fa9e4066Sahrens 		(void) printf("\t\t\thas blkptr, %s\n",
126*fa9e4066Sahrens 		    bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
127*fa9e4066Sahrens 		    "will claim" : "won't claim");
128*fa9e4066Sahrens 		print_log_bp(bp, "\t\t\t");
129*fa9e4066Sahrens 		if (bp->blk_birth == 0) {
130*fa9e4066Sahrens 			bzero(buf, sizeof (buf));
131*fa9e4066Sahrens 		} else {
132*fa9e4066Sahrens 			error = zio_wait(zio_read(NULL, zilog->zl_spa,
133*fa9e4066Sahrens 			    bp, buf, BP_GET_LSIZE(bp), NULL, NULL,
134*fa9e4066Sahrens 			    ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL));
135*fa9e4066Sahrens 			if (error)
136*fa9e4066Sahrens 				return;
137*fa9e4066Sahrens 		}
138*fa9e4066Sahrens 		data = buf + lr->lr_blkoff;
139*fa9e4066Sahrens 	} else {
140*fa9e4066Sahrens 		data = (char *)(lr + 1);
141*fa9e4066Sahrens 	}
142*fa9e4066Sahrens 
143*fa9e4066Sahrens 	dlimit = data + MIN(lr->lr_length,
144*fa9e4066Sahrens 	    (verbose < 6 ? 20 : SPA_MAXBLOCKSIZE));
145*fa9e4066Sahrens 
146*fa9e4066Sahrens 	(void) printf("\t\t\t");
147*fa9e4066Sahrens 	while (data < dlimit) {
148*fa9e4066Sahrens 		if (isprint(*data))
149*fa9e4066Sahrens 			(void) printf("%c ", *data);
150*fa9e4066Sahrens 		else
151*fa9e4066Sahrens 			(void) printf("%2X", *data);
152*fa9e4066Sahrens 		data++;
153*fa9e4066Sahrens 	}
154*fa9e4066Sahrens 	(void) printf("\n");
155*fa9e4066Sahrens }
156*fa9e4066Sahrens 
157*fa9e4066Sahrens /* ARGSUSED */
158*fa9e4066Sahrens static void
159*fa9e4066Sahrens zil_prt_rec_truncate(zilog_t *zilog, int txtype, lr_truncate_t *lr)
160*fa9e4066Sahrens {
161*fa9e4066Sahrens 	(void) printf("\t\t\tfoid %llu, offset 0x%llx, length 0x%llx\n",
162*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_foid, (longlong_t)lr->lr_offset,
163*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_length);
164*fa9e4066Sahrens }
165*fa9e4066Sahrens 
166*fa9e4066Sahrens /* ARGSUSED */
167*fa9e4066Sahrens static void
168*fa9e4066Sahrens zil_prt_rec_setattr(zilog_t *zilog, int txtype, lr_setattr_t *lr)
169*fa9e4066Sahrens {
170*fa9e4066Sahrens 	time_t atime = (time_t)lr->lr_atime[0];
171*fa9e4066Sahrens 	time_t mtime = (time_t)lr->lr_mtime[0];
172*fa9e4066Sahrens 
173*fa9e4066Sahrens 	(void) printf("\t\t\tfoid %llu, mask 0x%llx\n",
174*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_mask);
175*fa9e4066Sahrens 
176*fa9e4066Sahrens 	if (lr->lr_mask & AT_MODE) {
177*fa9e4066Sahrens 		(void) printf("\t\t\tAT_MODE  %llo\n",
178*fa9e4066Sahrens 		    (longlong_t)lr->lr_mode);
179*fa9e4066Sahrens 	}
180*fa9e4066Sahrens 
181*fa9e4066Sahrens 	if (lr->lr_mask & AT_UID) {
182*fa9e4066Sahrens 		(void) printf("\t\t\tAT_UID   %llu\n",
183*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_uid);
184*fa9e4066Sahrens 	}
185*fa9e4066Sahrens 
186*fa9e4066Sahrens 	if (lr->lr_mask & AT_GID) {
187*fa9e4066Sahrens 		(void) printf("\t\t\tAT_GID   %llu\n",
188*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_gid);
189*fa9e4066Sahrens 	}
190*fa9e4066Sahrens 
191*fa9e4066Sahrens 	if (lr->lr_mask & AT_SIZE) {
192*fa9e4066Sahrens 		(void) printf("\t\t\tAT_SIZE  %llu\n",
193*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_size);
194*fa9e4066Sahrens 	}
195*fa9e4066Sahrens 
196*fa9e4066Sahrens 	if (lr->lr_mask & AT_ATIME) {
197*fa9e4066Sahrens 		(void) printf("\t\t\tAT_ATIME %llu.%09llu %s",
198*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_atime[0],
199*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_atime[1],
200*fa9e4066Sahrens 		    ctime(&atime));
201*fa9e4066Sahrens 	}
202*fa9e4066Sahrens 
203*fa9e4066Sahrens 	if (lr->lr_mask & AT_MTIME) {
204*fa9e4066Sahrens 		(void) printf("\t\t\tAT_MTIME %llu.%09llu %s",
205*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_mtime[0],
206*fa9e4066Sahrens 		    (u_longlong_t)lr->lr_mtime[1],
207*fa9e4066Sahrens 		    ctime(&mtime));
208*fa9e4066Sahrens 	}
209*fa9e4066Sahrens }
210*fa9e4066Sahrens 
211*fa9e4066Sahrens /* ARGSUSED */
212*fa9e4066Sahrens static void
213*fa9e4066Sahrens zil_prt_rec_acl(zilog_t *zilog, int txtype, lr_acl_t *lr)
214*fa9e4066Sahrens {
215*fa9e4066Sahrens 	(void) printf("\t\t\tfoid %llu, aclcnt %llu\n",
216*fa9e4066Sahrens 	    (u_longlong_t)lr->lr_foid, (u_longlong_t)lr->lr_aclcnt);
217*fa9e4066Sahrens }
218*fa9e4066Sahrens 
219*fa9e4066Sahrens typedef void (*zil_prt_rec_func_t)();
220*fa9e4066Sahrens typedef struct zil_rec_info {
221*fa9e4066Sahrens 	zil_prt_rec_func_t	zri_print;
222*fa9e4066Sahrens 	char			*zri_name;
223*fa9e4066Sahrens 	uint64_t		zri_count;
224*fa9e4066Sahrens } zil_rec_info_t;
225*fa9e4066Sahrens 
226*fa9e4066Sahrens static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
227*fa9e4066Sahrens 	{	NULL,			"Total      "	},
228*fa9e4066Sahrens 	{	zil_prt_rec_create,	"TX_CREATE  "	},
229*fa9e4066Sahrens 	{	zil_prt_rec_create,	"TX_MKDIR   "	},
230*fa9e4066Sahrens 	{	zil_prt_rec_create,	"TX_MKXATTR "	},
231*fa9e4066Sahrens 	{	zil_prt_rec_create,	"TX_SYMLINK "	},
232*fa9e4066Sahrens 	{	zil_prt_rec_remove,	"TX_REMOVE  "	},
233*fa9e4066Sahrens 	{	zil_prt_rec_remove,	"TX_RMDIR   "	},
234*fa9e4066Sahrens 	{	zil_prt_rec_link,	"TX_LINK    "	},
235*fa9e4066Sahrens 	{	zil_prt_rec_rename,	"TX_RENAME  "	},
236*fa9e4066Sahrens 	{	zil_prt_rec_write,	"TX_WRITE   "	},
237*fa9e4066Sahrens 	{	zil_prt_rec_truncate,	"TX_TRUNCATE"	},
238*fa9e4066Sahrens 	{	zil_prt_rec_setattr,	"TX_SETATTR "	},
239*fa9e4066Sahrens 	{	zil_prt_rec_acl,	"TX_ACL     "	},
240*fa9e4066Sahrens };
241*fa9e4066Sahrens 
242*fa9e4066Sahrens /* ARGSUSED */
243*fa9e4066Sahrens static void
244*fa9e4066Sahrens print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t first_txg)
245*fa9e4066Sahrens {
246*fa9e4066Sahrens 	int txtype;
247*fa9e4066Sahrens 	int verbose = MAX(dump_opt['d'], dump_opt['i']);
248*fa9e4066Sahrens 
249*fa9e4066Sahrens 	txtype = lr->lrc_txtype;
250*fa9e4066Sahrens 
251*fa9e4066Sahrens 	ASSERT(txtype != 0 && (uint_t)txtype < TX_MAX_TYPE);
252*fa9e4066Sahrens 	ASSERT(lr->lrc_txg);
253*fa9e4066Sahrens 
254*fa9e4066Sahrens 	(void) printf("\t\t%s len %6llu, txg %llu, seq %llu\n",
255*fa9e4066Sahrens 	    zil_rec_info[txtype].zri_name,
256*fa9e4066Sahrens 	    (u_longlong_t)lr->lrc_reclen,
257*fa9e4066Sahrens 	    (u_longlong_t)lr->lrc_txg,
258*fa9e4066Sahrens 	    (u_longlong_t)lr->lrc_seq);
259*fa9e4066Sahrens 
260*fa9e4066Sahrens 	if (txtype && verbose >= 3)
261*fa9e4066Sahrens 		zil_rec_info[txtype].zri_print(zilog, txtype, lr);
262*fa9e4066Sahrens 
263*fa9e4066Sahrens 	zil_rec_info[txtype].zri_count++;
264*fa9e4066Sahrens 	zil_rec_info[0].zri_count++;
265*fa9e4066Sahrens }
266*fa9e4066Sahrens 
267*fa9e4066Sahrens /* ARGSUSED */
268*fa9e4066Sahrens static void
269*fa9e4066Sahrens print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t first_txg)
270*fa9e4066Sahrens {
271*fa9e4066Sahrens 	char blkbuf[200];
272*fa9e4066Sahrens 	int verbose = MAX(dump_opt['d'], dump_opt['i']);
273*fa9e4066Sahrens 
274*fa9e4066Sahrens 	if (verbose <= 3)
275*fa9e4066Sahrens 		return;
276*fa9e4066Sahrens 
277*fa9e4066Sahrens 	if (verbose >= 5) {
278*fa9e4066Sahrens 		(void) strcpy(blkbuf, ", ");
279*fa9e4066Sahrens 		sprintf_blkptr(blkbuf + strlen(blkbuf), bp);
280*fa9e4066Sahrens 	} else {
281*fa9e4066Sahrens 		blkbuf[0] = '\0';
282*fa9e4066Sahrens 	}
283*fa9e4066Sahrens 
284*fa9e4066Sahrens 	(void) printf("\tBlock seqno %llu, %s%s\n",
285*fa9e4066Sahrens 	    (u_longlong_t)bp->blk_cksum.zc_word[3],
286*fa9e4066Sahrens 	    bp->blk_birth >= first_txg ? "will claim" : "won't claim", blkbuf);
287*fa9e4066Sahrens }
288*fa9e4066Sahrens 
289*fa9e4066Sahrens static void
290*fa9e4066Sahrens print_log_stats(int verbose)
291*fa9e4066Sahrens {
292*fa9e4066Sahrens 	int i, w, p10;
293*fa9e4066Sahrens 
294*fa9e4066Sahrens 	if (verbose > 3)
295*fa9e4066Sahrens 		(void) printf("\n");
296*fa9e4066Sahrens 
297*fa9e4066Sahrens 	if (zil_rec_info[0].zri_count == 0)
298*fa9e4066Sahrens 		return;
299*fa9e4066Sahrens 
300*fa9e4066Sahrens 	for (w = 1, p10 = 10; zil_rec_info[0].zri_count >= p10; p10 *= 10)
301*fa9e4066Sahrens 		w++;
302*fa9e4066Sahrens 
303*fa9e4066Sahrens 	for (i = 0; i < TX_MAX_TYPE; i++)
304*fa9e4066Sahrens 		if (zil_rec_info[i].zri_count || verbose >= 3)
305*fa9e4066Sahrens 			(void) printf("\t\t%s %*llu\n",
306*fa9e4066Sahrens 			    zil_rec_info[i].zri_name, w,
307*fa9e4066Sahrens 			    (u_longlong_t)zil_rec_info[i].zri_count);
308*fa9e4066Sahrens 	(void) printf("\n");
309*fa9e4066Sahrens }
310*fa9e4066Sahrens 
311*fa9e4066Sahrens /* ARGSUSED */
312*fa9e4066Sahrens void
313*fa9e4066Sahrens dump_intent_log(zilog_t *zilog)
314*fa9e4066Sahrens {
315*fa9e4066Sahrens 	zil_header_t *zh = zilog->zl_header;
316*fa9e4066Sahrens 	int verbose = MAX(dump_opt['d'], dump_opt['i']);
317*fa9e4066Sahrens 	int i;
318*fa9e4066Sahrens 
319*fa9e4066Sahrens 	if (zh->zh_log.blk_birth == 0 || verbose < 2)
320*fa9e4066Sahrens 		return;
321*fa9e4066Sahrens 
322*fa9e4066Sahrens 	(void) printf("\n    ZIL header: claim_txg %llu, seq %llu\n",
323*fa9e4066Sahrens 	    (u_longlong_t)zh->zh_claim_txg, (u_longlong_t)zh->zh_replay_seq);
324*fa9e4066Sahrens 
325*fa9e4066Sahrens 	if (verbose >= 4)
326*fa9e4066Sahrens 		print_log_bp(&zh->zh_log, "\n\tfirst block: ");
327*fa9e4066Sahrens 
328*fa9e4066Sahrens 	for (i = 0; i < TX_MAX_TYPE; i++)
329*fa9e4066Sahrens 		zil_rec_info[i].zri_count = 0;
330*fa9e4066Sahrens 
331*fa9e4066Sahrens 	if (verbose >= 2) {
332*fa9e4066Sahrens 		(void) printf("\n");
333*fa9e4066Sahrens 		zil_parse(zilog, print_log_block, print_log_record, NULL,
334*fa9e4066Sahrens 		    spa_first_txg(zilog->zl_spa));
335*fa9e4066Sahrens 		print_log_stats(verbose);
336*fa9e4066Sahrens 	}
337*fa9e4066Sahrens }
338