summaryrefslogtreecommitdiffstats
path: root/cmd/zstreamdump
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2015-07-06 05:20:31 +0200
committerBrian Behlendorf <[email protected]>2015-12-30 14:24:14 -0800
commit37f8a8835a88da6122e2526d6aaeeef75556a7bd (patch)
treeded281ddf4f846ce47185d86cf4cb01ba2525731 /cmd/zstreamdump
parent43b4935e5358806de18461f3ee92e07c67071eb5 (diff)
Illumos 5746 - more checksumming in zfs send
5746 more checksumming in zfs send Reviewed by: Christopher Siden <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Bayard Bell <[email protected]> Approved by: Albert Lee <[email protected]> References: https://www.illumos.org/issues/5746 https://github.com/illumos/illumos-gate/commit/98110f0 https://github.com/zfsonlinux/zfs/issues/905 Porting notes: - Minor conflicts due to: - https://github.com/zfsonlinux/zfs/commit/2024041 - https://github.com/zfsonlinux/zfs/commit/044baf0 - https://github.com/zfsonlinux/zfs/commit/88904bb - Fix ISO C90 warnings (-Werror=declaration-after-statement) - arc_buf_t *abuf; - dmu_buf_t *bonus; - zio_cksum_t cksum_orig; - zio_cksum_t *cksump; - Fix format '%llx' format specifier warning - Align message in zstreamdump safe_malloc() with upstream Ported-by: kernelOfTruth [email protected] Signed-off-by: Brian Behlendorf <[email protected]> Closes #3611
Diffstat (limited to 'cmd/zstreamdump')
-rw-r--r--cmd/zstreamdump/zstreamdump.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/cmd/zstreamdump/zstreamdump.c b/cmd/zstreamdump/zstreamdump.c
index 176dd66b2..f288d148e 100644
--- a/cmd/zstreamdump/zstreamdump.c
+++ b/cmd/zstreamdump/zstreamdump.c
@@ -27,7 +27,7 @@
*/
/*
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
*/
#include <ctype.h>
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
+#include <stddef.h>
#include <sys/dmu.h>
#include <sys/zfs_ioctl.h>
@@ -73,8 +74,8 @@ safe_malloc(size_t size)
{
void *rv = malloc(size);
if (rv == NULL) {
- (void) fprintf(stderr, "ERROR; failed to allocate %u bytes\n",
- (unsigned)size);
+ (void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n",
+ size);
abort();
}
return (rv);
@@ -85,7 +86,6 @@ safe_malloc(size_t size)
*
* Read while computing incremental checksum
*/
-
static size_t
ssread(void *buf, size_t len, zio_cksum_t *cksum)
{
@@ -94,7 +94,7 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
if ((outlen = fread(buf, len, 1, send_stream)) == 0)
return (0);
- if (do_cksum && cksum) {
+ if (do_cksum) {
if (do_byteswap)
fletcher_4_incremental_byteswap(buf, len, cksum);
else
@@ -104,6 +104,34 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
return (outlen);
}
+static size_t
+read_hdr(dmu_replay_record_t *drr, zio_cksum_t *cksum)
+{
+ ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
+ ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
+ size_t r = ssread(drr, sizeof (*drr) - sizeof (zio_cksum_t), cksum);
+ if (r == 0)
+ return (0);
+ zio_cksum_t saved_cksum = *cksum;
+ r = ssread(&drr->drr_u.drr_checksum.drr_checksum,
+ sizeof (zio_cksum_t), cksum);
+ if (r == 0)
+ return (0);
+ if (!ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.drr_checksum.drr_checksum) &&
+ !ZIO_CHECKSUM_EQUAL(saved_cksum,
+ drr->drr_u.drr_checksum.drr_checksum)) {
+ fprintf(stderr, "invalid checksum\n");
+ (void) printf("Incorrect checksum in record header.\n");
+ (void) printf("Expected checksum = %llx/%llx/%llx/%llx\n",
+ (longlong_t)saved_cksum.zc_word[0],
+ (longlong_t)saved_cksum.zc_word[1],
+ (longlong_t)saved_cksum.zc_word[2],
+ (longlong_t)saved_cksum.zc_word[3]);
+ exit(1);
+ }
+ return (sizeof (*drr));
+}
+
/*
* Print part of a block in ASCII characters
*/
@@ -135,7 +163,7 @@ print_block(char *buf, int length)
* Start printing ASCII characters at a constant offset, after
* the hex prints. Leave 3 characters per byte on a line (2 digit
* hex number plus 1 space) plus spaces between characters and
- * groupings
+ * groupings.
*/
int ascii_start = BYTES_PER_LINE * 3 +
BYTES_PER_LINE / DUMP_GROUPING + 2;
@@ -185,8 +213,10 @@ main(int argc, char *argv[])
struct drr_free *drrf = &thedrr.drr_u.drr_free;
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
+ struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
char c;
boolean_t verbose = B_FALSE;
+ boolean_t very_verbose = B_FALSE;
boolean_t first = B_TRUE;
/*
* dump flag controls whether the contents of any modified data blocks
@@ -204,11 +234,14 @@ main(int argc, char *argv[])
do_cksum = B_FALSE;
break;
case 'v':
+ if (verbose)
+ very_verbose = B_TRUE;
verbose = B_TRUE;
break;
case 'd':
dump = B_TRUE;
verbose = B_TRUE;
+ very_verbose = B_TRUE;
break;
case ':':
(void) fprintf(stderr,
@@ -231,7 +264,7 @@ main(int argc, char *argv[])
}
send_stream = stdin;
- while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {
+ while (read_hdr(drr, &zc)) {
/*
* If this is the first DMU record being processed, check for
@@ -437,7 +470,7 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE object = %llu type = %u "
"checksum type = %u\n"
- "offset = %llu length = %llu "
+ " offset = %llu length = %llu "
"props = %llx\n",
(u_longlong_t)drrw->drr_object,
drrw->drr_type,
@@ -481,9 +514,9 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE_BYREF object = %llu "
"checksum type = %u props = %llx\n"
- "offset = %llu length = %llu\n"
+ " offset = %llu length = %llu\n"
"toguid = %llx refguid = %llx\n"
- "refobject = %llu refoffset = %llu\n",
+ " refobject = %llu refoffset = %llu\n",
(u_longlong_t)drrwbr->drr_object,
drrwbr->drr_checksumtype,
(u_longlong_t)drrwbr->drr_key.ddk_prop,
@@ -544,7 +577,7 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE_EMBEDDED object = %llu "
"offset = %llu length = %llu\n"
- "toguid = %llx comp = %u etype = %u "
+ " toguid = %llx comp = %u etype = %u "
"lsize = %u psize = %u\n",
(u_longlong_t)drrwe->drr_object,
(u_longlong_t)drrwe->drr_offset,
@@ -562,6 +595,13 @@ main(int argc, char *argv[])
/* should never be reached */
exit(1);
}
+ if (drr->drr_type != DRR_BEGIN && very_verbose) {
+ (void) printf(" checksum = %llx/%llx/%llx/%llx\n",
+ (longlong_t)drrc->drr_checksum.zc_word[0],
+ (longlong_t)drrc->drr_checksum.zc_word[1],
+ (longlong_t)drrc->drr_checksum.zc_word[2],
+ (longlong_t)drrc->drr_checksum.zc_word[3]);
+ }
pcksum = zc;
}
free(buf);