1495db6fbSLori Alt /* 2495db6fbSLori Alt * CDDL HEADER START 3495db6fbSLori Alt * 4495db6fbSLori Alt * The contents of this file are subject to the terms of the 5495db6fbSLori Alt * Common Development and Distribution License (the "License"). 6495db6fbSLori Alt * You may not use this file except in compliance with the License. 7495db6fbSLori Alt * 8495db6fbSLori Alt * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9495db6fbSLori Alt * or http://www.opensolaris.org/os/licensing. 10495db6fbSLori Alt * See the License for the specific language governing permissions 11495db6fbSLori Alt * and limitations under the License. 12495db6fbSLori Alt * 13495db6fbSLori Alt * When distributing Covered Code, include this CDDL HEADER in each 14495db6fbSLori Alt * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15495db6fbSLori Alt * If applicable, add the following below this CDDL HEADER, with the 16495db6fbSLori Alt * fields enclosed by brackets "[]" replaced with your own identifying 17495db6fbSLori Alt * information: Portions Copyright [yyyy] [name of copyright owner] 18495db6fbSLori Alt * 19495db6fbSLori Alt * CDDL HEADER END 20495db6fbSLori Alt */ 21495db6fbSLori Alt 22495db6fbSLori Alt /* 23*0a586ceaSMark Shellenbaum * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24495db6fbSLori Alt * Use is subject to license terms. 25495db6fbSLori Alt */ 26495db6fbSLori Alt 27495db6fbSLori Alt #include <libnvpair.h> 28495db6fbSLori Alt #include <stdio.h> 29495db6fbSLori Alt #include <stdlib.h> 30495db6fbSLori Alt #include <strings.h> 31495db6fbSLori Alt #include <unistd.h> 32495db6fbSLori Alt 33495db6fbSLori Alt #include <sys/dmu.h> 34495db6fbSLori Alt #include <sys/zfs_ioctl.h> 35495db6fbSLori Alt #include <zfs_fletcher.h> 36495db6fbSLori Alt 37495db6fbSLori Alt uint64_t drr_record_count[DRR_NUMTYPES]; 38495db6fbSLori Alt uint64_t total_write_size = 0; 39495db6fbSLori Alt uint64_t total_stream_len = 0; 40495db6fbSLori Alt FILE *send_stream = 0; 41495db6fbSLori Alt boolean_t do_byteswap = B_FALSE; 42495db6fbSLori Alt boolean_t do_cksum = B_TRUE; 43495db6fbSLori Alt #define INITIAL_BUFLEN (1<<20) 44495db6fbSLori Alt 45495db6fbSLori Alt static void 46495db6fbSLori Alt usage(void) 47495db6fbSLori Alt { 48495db6fbSLori Alt (void) fprintf(stderr, "usage: zstreamdump [-v] [-C] < file\n"); 49495db6fbSLori Alt (void) fprintf(stderr, "\t -v -- verbose\n"); 50495db6fbSLori Alt (void) fprintf(stderr, "\t -C -- suppress checksum verification\n"); 51495db6fbSLori Alt exit(1); 52495db6fbSLori Alt } 53495db6fbSLori Alt 54495db6fbSLori Alt /* 55495db6fbSLori Alt * ssread - send stream read. 56495db6fbSLori Alt * 57495db6fbSLori Alt * Read while computing incremental checksum 58495db6fbSLori Alt */ 59495db6fbSLori Alt 60495db6fbSLori Alt static size_t 61495db6fbSLori Alt ssread(void *buf, size_t len, zio_cksum_t *cksum) 62495db6fbSLori Alt { 63495db6fbSLori Alt size_t outlen; 64495db6fbSLori Alt 65495db6fbSLori Alt if ((outlen = fread(buf, len, 1, send_stream)) == 0) 66495db6fbSLori Alt return (0); 67495db6fbSLori Alt 68495db6fbSLori Alt if (do_cksum && cksum) { 69495db6fbSLori Alt if (do_byteswap) 70495db6fbSLori Alt fletcher_4_incremental_byteswap(buf, len, cksum); 71495db6fbSLori Alt else 72495db6fbSLori Alt fletcher_4_incremental_native(buf, len, cksum); 73495db6fbSLori Alt } 74495db6fbSLori Alt total_stream_len += len; 75495db6fbSLori Alt return (outlen); 76495db6fbSLori Alt } 77495db6fbSLori Alt 78495db6fbSLori Alt int 79495db6fbSLori Alt main(int argc, char *argv[]) 80495db6fbSLori Alt { 81495db6fbSLori Alt char *buf = malloc(INITIAL_BUFLEN); 82495db6fbSLori Alt dmu_replay_record_t thedrr; 83495db6fbSLori Alt dmu_replay_record_t *drr = &thedrr; 84495db6fbSLori Alt struct drr_begin *drrb = &thedrr.drr_u.drr_begin; 85495db6fbSLori Alt struct drr_end *drre = &thedrr.drr_u.drr_end; 86495db6fbSLori Alt struct drr_object *drro = &thedrr.drr_u.drr_object; 87495db6fbSLori Alt struct drr_freeobjects *drrfo = &thedrr.drr_u.drr_freeobjects; 88495db6fbSLori Alt struct drr_write *drrw = &thedrr.drr_u.drr_write; 899e69d7d0SLori Alt struct drr_write_byref *drrwbr = &thedrr.drr_u.drr_write_byref; 90495db6fbSLori Alt struct drr_free *drrf = &thedrr.drr_u.drr_free; 91*0a586ceaSMark Shellenbaum struct drr_spill *drrs = &thedrr.drr_u.drr_spill; 92495db6fbSLori Alt char c; 93495db6fbSLori Alt boolean_t verbose = B_FALSE; 94495db6fbSLori Alt boolean_t first = B_TRUE; 958e714474SLori Alt int err; 96495db6fbSLori Alt zio_cksum_t zc = { 0 }; 97495db6fbSLori Alt zio_cksum_t pcksum = { 0 }; 98495db6fbSLori Alt 99495db6fbSLori Alt while ((c = getopt(argc, argv, ":vC")) != -1) { 100495db6fbSLori Alt switch (c) { 101495db6fbSLori Alt case 'C': 102495db6fbSLori Alt do_cksum = B_FALSE; 103495db6fbSLori Alt break; 104495db6fbSLori Alt case 'v': 105495db6fbSLori Alt verbose = B_TRUE; 106495db6fbSLori Alt break; 107495db6fbSLori Alt case ':': 108495db6fbSLori Alt (void) fprintf(stderr, 109495db6fbSLori Alt "missing argument for '%c' option\n", optopt); 110495db6fbSLori Alt usage(); 111495db6fbSLori Alt break; 112495db6fbSLori Alt case '?': 113495db6fbSLori Alt (void) fprintf(stderr, "invalid option '%c'\n", 114495db6fbSLori Alt optopt); 115495db6fbSLori Alt usage(); 116495db6fbSLori Alt } 117495db6fbSLori Alt } 118495db6fbSLori Alt 119495db6fbSLori Alt if (isatty(STDIN_FILENO)) { 120495db6fbSLori Alt (void) fprintf(stderr, 121495db6fbSLori Alt "Error: Backup stream can not be read " 122495db6fbSLori Alt "from a terminal.\n" 123495db6fbSLori Alt "You must redirect standard input.\n"); 124495db6fbSLori Alt exit(1); 125495db6fbSLori Alt } 126495db6fbSLori Alt 127495db6fbSLori Alt send_stream = stdin; 128495db6fbSLori Alt pcksum = zc; 129495db6fbSLori Alt while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) { 130495db6fbSLori Alt 131495db6fbSLori Alt if (first) { 132495db6fbSLori Alt if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) { 133495db6fbSLori Alt do_byteswap = B_TRUE; 134495db6fbSLori Alt if (do_cksum) { 135495db6fbSLori Alt ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0); 136495db6fbSLori Alt /* 137495db6fbSLori Alt * recalculate header checksum now 138495db6fbSLori Alt * that we know it needs to be 139495db6fbSLori Alt * byteswapped. 140495db6fbSLori Alt */ 141495db6fbSLori Alt fletcher_4_incremental_byteswap(drr, 142495db6fbSLori Alt sizeof (dmu_replay_record_t), &zc); 143495db6fbSLori Alt } 144495db6fbSLori Alt } else if (drrb->drr_magic != DMU_BACKUP_MAGIC) { 145495db6fbSLori Alt (void) fprintf(stderr, "Invalid stream " 146495db6fbSLori Alt "(bad magic number)\n"); 147495db6fbSLori Alt exit(1); 148495db6fbSLori Alt } 149495db6fbSLori Alt first = B_FALSE; 150495db6fbSLori Alt } 151495db6fbSLori Alt if (do_byteswap) { 152495db6fbSLori Alt drr->drr_type = BSWAP_32(drr->drr_type); 153495db6fbSLori Alt drr->drr_payloadlen = 154495db6fbSLori Alt BSWAP_32(drr->drr_payloadlen); 155495db6fbSLori Alt } 156495db6fbSLori Alt 157495db6fbSLori Alt /* 158495db6fbSLori Alt * At this point, the leading fields of the replay record 159495db6fbSLori Alt * (drr_type and drr_payloadlen) have been byte-swapped if 160495db6fbSLori Alt * necessary, but the rest of the data structure (the 161495db6fbSLori Alt * union of type-specific structures) is still in its 162495db6fbSLori Alt * original state. 163495db6fbSLori Alt */ 164495db6fbSLori Alt if (drr->drr_type >= DRR_NUMTYPES) { 165495db6fbSLori Alt (void) printf("INVALID record found: type 0x%x\n", 166495db6fbSLori Alt drr->drr_type); 167495db6fbSLori Alt (void) printf("Aborting.\n"); 168495db6fbSLori Alt exit(1); 169495db6fbSLori Alt } 170495db6fbSLori Alt 171495db6fbSLori Alt drr_record_count[drr->drr_type]++; 172495db6fbSLori Alt 173495db6fbSLori Alt switch (drr->drr_type) { 174495db6fbSLori Alt case DRR_BEGIN: 175495db6fbSLori Alt if (do_byteswap) { 176495db6fbSLori Alt drrb->drr_magic = BSWAP_64(drrb->drr_magic); 1779e69d7d0SLori Alt drrb->drr_versioninfo = 1789e69d7d0SLori Alt BSWAP_64(drrb->drr_versioninfo); 179495db6fbSLori Alt drrb->drr_creation_time = 180495db6fbSLori Alt BSWAP_64(drrb->drr_creation_time); 181495db6fbSLori Alt drrb->drr_type = BSWAP_32(drrb->drr_type); 182495db6fbSLori Alt drrb->drr_flags = BSWAP_32(drrb->drr_flags); 183495db6fbSLori Alt drrb->drr_toguid = BSWAP_64(drrb->drr_toguid); 184495db6fbSLori Alt drrb->drr_fromguid = 185495db6fbSLori Alt BSWAP_64(drrb->drr_fromguid); 186495db6fbSLori Alt } 187495db6fbSLori Alt 188495db6fbSLori Alt (void) printf("BEGIN record\n"); 1899e69d7d0SLori Alt (void) printf("\thdrtype = %lld\n", 1909e69d7d0SLori Alt DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo)); 1919e69d7d0SLori Alt (void) printf("\tfeatures = %llx\n", 1929e69d7d0SLori Alt DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo)); 193495db6fbSLori Alt (void) printf("\tmagic = %llx\n", 194495db6fbSLori Alt (u_longlong_t)drrb->drr_magic); 195495db6fbSLori Alt (void) printf("\tcreation_time = %llx\n", 196495db6fbSLori Alt (u_longlong_t)drrb->drr_creation_time); 197495db6fbSLori Alt (void) printf("\ttype = %u\n", drrb->drr_type); 198495db6fbSLori Alt (void) printf("\tflags = 0x%x\n", drrb->drr_flags); 199495db6fbSLori Alt (void) printf("\ttoguid = %llx\n", 200495db6fbSLori Alt (u_longlong_t)drrb->drr_toguid); 201495db6fbSLori Alt (void) printf("\tfromguid = %llx\n", 202495db6fbSLori Alt (u_longlong_t)drrb->drr_fromguid); 203495db6fbSLori Alt (void) printf("\ttoname = %s\n", drrb->drr_toname); 204495db6fbSLori Alt if (verbose) 205495db6fbSLori Alt (void) printf("\n"); 206495db6fbSLori Alt 2079e69d7d0SLori Alt if ((DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == 2089e69d7d0SLori Alt DMU_COMPOUNDSTREAM) && drr->drr_payloadlen != 0) { 209495db6fbSLori Alt nvlist_t *nv; 210495db6fbSLori Alt int sz = drr->drr_payloadlen; 211495db6fbSLori Alt 212495db6fbSLori Alt if (sz > 1<<20) { 213495db6fbSLori Alt free(buf); 214495db6fbSLori Alt buf = malloc(sz); 215495db6fbSLori Alt } 216495db6fbSLori Alt (void) ssread(buf, sz, &zc); 217495db6fbSLori Alt if (ferror(send_stream)) 218495db6fbSLori Alt perror("fread"); 219495db6fbSLori Alt err = nvlist_unpack(buf, sz, &nv, 0); 220495db6fbSLori Alt if (err) 221495db6fbSLori Alt perror(strerror(err)); 222495db6fbSLori Alt nvlist_print(stdout, nv); 223495db6fbSLori Alt nvlist_free(nv); 224495db6fbSLori Alt } 225495db6fbSLori Alt break; 226495db6fbSLori Alt 227495db6fbSLori Alt case DRR_END: 228495db6fbSLori Alt if (do_byteswap) { 229495db6fbSLori Alt drre->drr_checksum.zc_word[0] = 230495db6fbSLori Alt BSWAP_64(drre->drr_checksum.zc_word[0]); 231495db6fbSLori Alt drre->drr_checksum.zc_word[1] = 232495db6fbSLori Alt BSWAP_64(drre->drr_checksum.zc_word[1]); 233495db6fbSLori Alt drre->drr_checksum.zc_word[2] = 234495db6fbSLori Alt BSWAP_64(drre->drr_checksum.zc_word[2]); 235495db6fbSLori Alt drre->drr_checksum.zc_word[3] = 236495db6fbSLori Alt BSWAP_64(drre->drr_checksum.zc_word[3]); 237495db6fbSLori Alt } 238495db6fbSLori Alt /* 239495db6fbSLori Alt * We compare against the *previous* checksum 240495db6fbSLori Alt * value, because the stored checksum is of 241495db6fbSLori Alt * everything before the DRR_END record. 242495db6fbSLori Alt */ 243495db6fbSLori Alt if (do_cksum && !ZIO_CHECKSUM_EQUAL(drre->drr_checksum, 244495db6fbSLori Alt pcksum)) { 245495db6fbSLori Alt (void) printf("Expected checksum differs from " 246495db6fbSLori Alt "checksum in stream.\n"); 247495db6fbSLori Alt (void) printf("Expected checksum = " 248495db6fbSLori Alt "%llx/%llx/%llx/%llx\n", 249495db6fbSLori Alt pcksum.zc_word[0], 250495db6fbSLori Alt pcksum.zc_word[1], 251495db6fbSLori Alt pcksum.zc_word[2], 252495db6fbSLori Alt pcksum.zc_word[3]); 253495db6fbSLori Alt } 254495db6fbSLori Alt (void) printf("END checksum = %llx/%llx/%llx/%llx\n", 255495db6fbSLori Alt drre->drr_checksum.zc_word[0], 256495db6fbSLori Alt drre->drr_checksum.zc_word[1], 257495db6fbSLori Alt drre->drr_checksum.zc_word[2], 258495db6fbSLori Alt drre->drr_checksum.zc_word[3]); 259495db6fbSLori Alt 260495db6fbSLori Alt ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0); 261495db6fbSLori Alt break; 262495db6fbSLori Alt 263495db6fbSLori Alt case DRR_OBJECT: 264495db6fbSLori Alt if (do_byteswap) { 265495db6fbSLori Alt drro->drr_object = BSWAP_64(drro->drr_object); 266495db6fbSLori Alt drro->drr_type = BSWAP_32(drro->drr_type); 267495db6fbSLori Alt drro->drr_bonustype = 268495db6fbSLori Alt BSWAP_32(drro->drr_bonustype); 269495db6fbSLori Alt drro->drr_blksz = BSWAP_32(drro->drr_blksz); 270495db6fbSLori Alt drro->drr_bonuslen = 271495db6fbSLori Alt BSWAP_32(drro->drr_bonuslen); 2729e69d7d0SLori Alt drro->drr_toguid = BSWAP_64(drro->drr_toguid); 273495db6fbSLori Alt } 274495db6fbSLori Alt if (verbose) { 275495db6fbSLori Alt (void) printf("OBJECT object = %llu type = %u " 276495db6fbSLori Alt "bonustype = %u blksz = %u bonuslen = %u\n", 277495db6fbSLori Alt (u_longlong_t)drro->drr_object, 278495db6fbSLori Alt drro->drr_type, 279495db6fbSLori Alt drro->drr_bonustype, 280495db6fbSLori Alt drro->drr_blksz, 281495db6fbSLori Alt drro->drr_bonuslen); 282495db6fbSLori Alt } 283495db6fbSLori Alt if (drro->drr_bonuslen > 0) { 284495db6fbSLori Alt (void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen, 285495db6fbSLori Alt 8), &zc); 286495db6fbSLori Alt } 287495db6fbSLori Alt break; 288495db6fbSLori Alt 289495db6fbSLori Alt case DRR_FREEOBJECTS: 290495db6fbSLori Alt if (do_byteswap) { 291495db6fbSLori Alt drrfo->drr_firstobj = 292495db6fbSLori Alt BSWAP_64(drrfo->drr_firstobj); 293495db6fbSLori Alt drrfo->drr_numobjs = 294495db6fbSLori Alt BSWAP_64(drrfo->drr_numobjs); 2959e69d7d0SLori Alt drrfo->drr_toguid = BSWAP_64(drrfo->drr_toguid); 296495db6fbSLori Alt } 297495db6fbSLori Alt if (verbose) { 298495db6fbSLori Alt (void) printf("FREEOBJECTS firstobj = %llu " 299495db6fbSLori Alt "numobjs = %llu\n", 300495db6fbSLori Alt (u_longlong_t)drrfo->drr_firstobj, 301495db6fbSLori Alt (u_longlong_t)drrfo->drr_numobjs); 302495db6fbSLori Alt } 303495db6fbSLori Alt break; 304495db6fbSLori Alt 305495db6fbSLori Alt case DRR_WRITE: 306495db6fbSLori Alt if (do_byteswap) { 307495db6fbSLori Alt drrw->drr_object = BSWAP_64(drrw->drr_object); 308495db6fbSLori Alt drrw->drr_type = BSWAP_32(drrw->drr_type); 309495db6fbSLori Alt drrw->drr_offset = BSWAP_64(drrw->drr_offset); 310495db6fbSLori Alt drrw->drr_length = BSWAP_64(drrw->drr_length); 3119e69d7d0SLori Alt drrw->drr_toguid = BSWAP_64(drrw->drr_toguid); 3128e714474SLori Alt drrw->drr_key.ddk_prop = 3138e714474SLori Alt BSWAP_64(drrw->drr_key.ddk_prop); 314495db6fbSLori Alt } 315495db6fbSLori Alt if (verbose) { 316495db6fbSLori Alt (void) printf("WRITE object = %llu type = %u " 3178e714474SLori Alt "checksum type = %u\n" 3188e714474SLori Alt "offset = %llu length = %llu " 3198e714474SLori Alt "props = %llx\n", 320495db6fbSLori Alt (u_longlong_t)drrw->drr_object, 321495db6fbSLori Alt drrw->drr_type, 3228e714474SLori Alt drrw->drr_checksumtype, 323495db6fbSLori Alt (u_longlong_t)drrw->drr_offset, 3248e714474SLori Alt (u_longlong_t)drrw->drr_length, 3258e714474SLori Alt (u_longlong_t)drrw->drr_key.ddk_prop); 326495db6fbSLori Alt } 327495db6fbSLori Alt (void) ssread(buf, drrw->drr_length, &zc); 328495db6fbSLori Alt total_write_size += drrw->drr_length; 329495db6fbSLori Alt break; 330495db6fbSLori Alt 3319e69d7d0SLori Alt case DRR_WRITE_BYREF: 3329e69d7d0SLori Alt if (do_byteswap) { 3339e69d7d0SLori Alt drrwbr->drr_object = 3349e69d7d0SLori Alt BSWAP_64(drrwbr->drr_object); 3359e69d7d0SLori Alt drrwbr->drr_offset = 3369e69d7d0SLori Alt BSWAP_64(drrwbr->drr_offset); 3379e69d7d0SLori Alt drrwbr->drr_length = 3389e69d7d0SLori Alt BSWAP_64(drrwbr->drr_length); 3399e69d7d0SLori Alt drrwbr->drr_toguid = 3409e69d7d0SLori Alt BSWAP_64(drrwbr->drr_toguid); 3419e69d7d0SLori Alt drrwbr->drr_refguid = 3429e69d7d0SLori Alt BSWAP_64(drrwbr->drr_refguid); 3439e69d7d0SLori Alt drrwbr->drr_refobject = 3449e69d7d0SLori Alt BSWAP_64(drrwbr->drr_refobject); 3459e69d7d0SLori Alt drrwbr->drr_refoffset = 3469e69d7d0SLori Alt BSWAP_64(drrwbr->drr_refoffset); 3478e714474SLori Alt drrwbr->drr_key.ddk_prop = 3488e714474SLori Alt BSWAP_64(drrwbr->drr_key.ddk_prop); 3499e69d7d0SLori Alt } 3509e69d7d0SLori Alt if (verbose) { 3519e69d7d0SLori Alt (void) printf("WRITE_BYREF object = %llu " 3528e714474SLori Alt "checksum type = %u props = %llx\n" 3539e69d7d0SLori Alt "offset = %llu length = %llu\n" 3549e69d7d0SLori Alt "toguid = %llx refguid = %llx\n" 3559e69d7d0SLori Alt "refobject = %llu refoffset = %llu\n", 3569e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_object, 3578e714474SLori Alt drrwbr->drr_checksumtype, 3588e714474SLori Alt (u_longlong_t)drrwbr->drr_key.ddk_prop, 3599e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_offset, 3609e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_length, 3619e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_toguid, 3629e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_refguid, 3639e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_refobject, 3649e69d7d0SLori Alt (u_longlong_t)drrwbr->drr_refoffset); 3659e69d7d0SLori Alt } 3669e69d7d0SLori Alt break; 3679e69d7d0SLori Alt 368495db6fbSLori Alt case DRR_FREE: 369495db6fbSLori Alt if (do_byteswap) { 370495db6fbSLori Alt drrf->drr_object = BSWAP_64(drrf->drr_object); 371495db6fbSLori Alt drrf->drr_offset = BSWAP_64(drrf->drr_offset); 372495db6fbSLori Alt drrf->drr_length = BSWAP_64(drrf->drr_length); 373495db6fbSLori Alt } 374495db6fbSLori Alt if (verbose) { 375495db6fbSLori Alt (void) printf("FREE object = %llu " 376495db6fbSLori Alt "offset = %llu length = %lld\n", 377495db6fbSLori Alt (u_longlong_t)drrf->drr_object, 378495db6fbSLori Alt (u_longlong_t)drrf->drr_offset, 379495db6fbSLori Alt (longlong_t)drrf->drr_length); 380495db6fbSLori Alt } 381495db6fbSLori Alt break; 382*0a586ceaSMark Shellenbaum case DRR_SPILL: 383*0a586ceaSMark Shellenbaum if (do_byteswap) { 384*0a586ceaSMark Shellenbaum drrs->drr_object = BSWAP_64(drrs->drr_object); 385*0a586ceaSMark Shellenbaum drrs->drr_length = BSWAP_64(drrs->drr_length); 386*0a586ceaSMark Shellenbaum } 387*0a586ceaSMark Shellenbaum if (verbose) { 388*0a586ceaSMark Shellenbaum (void) printf("SPILL block for object = %llu " 389*0a586ceaSMark Shellenbaum "length = %llu\n", drrs->drr_object, 390*0a586ceaSMark Shellenbaum drrs->drr_length); 391*0a586ceaSMark Shellenbaum } 392*0a586ceaSMark Shellenbaum (void) ssread(buf, drrs->drr_length, &zc); 393*0a586ceaSMark Shellenbaum break; 394495db6fbSLori Alt } 395495db6fbSLori Alt pcksum = zc; 396495db6fbSLori Alt } 397495db6fbSLori Alt free(buf); 398495db6fbSLori Alt 399495db6fbSLori Alt /* Print final summary */ 400495db6fbSLori Alt 401495db6fbSLori Alt (void) printf("SUMMARY:\n"); 402495db6fbSLori Alt (void) printf("\tTotal DRR_BEGIN records = %lld\n", 403495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_BEGIN]); 404495db6fbSLori Alt (void) printf("\tTotal DRR_END records = %lld\n", 405495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_END]); 406495db6fbSLori Alt (void) printf("\tTotal DRR_OBJECT records = %lld\n", 407495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_OBJECT]); 408495db6fbSLori Alt (void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n", 409495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_FREEOBJECTS]); 410495db6fbSLori Alt (void) printf("\tTotal DRR_WRITE records = %lld\n", 411495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_WRITE]); 412495db6fbSLori Alt (void) printf("\tTotal DRR_FREE records = %lld\n", 413495db6fbSLori Alt (u_longlong_t)drr_record_count[DRR_FREE]); 414*0a586ceaSMark Shellenbaum (void) printf("\tTotal DRR_SPILL records = %lld\n", 415*0a586ceaSMark Shellenbaum (u_longlong_t)drr_record_count[DRR_SPILL]); 416495db6fbSLori Alt (void) printf("\tTotal records = %lld\n", 417495db6fbSLori Alt (u_longlong_t)(drr_record_count[DRR_BEGIN] + 418495db6fbSLori Alt drr_record_count[DRR_OBJECT] + 419495db6fbSLori Alt drr_record_count[DRR_FREEOBJECTS] + 420495db6fbSLori Alt drr_record_count[DRR_WRITE] + 421495db6fbSLori Alt drr_record_count[DRR_FREE] + 422*0a586ceaSMark Shellenbaum drr_record_count[DRR_SPILL] + 423495db6fbSLori Alt drr_record_count[DRR_END])); 424495db6fbSLori Alt (void) printf("\tTotal write size = %lld (0x%llx)\n", 425495db6fbSLori Alt (u_longlong_t)total_write_size, (u_longlong_t)total_write_size); 426495db6fbSLori Alt (void) printf("\tTotal stream length = %lld (0x%llx)\n", 427495db6fbSLori Alt (u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len); 428495db6fbSLori Alt return (0); 429495db6fbSLori Alt } 430