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