495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt/*
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * CDDL HEADER START
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt *
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * The contents of this file are subject to the terms of the
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * Common Development and Distribution License (the "License").
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * You may not use this file except in compliance with the License.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt *
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * or http://www.opensolaris.org/os/licensing.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * See the License for the specific language governing permissions
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * and limitations under the License.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt *
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * When distributing Covered Code, include this CDDL HEADER in each
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * If applicable, add the following below this CDDL HEADER, with the
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * fields enclosed by brackets "[]" replaced with your own identifying
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * information: Portions Copyright [yyyy] [name of copyright owner]
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt *
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * CDDL HEADER END
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt/*
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * Use is subject to license terms.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman/*
c3d26abc9ee97b4f60233556aadeb57e0bd30bb9Matthew Ahrens * Copyright (c) 2014 Integros [integros.com]
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel * Copyright (c) 2013, 2015 by Delphix. All rights reserved.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman#include <ctype.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <libnvpair.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <stdio.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <stdlib.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <strings.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <unistd.h>
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens#include <stddef.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <sys/dmu.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <sys/zfs_ioctl.h>
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel#include <sys/zio.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt#include <zfs_fletcher.h>
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman/*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * If dump mode is enabled, the number of bytes to print per line
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman#define BYTES_PER_LINE 16
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman/*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * If dump mode is enabled, the number of bytes to group together, separated
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * by newlines or spaces
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman#define DUMP_GROUPING 4
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altuint64_t total_write_size = 0;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altuint64_t total_stream_len = 0;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori AltFILE *send_stream = 0;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altboolean_t do_byteswap = B_FALSE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altboolean_t do_cksum = B_TRUE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altstatic void
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altusage(void)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt{
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) fprintf(stderr, "usage: zstreamdump [-v] [-C] [-d] < file\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr, "\t -v -- verbose\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr, "\t -C -- suppress checksum verification\n");
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) fprintf(stderr, "\t -d -- dump contents of blocks modified, "
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman "implies verbose\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt exit(1);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt}
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrensstatic void *
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrenssafe_malloc(size_t size)
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens{
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens void *rv = malloc(size);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens if (rv == NULL) {
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens (void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n",
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens size);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens abort();
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens }
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens return (rv);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens}
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt/*
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * ssread - send stream read.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt *
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * Read while computing incremental checksum
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altstatic size_t
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altssread(void *buf, size_t len, zio_cksum_t *cksum)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt{
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt size_t outlen;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if ((outlen = fread(buf, len, 1, send_stream)) == 0)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt return (0);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (do_cksum) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt fletcher_4_incremental_byteswap(buf, len, cksum);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt else
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt fletcher_4_incremental_native(buf, len, cksum);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt total_stream_len += len;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt return (outlen);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt}
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrensstatic size_t
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrensread_hdr(dmu_replay_record_t *drr, zio_cksum_t *cksum)
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens{
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens size_t r = ssread(drr, sizeof (*drr) - sizeof (zio_cksum_t), cksum);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (r == 0)
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens return (0);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens zio_cksum_t saved_cksum = *cksum;
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens r = ssread(&drr->drr_u.drr_checksum.drr_checksum,
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens sizeof (zio_cksum_t), cksum);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (r == 0)
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens return (0);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (!ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.drr_checksum.drr_checksum) &&
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens !ZIO_CHECKSUM_EQUAL(saved_cksum,
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens drr->drr_u.drr_checksum.drr_checksum)) {
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens fprintf(stderr, "invalid checksum\n");
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (void) printf("Incorrect checksum in record header.\n");
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (void) printf("Expected checksum = %llx/%llx/%llx/%llx\n",
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens saved_cksum.zc_word[0],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens saved_cksum.zc_word[1],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens saved_cksum.zc_word[2],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens saved_cksum.zc_word[3]);
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens return (0);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens }
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens return (sizeof (*drr));
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens}
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman/*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Print part of a block in ASCII characters
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossmanstatic void
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossmanprint_ascii_block(char *subbuf, int length)
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman{
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int i;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman for (i = 0; i < length; i++) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman char char_print = isprint(subbuf[i]) ? subbuf[i] : '.';
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman if (i != 0 && i % DUMP_GROUPING == 0) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) printf(" ");
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) printf("%c", char_print);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) printf("\n");
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman}
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman/*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * print_block - Dump the contents of a modified block to STDOUT
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman *
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Assume that buf has capacity evenly divisible by BYTES_PER_LINE
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossmanstatic void
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossmanprint_block(char *buf, int length)
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman{
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int i;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Start printing ASCII characters at a constant offset, after
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * the hex prints. Leave 3 characters per byte on a line (2 digit
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * hex number plus 1 space) plus spaces between characters and
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens * groupings.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int ascii_start = BYTES_PER_LINE * 3 +
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman BYTES_PER_LINE / DUMP_GROUPING + 2;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman for (i = 0; i < length; i += BYTES_PER_LINE) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int j;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int this_line_length = MIN(BYTES_PER_LINE, length - i);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int print_offset = 0;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman for (j = 0; j < this_line_length; j++) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman int buf_offset = i + j;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Separate every DUMP_GROUPING bytes by a space.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman if (buf_offset % DUMP_GROUPING == 0) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman print_offset += printf(" ");
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Print the two-digit hex value for this byte.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman unsigned char hex_print = buf[buf_offset];
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman print_offset += printf("%02x ", hex_print);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman (void) printf("%*s", ascii_start - print_offset, " ");
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman print_ascii_block(buf + i, this_line_length);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman}
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altint
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Altmain(int argc, char *argv[])
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt{
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens uint64_t total_records = 0;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt dmu_replay_record_t thedrr;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt dmu_replay_record_t *drr = &thedrr;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_end *drre = &thedrr.drr_u.drr_end;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_object *drro = &thedrr.drr_u.drr_object;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_freeobjects *drrfo = &thedrr.drr_u.drr_freeobjects;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_write *drrw = &thedrr.drr_u.drr_write;
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt struct drr_write_byref *drrwbr = &thedrr.drr_u.drr_write_byref;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt struct drr_free *drrf = &thedrr.drr_u.drr_free;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt char c;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt boolean_t verbose = B_FALSE;
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens boolean_t very_verbose = B_FALSE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt boolean_t first = B_TRUE;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * dump flag controls whether the contents of any modified data blocks
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * are printed to the console during processing of the stream. Warning:
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * for large streams, this can obviously lead to massive prints.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman boolean_t dump = B_FALSE;
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt int err;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt zio_cksum_t zc = { 0 };
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt zio_cksum_t pcksum = { 0 };
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman while ((c = getopt(argc, argv, ":vCd")) != -1) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt switch (c) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case 'C':
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt do_cksum = B_FALSE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case 'v':
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (verbose)
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens very_verbose = B_TRUE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt verbose = B_TRUE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman case 'd':
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman dump = B_TRUE;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman verbose = B_TRUE;
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens very_verbose = B_TRUE;
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case ':':
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "missing argument for '%c' option\n", optopt);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt usage();
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case '?':
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr, "invalid option '%c'\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt optopt);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt usage();
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (isatty(STDIN_FILENO)) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "Error: Backup stream can not be read "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "from a terminal.\n"
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "You must redirect standard input.\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt exit(1);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt send_stream = stdin;
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens while (read_hdr(drr, &zc)) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * If this is the first DMU record being processed, check for
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * the magic bytes and figure out the endian-ness based on them.
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (first) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt do_byteswap = B_TRUE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_cksum) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt /*
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * recalculate header checksum now
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * that we know it needs to be
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * byteswapped.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt fletcher_4_incremental_byteswap(drr,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt sizeof (dmu_replay_record_t), &zc);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt } else if (drrb->drr_magic != DMU_BACKUP_MAGIC) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) fprintf(stderr, "Invalid stream "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "(bad magic number)\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt exit(1);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt first = B_FALSE;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drr->drr_type = BSWAP_32(drr->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drr->drr_payloadlen =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_32(drr->drr_payloadlen);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt /*
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * At this point, the leading fields of the replay record
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * (drr_type and drr_payloadlen) have been byte-swapped if
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * necessary, but the rest of the data structure (the
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * union of type-specific structures) is still in its
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * original state.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (drr->drr_type >= DRR_NUMTYPES) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("INVALID record found: type 0x%x\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drr->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("Aborting.\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt exit(1);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drr_record_count[drr->drr_type]++;
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens total_records++;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt switch (drr->drr_type) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_BEGIN:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_magic = BSWAP_64(drrb->drr_magic);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrb->drr_versioninfo =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrb->drr_versioninfo);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_creation_time =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drrb->drr_creation_time);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_type = BSWAP_32(drrb->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_flags = BSWAP_32(drrb->drr_flags);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrb->drr_fromguid =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drrb->drr_fromguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("BEGIN record\n");
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (void) printf("\thdrtype = %lld\n",
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo));
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (void) printf("\tfeatures = %llx\n",
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo));
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tmagic = %llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrb->drr_magic);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tcreation_time = %llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrb->drr_creation_time);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\ttype = %u\n", drrb->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tflags = 0x%x\n", drrb->drr_flags);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\ttoguid = %llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrb->drr_toguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tfromguid = %llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrb->drr_fromguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\ttoname = %s\n", drrb->drr_toname);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (verbose)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
9c3fd1216fa7fb02cfbc78a2518a686d54b48ab8Matthew Ahrens if (drr->drr_payloadlen != 0) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt nvlist_t *nv;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt int sz = drr->drr_payloadlen;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens if (sz > SPA_MAXBLOCKSIZE) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt free(buf);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens buf = safe_malloc(sz);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) ssread(buf, sz, &zc);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (ferror(send_stream))
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt perror("fread");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt err = nvlist_unpack(buf, sz, &nv, 0);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (err)
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt perror(strerror(err));
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt nvlist_print(stdout, nv);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt nvlist_free(nv);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_END:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[0] =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drre->drr_checksum.zc_word[0]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[1] =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drre->drr_checksum.zc_word[1]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[2] =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drre->drr_checksum.zc_word[2]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[3] =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drre->drr_checksum.zc_word[3]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt /*
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * We compare against the *previous* checksum
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * value, because the stored checksum is of
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt * everything before the DRR_END record.
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_cksum && !ZIO_CHECKSUM_EQUAL(drre->drr_checksum,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum)) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("Expected checksum differs from "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "checksum in stream.\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("Expected checksum = "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "%llx/%llx/%llx/%llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum.zc_word[0],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum.zc_word[1],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum.zc_word[2],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum.zc_word[3]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("END checksum = %llx/%llx/%llx/%llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[0],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[1],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[2],
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drre->drr_checksum.zc_word[3]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_OBJECT:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_object = BSWAP_64(drro->drr_object);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_type = BSWAP_32(drro->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_bonustype =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_32(drro->drr_bonustype);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_blksz = BSWAP_32(drro->drr_blksz);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_bonuslen =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_32(drro->drr_bonuslen);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drro->drr_toguid = BSWAP_64(drro->drr_toguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (verbose) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("OBJECT object = %llu type = %u "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "bonustype = %u blksz = %u bonuslen = %u\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drro->drr_object,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_type,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_bonustype,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_blksz,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drro->drr_bonuslen);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (drro->drr_bonuslen > 0) {
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (void) ssread(buf,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens P2ROUNDUP(drro->drr_bonuslen, 8), &zc);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman if (dump) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman print_block(buf,
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman P2ROUNDUP(drro->drr_bonuslen, 8));
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_FREEOBJECTS:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrfo->drr_firstobj =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drrfo->drr_firstobj);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrfo->drr_numobjs =
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt BSWAP_64(drrfo->drr_numobjs);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrfo->drr_toguid = BSWAP_64(drrfo->drr_toguid);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (verbose) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("FREEOBJECTS firstobj = %llu "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "numobjs = %llu\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrfo->drr_firstobj,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrfo->drr_numobjs);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_WRITE:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrw->drr_object = BSWAP_64(drrw->drr_object);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrw->drr_type = BSWAP_32(drrw->drr_type);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrw->drr_offset = BSWAP_64(drrw->drr_offset);
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel drrw->drr_logical_size =
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel BSWAP_64(drrw->drr_logical_size);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrw->drr_toguid = BSWAP_64(drrw->drr_toguid);
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt drrw->drr_key.ddk_prop =
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt BSWAP_64(drrw->drr_key.ddk_prop);
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel drrw->drr_compressed_size =
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel BSWAP_64(drrw->drr_compressed_size);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel uint64_t payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * If this is verbose and/or dump output,
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * print info on the modified block
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (verbose) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("WRITE object = %llu type = %u "
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel "checksum type = %u compression type = %u\n"
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel " offset = %llu logical_size = %llu "
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel "compressed_size = %llu "
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel "payload_size = %llu "
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt "props = %llx\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrw->drr_object,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrw->drr_type,
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt drrw->drr_checksumtype,
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel drrw->drr_compressiontype,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrw->drr_offset,
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel (u_longlong_t)drrw->drr_logical_size,
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel (u_longlong_t)drrw->drr_compressed_size,
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel (u_longlong_t)payload_size,
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt (u_longlong_t)drrw->drr_key.ddk_prop);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * Read the contents of the block in from STDIN to buf
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel (void) ssread(buf, payload_size, &zc);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman /*
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman * If in dump mode
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman */
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman if (dump) {
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel print_block(buf, payload_size);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
5602294fda888d923d57a78bafdaf48ae6223deaDan Kimmel total_write_size += payload_size;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt case DRR_WRITE_BYREF:
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt if (do_byteswap) {
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_object =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_object);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_offset =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_offset);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_length =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_length);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_toguid =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_toguid);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_refguid =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_refguid);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_refobject =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_refobject);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt drrwbr->drr_refoffset =
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt BSWAP_64(drrwbr->drr_refoffset);
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt drrwbr->drr_key.ddk_prop =
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt BSWAP_64(drrwbr->drr_key.ddk_prop);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt }
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt if (verbose) {
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (void) printf("WRITE_BYREF object = %llu "
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt "checksum type = %u props = %llx\n"
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens " offset = %llu length = %llu\n"
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt "toguid = %llx refguid = %llx\n"
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens " refobject = %llu refoffset = %llu\n",
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_object,
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt drrwbr->drr_checksumtype,
8e7144747a94247ce9dbb4fb1f67bdcb666b30d8Lori Alt (u_longlong_t)drrwbr->drr_key.ddk_prop,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_offset,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_length,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_toguid,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_refguid,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_refobject,
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt (u_longlong_t)drrwbr->drr_refoffset);
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt }
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt break;
9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22Lori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt case DRR_FREE:
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (do_byteswap) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrf->drr_object = BSWAP_64(drrf->drr_object);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrf->drr_offset = BSWAP_64(drrf->drr_offset);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt drrf->drr_length = BSWAP_64(drrf->drr_length);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt if (verbose) {
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("FREE object = %llu "
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt "offset = %llu length = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrf->drr_object,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drrf->drr_offset,
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (longlong_t)drrf->drr_length);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt break;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum case DRR_SPILL:
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (do_byteswap) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum drrs->drr_object = BSWAP_64(drrs->drr_object);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum drrs->drr_length = BSWAP_64(drrs->drr_length);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (verbose) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (void) printf("SPILL block for object = %llu "
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum "length = %llu\n", drrs->drr_object,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum drrs->drr_length);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (void) ssread(buf, drrs->drr_length, &zc);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman if (dump) {
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman print_block(buf, drrs->drr_length);
994fb6b8a9d07a8021d77d79f46e30637bca3ad3Max Grossman }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum break;
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens case DRR_WRITE_EMBEDDED:
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens if (do_byteswap) {
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_object =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_64(drrwe->drr_object);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_offset =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_64(drrwe->drr_offset);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_length =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_64(drrwe->drr_length);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_toguid =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_64(drrwe->drr_toguid);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_lsize =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_32(drrwe->drr_lsize);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_psize =
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens BSWAP_32(drrwe->drr_psize);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens }
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens if (verbose) {
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (void) printf("WRITE_EMBEDDED object = %llu "
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens "offset = %llu length = %llu\n"
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens " toguid = %llx comp = %u etype = %u "
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens "lsize = %u psize = %u\n",
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drrwe->drr_object,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drrwe->drr_offset,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drrwe->drr_length,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drrwe->drr_toguid,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_compression,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_etype,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_lsize,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens drrwe->drr_psize);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens }
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (void) ssread(buf,
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens P2ROUNDUP(drrwe->drr_psize, 8), &zc);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens break;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens if (drr->drr_type != DRR_BEGIN && very_verbose) {
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (void) printf(" checksum = %llx/%llx/%llx/%llx\n",
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (longlong_t)drrc->drr_checksum.zc_word[0],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (longlong_t)drrc->drr_checksum.zc_word[1],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (longlong_t)drrc->drr_checksum.zc_word[2],
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens (longlong_t)drrc->drr_checksum.zc_word[3]);
98110f08fa182032082d98be2ddb9391fcd62bf1Matthew Ahrens }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt pcksum = zc;
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt }
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt free(buf);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt /* Print final summary */
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("SUMMARY:\n");
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_BEGIN records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_BEGIN]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_END records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_END]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_OBJECT records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_OBJECT]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_FREEOBJECTS records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_FREEOBJECTS]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_WRITE records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_WRITE]);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (void) printf("\tTotal DRR_WRITE_BYREF records = %lld\n",
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drr_record_count[DRR_WRITE_BYREF]);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (void) printf("\tTotal DRR_WRITE_EMBEDDED records = %lld\n",
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)drr_record_count[DRR_WRITE_EMBEDDED]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal DRR_FREE records = %lld\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)drr_record_count[DRR_FREE]);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (void) printf("\tTotal DRR_SPILL records = %lld\n",
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (u_longlong_t)drr_record_count[DRR_SPILL]);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal records = %lld\n",
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens (u_longlong_t)total_records);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal write size = %lld (0x%llx)\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)total_write_size, (u_longlong_t)total_write_size);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (void) printf("\tTotal stream length = %lld (0x%llx)\n",
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt (u_longlong_t)total_stream_len, (u_longlong_t)total_stream_len);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt return (0);
495db6fbcd9e8ab893e91f6f5627df6e0cec63cfLori Alt}