27
27
*/
28
28
29
29
/*
30
- * Copyright (c) 2013 by Delphix. All rights reserved.
30
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
31
31
*/
32
32
33
33
#include <ctype.h>
36
36
#include <stdlib.h>
37
37
#include <strings.h>
38
38
#include <unistd.h>
39
+ #include <stddef.h>
39
40
40
41
#include <sys/dmu.h>
41
42
#include <sys/zfs_ioctl.h>
@@ -73,8 +74,8 @@ safe_malloc(size_t size)
73
74
{
74
75
void * rv = malloc (size );
75
76
if (rv == NULL ) {
76
- (void ) fprintf (stderr , "ERROR; failed to allocate %u bytes\n" ,
77
- ( unsigned ) size );
77
+ (void ) fprintf (stderr , "ERROR; failed to allocate %zu bytes\n" ,
78
+ size );
78
79
abort ();
79
80
}
80
81
return (rv );
@@ -85,7 +86,6 @@ safe_malloc(size_t size)
85
86
*
86
87
* Read while computing incremental checksum
87
88
*/
88
-
89
89
static size_t
90
90
ssread (void * buf , size_t len , zio_cksum_t * cksum )
91
91
{
@@ -94,7 +94,7 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
94
94
if ((outlen = fread (buf , len , 1 , send_stream )) == 0 )
95
95
return (0 );
96
96
97
- if (do_cksum && cksum ) {
97
+ if (do_cksum ) {
98
98
if (do_byteswap )
99
99
fletcher_4_incremental_byteswap (buf , len , cksum );
100
100
else
@@ -104,6 +104,34 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
104
104
return (outlen );
105
105
}
106
106
107
+ static size_t
108
+ read_hdr (dmu_replay_record_t * drr , zio_cksum_t * cksum )
109
+ {
110
+ ASSERT3U (offsetof (dmu_replay_record_t , drr_u .drr_checksum .drr_checksum ),
111
+ == , sizeof (dmu_replay_record_t ) - sizeof (zio_cksum_t ));
112
+ size_t r = ssread (drr , sizeof (* drr ) - sizeof (zio_cksum_t ), cksum );
113
+ if (r == 0 )
114
+ return (0 );
115
+ zio_cksum_t saved_cksum = * cksum ;
116
+ r = ssread (& drr -> drr_u .drr_checksum .drr_checksum ,
117
+ sizeof (zio_cksum_t ), cksum );
118
+ if (r == 0 )
119
+ return (0 );
120
+ if (!ZIO_CHECKSUM_IS_ZERO (& drr -> drr_u .drr_checksum .drr_checksum ) &&
121
+ !ZIO_CHECKSUM_EQUAL (saved_cksum ,
122
+ drr -> drr_u .drr_checksum .drr_checksum )) {
123
+ fprintf (stderr , "invalid checksum\n" );
124
+ (void ) printf ("Incorrect checksum in record header.\n" );
125
+ (void ) printf ("Expected checksum = %llx/%llx/%llx/%llx\n" ,
126
+ (longlong_t )saved_cksum .zc_word [0 ],
127
+ (longlong_t )saved_cksum .zc_word [1 ],
128
+ (longlong_t )saved_cksum .zc_word [2 ],
129
+ (longlong_t )saved_cksum .zc_word [3 ]);
130
+ exit (1 );
131
+ }
132
+ return (sizeof (* drr ));
133
+ }
134
+
107
135
/*
108
136
* Print part of a block in ASCII characters
109
137
*/
@@ -135,7 +163,7 @@ print_block(char *buf, int length)
135
163
* Start printing ASCII characters at a constant offset, after
136
164
* the hex prints. Leave 3 characters per byte on a line (2 digit
137
165
* hex number plus 1 space) plus spaces between characters and
138
- * groupings
166
+ * groupings.
139
167
*/
140
168
int ascii_start = BYTES_PER_LINE * 3 +
141
169
BYTES_PER_LINE / DUMP_GROUPING + 2 ;
@@ -185,8 +213,10 @@ main(int argc, char *argv[])
185
213
struct drr_free * drrf = & thedrr .drr_u .drr_free ;
186
214
struct drr_spill * drrs = & thedrr .drr_u .drr_spill ;
187
215
struct drr_write_embedded * drrwe = & thedrr .drr_u .drr_write_embedded ;
216
+ struct drr_checksum * drrc = & thedrr .drr_u .drr_checksum ;
188
217
char c ;
189
218
boolean_t verbose = B_FALSE ;
219
+ boolean_t very_verbose = B_FALSE ;
190
220
boolean_t first = B_TRUE ;
191
221
/*
192
222
* dump flag controls whether the contents of any modified data blocks
@@ -204,11 +234,14 @@ main(int argc, char *argv[])
204
234
do_cksum = B_FALSE ;
205
235
break ;
206
236
case 'v' :
237
+ if (verbose )
238
+ very_verbose = B_TRUE ;
207
239
verbose = B_TRUE ;
208
240
break ;
209
241
case 'd' :
210
242
dump = B_TRUE ;
211
243
verbose = B_TRUE ;
244
+ very_verbose = B_TRUE ;
212
245
break ;
213
246
case ':' :
214
247
(void ) fprintf (stderr ,
@@ -231,7 +264,7 @@ main(int argc, char *argv[])
231
264
}
232
265
233
266
send_stream = stdin ;
234
- while (ssread (drr , sizeof ( dmu_replay_record_t ) , & zc )) {
267
+ while (read_hdr (drr , & zc )) {
235
268
236
269
/*
237
270
* If this is the first DMU record being processed, check for
@@ -437,7 +470,7 @@ main(int argc, char *argv[])
437
470
if (verbose ) {
438
471
(void ) printf ("WRITE object = %llu type = %u "
439
472
"checksum type = %u\n"
440
- "offset = %llu length = %llu "
473
+ " offset = %llu length = %llu "
441
474
"props = %llx\n" ,
442
475
(u_longlong_t )drrw -> drr_object ,
443
476
drrw -> drr_type ,
@@ -481,9 +514,9 @@ main(int argc, char *argv[])
481
514
if (verbose ) {
482
515
(void ) printf ("WRITE_BYREF object = %llu "
483
516
"checksum type = %u props = %llx\n"
484
- "offset = %llu length = %llu\n"
517
+ " offset = %llu length = %llu\n"
485
518
"toguid = %llx refguid = %llx\n"
486
- "refobject = %llu refoffset = %llu\n" ,
519
+ " refobject = %llu refoffset = %llu\n" ,
487
520
(u_longlong_t )drrwbr -> drr_object ,
488
521
drrwbr -> drr_checksumtype ,
489
522
(u_longlong_t )drrwbr -> drr_key .ddk_prop ,
@@ -544,7 +577,7 @@ main(int argc, char *argv[])
544
577
if (verbose ) {
545
578
(void ) printf ("WRITE_EMBEDDED object = %llu "
546
579
"offset = %llu length = %llu\n"
547
- "toguid = %llx comp = %u etype = %u "
580
+ " toguid = %llx comp = %u etype = %u "
548
581
"lsize = %u psize = %u\n" ,
549
582
(u_longlong_t )drrwe -> drr_object ,
550
583
(u_longlong_t )drrwe -> drr_offset ,
@@ -562,6 +595,13 @@ main(int argc, char *argv[])
562
595
/* should never be reached */
563
596
exit (1 );
564
597
}
598
+ if (drr -> drr_type != DRR_BEGIN && very_verbose ) {
599
+ (void ) printf (" checksum = %llx/%llx/%llx/%llx\n" ,
600
+ (longlong_t )drrc -> drr_checksum .zc_word [0 ],
601
+ (longlong_t )drrc -> drr_checksum .zc_word [1 ],
602
+ (longlong_t )drrc -> drr_checksum .zc_word [2 ],
603
+ (longlong_t )drrc -> drr_checksum .zc_word [3 ]);
604
+ }
565
605
pcksum = zc ;
566
606
}
567
607
free (buf );
0 commit comments