Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/zdb/zdb.c
+++ new/usr/src/cmd/zdb/zdb.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 +
21 22 /*
22 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright (c) 2012 by Delphix. All rights reserved.
23 25 */
24 26
25 27 #include <stdio.h>
26 28 #include <stdio_ext.h>
27 29 #include <stdlib.h>
28 30 #include <ctype.h>
29 31 #include <sys/zfs_context.h>
30 32 #include <sys/spa.h>
31 33 #include <sys/spa_impl.h>
32 34 #include <sys/dmu.h>
33 35 #include <sys/zap.h>
34 36 #include <sys/fs/zfs.h>
35 37 #include <sys/zfs_znode.h>
36 38 #include <sys/zfs_sa.h>
37 39 #include <sys/sa.h>
38 40 #include <sys/sa_impl.h>
39 41 #include <sys/vdev.h>
40 42 #include <sys/vdev_impl.h>
41 43 #include <sys/metaslab_impl.h>
42 44 #include <sys/dmu_objset.h>
43 45 #include <sys/dsl_dir.h>
44 46 #include <sys/dsl_dataset.h>
45 47 #include <sys/dsl_pool.h>
46 48 #include <sys/dbuf.h>
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
47 49 #include <sys/zil.h>
48 50 #include <sys/zil_impl.h>
49 51 #include <sys/stat.h>
50 52 #include <sys/resource.h>
51 53 #include <sys/dmu_traverse.h>
52 54 #include <sys/zio_checksum.h>
53 55 #include <sys/zio_compress.h>
54 56 #include <sys/zfs_fuid.h>
55 57 #include <sys/arc.h>
56 58 #include <sys/ddt.h>
59 +#include <sys/zfeature.h>
57 60 #undef ZFS_MAXNAMELEN
58 61 #undef verify
59 62 #include <libzfs.h>
60 63
61 64 #define ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \
62 65 zio_compress_table[(idx)].ci_name : "UNKNOWN")
63 66 #define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
64 67 zio_checksum_table[(idx)].ci_name : "UNKNOWN")
65 68 #define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
66 - dmu_ot[(idx)].ot_name : "UNKNOWN")
69 + dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \
70 + dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
67 71 #define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES)
68 72
69 73 #ifndef lint
70 74 extern int zfs_recover;
71 75 #else
72 76 int zfs_recover;
73 77 #endif
74 78
75 79 const char cmdname[] = "zdb";
76 80 uint8_t dump_opt[256];
77 81
78 82 typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
79 83
80 84 extern void dump_intent_log(zilog_t *);
81 85 uint64_t *zopt_object = NULL;
82 86 int zopt_objects = 0;
83 87 libzfs_handle_t *g_zfs;
84 88
85 89 /*
86 90 * These libumem hooks provide a reasonable set of defaults for the allocator's
87 91 * debugging facilities.
88 92 */
89 93 const char *
90 94 _umem_debug_init()
91 95 {
92 96 return ("default,verbose"); /* $UMEM_DEBUG setting */
93 97 }
94 98
95 99 const char *
96 100 _umem_logging_init(void)
97 101 {
98 102 return ("fail,contents"); /* $UMEM_LOGGING setting */
99 103 }
100 104
101 105 static void
102 106 usage(void)
103 107 {
104 108 (void) fprintf(stderr,
105 109 "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
106 110 "poolname [object...]\n"
107 111 " %s [-divPA] [-e -p path...] dataset [object...]\n"
108 112 " %s -m [-LXFPA] [-t txg] [-e [-p path...]] "
109 113 "poolname [vdev [metaslab...]]\n"
110 114 " %s -R [-A] [-e [-p path...]] poolname "
111 115 "vdev:offset:size[:flags]\n"
112 116 " %s -S [-PA] [-e [-p path...]] poolname\n"
113 117 " %s -l [-uA] device\n"
114 118 " %s -C [-A] [-U config]\n\n",
115 119 cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
116 120
117 121 (void) fprintf(stderr, " Dataset name must include at least one "
118 122 "separator character '/' or '@'\n");
119 123 (void) fprintf(stderr, " If dataset name is specified, only that "
120 124 "dataset is dumped\n");
121 125 (void) fprintf(stderr, " If object numbers are specified, only "
122 126 "those objects are dumped\n\n");
123 127 (void) fprintf(stderr, " Options to control amount of output:\n");
124 128 (void) fprintf(stderr, " -u uberblock\n");
125 129 (void) fprintf(stderr, " -d dataset(s)\n");
126 130 (void) fprintf(stderr, " -i intent logs\n");
127 131 (void) fprintf(stderr, " -C config (or cachefile if alone)\n");
128 132 (void) fprintf(stderr, " -h pool history\n");
129 133 (void) fprintf(stderr, " -b block statistics\n");
130 134 (void) fprintf(stderr, " -m metaslabs\n");
131 135 (void) fprintf(stderr, " -c checksum all metadata (twice for "
132 136 "all data) blocks\n");
133 137 (void) fprintf(stderr, " -s report stats on zdb's I/O\n");
134 138 (void) fprintf(stderr, " -D dedup statistics\n");
135 139 (void) fprintf(stderr, " -S simulate dedup to measure effect\n");
136 140 (void) fprintf(stderr, " -v verbose (applies to all others)\n");
137 141 (void) fprintf(stderr, " -l dump label contents\n");
138 142 (void) fprintf(stderr, " -L disable leak tracking (do not "
139 143 "load spacemaps)\n");
140 144 (void) fprintf(stderr, " -R read and display block from a "
141 145 "device\n\n");
142 146 (void) fprintf(stderr, " Below options are intended for use "
143 147 "with other options (except -l):\n");
144 148 (void) fprintf(stderr, " -A ignore assertions (-A), enable "
145 149 "panic recovery (-AA) or both (-AAA)\n");
146 150 (void) fprintf(stderr, " -F attempt automatic rewind within "
147 151 "safe range of transaction groups\n");
148 152 (void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
149 153 "cachefile\n");
150 154 (void) fprintf(stderr, " -X attempt extreme rewind (does not "
151 155 "work with dataset)\n");
152 156 (void) fprintf(stderr, " -e pool is exported/destroyed/"
153 157 "has altroot/not in a cachefile\n");
154 158 (void) fprintf(stderr, " -p <path> -- use one or more with "
155 159 "-e to specify path to vdev dir\n");
156 160 (void) fprintf(stderr, " -P print numbers in parseable form\n");
157 161 (void) fprintf(stderr, " -t <txg> -- highest txg to use when "
158 162 "searching for uberblocks\n");
159 163 (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
160 164 "to make only that option verbose\n");
161 165 (void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
162 166 exit(1);
163 167 }
164 168
165 169 /*
166 170 * Called for usage errors that are discovered after a call to spa_open(),
167 171 * dmu_bonus_hold(), or pool_match(). abort() is called for other errors.
168 172 */
169 173
170 174 static void
171 175 fatal(const char *fmt, ...)
172 176 {
173 177 va_list ap;
174 178
175 179 va_start(ap, fmt);
176 180 (void) fprintf(stderr, "%s: ", cmdname);
177 181 (void) vfprintf(stderr, fmt, ap);
178 182 va_end(ap);
179 183 (void) fprintf(stderr, "\n");
180 184
181 185 exit(1);
182 186 }
183 187
184 188 /* ARGSUSED */
185 189 static void
186 190 dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
187 191 {
188 192 nvlist_t *nv;
189 193 size_t nvsize = *(uint64_t *)data;
190 194 char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
191 195
192 196 VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
193 197
194 198 VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
195 199
196 200 umem_free(packed, nvsize);
197 201
198 202 dump_nvlist(nv, 8);
199 203
200 204 nvlist_free(nv);
201 205 }
202 206
203 207 static void
204 208 zdb_nicenum(uint64_t num, char *buf)
205 209 {
206 210 if (dump_opt['P'])
207 211 (void) sprintf(buf, "%llu", (longlong_t)num);
208 212 else
209 213 nicenum(num, buf);
210 214 }
211 215
212 216 const char dump_zap_stars[] = "****************************************";
213 217 const int dump_zap_width = sizeof (dump_zap_stars) - 1;
214 218
215 219 static void
216 220 dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
217 221 {
218 222 int i;
219 223 int minidx = ZAP_HISTOGRAM_SIZE - 1;
220 224 int maxidx = 0;
221 225 uint64_t max = 0;
222 226
223 227 for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
224 228 if (histo[i] > max)
225 229 max = histo[i];
226 230 if (histo[i] > 0 && i > maxidx)
227 231 maxidx = i;
228 232 if (histo[i] > 0 && i < minidx)
229 233 minidx = i;
230 234 }
231 235
232 236 if (max < dump_zap_width)
233 237 max = dump_zap_width;
234 238
235 239 for (i = minidx; i <= maxidx; i++)
236 240 (void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
237 241 &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
238 242 }
239 243
240 244 static void
241 245 dump_zap_stats(objset_t *os, uint64_t object)
242 246 {
243 247 int error;
244 248 zap_stats_t zs;
245 249
246 250 error = zap_get_stats(os, object, &zs);
247 251 if (error)
248 252 return;
249 253
250 254 if (zs.zs_ptrtbl_len == 0) {
251 255 ASSERT(zs.zs_num_blocks == 1);
252 256 (void) printf("\tmicrozap: %llu bytes, %llu entries\n",
253 257 (u_longlong_t)zs.zs_blocksize,
254 258 (u_longlong_t)zs.zs_num_entries);
255 259 return;
256 260 }
257 261
258 262 (void) printf("\tFat ZAP stats:\n");
259 263
260 264 (void) printf("\t\tPointer table:\n");
261 265 (void) printf("\t\t\t%llu elements\n",
262 266 (u_longlong_t)zs.zs_ptrtbl_len);
263 267 (void) printf("\t\t\tzt_blk: %llu\n",
264 268 (u_longlong_t)zs.zs_ptrtbl_zt_blk);
265 269 (void) printf("\t\t\tzt_numblks: %llu\n",
266 270 (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
267 271 (void) printf("\t\t\tzt_shift: %llu\n",
268 272 (u_longlong_t)zs.zs_ptrtbl_zt_shift);
269 273 (void) printf("\t\t\tzt_blks_copied: %llu\n",
270 274 (u_longlong_t)zs.zs_ptrtbl_blks_copied);
271 275 (void) printf("\t\t\tzt_nextblk: %llu\n",
272 276 (u_longlong_t)zs.zs_ptrtbl_nextblk);
273 277
274 278 (void) printf("\t\tZAP entries: %llu\n",
275 279 (u_longlong_t)zs.zs_num_entries);
276 280 (void) printf("\t\tLeaf blocks: %llu\n",
277 281 (u_longlong_t)zs.zs_num_leafs);
278 282 (void) printf("\t\tTotal blocks: %llu\n",
279 283 (u_longlong_t)zs.zs_num_blocks);
280 284 (void) printf("\t\tzap_block_type: 0x%llx\n",
281 285 (u_longlong_t)zs.zs_block_type);
282 286 (void) printf("\t\tzap_magic: 0x%llx\n",
283 287 (u_longlong_t)zs.zs_magic);
284 288 (void) printf("\t\tzap_salt: 0x%llx\n",
285 289 (u_longlong_t)zs.zs_salt);
286 290
287 291 (void) printf("\t\tLeafs with 2^n pointers:\n");
288 292 dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
289 293
290 294 (void) printf("\t\tBlocks with n*5 entries:\n");
291 295 dump_zap_histogram(zs.zs_blocks_with_n5_entries);
292 296
293 297 (void) printf("\t\tBlocks n/10 full:\n");
294 298 dump_zap_histogram(zs.zs_blocks_n_tenths_full);
295 299
296 300 (void) printf("\t\tEntries with n chunks:\n");
297 301 dump_zap_histogram(zs.zs_entries_using_n_chunks);
298 302
299 303 (void) printf("\t\tBuckets with n entries:\n");
300 304 dump_zap_histogram(zs.zs_buckets_with_n_entries);
301 305 }
302 306
303 307 /*ARGSUSED*/
304 308 static void
305 309 dump_none(objset_t *os, uint64_t object, void *data, size_t size)
306 310 {
307 311 }
308 312
309 313 /*ARGSUSED*/
310 314 static void
311 315 dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
312 316 {
313 317 (void) printf("\tUNKNOWN OBJECT TYPE\n");
314 318 }
315 319
316 320 /*ARGSUSED*/
317 321 void
318 322 dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
319 323 {
320 324 }
321 325
322 326 /*ARGSUSED*/
323 327 static void
324 328 dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
325 329 {
326 330 }
327 331
328 332 /*ARGSUSED*/
329 333 static void
330 334 dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
331 335 {
332 336 zap_cursor_t zc;
333 337 zap_attribute_t attr;
334 338 void *prop;
335 339 int i;
336 340
337 341 dump_zap_stats(os, object);
338 342 (void) printf("\n");
339 343
340 344 for (zap_cursor_init(&zc, os, object);
341 345 zap_cursor_retrieve(&zc, &attr) == 0;
342 346 zap_cursor_advance(&zc)) {
343 347 (void) printf("\t\t%s = ", attr.za_name);
344 348 if (attr.za_num_integers == 0) {
345 349 (void) printf("\n");
346 350 continue;
347 351 }
348 352 prop = umem_zalloc(attr.za_num_integers *
349 353 attr.za_integer_length, UMEM_NOFAIL);
350 354 (void) zap_lookup(os, object, attr.za_name,
351 355 attr.za_integer_length, attr.za_num_integers, prop);
352 356 if (attr.za_integer_length == 1) {
353 357 (void) printf("%s", (char *)prop);
354 358 } else {
355 359 for (i = 0; i < attr.za_num_integers; i++) {
356 360 switch (attr.za_integer_length) {
357 361 case 2:
358 362 (void) printf("%u ",
359 363 ((uint16_t *)prop)[i]);
360 364 break;
361 365 case 4:
362 366 (void) printf("%u ",
363 367 ((uint32_t *)prop)[i]);
364 368 break;
365 369 case 8:
366 370 (void) printf("%lld ",
367 371 (u_longlong_t)((int64_t *)prop)[i]);
368 372 break;
369 373 }
370 374 }
371 375 }
372 376 (void) printf("\n");
373 377 umem_free(prop, attr.za_num_integers * attr.za_integer_length);
374 378 }
375 379 zap_cursor_fini(&zc);
376 380 }
377 381
378 382 /*ARGSUSED*/
379 383 static void
380 384 dump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
381 385 {
382 386 dump_zap_stats(os, object);
383 387 /* contents are printed elsewhere, properly decoded */
384 388 }
385 389
386 390 /*ARGSUSED*/
387 391 static void
388 392 dump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
389 393 {
390 394 zap_cursor_t zc;
391 395 zap_attribute_t attr;
392 396
393 397 dump_zap_stats(os, object);
394 398 (void) printf("\n");
395 399
396 400 for (zap_cursor_init(&zc, os, object);
397 401 zap_cursor_retrieve(&zc, &attr) == 0;
398 402 zap_cursor_advance(&zc)) {
399 403 (void) printf("\t\t%s = ", attr.za_name);
400 404 if (attr.za_num_integers == 0) {
401 405 (void) printf("\n");
402 406 continue;
403 407 }
404 408 (void) printf(" %llx : [%d:%d:%d]\n",
405 409 (u_longlong_t)attr.za_first_integer,
406 410 (int)ATTR_LENGTH(attr.za_first_integer),
407 411 (int)ATTR_BSWAP(attr.za_first_integer),
408 412 (int)ATTR_NUM(attr.za_first_integer));
409 413 }
410 414 zap_cursor_fini(&zc);
411 415 }
412 416
413 417 /*ARGSUSED*/
414 418 static void
415 419 dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
416 420 {
417 421 zap_cursor_t zc;
418 422 zap_attribute_t attr;
419 423 uint16_t *layout_attrs;
420 424 int i;
421 425
422 426 dump_zap_stats(os, object);
423 427 (void) printf("\n");
424 428
425 429 for (zap_cursor_init(&zc, os, object);
426 430 zap_cursor_retrieve(&zc, &attr) == 0;
427 431 zap_cursor_advance(&zc)) {
428 432 (void) printf("\t\t%s = [", attr.za_name);
429 433 if (attr.za_num_integers == 0) {
430 434 (void) printf("\n");
431 435 continue;
432 436 }
433 437
434 438 VERIFY(attr.za_integer_length == 2);
435 439 layout_attrs = umem_zalloc(attr.za_num_integers *
436 440 attr.za_integer_length, UMEM_NOFAIL);
437 441
438 442 VERIFY(zap_lookup(os, object, attr.za_name,
439 443 attr.za_integer_length,
440 444 attr.za_num_integers, layout_attrs) == 0);
441 445
442 446 for (i = 0; i != attr.za_num_integers; i++)
443 447 (void) printf(" %d ", (int)layout_attrs[i]);
444 448 (void) printf("]\n");
445 449 umem_free(layout_attrs,
446 450 attr.za_num_integers * attr.za_integer_length);
447 451 }
448 452 zap_cursor_fini(&zc);
449 453 }
450 454
451 455 /*ARGSUSED*/
452 456 static void
453 457 dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
454 458 {
455 459 zap_cursor_t zc;
456 460 zap_attribute_t attr;
457 461 const char *typenames[] = {
458 462 /* 0 */ "not specified",
459 463 /* 1 */ "FIFO",
460 464 /* 2 */ "Character Device",
461 465 /* 3 */ "3 (invalid)",
462 466 /* 4 */ "Directory",
463 467 /* 5 */ "5 (invalid)",
464 468 /* 6 */ "Block Device",
465 469 /* 7 */ "7 (invalid)",
466 470 /* 8 */ "Regular File",
467 471 /* 9 */ "9 (invalid)",
468 472 /* 10 */ "Symbolic Link",
469 473 /* 11 */ "11 (invalid)",
470 474 /* 12 */ "Socket",
471 475 /* 13 */ "Door",
472 476 /* 14 */ "Event Port",
473 477 /* 15 */ "15 (invalid)",
474 478 };
475 479
476 480 dump_zap_stats(os, object);
477 481 (void) printf("\n");
478 482
479 483 for (zap_cursor_init(&zc, os, object);
480 484 zap_cursor_retrieve(&zc, &attr) == 0;
481 485 zap_cursor_advance(&zc)) {
482 486 (void) printf("\t\t%s = %lld (type: %s)\n",
483 487 attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
484 488 typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
485 489 }
486 490 zap_cursor_fini(&zc);
487 491 }
488 492
489 493 static void
490 494 dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
491 495 {
492 496 uint64_t alloc, offset, entry;
493 497 uint8_t mapshift = sm->sm_shift;
494 498 uint64_t mapstart = sm->sm_start;
495 499 char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
496 500 "INVALID", "INVALID", "INVALID", "INVALID" };
497 501
498 502 if (smo->smo_object == 0)
499 503 return;
500 504
501 505 /*
502 506 * Print out the freelist entries in both encoded and decoded form.
503 507 */
504 508 alloc = 0;
505 509 for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
506 510 VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
507 511 sizeof (entry), &entry, DMU_READ_PREFETCH));
508 512 if (SM_DEBUG_DECODE(entry)) {
509 513 (void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
510 514 (u_longlong_t)(offset / sizeof (entry)),
511 515 ddata[SM_DEBUG_ACTION_DECODE(entry)],
512 516 (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
513 517 (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
514 518 } else {
515 519 (void) printf("\t [%6llu] %c range:"
516 520 " %010llx-%010llx size: %06llx\n",
517 521 (u_longlong_t)(offset / sizeof (entry)),
518 522 SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
519 523 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
520 524 mapshift) + mapstart),
521 525 (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
522 526 mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
523 527 mapshift)),
524 528 (u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
525 529 if (SM_TYPE_DECODE(entry) == SM_ALLOC)
526 530 alloc += SM_RUN_DECODE(entry) << mapshift;
527 531 else
528 532 alloc -= SM_RUN_DECODE(entry) << mapshift;
529 533 }
530 534 }
531 535 if (alloc != smo->smo_alloc) {
532 536 (void) printf("space_map_object alloc (%llu) INCONSISTENT "
533 537 "with space map summary (%llu)\n",
534 538 (u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
535 539 }
536 540 }
537 541
538 542 static void
539 543 dump_metaslab_stats(metaslab_t *msp)
540 544 {
541 545 char maxbuf[32];
542 546 space_map_t *sm = &msp->ms_map;
543 547 avl_tree_t *t = sm->sm_pp_root;
544 548 int free_pct = sm->sm_space * 100 / sm->sm_size;
545 549
546 550 zdb_nicenum(space_map_maxsize(sm), maxbuf);
547 551
548 552 (void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
549 553 "segments", avl_numnodes(t), "maxsize", maxbuf,
550 554 "freepct", free_pct);
551 555 }
552 556
553 557 static void
554 558 dump_metaslab(metaslab_t *msp)
555 559 {
556 560 vdev_t *vd = msp->ms_group->mg_vd;
557 561 spa_t *spa = vd->vdev_spa;
558 562 space_map_t *sm = &msp->ms_map;
559 563 space_map_obj_t *smo = &msp->ms_smo;
560 564 char freebuf[32];
561 565
562 566 zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
563 567
564 568 (void) printf(
565 569 "\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
566 570 (u_longlong_t)(sm->sm_start / sm->sm_size),
567 571 (u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf);
568 572
569 573 if (dump_opt['m'] > 1 && !dump_opt['L']) {
570 574 mutex_enter(&msp->ms_lock);
571 575 space_map_load_wait(sm);
572 576 if (!sm->sm_loaded)
573 577 VERIFY(space_map_load(sm, zfs_metaslab_ops,
574 578 SM_FREE, smo, spa->spa_meta_objset) == 0);
575 579 dump_metaslab_stats(msp);
576 580 space_map_unload(sm);
577 581 mutex_exit(&msp->ms_lock);
578 582 }
579 583
580 584 if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
581 585 ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));
582 586
583 587 mutex_enter(&msp->ms_lock);
584 588 dump_spacemap(spa->spa_meta_objset, smo, sm);
585 589 mutex_exit(&msp->ms_lock);
586 590 }
587 591 }
588 592
589 593 static void
590 594 print_vdev_metaslab_header(vdev_t *vd)
591 595 {
592 596 (void) printf("\tvdev %10llu\n\t%-10s%5llu %-19s %-15s %-10s\n",
593 597 (u_longlong_t)vd->vdev_id,
594 598 "metaslabs", (u_longlong_t)vd->vdev_ms_count,
595 599 "offset", "spacemap", "free");
596 600 (void) printf("\t%15s %19s %15s %10s\n",
597 601 "---------------", "-------------------",
598 602 "---------------", "-------------");
599 603 }
600 604
601 605 static void
602 606 dump_metaslabs(spa_t *spa)
603 607 {
604 608 vdev_t *vd, *rvd = spa->spa_root_vdev;
605 609 uint64_t m, c = 0, children = rvd->vdev_children;
606 610
607 611 (void) printf("\nMetaslabs:\n");
608 612
609 613 if (!dump_opt['d'] && zopt_objects > 0) {
610 614 c = zopt_object[0];
611 615
612 616 if (c >= children)
613 617 (void) fatal("bad vdev id: %llu", (u_longlong_t)c);
614 618
615 619 if (zopt_objects > 1) {
616 620 vd = rvd->vdev_child[c];
617 621 print_vdev_metaslab_header(vd);
618 622
619 623 for (m = 1; m < zopt_objects; m++) {
620 624 if (zopt_object[m] < vd->vdev_ms_count)
621 625 dump_metaslab(
622 626 vd->vdev_ms[zopt_object[m]]);
623 627 else
624 628 (void) fprintf(stderr, "bad metaslab "
625 629 "number %llu\n",
626 630 (u_longlong_t)zopt_object[m]);
627 631 }
628 632 (void) printf("\n");
629 633 return;
630 634 }
631 635 children = c + 1;
632 636 }
633 637 for (; c < children; c++) {
634 638 vd = rvd->vdev_child[c];
635 639 print_vdev_metaslab_header(vd);
636 640
637 641 for (m = 0; m < vd->vdev_ms_count; m++)
638 642 dump_metaslab(vd->vdev_ms[m]);
639 643 (void) printf("\n");
640 644 }
641 645 }
642 646
643 647 static void
644 648 dump_dde(const ddt_t *ddt, const ddt_entry_t *dde, uint64_t index)
645 649 {
646 650 const ddt_phys_t *ddp = dde->dde_phys;
647 651 const ddt_key_t *ddk = &dde->dde_key;
648 652 char *types[4] = { "ditto", "single", "double", "triple" };
649 653 char blkbuf[BP_SPRINTF_LEN];
650 654 blkptr_t blk;
651 655
652 656 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
653 657 if (ddp->ddp_phys_birth == 0)
654 658 continue;
655 659 ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
656 660 sprintf_blkptr(blkbuf, &blk);
657 661 (void) printf("index %llx refcnt %llu %s %s\n",
658 662 (u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
659 663 types[p], blkbuf);
660 664 }
661 665 }
662 666
663 667 static void
664 668 dump_dedup_ratio(const ddt_stat_t *dds)
665 669 {
666 670 double rL, rP, rD, D, dedup, compress, copies;
667 671
668 672 if (dds->dds_blocks == 0)
669 673 return;
670 674
671 675 rL = (double)dds->dds_ref_lsize;
672 676 rP = (double)dds->dds_ref_psize;
673 677 rD = (double)dds->dds_ref_dsize;
674 678 D = (double)dds->dds_dsize;
675 679
676 680 dedup = rD / D;
677 681 compress = rL / rP;
678 682 copies = rD / rP;
679 683
680 684 (void) printf("dedup = %.2f, compress = %.2f, copies = %.2f, "
681 685 "dedup * compress / copies = %.2f\n\n",
682 686 dedup, compress, copies, dedup * compress / copies);
683 687 }
684 688
685 689 static void
686 690 dump_ddt(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
687 691 {
688 692 char name[DDT_NAMELEN];
689 693 ddt_entry_t dde;
690 694 uint64_t walk = 0;
691 695 dmu_object_info_t doi;
692 696 uint64_t count, dspace, mspace;
693 697 int error;
694 698
695 699 error = ddt_object_info(ddt, type, class, &doi);
696 700
697 701 if (error == ENOENT)
698 702 return;
699 703 ASSERT(error == 0);
700 704
701 705 if ((count = ddt_object_count(ddt, type, class)) == 0)
702 706 return;
703 707
704 708 dspace = doi.doi_physical_blocks_512 << 9;
705 709 mspace = doi.doi_fill_count * doi.doi_data_block_size;
706 710
707 711 ddt_object_name(ddt, type, class, name);
708 712
709 713 (void) printf("%s: %llu entries, size %llu on disk, %llu in core\n",
710 714 name,
711 715 (u_longlong_t)count,
712 716 (u_longlong_t)(dspace / count),
713 717 (u_longlong_t)(mspace / count));
714 718
715 719 if (dump_opt['D'] < 3)
716 720 return;
717 721
718 722 zpool_dump_ddt(NULL, &ddt->ddt_histogram[type][class]);
719 723
720 724 if (dump_opt['D'] < 4)
721 725 return;
722 726
723 727 if (dump_opt['D'] < 5 && class == DDT_CLASS_UNIQUE)
724 728 return;
725 729
726 730 (void) printf("%s contents:\n\n", name);
727 731
728 732 while ((error = ddt_object_walk(ddt, type, class, &walk, &dde)) == 0)
729 733 dump_dde(ddt, &dde, walk);
730 734
731 735 ASSERT(error == ENOENT);
732 736
733 737 (void) printf("\n");
734 738 }
735 739
736 740 static void
737 741 dump_all_ddts(spa_t *spa)
738 742 {
739 743 ddt_histogram_t ddh_total = { 0 };
740 744 ddt_stat_t dds_total = { 0 };
741 745
742 746 for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
743 747 ddt_t *ddt = spa->spa_ddt[c];
744 748 for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
745 749 for (enum ddt_class class = 0; class < DDT_CLASSES;
746 750 class++) {
747 751 dump_ddt(ddt, type, class);
748 752 }
749 753 }
750 754 }
751 755
752 756 ddt_get_dedup_stats(spa, &dds_total);
753 757
754 758 if (dds_total.dds_blocks == 0) {
755 759 (void) printf("All DDTs are empty\n");
756 760 return;
757 761 }
758 762
759 763 (void) printf("\n");
760 764
761 765 if (dump_opt['D'] > 1) {
762 766 (void) printf("DDT histogram (aggregated over all DDTs):\n");
763 767 ddt_get_dedup_histogram(spa, &ddh_total);
764 768 zpool_dump_ddt(&dds_total, &ddh_total);
765 769 }
766 770
767 771 dump_dedup_ratio(&dds_total);
768 772 }
769 773
770 774 static void
771 775 dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
772 776 {
773 777 char *prefix = (void *)sm;
774 778
775 779 (void) printf("%s [%llu,%llu) length %llu\n",
776 780 prefix,
777 781 (u_longlong_t)start,
778 782 (u_longlong_t)(start + size),
779 783 (u_longlong_t)(size));
780 784 }
781 785
782 786 static void
783 787 dump_dtl(vdev_t *vd, int indent)
784 788 {
785 789 spa_t *spa = vd->vdev_spa;
786 790 boolean_t required;
787 791 char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
788 792 char prefix[256];
789 793
790 794 spa_vdev_state_enter(spa, SCL_NONE);
791 795 required = vdev_dtl_required(vd);
792 796 (void) spa_vdev_state_exit(spa, NULL, 0);
793 797
794 798 if (indent == 0)
795 799 (void) printf("\nDirty time logs:\n\n");
796 800
797 801 (void) printf("\t%*s%s [%s]\n", indent, "",
798 802 vd->vdev_path ? vd->vdev_path :
799 803 vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
800 804 required ? "DTL-required" : "DTL-expendable");
801 805
802 806 for (int t = 0; t < DTL_TYPES; t++) {
803 807 space_map_t *sm = &vd->vdev_dtl[t];
804 808 if (sm->sm_space == 0)
805 809 continue;
806 810 (void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
807 811 indent + 2, "", name[t]);
808 812 mutex_enter(sm->sm_lock);
809 813 space_map_walk(sm, dump_dtl_seg, (void *)prefix);
810 814 mutex_exit(sm->sm_lock);
811 815 if (dump_opt['d'] > 5 && vd->vdev_children == 0)
812 816 dump_spacemap(spa->spa_meta_objset,
813 817 &vd->vdev_dtl_smo, sm);
814 818 }
815 819
816 820 for (int c = 0; c < vd->vdev_children; c++)
817 821 dump_dtl(vd->vdev_child[c], indent + 4);
818 822 }
819 823
820 824 static void
821 825 dump_history(spa_t *spa)
822 826 {
823 827 nvlist_t **events = NULL;
824 828 char buf[SPA_MAXBLOCKSIZE];
825 829 uint64_t resid, len, off = 0;
826 830 uint_t num = 0;
827 831 int error;
828 832 time_t tsec;
829 833 struct tm t;
830 834 char tbuf[30];
831 835 char internalstr[MAXPATHLEN];
832 836
833 837 do {
834 838 len = sizeof (buf);
835 839
836 840 if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
837 841 (void) fprintf(stderr, "Unable to read history: "
838 842 "error %d\n", error);
839 843 return;
840 844 }
841 845
842 846 if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0)
843 847 break;
844 848
845 849 off -= resid;
846 850 } while (len != 0);
847 851
848 852 (void) printf("\nHistory:\n");
849 853 for (int i = 0; i < num; i++) {
850 854 uint64_t time, txg, ievent;
851 855 char *cmd, *intstr;
852 856
853 857 if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME,
854 858 &time) != 0)
855 859 continue;
856 860 if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD,
857 861 &cmd) != 0) {
858 862 if (nvlist_lookup_uint64(events[i],
859 863 ZPOOL_HIST_INT_EVENT, &ievent) != 0)
860 864 continue;
861 865 verify(nvlist_lookup_uint64(events[i],
862 866 ZPOOL_HIST_TXG, &txg) == 0);
863 867 verify(nvlist_lookup_string(events[i],
864 868 ZPOOL_HIST_INT_STR, &intstr) == 0);
865 869 if (ievent >= LOG_END)
866 870 continue;
867 871
868 872 (void) snprintf(internalstr,
869 873 sizeof (internalstr),
870 874 "[internal %s txg:%lld] %s",
871 875 zfs_history_event_names[ievent], txg,
872 876 intstr);
873 877 cmd = internalstr;
874 878 }
875 879 tsec = time;
876 880 (void) localtime_r(&tsec, &t);
877 881 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
878 882 (void) printf("%s %s\n", tbuf, cmd);
879 883 }
880 884 }
881 885
882 886 /*ARGSUSED*/
883 887 static void
884 888 dump_dnode(objset_t *os, uint64_t object, void *data, size_t size)
885 889 {
886 890 }
887 891
888 892 static uint64_t
889 893 blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb)
890 894 {
891 895 if (dnp == NULL) {
892 896 ASSERT(zb->zb_level < 0);
893 897 if (zb->zb_object == 0)
894 898 return (zb->zb_blkid);
895 899 return (zb->zb_blkid * BP_GET_LSIZE(bp));
896 900 }
897 901
898 902 ASSERT(zb->zb_level >= 0);
899 903
900 904 return ((zb->zb_blkid <<
901 905 (zb->zb_level * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT))) *
902 906 dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT);
903 907 }
904 908
905 909 static void
906 910 sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
907 911 {
908 912 const dva_t *dva = bp->blk_dva;
909 913 int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
910 914
911 915 if (dump_opt['b'] >= 5) {
912 916 sprintf_blkptr(blkbuf, bp);
913 917 return;
914 918 }
915 919
916 920 blkbuf[0] = '\0';
917 921
918 922 for (int i = 0; i < ndvas; i++)
919 923 (void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ",
920 924 (u_longlong_t)DVA_GET_VDEV(&dva[i]),
921 925 (u_longlong_t)DVA_GET_OFFSET(&dva[i]),
922 926 (u_longlong_t)DVA_GET_ASIZE(&dva[i]));
923 927
924 928 (void) sprintf(blkbuf + strlen(blkbuf),
925 929 "%llxL/%llxP F=%llu B=%llu/%llu",
926 930 (u_longlong_t)BP_GET_LSIZE(bp),
927 931 (u_longlong_t)BP_GET_PSIZE(bp),
928 932 (u_longlong_t)bp->blk_fill,
929 933 (u_longlong_t)bp->blk_birth,
930 934 (u_longlong_t)BP_PHYSICAL_BIRTH(bp));
931 935 }
932 936
933 937 static void
934 938 print_indirect(blkptr_t *bp, const zbookmark_t *zb,
935 939 const dnode_phys_t *dnp)
936 940 {
937 941 char blkbuf[BP_SPRINTF_LEN];
938 942 int l;
939 943
940 944 ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
941 945 ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
942 946
943 947 (void) printf("%16llx ", (u_longlong_t)blkid2offset(dnp, bp, zb));
944 948
945 949 ASSERT(zb->zb_level >= 0);
946 950
947 951 for (l = dnp->dn_nlevels - 1; l >= -1; l--) {
948 952 if (l == zb->zb_level) {
949 953 (void) printf("L%llx", (u_longlong_t)zb->zb_level);
950 954 } else {
951 955 (void) printf(" ");
952 956 }
953 957 }
954 958
955 959 sprintf_blkptr_compact(blkbuf, bp);
956 960 (void) printf("%s\n", blkbuf);
957 961 }
958 962
959 963 static int
960 964 visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
961 965 blkptr_t *bp, const zbookmark_t *zb)
962 966 {
963 967 int err = 0;
964 968
965 969 if (bp->blk_birth == 0)
966 970 return (0);
967 971
968 972 print_indirect(bp, zb, dnp);
969 973
970 974 if (BP_GET_LEVEL(bp) > 0) {
971 975 uint32_t flags = ARC_WAIT;
972 976 int i;
973 977 blkptr_t *cbp;
974 978 int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
975 979 arc_buf_t *buf;
976 980 uint64_t fill = 0;
977 981
978 982 err = arc_read_nolock(NULL, spa, bp, arc_getbuf_func, &buf,
979 983 ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
980 984 if (err)
981 985 return (err);
982 986 ASSERT(buf->b_data);
983 987
984 988 /* recursively visit blocks below this */
985 989 cbp = buf->b_data;
986 990 for (i = 0; i < epb; i++, cbp++) {
987 991 zbookmark_t czb;
988 992
989 993 SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
990 994 zb->zb_level - 1,
991 995 zb->zb_blkid * epb + i);
992 996 err = visit_indirect(spa, dnp, cbp, &czb);
993 997 if (err)
994 998 break;
995 999 fill += cbp->blk_fill;
996 1000 }
997 1001 if (!err)
998 1002 ASSERT3U(fill, ==, bp->blk_fill);
999 1003 (void) arc_buf_remove_ref(buf, &buf);
1000 1004 }
1001 1005
1002 1006 return (err);
1003 1007 }
1004 1008
1005 1009 /*ARGSUSED*/
1006 1010 static void
1007 1011 dump_indirect(dnode_t *dn)
1008 1012 {
1009 1013 dnode_phys_t *dnp = dn->dn_phys;
1010 1014 int j;
1011 1015 zbookmark_t czb;
1012 1016
1013 1017 (void) printf("Indirect blocks:\n");
1014 1018
1015 1019 SET_BOOKMARK(&czb, dmu_objset_id(dn->dn_objset),
1016 1020 dn->dn_object, dnp->dn_nlevels - 1, 0);
1017 1021 for (j = 0; j < dnp->dn_nblkptr; j++) {
1018 1022 czb.zb_blkid = j;
1019 1023 (void) visit_indirect(dmu_objset_spa(dn->dn_objset), dnp,
1020 1024 &dnp->dn_blkptr[j], &czb);
1021 1025 }
1022 1026
1023 1027 (void) printf("\n");
1024 1028 }
1025 1029
1026 1030 /*ARGSUSED*/
1027 1031 static void
1028 1032 dump_dsl_dir(objset_t *os, uint64_t object, void *data, size_t size)
1029 1033 {
1030 1034 dsl_dir_phys_t *dd = data;
1031 1035 time_t crtime;
1032 1036 char nice[32];
1033 1037
1034 1038 if (dd == NULL)
1035 1039 return;
1036 1040
1037 1041 ASSERT3U(size, >=, sizeof (dsl_dir_phys_t));
1038 1042
1039 1043 crtime = dd->dd_creation_time;
1040 1044 (void) printf("\t\tcreation_time = %s", ctime(&crtime));
1041 1045 (void) printf("\t\thead_dataset_obj = %llu\n",
1042 1046 (u_longlong_t)dd->dd_head_dataset_obj);
1043 1047 (void) printf("\t\tparent_dir_obj = %llu\n",
1044 1048 (u_longlong_t)dd->dd_parent_obj);
1045 1049 (void) printf("\t\torigin_obj = %llu\n",
1046 1050 (u_longlong_t)dd->dd_origin_obj);
1047 1051 (void) printf("\t\tchild_dir_zapobj = %llu\n",
1048 1052 (u_longlong_t)dd->dd_child_dir_zapobj);
1049 1053 zdb_nicenum(dd->dd_used_bytes, nice);
1050 1054 (void) printf("\t\tused_bytes = %s\n", nice);
1051 1055 zdb_nicenum(dd->dd_compressed_bytes, nice);
1052 1056 (void) printf("\t\tcompressed_bytes = %s\n", nice);
1053 1057 zdb_nicenum(dd->dd_uncompressed_bytes, nice);
1054 1058 (void) printf("\t\tuncompressed_bytes = %s\n", nice);
1055 1059 zdb_nicenum(dd->dd_quota, nice);
1056 1060 (void) printf("\t\tquota = %s\n", nice);
1057 1061 zdb_nicenum(dd->dd_reserved, nice);
1058 1062 (void) printf("\t\treserved = %s\n", nice);
1059 1063 (void) printf("\t\tprops_zapobj = %llu\n",
1060 1064 (u_longlong_t)dd->dd_props_zapobj);
1061 1065 (void) printf("\t\tdeleg_zapobj = %llu\n",
1062 1066 (u_longlong_t)dd->dd_deleg_zapobj);
1063 1067 (void) printf("\t\tflags = %llx\n",
1064 1068 (u_longlong_t)dd->dd_flags);
1065 1069
1066 1070 #define DO(which) \
1067 1071 zdb_nicenum(dd->dd_used_breakdown[DD_USED_ ## which], nice); \
1068 1072 (void) printf("\t\tused_breakdown[" #which "] = %s\n", nice)
1069 1073 DO(HEAD);
1070 1074 DO(SNAP);
1071 1075 DO(CHILD);
1072 1076 DO(CHILD_RSRV);
1073 1077 DO(REFRSRV);
1074 1078 #undef DO
1075 1079 }
1076 1080
1077 1081 /*ARGSUSED*/
1078 1082 static void
1079 1083 dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size)
1080 1084 {
|
↓ open down ↓ |
1004 lines elided |
↑ open up ↑ |
1081 1085 dsl_dataset_phys_t *ds = data;
1082 1086 time_t crtime;
1083 1087 char used[32], compressed[32], uncompressed[32], unique[32];
1084 1088 char blkbuf[BP_SPRINTF_LEN];
1085 1089
1086 1090 if (ds == NULL)
1087 1091 return;
1088 1092
1089 1093 ASSERT(size == sizeof (*ds));
1090 1094 crtime = ds->ds_creation_time;
1091 - zdb_nicenum(ds->ds_used_bytes, used);
1095 + zdb_nicenum(ds->ds_referenced_bytes, used);
1092 1096 zdb_nicenum(ds->ds_compressed_bytes, compressed);
1093 1097 zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
1094 1098 zdb_nicenum(ds->ds_unique_bytes, unique);
1095 1099 sprintf_blkptr(blkbuf, &ds->ds_bp);
1096 1100
1097 1101 (void) printf("\t\tdir_obj = %llu\n",
1098 1102 (u_longlong_t)ds->ds_dir_obj);
1099 1103 (void) printf("\t\tprev_snap_obj = %llu\n",
1100 1104 (u_longlong_t)ds->ds_prev_snap_obj);
1101 1105 (void) printf("\t\tprev_snap_txg = %llu\n",
1102 1106 (u_longlong_t)ds->ds_prev_snap_txg);
1103 1107 (void) printf("\t\tnext_snap_obj = %llu\n",
1104 1108 (u_longlong_t)ds->ds_next_snap_obj);
1105 1109 (void) printf("\t\tsnapnames_zapobj = %llu\n",
1106 1110 (u_longlong_t)ds->ds_snapnames_zapobj);
1107 1111 (void) printf("\t\tnum_children = %llu\n",
1108 1112 (u_longlong_t)ds->ds_num_children);
1109 1113 (void) printf("\t\tuserrefs_obj = %llu\n",
1110 1114 (u_longlong_t)ds->ds_userrefs_obj);
1111 1115 (void) printf("\t\tcreation_time = %s", ctime(&crtime));
1112 1116 (void) printf("\t\tcreation_txg = %llu\n",
1113 1117 (u_longlong_t)ds->ds_creation_txg);
1114 1118 (void) printf("\t\tdeadlist_obj = %llu\n",
1115 1119 (u_longlong_t)ds->ds_deadlist_obj);
1116 1120 (void) printf("\t\tused_bytes = %s\n", used);
1117 1121 (void) printf("\t\tcompressed_bytes = %s\n", compressed);
1118 1122 (void) printf("\t\tuncompressed_bytes = %s\n", uncompressed);
1119 1123 (void) printf("\t\tunique = %s\n", unique);
1120 1124 (void) printf("\t\tfsid_guid = %llu\n",
1121 1125 (u_longlong_t)ds->ds_fsid_guid);
1122 1126 (void) printf("\t\tguid = %llu\n",
1123 1127 (u_longlong_t)ds->ds_guid);
1124 1128 (void) printf("\t\tflags = %llx\n",
|
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
1125 1129 (u_longlong_t)ds->ds_flags);
1126 1130 (void) printf("\t\tnext_clones_obj = %llu\n",
1127 1131 (u_longlong_t)ds->ds_next_clones_obj);
1128 1132 (void) printf("\t\tprops_obj = %llu\n",
1129 1133 (u_longlong_t)ds->ds_props_obj);
1130 1134 (void) printf("\t\tbp = %s\n", blkbuf);
1131 1135 }
1132 1136
1133 1137 /* ARGSUSED */
1134 1138 static int
1139 +dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
1140 +{
1141 + char blkbuf[BP_SPRINTF_LEN];
1142 +
1143 + if (bp->blk_birth != 0) {
1144 + sprintf_blkptr(blkbuf, bp);
1145 + (void) printf("\t%s\n", blkbuf);
1146 + }
1147 + return (0);
1148 +}
1149 +
1150 +static void
1151 +dump_bptree(objset_t *os, uint64_t obj, char *name)
1152 +{
1153 + char bytes[32];
1154 + bptree_phys_t *bt;
1155 + dmu_buf_t *db;
1156 +
1157 + if (dump_opt['d'] < 3)
1158 + return;
1159 +
1160 + VERIFY3U(0, ==, dmu_bonus_hold(os, obj, FTAG, &db));
1161 + bt = db->db_data;
1162 + zdb_nicenum(bt->bt_bytes, bytes);
1163 + (void) printf("\n %s: %llu datasets, %s\n",
1164 + name, (unsigned long long)(bt->bt_end - bt->bt_begin), bytes);
1165 + dmu_buf_rele(db, FTAG);
1166 +
1167 + if (dump_opt['d'] < 5)
1168 + return;
1169 +
1170 + (void) printf("\n");
1171 +
1172 + (void) bptree_iterate(os, obj, B_FALSE, dump_bptree_cb, NULL, NULL);
1173 +}
1174 +
1175 +/* ARGSUSED */
1176 +static int
1135 1177 dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
1136 1178 {
1137 1179 char blkbuf[BP_SPRINTF_LEN];
1138 1180
1139 1181 ASSERT(bp->blk_birth != 0);
1140 1182 sprintf_blkptr_compact(blkbuf, bp);
1141 1183 (void) printf("\t%s\n", blkbuf);
1142 1184 return (0);
1143 1185 }
1144 1186
1145 1187 static void
1146 1188 dump_bpobj(bpobj_t *bpo, char *name)
1147 1189 {
1148 1190 char bytes[32];
1149 1191 char comp[32];
1150 1192 char uncomp[32];
1151 1193
1152 1194 if (dump_opt['d'] < 3)
1153 1195 return;
1154 1196
1155 1197 zdb_nicenum(bpo->bpo_phys->bpo_bytes, bytes);
1156 1198 if (bpo->bpo_havesubobj) {
1157 1199 zdb_nicenum(bpo->bpo_phys->bpo_comp, comp);
1158 1200 zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp);
1159 1201 (void) printf("\n %s: %llu local blkptrs, %llu subobjs, "
1160 1202 "%s (%s/%s comp)\n",
1161 1203 name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
1162 1204 (u_longlong_t)bpo->bpo_phys->bpo_num_subobjs,
1163 1205 bytes, comp, uncomp);
1164 1206 } else {
1165 1207 (void) printf("\n %s: %llu blkptrs, %s\n",
1166 1208 name, (u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs, bytes);
1167 1209 }
1168 1210
1169 1211 if (dump_opt['d'] < 5)
1170 1212 return;
1171 1213
1172 1214 (void) printf("\n");
1173 1215
1174 1216 (void) bpobj_iterate_nofree(bpo, dump_bpobj_cb, NULL, NULL);
1175 1217 }
1176 1218
1177 1219 static void
1178 1220 dump_deadlist(dsl_deadlist_t *dl)
1179 1221 {
1180 1222 dsl_deadlist_entry_t *dle;
1181 1223 char bytes[32];
1182 1224 char comp[32];
1183 1225 char uncomp[32];
1184 1226
1185 1227 if (dump_opt['d'] < 3)
1186 1228 return;
1187 1229
1188 1230 zdb_nicenum(dl->dl_phys->dl_used, bytes);
1189 1231 zdb_nicenum(dl->dl_phys->dl_comp, comp);
1190 1232 zdb_nicenum(dl->dl_phys->dl_uncomp, uncomp);
1191 1233 (void) printf("\n Deadlist: %s (%s/%s comp)\n",
1192 1234 bytes, comp, uncomp);
1193 1235
1194 1236 if (dump_opt['d'] < 4)
1195 1237 return;
1196 1238
1197 1239 (void) printf("\n");
1198 1240
1199 1241 for (dle = avl_first(&dl->dl_tree); dle;
1200 1242 dle = AVL_NEXT(&dl->dl_tree, dle)) {
1201 1243 (void) printf(" mintxg %llu -> obj %llu\n",
1202 1244 (longlong_t)dle->dle_mintxg,
1203 1245 (longlong_t)dle->dle_bpobj.bpo_object);
1204 1246
1205 1247 if (dump_opt['d'] >= 5)
1206 1248 dump_bpobj(&dle->dle_bpobj, "");
1207 1249 }
1208 1250 }
1209 1251
1210 1252 static avl_tree_t idx_tree;
1211 1253 static avl_tree_t domain_tree;
1212 1254 static boolean_t fuid_table_loaded;
1213 1255 static boolean_t sa_loaded;
1214 1256 sa_attr_type_t *sa_attr_table;
1215 1257
1216 1258 static void
1217 1259 fuid_table_destroy()
1218 1260 {
1219 1261 if (fuid_table_loaded) {
1220 1262 zfs_fuid_table_destroy(&idx_tree, &domain_tree);
1221 1263 fuid_table_loaded = B_FALSE;
1222 1264 }
1223 1265 }
1224 1266
1225 1267 /*
1226 1268 * print uid or gid information.
1227 1269 * For normal POSIX id just the id is printed in decimal format.
1228 1270 * For CIFS files with FUID the fuid is printed in hex followed by
1229 1271 * the doman-rid string.
1230 1272 */
1231 1273 static void
1232 1274 print_idstr(uint64_t id, const char *id_type)
1233 1275 {
1234 1276 if (FUID_INDEX(id)) {
1235 1277 char *domain;
1236 1278
1237 1279 domain = zfs_fuid_idx_domain(&idx_tree, FUID_INDEX(id));
1238 1280 (void) printf("\t%s %llx [%s-%d]\n", id_type,
1239 1281 (u_longlong_t)id, domain, (int)FUID_RID(id));
1240 1282 } else {
1241 1283 (void) printf("\t%s %llu\n", id_type, (u_longlong_t)id);
1242 1284 }
1243 1285
1244 1286 }
1245 1287
1246 1288 static void
1247 1289 dump_uidgid(objset_t *os, uint64_t uid, uint64_t gid)
1248 1290 {
1249 1291 uint32_t uid_idx, gid_idx;
1250 1292
1251 1293 uid_idx = FUID_INDEX(uid);
1252 1294 gid_idx = FUID_INDEX(gid);
1253 1295
1254 1296 /* Load domain table, if not already loaded */
1255 1297 if (!fuid_table_loaded && (uid_idx || gid_idx)) {
1256 1298 uint64_t fuid_obj;
1257 1299
1258 1300 /* first find the fuid object. It lives in the master node */
1259 1301 VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES,
1260 1302 8, 1, &fuid_obj) == 0);
1261 1303 zfs_fuid_avl_tree_create(&idx_tree, &domain_tree);
1262 1304 (void) zfs_fuid_table_load(os, fuid_obj,
1263 1305 &idx_tree, &domain_tree);
1264 1306 fuid_table_loaded = B_TRUE;
1265 1307 }
1266 1308
1267 1309 print_idstr(uid, "uid");
1268 1310 print_idstr(gid, "gid");
1269 1311 }
1270 1312
1271 1313 /*ARGSUSED*/
1272 1314 static void
1273 1315 dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
1274 1316 {
1275 1317 char path[MAXPATHLEN * 2]; /* allow for xattr and failure prefix */
1276 1318 sa_handle_t *hdl;
1277 1319 uint64_t xattr, rdev, gen;
1278 1320 uint64_t uid, gid, mode, fsize, parent, links;
1279 1321 uint64_t pflags;
1280 1322 uint64_t acctm[2], modtm[2], chgtm[2], crtm[2];
1281 1323 time_t z_crtime, z_atime, z_mtime, z_ctime;
1282 1324 sa_bulk_attr_t bulk[12];
1283 1325 int idx = 0;
1284 1326 int error;
1285 1327
1286 1328 if (!sa_loaded) {
1287 1329 uint64_t sa_attrs = 0;
1288 1330 uint64_t version;
1289 1331
1290 1332 VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
1291 1333 8, 1, &version) == 0);
1292 1334 if (version >= ZPL_VERSION_SA) {
1293 1335 VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
1294 1336 8, 1, &sa_attrs) == 0);
1295 1337 }
1296 1338 if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
1297 1339 ZPL_END, &sa_attr_table)) != 0) {
1298 1340 (void) printf("sa_setup failed errno %d, can't "
1299 1341 "display znode contents\n", error);
1300 1342 return;
1301 1343 }
1302 1344 sa_loaded = B_TRUE;
1303 1345 }
1304 1346
1305 1347 if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) {
1306 1348 (void) printf("Failed to get handle for SA znode\n");
1307 1349 return;
1308 1350 }
1309 1351
1310 1352 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_UID], NULL, &uid, 8);
1311 1353 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_GID], NULL, &gid, 8);
1312 1354 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_LINKS], NULL,
1313 1355 &links, 8);
1314 1356 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_GEN], NULL, &gen, 8);
1315 1357 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_MODE], NULL,
1316 1358 &mode, 8);
1317 1359 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_PARENT],
1318 1360 NULL, &parent, 8);
1319 1361 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_SIZE], NULL,
1320 1362 &fsize, 8);
1321 1363 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_ATIME], NULL,
1322 1364 acctm, 16);
1323 1365 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_MTIME], NULL,
1324 1366 modtm, 16);
1325 1367 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_CRTIME], NULL,
1326 1368 crtm, 16);
1327 1369 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_CTIME], NULL,
1328 1370 chgtm, 16);
1329 1371 SA_ADD_BULK_ATTR(bulk, idx, sa_attr_table[ZPL_FLAGS], NULL,
1330 1372 &pflags, 8);
1331 1373
1332 1374 if (sa_bulk_lookup(hdl, bulk, idx)) {
1333 1375 (void) sa_handle_destroy(hdl);
1334 1376 return;
1335 1377 }
1336 1378
1337 1379 error = zfs_obj_to_path(os, object, path, sizeof (path));
1338 1380 if (error != 0) {
1339 1381 (void) snprintf(path, sizeof (path), "\?\?\?<object#%llu>",
1340 1382 (u_longlong_t)object);
1341 1383 }
1342 1384 if (dump_opt['d'] < 3) {
1343 1385 (void) printf("\t%s\n", path);
1344 1386 (void) sa_handle_destroy(hdl);
1345 1387 return;
1346 1388 }
1347 1389
1348 1390 z_crtime = (time_t)crtm[0];
1349 1391 z_atime = (time_t)acctm[0];
1350 1392 z_mtime = (time_t)modtm[0];
1351 1393 z_ctime = (time_t)chgtm[0];
1352 1394
1353 1395 (void) printf("\tpath %s\n", path);
1354 1396 dump_uidgid(os, uid, gid);
1355 1397 (void) printf("\tatime %s", ctime(&z_atime));
1356 1398 (void) printf("\tmtime %s", ctime(&z_mtime));
1357 1399 (void) printf("\tctime %s", ctime(&z_ctime));
1358 1400 (void) printf("\tcrtime %s", ctime(&z_crtime));
1359 1401 (void) printf("\tgen %llu\n", (u_longlong_t)gen);
1360 1402 (void) printf("\tmode %llo\n", (u_longlong_t)mode);
1361 1403 (void) printf("\tsize %llu\n", (u_longlong_t)fsize);
1362 1404 (void) printf("\tparent %llu\n", (u_longlong_t)parent);
1363 1405 (void) printf("\tlinks %llu\n", (u_longlong_t)links);
1364 1406 (void) printf("\tpflags %llx\n", (u_longlong_t)pflags);
1365 1407 if (sa_lookup(hdl, sa_attr_table[ZPL_XATTR], &xattr,
1366 1408 sizeof (uint64_t)) == 0)
1367 1409 (void) printf("\txattr %llu\n", (u_longlong_t)xattr);
1368 1410 if (sa_lookup(hdl, sa_attr_table[ZPL_RDEV], &rdev,
1369 1411 sizeof (uint64_t)) == 0)
1370 1412 (void) printf("\trdev 0x%016llx\n", (u_longlong_t)rdev);
1371 1413 sa_handle_destroy(hdl);
1372 1414 }
1373 1415
1374 1416 /*ARGSUSED*/
1375 1417 static void
1376 1418 dump_acl(objset_t *os, uint64_t object, void *data, size_t size)
1377 1419 {
1378 1420 }
1379 1421
1380 1422 /*ARGSUSED*/
1381 1423 static void
1382 1424 dump_dmu_objset(objset_t *os, uint64_t object, void *data, size_t size)
1383 1425 {
1384 1426 }
1385 1427
1386 1428 static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
1387 1429 dump_none, /* unallocated */
1388 1430 dump_zap, /* object directory */
1389 1431 dump_uint64, /* object array */
1390 1432 dump_none, /* packed nvlist */
1391 1433 dump_packed_nvlist, /* packed nvlist size */
1392 1434 dump_none, /* bplist */
1393 1435 dump_none, /* bplist header */
1394 1436 dump_none, /* SPA space map header */
1395 1437 dump_none, /* SPA space map */
1396 1438 dump_none, /* ZIL intent log */
1397 1439 dump_dnode, /* DMU dnode */
1398 1440 dump_dmu_objset, /* DMU objset */
1399 1441 dump_dsl_dir, /* DSL directory */
1400 1442 dump_zap, /* DSL directory child map */
1401 1443 dump_zap, /* DSL dataset snap map */
1402 1444 dump_zap, /* DSL props */
1403 1445 dump_dsl_dataset, /* DSL dataset */
1404 1446 dump_znode, /* ZFS znode */
1405 1447 dump_acl, /* ZFS V0 ACL */
1406 1448 dump_uint8, /* ZFS plain file */
1407 1449 dump_zpldir, /* ZFS directory */
1408 1450 dump_zap, /* ZFS master node */
1409 1451 dump_zap, /* ZFS delete queue */
1410 1452 dump_uint8, /* zvol object */
1411 1453 dump_zap, /* zvol prop */
1412 1454 dump_uint8, /* other uint8[] */
1413 1455 dump_uint64, /* other uint64[] */
1414 1456 dump_zap, /* other ZAP */
1415 1457 dump_zap, /* persistent error log */
1416 1458 dump_uint8, /* SPA history */
1417 1459 dump_uint64, /* SPA history offsets */
1418 1460 dump_zap, /* Pool properties */
1419 1461 dump_zap, /* DSL permissions */
1420 1462 dump_acl, /* ZFS ACL */
1421 1463 dump_uint8, /* ZFS SYSACL */
1422 1464 dump_none, /* FUID nvlist */
1423 1465 dump_packed_nvlist, /* FUID nvlist size */
1424 1466 dump_zap, /* DSL dataset next clones */
1425 1467 dump_zap, /* DSL scrub queue */
1426 1468 dump_zap, /* ZFS user/group used */
1427 1469 dump_zap, /* ZFS user/group quota */
1428 1470 dump_zap, /* snapshot refcount tags */
1429 1471 dump_ddt_zap, /* DDT ZAP object */
1430 1472 dump_zap, /* DDT statistics */
1431 1473 dump_znode, /* SA object */
1432 1474 dump_zap, /* SA Master Node */
1433 1475 dump_sa_attrs, /* SA attribute registration */
1434 1476 dump_sa_layouts, /* SA attribute layouts */
1435 1477 dump_zap, /* DSL scrub translations */
1436 1478 dump_none, /* fake dedup BP */
1437 1479 dump_zap, /* deadlist */
1438 1480 dump_none, /* deadlist hdr */
1439 1481 dump_zap, /* dsl clones */
1440 1482 dump_none, /* bpobj subobjs */
1441 1483 dump_unknown, /* Unknown type, must be last */
1442 1484 };
1443 1485
1444 1486 static void
1445 1487 dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
1446 1488 {
1447 1489 dmu_buf_t *db = NULL;
1448 1490 dmu_object_info_t doi;
1449 1491 dnode_t *dn;
1450 1492 void *bonus = NULL;
1451 1493 size_t bsize = 0;
1452 1494 char iblk[32], dblk[32], lsize[32], asize[32], fill[32];
1453 1495 char bonus_size[32];
1454 1496 char aux[50];
1455 1497 int error;
1456 1498
1457 1499 if (*print_header) {
1458 1500 (void) printf("\n%10s %3s %5s %5s %5s %5s %6s %s\n",
1459 1501 "Object", "lvl", "iblk", "dblk", "dsize", "lsize",
1460 1502 "%full", "type");
1461 1503 *print_header = 0;
1462 1504 }
1463 1505
1464 1506 if (object == 0) {
1465 1507 dn = DMU_META_DNODE(os);
1466 1508 } else {
1467 1509 error = dmu_bonus_hold(os, object, FTAG, &db);
1468 1510 if (error)
1469 1511 fatal("dmu_bonus_hold(%llu) failed, errno %u",
1470 1512 object, error);
1471 1513 bonus = db->db_data;
1472 1514 bsize = db->db_size;
1473 1515 dn = DB_DNODE((dmu_buf_impl_t *)db);
1474 1516 }
1475 1517 dmu_object_info_from_dnode(dn, &doi);
1476 1518
1477 1519 zdb_nicenum(doi.doi_metadata_block_size, iblk);
1478 1520 zdb_nicenum(doi.doi_data_block_size, dblk);
1479 1521 zdb_nicenum(doi.doi_max_offset, lsize);
1480 1522 zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize);
1481 1523 zdb_nicenum(doi.doi_bonus_size, bonus_size);
1482 1524 (void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count *
1483 1525 doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) /
1484 1526 doi.doi_max_offset);
1485 1527
1486 1528 aux[0] = '\0';
1487 1529
1488 1530 if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) {
1489 1531 (void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)",
1490 1532 ZDB_CHECKSUM_NAME(doi.doi_checksum));
1491 1533 }
1492 1534
1493 1535 if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) {
1494 1536 (void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)",
1495 1537 ZDB_COMPRESS_NAME(doi.doi_compress));
1496 1538 }
1497 1539
1498 1540 (void) printf("%10lld %3u %5s %5s %5s %5s %6s %s%s\n",
1499 1541 (u_longlong_t)object, doi.doi_indirection, iblk, dblk,
1500 1542 asize, lsize, fill, ZDB_OT_NAME(doi.doi_type), aux);
1501 1543
1502 1544 if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
1503 1545 (void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n",
1504 1546 "", "", "", "", "", bonus_size, "bonus",
1505 1547 ZDB_OT_NAME(doi.doi_bonus_type));
1506 1548 }
1507 1549
1508 1550 if (verbosity >= 4) {
1509 1551 (void) printf("\tdnode flags: %s%s%s\n",
1510 1552 (dn->dn_phys->dn_flags & DNODE_FLAG_USED_BYTES) ?
1511 1553 "USED_BYTES " : "",
1512 1554 (dn->dn_phys->dn_flags & DNODE_FLAG_USERUSED_ACCOUNTED) ?
1513 1555 "USERUSED_ACCOUNTED " : "",
1514 1556 (dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR) ?
1515 1557 "SPILL_BLKPTR" : "");
1516 1558 (void) printf("\tdnode maxblkid: %llu\n",
1517 1559 (longlong_t)dn->dn_phys->dn_maxblkid);
1518 1560
1519 1561 object_viewer[ZDB_OT_TYPE(doi.doi_bonus_type)](os, object,
1520 1562 bonus, bsize);
1521 1563 object_viewer[ZDB_OT_TYPE(doi.doi_type)](os, object, NULL, 0);
1522 1564 *print_header = 1;
1523 1565 }
1524 1566
1525 1567 if (verbosity >= 5)
1526 1568 dump_indirect(dn);
1527 1569
1528 1570 if (verbosity >= 5) {
1529 1571 /*
1530 1572 * Report the list of segments that comprise the object.
1531 1573 */
1532 1574 uint64_t start = 0;
1533 1575 uint64_t end;
1534 1576 uint64_t blkfill = 1;
1535 1577 int minlvl = 1;
1536 1578
1537 1579 if (dn->dn_type == DMU_OT_DNODE) {
1538 1580 minlvl = 0;
1539 1581 blkfill = DNODES_PER_BLOCK;
1540 1582 }
1541 1583
1542 1584 for (;;) {
1543 1585 char segsize[32];
1544 1586 error = dnode_next_offset(dn,
1545 1587 0, &start, minlvl, blkfill, 0);
1546 1588 if (error)
1547 1589 break;
1548 1590 end = start;
1549 1591 error = dnode_next_offset(dn,
1550 1592 DNODE_FIND_HOLE, &end, minlvl, blkfill, 0);
1551 1593 zdb_nicenum(end - start, segsize);
1552 1594 (void) printf("\t\tsegment [%016llx, %016llx)"
1553 1595 " size %5s\n", (u_longlong_t)start,
1554 1596 (u_longlong_t)end, segsize);
1555 1597 if (error)
1556 1598 break;
1557 1599 start = end;
1558 1600 }
1559 1601 }
1560 1602
1561 1603 if (db != NULL)
1562 1604 dmu_buf_rele(db, FTAG);
1563 1605 }
1564 1606
1565 1607 static char *objset_types[DMU_OST_NUMTYPES] = {
1566 1608 "NONE", "META", "ZPL", "ZVOL", "OTHER", "ANY" };
1567 1609
1568 1610 static void
1569 1611 dump_dir(objset_t *os)
1570 1612 {
1571 1613 dmu_objset_stats_t dds;
1572 1614 uint64_t object, object_count;
1573 1615 uint64_t refdbytes, usedobjs, scratch;
1574 1616 char numbuf[32];
1575 1617 char blkbuf[BP_SPRINTF_LEN + 20];
1576 1618 char osname[MAXNAMELEN];
1577 1619 char *type = "UNKNOWN";
1578 1620 int verbosity = dump_opt['d'];
1579 1621 int print_header = 1;
1580 1622 int i, error;
1581 1623
1582 1624 dmu_objset_fast_stat(os, &dds);
1583 1625
1584 1626 if (dds.dds_type < DMU_OST_NUMTYPES)
1585 1627 type = objset_types[dds.dds_type];
1586 1628
1587 1629 if (dds.dds_type == DMU_OST_META) {
1588 1630 dds.dds_creation_txg = TXG_INITIAL;
1589 1631 usedobjs = os->os_rootbp->blk_fill;
1590 1632 refdbytes = os->os_spa->spa_dsl_pool->
1591 1633 dp_mos_dir->dd_phys->dd_used_bytes;
1592 1634 } else {
1593 1635 dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch);
1594 1636 }
1595 1637
1596 1638 ASSERT3U(usedobjs, ==, os->os_rootbp->blk_fill);
1597 1639
1598 1640 zdb_nicenum(refdbytes, numbuf);
1599 1641
1600 1642 if (verbosity >= 4) {
1601 1643 (void) sprintf(blkbuf, ", rootbp ");
1602 1644 (void) sprintf_blkptr(blkbuf + strlen(blkbuf), os->os_rootbp);
1603 1645 } else {
1604 1646 blkbuf[0] = '\0';
1605 1647 }
1606 1648
1607 1649 dmu_objset_name(os, osname);
1608 1650
1609 1651 (void) printf("Dataset %s [%s], ID %llu, cr_txg %llu, "
1610 1652 "%s, %llu objects%s\n",
1611 1653 osname, type, (u_longlong_t)dmu_objset_id(os),
1612 1654 (u_longlong_t)dds.dds_creation_txg,
1613 1655 numbuf, (u_longlong_t)usedobjs, blkbuf);
1614 1656
1615 1657 if (zopt_objects != 0) {
1616 1658 for (i = 0; i < zopt_objects; i++)
1617 1659 dump_object(os, zopt_object[i], verbosity,
1618 1660 &print_header);
1619 1661 (void) printf("\n");
1620 1662 return;
1621 1663 }
1622 1664
1623 1665 if (dump_opt['i'] != 0 || verbosity >= 2)
1624 1666 dump_intent_log(dmu_objset_zil(os));
1625 1667
1626 1668 if (dmu_objset_ds(os) != NULL)
1627 1669 dump_deadlist(&dmu_objset_ds(os)->ds_deadlist);
1628 1670
1629 1671 if (verbosity < 2)
1630 1672 return;
1631 1673
1632 1674 if (os->os_rootbp->blk_birth == 0)
1633 1675 return;
1634 1676
1635 1677 dump_object(os, 0, verbosity, &print_header);
1636 1678 object_count = 0;
1637 1679 if (DMU_USERUSED_DNODE(os) != NULL &&
1638 1680 DMU_USERUSED_DNODE(os)->dn_type != 0) {
1639 1681 dump_object(os, DMU_USERUSED_OBJECT, verbosity, &print_header);
1640 1682 dump_object(os, DMU_GROUPUSED_OBJECT, verbosity, &print_header);
1641 1683 }
1642 1684
1643 1685 object = 0;
1644 1686 while ((error = dmu_object_next(os, &object, B_FALSE, 0)) == 0) {
1645 1687 dump_object(os, object, verbosity, &print_header);
1646 1688 object_count++;
1647 1689 }
1648 1690
1649 1691 ASSERT3U(object_count, ==, usedobjs);
1650 1692
1651 1693 (void) printf("\n");
1652 1694
1653 1695 if (error != ESRCH) {
1654 1696 (void) fprintf(stderr, "dmu_object_next() = %d\n", error);
1655 1697 abort();
1656 1698 }
1657 1699 }
1658 1700
1659 1701 static void
1660 1702 dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
1661 1703 {
1662 1704 time_t timestamp = ub->ub_timestamp;
1663 1705
1664 1706 (void) printf(header ? header : "");
1665 1707 (void) printf("\tmagic = %016llx\n", (u_longlong_t)ub->ub_magic);
1666 1708 (void) printf("\tversion = %llu\n", (u_longlong_t)ub->ub_version);
1667 1709 (void) printf("\ttxg = %llu\n", (u_longlong_t)ub->ub_txg);
1668 1710 (void) printf("\tguid_sum = %llu\n", (u_longlong_t)ub->ub_guid_sum);
1669 1711 (void) printf("\ttimestamp = %llu UTC = %s",
1670 1712 (u_longlong_t)ub->ub_timestamp, asctime(localtime(×tamp)));
1671 1713 if (dump_opt['u'] >= 3) {
1672 1714 char blkbuf[BP_SPRINTF_LEN];
1673 1715 sprintf_blkptr(blkbuf, &ub->ub_rootbp);
1674 1716 (void) printf("\trootbp = %s\n", blkbuf);
1675 1717 }
1676 1718 (void) printf(footer ? footer : "");
1677 1719 }
1678 1720
1679 1721 static void
1680 1722 dump_config(spa_t *spa)
1681 1723 {
1682 1724 dmu_buf_t *db;
1683 1725 size_t nvsize = 0;
1684 1726 int error = 0;
1685 1727
1686 1728
1687 1729 error = dmu_bonus_hold(spa->spa_meta_objset,
1688 1730 spa->spa_config_object, FTAG, &db);
1689 1731
1690 1732 if (error == 0) {
1691 1733 nvsize = *(uint64_t *)db->db_data;
1692 1734 dmu_buf_rele(db, FTAG);
1693 1735
1694 1736 (void) printf("\nMOS Configuration:\n");
1695 1737 dump_packed_nvlist(spa->spa_meta_objset,
1696 1738 spa->spa_config_object, (void *)&nvsize, 1);
1697 1739 } else {
1698 1740 (void) fprintf(stderr, "dmu_bonus_hold(%llu) failed, errno %d",
1699 1741 (u_longlong_t)spa->spa_config_object, error);
1700 1742 }
1701 1743 }
1702 1744
1703 1745 static void
1704 1746 dump_cachefile(const char *cachefile)
1705 1747 {
1706 1748 int fd;
1707 1749 struct stat64 statbuf;
1708 1750 char *buf;
1709 1751 nvlist_t *config;
1710 1752
1711 1753 if ((fd = open64(cachefile, O_RDONLY)) < 0) {
1712 1754 (void) printf("cannot open '%s': %s\n", cachefile,
1713 1755 strerror(errno));
1714 1756 exit(1);
1715 1757 }
1716 1758
1717 1759 if (fstat64(fd, &statbuf) != 0) {
1718 1760 (void) printf("failed to stat '%s': %s\n", cachefile,
1719 1761 strerror(errno));
1720 1762 exit(1);
1721 1763 }
1722 1764
1723 1765 if ((buf = malloc(statbuf.st_size)) == NULL) {
1724 1766 (void) fprintf(stderr, "failed to allocate %llu bytes\n",
1725 1767 (u_longlong_t)statbuf.st_size);
1726 1768 exit(1);
1727 1769 }
1728 1770
1729 1771 if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
1730 1772 (void) fprintf(stderr, "failed to read %llu bytes\n",
1731 1773 (u_longlong_t)statbuf.st_size);
1732 1774 exit(1);
1733 1775 }
1734 1776
1735 1777 (void) close(fd);
1736 1778
1737 1779 if (nvlist_unpack(buf, statbuf.st_size, &config, 0) != 0) {
1738 1780 (void) fprintf(stderr, "failed to unpack nvlist\n");
1739 1781 exit(1);
1740 1782 }
1741 1783
1742 1784 free(buf);
1743 1785
1744 1786 dump_nvlist(config, 0);
1745 1787
1746 1788 nvlist_free(config);
1747 1789 }
1748 1790
1749 1791 #define ZDB_MAX_UB_HEADER_SIZE 32
1750 1792
1751 1793 static void
1752 1794 dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift)
1753 1795 {
1754 1796 vdev_t vd;
1755 1797 vdev_t *vdp = &vd;
1756 1798 char header[ZDB_MAX_UB_HEADER_SIZE];
1757 1799
1758 1800 vd.vdev_ashift = ashift;
1759 1801 vdp->vdev_top = vdp;
1760 1802
1761 1803 for (int i = 0; i < VDEV_UBERBLOCK_COUNT(vdp); i++) {
1762 1804 uint64_t uoff = VDEV_UBERBLOCK_OFFSET(vdp, i);
1763 1805 uberblock_t *ub = (void *)((char *)lbl + uoff);
1764 1806
1765 1807 if (uberblock_verify(ub))
1766 1808 continue;
1767 1809 (void) snprintf(header, ZDB_MAX_UB_HEADER_SIZE,
1768 1810 "Uberblock[%d]\n", i);
1769 1811 dump_uberblock(ub, header, "");
1770 1812 }
1771 1813 }
1772 1814
1773 1815 static void
1774 1816 dump_label(const char *dev)
1775 1817 {
1776 1818 int fd;
1777 1819 vdev_label_t label;
1778 1820 char *path, *buf = label.vl_vdev_phys.vp_nvlist;
1779 1821 size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
1780 1822 struct stat64 statbuf;
1781 1823 uint64_t psize, ashift;
1782 1824 int len = strlen(dev) + 1;
1783 1825
1784 1826 if (strncmp(dev, "/dev/dsk/", 9) == 0) {
1785 1827 len++;
1786 1828 path = malloc(len);
1787 1829 (void) snprintf(path, len, "%s%s", "/dev/rdsk/", dev + 9);
1788 1830 } else {
1789 1831 path = strdup(dev);
1790 1832 }
1791 1833
1792 1834 if ((fd = open64(path, O_RDONLY)) < 0) {
1793 1835 (void) printf("cannot open '%s': %s\n", path, strerror(errno));
1794 1836 free(path);
1795 1837 exit(1);
1796 1838 }
1797 1839
1798 1840 if (fstat64(fd, &statbuf) != 0) {
1799 1841 (void) printf("failed to stat '%s': %s\n", path,
1800 1842 strerror(errno));
1801 1843 free(path);
1802 1844 (void) close(fd);
1803 1845 exit(1);
1804 1846 }
1805 1847
1806 1848 if (S_ISBLK(statbuf.st_mode)) {
1807 1849 (void) printf("cannot use '%s': character device required\n",
1808 1850 path);
1809 1851 free(path);
1810 1852 (void) close(fd);
1811 1853 exit(1);
1812 1854 }
1813 1855
1814 1856 psize = statbuf.st_size;
1815 1857 psize = P2ALIGN(psize, (uint64_t)sizeof (vdev_label_t));
1816 1858
1817 1859 for (int l = 0; l < VDEV_LABELS; l++) {
1818 1860 nvlist_t *config = NULL;
1819 1861
1820 1862 (void) printf("--------------------------------------------\n");
1821 1863 (void) printf("LABEL %d\n", l);
1822 1864 (void) printf("--------------------------------------------\n");
1823 1865
1824 1866 if (pread64(fd, &label, sizeof (label),
1825 1867 vdev_label_offset(psize, l, 0)) != sizeof (label)) {
1826 1868 (void) printf("failed to read label %d\n", l);
1827 1869 continue;
1828 1870 }
1829 1871
1830 1872 if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
1831 1873 (void) printf("failed to unpack label %d\n", l);
1832 1874 ashift = SPA_MINBLOCKSHIFT;
1833 1875 } else {
1834 1876 nvlist_t *vdev_tree = NULL;
1835 1877
1836 1878 dump_nvlist(config, 4);
1837 1879 if ((nvlist_lookup_nvlist(config,
1838 1880 ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) ||
1839 1881 (nvlist_lookup_uint64(vdev_tree,
1840 1882 ZPOOL_CONFIG_ASHIFT, &ashift) != 0))
1841 1883 ashift = SPA_MINBLOCKSHIFT;
1842 1884 nvlist_free(config);
1843 1885 }
1844 1886 if (dump_opt['u'])
1845 1887 dump_label_uberblocks(&label, ashift);
1846 1888 }
1847 1889
1848 1890 free(path);
1849 1891 (void) close(fd);
1850 1892 }
1851 1893
1852 1894 /*ARGSUSED*/
1853 1895 static int
1854 1896 dump_one_dir(const char *dsname, void *arg)
1855 1897 {
1856 1898 int error;
1857 1899 objset_t *os;
1858 1900
1859 1901 error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
1860 1902 if (error) {
1861 1903 (void) printf("Could not open %s, error %d\n", dsname, error);
1862 1904 return (0);
1863 1905 }
1864 1906 dump_dir(os);
1865 1907 dmu_objset_disown(os, FTAG);
1866 1908 fuid_table_destroy();
1867 1909 sa_loaded = B_FALSE;
1868 1910 return (0);
1869 1911 }
1870 1912
1871 1913 /*
1872 1914 * Block statistics.
1873 1915 */
1874 1916 typedef struct zdb_blkstats {
1875 1917 uint64_t zb_asize;
|
↓ open down ↓ |
731 lines elided |
↑ open up ↑ |
1876 1918 uint64_t zb_lsize;
1877 1919 uint64_t zb_psize;
1878 1920 uint64_t zb_count;
1879 1921 } zdb_blkstats_t;
1880 1922
1881 1923 /*
1882 1924 * Extended object types to report deferred frees and dedup auto-ditto blocks.
1883 1925 */
1884 1926 #define ZDB_OT_DEFERRED (DMU_OT_NUMTYPES + 0)
1885 1927 #define ZDB_OT_DITTO (DMU_OT_NUMTYPES + 1)
1886 -#define ZDB_OT_TOTAL (DMU_OT_NUMTYPES + 2)
1928 +#define ZDB_OT_OTHER (DMU_OT_NUMTYPES + 2)
1929 +#define ZDB_OT_TOTAL (DMU_OT_NUMTYPES + 3)
1887 1930
1888 1931 static char *zdb_ot_extname[] = {
1889 1932 "deferred free",
1890 1933 "dedup ditto",
1934 + "other",
1891 1935 "Total",
1892 1936 };
1893 1937
1894 1938 #define ZB_TOTAL DN_MAX_LEVELS
1895 1939
1896 1940 typedef struct zdb_cb {
1897 1941 zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1];
1898 1942 uint64_t zcb_dedup_asize;
1899 1943 uint64_t zcb_dedup_blocks;
1900 1944 uint64_t zcb_errors[256];
1901 1945 int zcb_readfails;
1902 1946 int zcb_haderrors;
1903 1947 spa_t *zcb_spa;
1904 1948 } zdb_cb_t;
1905 1949
1906 1950 static void
1907 1951 zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
1908 1952 dmu_object_type_t type)
1909 1953 {
1910 1954 uint64_t refcnt = 0;
1911 1955
1912 1956 ASSERT(type < ZDB_OT_TOTAL);
1913 1957
1914 1958 if (zilog && zil_bp_tree_add(zilog, bp) != 0)
1915 1959 return;
1916 1960
1917 1961 for (int i = 0; i < 4; i++) {
1918 1962 int l = (i < 2) ? BP_GET_LEVEL(bp) : ZB_TOTAL;
1919 1963 int t = (i & 1) ? type : ZDB_OT_TOTAL;
1920 1964 zdb_blkstats_t *zb = &zcb->zcb_type[l][t];
1921 1965
1922 1966 zb->zb_asize += BP_GET_ASIZE(bp);
1923 1967 zb->zb_lsize += BP_GET_LSIZE(bp);
1924 1968 zb->zb_psize += BP_GET_PSIZE(bp);
1925 1969 zb->zb_count++;
1926 1970 }
1927 1971
1928 1972 if (dump_opt['L'])
1929 1973 return;
1930 1974
1931 1975 if (BP_GET_DEDUP(bp)) {
1932 1976 ddt_t *ddt;
1933 1977 ddt_entry_t *dde;
1934 1978
1935 1979 ddt = ddt_select(zcb->zcb_spa, bp);
1936 1980 ddt_enter(ddt);
1937 1981 dde = ddt_lookup(ddt, bp, B_FALSE);
1938 1982
1939 1983 if (dde == NULL) {
1940 1984 refcnt = 0;
1941 1985 } else {
1942 1986 ddt_phys_t *ddp = ddt_phys_select(dde, bp);
1943 1987 ddt_phys_decref(ddp);
1944 1988 refcnt = ddp->ddp_refcnt;
1945 1989 if (ddt_phys_total_refcnt(dde) == 0)
1946 1990 ddt_remove(ddt, dde);
1947 1991 }
1948 1992 ddt_exit(ddt);
1949 1993 }
1950 1994
1951 1995 VERIFY3U(zio_wait(zio_claim(NULL, zcb->zcb_spa,
1952 1996 refcnt ? 0 : spa_first_txg(zcb->zcb_spa),
1953 1997 bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0);
1954 1998 }
1955 1999
1956 2000 /* ARGSUSED */
1957 2001 static int
1958 2002 zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, arc_buf_t *pbuf,
1959 2003 const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
1960 2004 {
|
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
1961 2005 zdb_cb_t *zcb = arg;
1962 2006 char blkbuf[BP_SPRINTF_LEN];
1963 2007 dmu_object_type_t type;
1964 2008 boolean_t is_metadata;
1965 2009
1966 2010 if (bp == NULL)
1967 2011 return (0);
1968 2012
1969 2013 type = BP_GET_TYPE(bp);
1970 2014
1971 - zdb_count_block(zcb, zilog, bp, type);
2015 + zdb_count_block(zcb, zilog, bp,
2016 + (type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type);
1972 2017
1973 - is_metadata = (BP_GET_LEVEL(bp) != 0 || dmu_ot[type].ot_metadata);
2018 + is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type));
1974 2019
1975 2020 if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) {
1976 2021 int ioerr;
1977 2022 size_t size = BP_GET_PSIZE(bp);
1978 2023 void *data = malloc(size);
1979 2024 int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;
1980 2025
1981 2026 /* If it's an intent log block, failure is expected. */
1982 2027 if (zb->zb_level == ZB_ZIL_LEVEL)
1983 2028 flags |= ZIO_FLAG_SPECULATIVE;
1984 2029
1985 2030 ioerr = zio_wait(zio_read(NULL, spa, bp, data, size,
1986 2031 NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb));
1987 2032
1988 2033 free(data);
1989 2034
1990 2035 if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) {
1991 2036 zcb->zcb_haderrors = 1;
1992 2037 zcb->zcb_errors[ioerr]++;
1993 2038
1994 2039 if (dump_opt['b'] >= 2)
1995 2040 sprintf_blkptr(blkbuf, bp);
1996 2041 else
1997 2042 blkbuf[0] = '\0';
1998 2043
1999 2044 (void) printf("zdb_blkptr_cb: "
2000 2045 "Got error %d reading "
2001 2046 "<%llu, %llu, %lld, %llx> %s -- skipping\n",
2002 2047 ioerr,
2003 2048 (u_longlong_t)zb->zb_objset,
2004 2049 (u_longlong_t)zb->zb_object,
2005 2050 (u_longlong_t)zb->zb_level,
2006 2051 (u_longlong_t)zb->zb_blkid,
2007 2052 blkbuf);
2008 2053 }
2009 2054 }
2010 2055
2011 2056 zcb->zcb_readfails = 0;
2012 2057
2013 2058 if (dump_opt['b'] >= 4) {
2014 2059 sprintf_blkptr(blkbuf, bp);
2015 2060 (void) printf("objset %llu object %llu "
2016 2061 "level %lld offset 0x%llx %s\n",
2017 2062 (u_longlong_t)zb->zb_objset,
2018 2063 (u_longlong_t)zb->zb_object,
2019 2064 (longlong_t)zb->zb_level,
2020 2065 (u_longlong_t)blkid2offset(dnp, bp, zb),
2021 2066 blkbuf);
2022 2067 }
2023 2068
2024 2069 return (0);
2025 2070 }
2026 2071
2027 2072 static void
2028 2073 zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
2029 2074 {
2030 2075 vdev_t *vd = sm->sm_ppd;
2031 2076
2032 2077 (void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
2033 2078 (u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
2034 2079 }
2035 2080
2036 2081 /* ARGSUSED */
2037 2082 static void
2038 2083 zdb_space_map_load(space_map_t *sm)
2039 2084 {
2040 2085 }
2041 2086
2042 2087 static void
2043 2088 zdb_space_map_unload(space_map_t *sm)
2044 2089 {
2045 2090 space_map_vacate(sm, zdb_leak, sm);
2046 2091 }
2047 2092
2048 2093 /* ARGSUSED */
2049 2094 static void
2050 2095 zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
2051 2096 {
2052 2097 }
2053 2098
2054 2099 static space_map_ops_t zdb_space_map_ops = {
2055 2100 zdb_space_map_load,
2056 2101 zdb_space_map_unload,
2057 2102 NULL, /* alloc */
2058 2103 zdb_space_map_claim,
2059 2104 NULL, /* free */
2060 2105 NULL /* maxsize */
2061 2106 };
2062 2107
2063 2108 static void
2064 2109 zdb_ddt_leak_init(spa_t *spa, zdb_cb_t *zcb)
2065 2110 {
2066 2111 ddt_bookmark_t ddb = { 0 };
2067 2112 ddt_entry_t dde;
2068 2113 int error;
2069 2114
2070 2115 while ((error = ddt_walk(spa, &ddb, &dde)) == 0) {
2071 2116 blkptr_t blk;
2072 2117 ddt_phys_t *ddp = dde.dde_phys;
2073 2118
2074 2119 if (ddb.ddb_class == DDT_CLASS_UNIQUE)
2075 2120 return;
2076 2121
2077 2122 ASSERT(ddt_phys_total_refcnt(&dde) > 1);
2078 2123
2079 2124 for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
2080 2125 if (ddp->ddp_phys_birth == 0)
2081 2126 continue;
2082 2127 ddt_bp_create(ddb.ddb_checksum,
2083 2128 &dde.dde_key, ddp, &blk);
2084 2129 if (p == DDT_PHYS_DITTO) {
2085 2130 zdb_count_block(zcb, NULL, &blk, ZDB_OT_DITTO);
2086 2131 } else {
2087 2132 zcb->zcb_dedup_asize +=
2088 2133 BP_GET_ASIZE(&blk) * (ddp->ddp_refcnt - 1);
2089 2134 zcb->zcb_dedup_blocks++;
2090 2135 }
2091 2136 }
2092 2137 if (!dump_opt['L']) {
2093 2138 ddt_t *ddt = spa->spa_ddt[ddb.ddb_checksum];
2094 2139 ddt_enter(ddt);
2095 2140 VERIFY(ddt_lookup(ddt, &blk, B_TRUE) != NULL);
2096 2141 ddt_exit(ddt);
2097 2142 }
2098 2143 }
2099 2144
2100 2145 ASSERT(error == ENOENT);
2101 2146 }
2102 2147
2103 2148 static void
2104 2149 zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
2105 2150 {
2106 2151 zcb->zcb_spa = spa;
2107 2152
2108 2153 if (!dump_opt['L']) {
2109 2154 vdev_t *rvd = spa->spa_root_vdev;
2110 2155 for (int c = 0; c < rvd->vdev_children; c++) {
2111 2156 vdev_t *vd = rvd->vdev_child[c];
2112 2157 for (int m = 0; m < vd->vdev_ms_count; m++) {
2113 2158 metaslab_t *msp = vd->vdev_ms[m];
2114 2159 mutex_enter(&msp->ms_lock);
2115 2160 space_map_unload(&msp->ms_map);
2116 2161 VERIFY(space_map_load(&msp->ms_map,
2117 2162 &zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
2118 2163 spa->spa_meta_objset) == 0);
2119 2164 msp->ms_map.sm_ppd = vd;
2120 2165 mutex_exit(&msp->ms_lock);
2121 2166 }
2122 2167 }
2123 2168 }
2124 2169
2125 2170 spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2126 2171
2127 2172 zdb_ddt_leak_init(spa, zcb);
2128 2173
2129 2174 spa_config_exit(spa, SCL_CONFIG, FTAG);
2130 2175 }
2131 2176
2132 2177 static void
2133 2178 zdb_leak_fini(spa_t *spa)
2134 2179 {
2135 2180 if (!dump_opt['L']) {
2136 2181 vdev_t *rvd = spa->spa_root_vdev;
2137 2182 for (int c = 0; c < rvd->vdev_children; c++) {
2138 2183 vdev_t *vd = rvd->vdev_child[c];
2139 2184 for (int m = 0; m < vd->vdev_ms_count; m++) {
2140 2185 metaslab_t *msp = vd->vdev_ms[m];
2141 2186 mutex_enter(&msp->ms_lock);
2142 2187 space_map_unload(&msp->ms_map);
2143 2188 mutex_exit(&msp->ms_lock);
2144 2189 }
2145 2190 }
2146 2191 }
2147 2192 }
2148 2193
2149 2194 /* ARGSUSED */
2150 2195 static int
2151 2196 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
2152 2197 {
2153 2198 zdb_cb_t *zcb = arg;
2154 2199
2155 2200 if (dump_opt['b'] >= 4) {
2156 2201 char blkbuf[BP_SPRINTF_LEN];
2157 2202 sprintf_blkptr(blkbuf, bp);
2158 2203 (void) printf("[%s] %s\n",
2159 2204 "deferred free", blkbuf);
2160 2205 }
2161 2206 zdb_count_block(zcb, NULL, bp, ZDB_OT_DEFERRED);
2162 2207 return (0);
2163 2208 }
2164 2209
2165 2210 static int
2166 2211 dump_block_stats(spa_t *spa)
2167 2212 {
2168 2213 zdb_cb_t zcb = { 0 };
2169 2214 zdb_blkstats_t *zb, *tzb;
2170 2215 uint64_t norm_alloc, norm_space, total_alloc, total_found;
2171 2216 int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD;
2172 2217 int leaks = 0;
2173 2218
2174 2219 (void) printf("\nTraversing all blocks %s%s%s%s%s...\n",
2175 2220 (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
2176 2221 (dump_opt['c'] == 1) ? "metadata " : "",
2177 2222 dump_opt['c'] ? "checksums " : "",
2178 2223 (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
2179 2224 !dump_opt['L'] ? "nothing leaked " : "");
2180 2225
2181 2226 /*
2182 2227 * Load all space maps as SM_ALLOC maps, then traverse the pool
2183 2228 * claiming each block we discover. If the pool is perfectly
2184 2229 * consistent, the space maps will be empty when we're done.
2185 2230 * Anything left over is a leak; any block we can't claim (because
2186 2231 * it's not part of any space map) is a double allocation,
2187 2232 * reference to a freed block, or an unclaimed log block.
|
↓ open down ↓ |
204 lines elided |
↑ open up ↑ |
2188 2233 */
2189 2234 zdb_leak_init(spa, &zcb);
2190 2235
2191 2236 /*
2192 2237 * If there's a deferred-free bplist, process that first.
2193 2238 */
2194 2239 (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj,
2195 2240 count_block_cb, &zcb, NULL);
2196 2241 (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
2197 2242 count_block_cb, &zcb, NULL);
2243 + if (spa_feature_is_active(spa,
2244 + &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2245 + VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
2246 + spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
2247 + &zcb, NULL));
2248 + }
2198 2249
2199 2250 if (dump_opt['c'] > 1)
2200 2251 flags |= TRAVERSE_PREFETCH_DATA;
2201 2252
2202 2253 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
2203 2254
2204 2255 if (zcb.zcb_haderrors) {
2205 2256 (void) printf("\nError counts:\n\n");
2206 2257 (void) printf("\t%5s %s\n", "errno", "count");
2207 2258 for (int e = 0; e < 256; e++) {
2208 2259 if (zcb.zcb_errors[e] != 0) {
2209 2260 (void) printf("\t%5d %llu\n",
2210 2261 e, (u_longlong_t)zcb.zcb_errors[e]);
2211 2262 }
2212 2263 }
2213 2264 }
2214 2265
2215 2266 /*
2216 2267 * Report any leaked segments.
2217 2268 */
2218 2269 zdb_leak_fini(spa);
2219 2270
2220 2271 tzb = &zcb.zcb_type[ZB_TOTAL][ZDB_OT_TOTAL];
2221 2272
2222 2273 norm_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
2223 2274 norm_space = metaslab_class_get_space(spa_normal_class(spa));
2224 2275
2225 2276 total_alloc = norm_alloc + metaslab_class_get_alloc(spa_log_class(spa));
2226 2277 total_found = tzb->zb_asize - zcb.zcb_dedup_asize;
2227 2278
2228 2279 if (total_found == total_alloc) {
2229 2280 if (!dump_opt['L'])
2230 2281 (void) printf("\n\tNo leaks (block sum matches space"
2231 2282 " maps exactly)\n");
2232 2283 } else {
2233 2284 (void) printf("block traversal size %llu != alloc %llu "
2234 2285 "(%s %lld)\n",
2235 2286 (u_longlong_t)total_found,
2236 2287 (u_longlong_t)total_alloc,
2237 2288 (dump_opt['L']) ? "unreachable" : "leaked",
2238 2289 (longlong_t)(total_alloc - total_found));
2239 2290 leaks = 1;
2240 2291 }
2241 2292
2242 2293 if (tzb->zb_count == 0)
2243 2294 return (2);
2244 2295
2245 2296 (void) printf("\n");
2246 2297 (void) printf("\tbp count: %10llu\n",
2247 2298 (u_longlong_t)tzb->zb_count);
2248 2299 (void) printf("\tbp logical: %10llu avg: %6llu\n",
2249 2300 (u_longlong_t)tzb->zb_lsize,
2250 2301 (u_longlong_t)(tzb->zb_lsize / tzb->zb_count));
2251 2302 (void) printf("\tbp physical: %10llu avg:"
2252 2303 " %6llu compression: %6.2f\n",
2253 2304 (u_longlong_t)tzb->zb_psize,
2254 2305 (u_longlong_t)(tzb->zb_psize / tzb->zb_count),
2255 2306 (double)tzb->zb_lsize / tzb->zb_psize);
2256 2307 (void) printf("\tbp allocated: %10llu avg:"
2257 2308 " %6llu compression: %6.2f\n",
2258 2309 (u_longlong_t)tzb->zb_asize,
2259 2310 (u_longlong_t)(tzb->zb_asize / tzb->zb_count),
2260 2311 (double)tzb->zb_lsize / tzb->zb_asize);
2261 2312 (void) printf("\tbp deduped: %10llu ref>1:"
2262 2313 " %6llu deduplication: %6.2f\n",
2263 2314 (u_longlong_t)zcb.zcb_dedup_asize,
2264 2315 (u_longlong_t)zcb.zcb_dedup_blocks,
2265 2316 (double)zcb.zcb_dedup_asize / tzb->zb_asize + 1.0);
2266 2317 (void) printf("\tSPA allocated: %10llu used: %5.2f%%\n",
2267 2318 (u_longlong_t)norm_alloc, 100.0 * norm_alloc / norm_space);
2268 2319
2269 2320 if (dump_opt['b'] >= 2) {
2270 2321 int l, t, level;
2271 2322 (void) printf("\nBlocks\tLSIZE\tPSIZE\tASIZE"
2272 2323 "\t avg\t comp\t%%Total\tType\n");
2273 2324
2274 2325 for (t = 0; t <= ZDB_OT_TOTAL; t++) {
2275 2326 char csize[32], lsize[32], psize[32], asize[32];
2276 2327 char avg[32];
2277 2328 char *typename;
2278 2329
2279 2330 if (t < DMU_OT_NUMTYPES)
2280 2331 typename = dmu_ot[t].ot_name;
2281 2332 else
2282 2333 typename = zdb_ot_extname[t - DMU_OT_NUMTYPES];
2283 2334
2284 2335 if (zcb.zcb_type[ZB_TOTAL][t].zb_asize == 0) {
2285 2336 (void) printf("%6s\t%5s\t%5s\t%5s"
2286 2337 "\t%5s\t%5s\t%6s\t%s\n",
2287 2338 "-",
2288 2339 "-",
2289 2340 "-",
2290 2341 "-",
2291 2342 "-",
2292 2343 "-",
2293 2344 "-",
2294 2345 typename);
2295 2346 continue;
2296 2347 }
2297 2348
2298 2349 for (l = ZB_TOTAL - 1; l >= -1; l--) {
2299 2350 level = (l == -1 ? ZB_TOTAL : l);
2300 2351 zb = &zcb.zcb_type[level][t];
2301 2352
2302 2353 if (zb->zb_asize == 0)
2303 2354 continue;
2304 2355
2305 2356 if (dump_opt['b'] < 3 && level != ZB_TOTAL)
2306 2357 continue;
2307 2358
2308 2359 if (level == 0 && zb->zb_asize ==
2309 2360 zcb.zcb_type[ZB_TOTAL][t].zb_asize)
2310 2361 continue;
2311 2362
2312 2363 zdb_nicenum(zb->zb_count, csize);
2313 2364 zdb_nicenum(zb->zb_lsize, lsize);
2314 2365 zdb_nicenum(zb->zb_psize, psize);
2315 2366 zdb_nicenum(zb->zb_asize, asize);
2316 2367 zdb_nicenum(zb->zb_asize / zb->zb_count, avg);
2317 2368
2318 2369 (void) printf("%6s\t%5s\t%5s\t%5s\t%5s"
2319 2370 "\t%5.2f\t%6.2f\t",
2320 2371 csize, lsize, psize, asize, avg,
2321 2372 (double)zb->zb_lsize / zb->zb_psize,
2322 2373 100.0 * zb->zb_asize / tzb->zb_asize);
2323 2374
2324 2375 if (level == ZB_TOTAL)
2325 2376 (void) printf("%s\n", typename);
2326 2377 else
2327 2378 (void) printf(" L%d %s\n",
2328 2379 level, typename);
2329 2380 }
2330 2381 }
2331 2382 }
2332 2383
2333 2384 (void) printf("\n");
2334 2385
2335 2386 if (leaks)
2336 2387 return (2);
2337 2388
2338 2389 if (zcb.zcb_haderrors)
2339 2390 return (3);
2340 2391
2341 2392 return (0);
2342 2393 }
2343 2394
2344 2395 typedef struct zdb_ddt_entry {
2345 2396 ddt_key_t zdde_key;
2346 2397 uint64_t zdde_ref_blocks;
2347 2398 uint64_t zdde_ref_lsize;
2348 2399 uint64_t zdde_ref_psize;
2349 2400 uint64_t zdde_ref_dsize;
2350 2401 avl_node_t zdde_node;
2351 2402 } zdb_ddt_entry_t;
2352 2403
2353 2404 /* ARGSUSED */
2354 2405 static int
2355 2406 zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
2356 2407 arc_buf_t *pbuf, const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
2357 2408 {
2358 2409 avl_tree_t *t = arg;
2359 2410 avl_index_t where;
2360 2411 zdb_ddt_entry_t *zdde, zdde_search;
2361 2412
2362 2413 if (bp == NULL)
2363 2414 return (0);
|
↓ open down ↓ |
156 lines elided |
↑ open up ↑ |
2364 2415
2365 2416 if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
2366 2417 (void) printf("traversing objset %llu, %llu objects, "
2367 2418 "%lu blocks so far\n",
2368 2419 (u_longlong_t)zb->zb_objset,
2369 2420 (u_longlong_t)bp->blk_fill,
2370 2421 avl_numnodes(t));
2371 2422 }
2372 2423
2373 2424 if (BP_IS_HOLE(bp) || BP_GET_CHECKSUM(bp) == ZIO_CHECKSUM_OFF ||
2374 - BP_GET_LEVEL(bp) > 0 || dmu_ot[BP_GET_TYPE(bp)].ot_metadata)
2425 + BP_GET_LEVEL(bp) > 0 || DMU_OT_IS_METADATA(BP_GET_TYPE(bp)))
2375 2426 return (0);
2376 2427
2377 2428 ddt_key_fill(&zdde_search.zdde_key, bp);
2378 2429
2379 2430 zdde = avl_find(t, &zdde_search, &where);
2380 2431
2381 2432 if (zdde == NULL) {
2382 2433 zdde = umem_zalloc(sizeof (*zdde), UMEM_NOFAIL);
2383 2434 zdde->zdde_key = zdde_search.zdde_key;
2384 2435 avl_insert(t, zdde, where);
2385 2436 }
2386 2437
2387 2438 zdde->zdde_ref_blocks += 1;
2388 2439 zdde->zdde_ref_lsize += BP_GET_LSIZE(bp);
2389 2440 zdde->zdde_ref_psize += BP_GET_PSIZE(bp);
2390 2441 zdde->zdde_ref_dsize += bp_get_dsize_sync(spa, bp);
2391 2442
2392 2443 return (0);
2393 2444 }
2394 2445
2395 2446 static void
2396 2447 dump_simulated_ddt(spa_t *spa)
2397 2448 {
2398 2449 avl_tree_t t;
2399 2450 void *cookie = NULL;
2400 2451 zdb_ddt_entry_t *zdde;
2401 2452 ddt_histogram_t ddh_total = { 0 };
2402 2453 ddt_stat_t dds_total = { 0 };
2403 2454
2404 2455 avl_create(&t, ddt_entry_compare,
2405 2456 sizeof (zdb_ddt_entry_t), offsetof(zdb_ddt_entry_t, zdde_node));
2406 2457
2407 2458 spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
2408 2459
2409 2460 (void) traverse_pool(spa, 0, TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
2410 2461 zdb_ddt_add_cb, &t);
2411 2462
2412 2463 spa_config_exit(spa, SCL_CONFIG, FTAG);
2413 2464
2414 2465 while ((zdde = avl_destroy_nodes(&t, &cookie)) != NULL) {
2415 2466 ddt_stat_t dds;
2416 2467 uint64_t refcnt = zdde->zdde_ref_blocks;
2417 2468 ASSERT(refcnt != 0);
2418 2469
2419 2470 dds.dds_blocks = zdde->zdde_ref_blocks / refcnt;
2420 2471 dds.dds_lsize = zdde->zdde_ref_lsize / refcnt;
2421 2472 dds.dds_psize = zdde->zdde_ref_psize / refcnt;
2422 2473 dds.dds_dsize = zdde->zdde_ref_dsize / refcnt;
2423 2474
2424 2475 dds.dds_ref_blocks = zdde->zdde_ref_blocks;
2425 2476 dds.dds_ref_lsize = zdde->zdde_ref_lsize;
2426 2477 dds.dds_ref_psize = zdde->zdde_ref_psize;
2427 2478 dds.dds_ref_dsize = zdde->zdde_ref_dsize;
2428 2479
2429 2480 ddt_stat_add(&ddh_total.ddh_stat[highbit(refcnt) - 1], &dds, 0);
2430 2481
2431 2482 umem_free(zdde, sizeof (*zdde));
2432 2483 }
2433 2484
2434 2485 avl_destroy(&t);
2435 2486
2436 2487 ddt_histogram_stat(&dds_total, &ddh_total);
2437 2488
2438 2489 (void) printf("Simulated DDT histogram:\n");
2439 2490
2440 2491 zpool_dump_ddt(&dds_total, &ddh_total);
2441 2492
2442 2493 dump_dedup_ratio(&dds_total);
2443 2494 }
2444 2495
2445 2496 static void
2446 2497 dump_zpool(spa_t *spa)
2447 2498 {
2448 2499 dsl_pool_t *dp = spa_get_dsl(spa);
2449 2500 int rc = 0;
2450 2501
2451 2502 if (dump_opt['S']) {
2452 2503 dump_simulated_ddt(spa);
2453 2504 return;
2454 2505 }
2455 2506
2456 2507 if (!dump_opt['e'] && dump_opt['C'] > 1) {
2457 2508 (void) printf("\nCached configuration:\n");
2458 2509 dump_nvlist(spa->spa_config, 8);
2459 2510 }
2460 2511
2461 2512 if (dump_opt['C'])
2462 2513 dump_config(spa);
2463 2514
2464 2515 if (dump_opt['u'])
2465 2516 dump_uberblock(&spa->spa_uberblock, "\nUberblock:\n", "\n");
2466 2517
2467 2518 if (dump_opt['D'])
2468 2519 dump_all_ddts(spa);
|
↓ open down ↓ |
84 lines elided |
↑ open up ↑ |
2469 2520
2470 2521 if (dump_opt['d'] > 2 || dump_opt['m'])
2471 2522 dump_metaslabs(spa);
2472 2523
2473 2524 if (dump_opt['d'] || dump_opt['i']) {
2474 2525 dump_dir(dp->dp_meta_objset);
2475 2526 if (dump_opt['d'] >= 3) {
2476 2527 dump_bpobj(&spa->spa_deferred_bpobj, "Deferred frees");
2477 2528 if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
2478 2529 dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
2479 - "Pool frees");
2530 + "Pool snapshot frees");
2480 2531 }
2532 +
2533 + if (spa_feature_is_active(spa,
2534 + &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
2535 + dump_bptree(spa->spa_meta_objset,
2536 + spa->spa_dsl_pool->dp_bptree_obj,
2537 + "Pool dataset frees");
2538 + }
2481 2539 dump_dtl(spa->spa_root_vdev, 0);
2482 2540 }
2483 2541 (void) dmu_objset_find(spa_name(spa), dump_one_dir,
2484 2542 NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
2485 2543 }
2486 2544 if (dump_opt['b'] || dump_opt['c'])
2487 2545 rc = dump_block_stats(spa);
2488 2546
2489 2547 if (dump_opt['s'])
2490 2548 show_pool_stats(spa);
2491 2549
2492 2550 if (dump_opt['h'])
2493 2551 dump_history(spa);
2494 2552
2495 2553 if (rc != 0)
2496 2554 exit(rc);
2497 2555 }
2498 2556
2499 2557 #define ZDB_FLAG_CHECKSUM 0x0001
2500 2558 #define ZDB_FLAG_DECOMPRESS 0x0002
2501 2559 #define ZDB_FLAG_BSWAP 0x0004
2502 2560 #define ZDB_FLAG_GBH 0x0008
2503 2561 #define ZDB_FLAG_INDIRECT 0x0010
2504 2562 #define ZDB_FLAG_PHYS 0x0020
2505 2563 #define ZDB_FLAG_RAW 0x0040
2506 2564 #define ZDB_FLAG_PRINT_BLKPTR 0x0080
2507 2565
2508 2566 int flagbits[256];
2509 2567
2510 2568 static void
2511 2569 zdb_print_blkptr(blkptr_t *bp, int flags)
2512 2570 {
2513 2571 char blkbuf[BP_SPRINTF_LEN];
2514 2572
2515 2573 if (flags & ZDB_FLAG_BSWAP)
2516 2574 byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
2517 2575
2518 2576 sprintf_blkptr(blkbuf, bp);
2519 2577 (void) printf("%s\n", blkbuf);
2520 2578 }
2521 2579
2522 2580 static void
2523 2581 zdb_dump_indirect(blkptr_t *bp, int nbps, int flags)
2524 2582 {
2525 2583 int i;
2526 2584
2527 2585 for (i = 0; i < nbps; i++)
2528 2586 zdb_print_blkptr(&bp[i], flags);
2529 2587 }
2530 2588
2531 2589 static void
2532 2590 zdb_dump_gbh(void *buf, int flags)
2533 2591 {
2534 2592 zdb_dump_indirect((blkptr_t *)buf, SPA_GBH_NBLKPTRS, flags);
2535 2593 }
2536 2594
2537 2595 static void
2538 2596 zdb_dump_block_raw(void *buf, uint64_t size, int flags)
2539 2597 {
2540 2598 if (flags & ZDB_FLAG_BSWAP)
2541 2599 byteswap_uint64_array(buf, size);
2542 2600 (void) write(1, buf, size);
2543 2601 }
2544 2602
2545 2603 static void
2546 2604 zdb_dump_block(char *label, void *buf, uint64_t size, int flags)
2547 2605 {
2548 2606 uint64_t *d = (uint64_t *)buf;
2549 2607 int nwords = size / sizeof (uint64_t);
2550 2608 int do_bswap = !!(flags & ZDB_FLAG_BSWAP);
2551 2609 int i, j;
2552 2610 char *hdr, *c;
2553 2611
2554 2612
2555 2613 if (do_bswap)
2556 2614 hdr = " 7 6 5 4 3 2 1 0 f e d c b a 9 8";
2557 2615 else
2558 2616 hdr = " 0 1 2 3 4 5 6 7 8 9 a b c d e f";
2559 2617
2560 2618 (void) printf("\n%s\n%6s %s 0123456789abcdef\n", label, "", hdr);
2561 2619
2562 2620 for (i = 0; i < nwords; i += 2) {
2563 2621 (void) printf("%06llx: %016llx %016llx ",
2564 2622 (u_longlong_t)(i * sizeof (uint64_t)),
2565 2623 (u_longlong_t)(do_bswap ? BSWAP_64(d[i]) : d[i]),
2566 2624 (u_longlong_t)(do_bswap ? BSWAP_64(d[i + 1]) : d[i + 1]));
2567 2625
2568 2626 c = (char *)&d[i];
2569 2627 for (j = 0; j < 2 * sizeof (uint64_t); j++)
2570 2628 (void) printf("%c", isprint(c[j]) ? c[j] : '.');
2571 2629 (void) printf("\n");
2572 2630 }
2573 2631 }
2574 2632
2575 2633 /*
2576 2634 * There are two acceptable formats:
2577 2635 * leaf_name - For example: c1t0d0 or /tmp/ztest.0a
2578 2636 * child[.child]* - For example: 0.1.1
2579 2637 *
2580 2638 * The second form can be used to specify arbitrary vdevs anywhere
2581 2639 * in the heirarchy. For example, in a pool with a mirror of
2582 2640 * RAID-Zs, you can specify either RAID-Z vdev with 0.0 or 0.1 .
2583 2641 */
2584 2642 static vdev_t *
2585 2643 zdb_vdev_lookup(vdev_t *vdev, char *path)
2586 2644 {
2587 2645 char *s, *p, *q;
2588 2646 int i;
2589 2647
2590 2648 if (vdev == NULL)
2591 2649 return (NULL);
2592 2650
2593 2651 /* First, assume the x.x.x.x format */
2594 2652 i = (int)strtoul(path, &s, 10);
2595 2653 if (s == path || (s && *s != '.' && *s != '\0'))
2596 2654 goto name;
2597 2655 if (i < 0 || i >= vdev->vdev_children)
2598 2656 return (NULL);
2599 2657
2600 2658 vdev = vdev->vdev_child[i];
2601 2659 if (*s == '\0')
2602 2660 return (vdev);
2603 2661 return (zdb_vdev_lookup(vdev, s+1));
2604 2662
2605 2663 name:
2606 2664 for (i = 0; i < vdev->vdev_children; i++) {
2607 2665 vdev_t *vc = vdev->vdev_child[i];
2608 2666
2609 2667 if (vc->vdev_path == NULL) {
2610 2668 vc = zdb_vdev_lookup(vc, path);
2611 2669 if (vc == NULL)
2612 2670 continue;
2613 2671 else
2614 2672 return (vc);
2615 2673 }
2616 2674
2617 2675 p = strrchr(vc->vdev_path, '/');
2618 2676 p = p ? p + 1 : vc->vdev_path;
2619 2677 q = &vc->vdev_path[strlen(vc->vdev_path) - 2];
2620 2678
2621 2679 if (strcmp(vc->vdev_path, path) == 0)
2622 2680 return (vc);
2623 2681 if (strcmp(p, path) == 0)
2624 2682 return (vc);
2625 2683 if (strcmp(q, "s0") == 0 && strncmp(p, path, q - p) == 0)
2626 2684 return (vc);
2627 2685 }
2628 2686
2629 2687 return (NULL);
2630 2688 }
2631 2689
2632 2690 /*
2633 2691 * Read a block from a pool and print it out. The syntax of the
2634 2692 * block descriptor is:
2635 2693 *
2636 2694 * pool:vdev_specifier:offset:size[:flags]
2637 2695 *
2638 2696 * pool - The name of the pool you wish to read from
2639 2697 * vdev_specifier - Which vdev (see comment for zdb_vdev_lookup)
2640 2698 * offset - offset, in hex, in bytes
2641 2699 * size - Amount of data to read, in hex, in bytes
2642 2700 * flags - A string of characters specifying options
2643 2701 * b: Decode a blkptr at given offset within block
2644 2702 * *c: Calculate and display checksums
2645 2703 * d: Decompress data before dumping
2646 2704 * e: Byteswap data before dumping
2647 2705 * g: Display data as a gang block header
2648 2706 * i: Display as an indirect block
2649 2707 * p: Do I/O to physical offset
2650 2708 * r: Dump raw data to stdout
2651 2709 *
2652 2710 * * = not yet implemented
2653 2711 */
2654 2712 static void
2655 2713 zdb_read_block(char *thing, spa_t *spa)
2656 2714 {
2657 2715 blkptr_t blk, *bp = &blk;
2658 2716 dva_t *dva = bp->blk_dva;
2659 2717 int flags = 0;
2660 2718 uint64_t offset = 0, size = 0, psize = 0, lsize = 0, blkptr_offset = 0;
2661 2719 zio_t *zio;
2662 2720 vdev_t *vd;
2663 2721 void *pbuf, *lbuf, *buf;
2664 2722 char *s, *p, *dup, *vdev, *flagstr;
2665 2723 int i, error;
2666 2724
2667 2725 dup = strdup(thing);
2668 2726 s = strtok(dup, ":");
2669 2727 vdev = s ? s : "";
2670 2728 s = strtok(NULL, ":");
2671 2729 offset = strtoull(s ? s : "", NULL, 16);
2672 2730 s = strtok(NULL, ":");
2673 2731 size = strtoull(s ? s : "", NULL, 16);
2674 2732 s = strtok(NULL, ":");
2675 2733 flagstr = s ? s : "";
2676 2734
2677 2735 s = NULL;
2678 2736 if (size == 0)
2679 2737 s = "size must not be zero";
2680 2738 if (!IS_P2ALIGNED(size, DEV_BSIZE))
2681 2739 s = "size must be a multiple of sector size";
2682 2740 if (!IS_P2ALIGNED(offset, DEV_BSIZE))
2683 2741 s = "offset must be a multiple of sector size";
2684 2742 if (s) {
2685 2743 (void) printf("Invalid block specifier: %s - %s\n", thing, s);
2686 2744 free(dup);
2687 2745 return;
2688 2746 }
2689 2747
2690 2748 for (s = strtok(flagstr, ":"); s; s = strtok(NULL, ":")) {
2691 2749 for (i = 0; flagstr[i]; i++) {
2692 2750 int bit = flagbits[(uchar_t)flagstr[i]];
2693 2751
2694 2752 if (bit == 0) {
2695 2753 (void) printf("***Invalid flag: %c\n",
2696 2754 flagstr[i]);
2697 2755 continue;
2698 2756 }
2699 2757 flags |= bit;
2700 2758
2701 2759 /* If it's not something with an argument, keep going */
2702 2760 if ((bit & (ZDB_FLAG_CHECKSUM |
2703 2761 ZDB_FLAG_PRINT_BLKPTR)) == 0)
2704 2762 continue;
2705 2763
2706 2764 p = &flagstr[i + 1];
2707 2765 if (bit == ZDB_FLAG_PRINT_BLKPTR)
2708 2766 blkptr_offset = strtoull(p, &p, 16);
2709 2767 if (*p != ':' && *p != '\0') {
2710 2768 (void) printf("***Invalid flag arg: '%s'\n", s);
2711 2769 free(dup);
2712 2770 return;
2713 2771 }
2714 2772 }
2715 2773 }
2716 2774
2717 2775 vd = zdb_vdev_lookup(spa->spa_root_vdev, vdev);
2718 2776 if (vd == NULL) {
2719 2777 (void) printf("***Invalid vdev: %s\n", vdev);
2720 2778 free(dup);
2721 2779 return;
2722 2780 } else {
2723 2781 if (vd->vdev_path)
2724 2782 (void) fprintf(stderr, "Found vdev: %s\n",
2725 2783 vd->vdev_path);
2726 2784 else
2727 2785 (void) fprintf(stderr, "Found vdev type: %s\n",
2728 2786 vd->vdev_ops->vdev_op_type);
2729 2787 }
2730 2788
2731 2789 psize = size;
2732 2790 lsize = size;
2733 2791
2734 2792 pbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
2735 2793 lbuf = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
2736 2794
2737 2795 BP_ZERO(bp);
2738 2796
2739 2797 DVA_SET_VDEV(&dva[0], vd->vdev_id);
2740 2798 DVA_SET_OFFSET(&dva[0], offset);
2741 2799 DVA_SET_GANG(&dva[0], !!(flags & ZDB_FLAG_GBH));
2742 2800 DVA_SET_ASIZE(&dva[0], vdev_psize_to_asize(vd, psize));
2743 2801
2744 2802 BP_SET_BIRTH(bp, TXG_INITIAL, TXG_INITIAL);
2745 2803
2746 2804 BP_SET_LSIZE(bp, lsize);
2747 2805 BP_SET_PSIZE(bp, psize);
2748 2806 BP_SET_COMPRESS(bp, ZIO_COMPRESS_OFF);
2749 2807 BP_SET_CHECKSUM(bp, ZIO_CHECKSUM_OFF);
2750 2808 BP_SET_TYPE(bp, DMU_OT_NONE);
2751 2809 BP_SET_LEVEL(bp, 0);
2752 2810 BP_SET_DEDUP(bp, 0);
2753 2811 BP_SET_BYTEORDER(bp, ZFS_HOST_BYTEORDER);
2754 2812
2755 2813 spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
2756 2814 zio = zio_root(spa, NULL, NULL, 0);
2757 2815
2758 2816 if (vd == vd->vdev_top) {
2759 2817 /*
2760 2818 * Treat this as a normal block read.
2761 2819 */
2762 2820 zio_nowait(zio_read(zio, spa, bp, pbuf, psize, NULL, NULL,
2763 2821 ZIO_PRIORITY_SYNC_READ,
2764 2822 ZIO_FLAG_CANFAIL | ZIO_FLAG_RAW, NULL));
2765 2823 } else {
2766 2824 /*
2767 2825 * Treat this as a vdev child I/O.
2768 2826 */
2769 2827 zio_nowait(zio_vdev_child_io(zio, bp, vd, offset, pbuf, psize,
2770 2828 ZIO_TYPE_READ, ZIO_PRIORITY_SYNC_READ,
2771 2829 ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE |
2772 2830 ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY |
2773 2831 ZIO_FLAG_CANFAIL | ZIO_FLAG_RAW, NULL, NULL));
2774 2832 }
2775 2833
2776 2834 error = zio_wait(zio);
2777 2835 spa_config_exit(spa, SCL_STATE, FTAG);
2778 2836
2779 2837 if (error) {
2780 2838 (void) printf("Read of %s failed, error: %d\n", thing, error);
2781 2839 goto out;
2782 2840 }
2783 2841
2784 2842 if (flags & ZDB_FLAG_DECOMPRESS) {
2785 2843 /*
2786 2844 * We don't know how the data was compressed, so just try
2787 2845 * every decompress function at every inflated blocksize.
2788 2846 */
2789 2847 enum zio_compress c;
2790 2848 void *pbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
2791 2849 void *lbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
2792 2850
2793 2851 bcopy(pbuf, pbuf2, psize);
2794 2852
2795 2853 VERIFY(random_get_pseudo_bytes((uint8_t *)pbuf + psize,
2796 2854 SPA_MAXBLOCKSIZE - psize) == 0);
2797 2855
2798 2856 VERIFY(random_get_pseudo_bytes((uint8_t *)pbuf2 + psize,
2799 2857 SPA_MAXBLOCKSIZE - psize) == 0);
2800 2858
2801 2859 for (lsize = SPA_MAXBLOCKSIZE; lsize > psize;
2802 2860 lsize -= SPA_MINBLOCKSIZE) {
2803 2861 for (c = 0; c < ZIO_COMPRESS_FUNCTIONS; c++) {
2804 2862 if (zio_decompress_data(c, pbuf, lbuf,
2805 2863 psize, lsize) == 0 &&
2806 2864 zio_decompress_data(c, pbuf2, lbuf2,
2807 2865 psize, lsize) == 0 &&
2808 2866 bcmp(lbuf, lbuf2, lsize) == 0)
2809 2867 break;
2810 2868 }
2811 2869 if (c != ZIO_COMPRESS_FUNCTIONS)
2812 2870 break;
2813 2871 lsize -= SPA_MINBLOCKSIZE;
2814 2872 }
2815 2873
2816 2874 umem_free(pbuf2, SPA_MAXBLOCKSIZE);
2817 2875 umem_free(lbuf2, SPA_MAXBLOCKSIZE);
2818 2876
2819 2877 if (lsize <= psize) {
2820 2878 (void) printf("Decompress of %s failed\n", thing);
2821 2879 goto out;
2822 2880 }
2823 2881 buf = lbuf;
2824 2882 size = lsize;
2825 2883 } else {
2826 2884 buf = pbuf;
2827 2885 size = psize;
2828 2886 }
2829 2887
2830 2888 if (flags & ZDB_FLAG_PRINT_BLKPTR)
2831 2889 zdb_print_blkptr((blkptr_t *)(void *)
2832 2890 ((uintptr_t)buf + (uintptr_t)blkptr_offset), flags);
2833 2891 else if (flags & ZDB_FLAG_RAW)
2834 2892 zdb_dump_block_raw(buf, size, flags);
2835 2893 else if (flags & ZDB_FLAG_INDIRECT)
2836 2894 zdb_dump_indirect((blkptr_t *)buf, size / sizeof (blkptr_t),
2837 2895 flags);
2838 2896 else if (flags & ZDB_FLAG_GBH)
2839 2897 zdb_dump_gbh(buf, flags);
2840 2898 else
2841 2899 zdb_dump_block(thing, buf, size, flags);
2842 2900
2843 2901 out:
2844 2902 umem_free(pbuf, SPA_MAXBLOCKSIZE);
2845 2903 umem_free(lbuf, SPA_MAXBLOCKSIZE);
2846 2904 free(dup);
2847 2905 }
2848 2906
2849 2907 static boolean_t
2850 2908 pool_match(nvlist_t *cfg, char *tgt)
2851 2909 {
2852 2910 uint64_t v, guid = strtoull(tgt, NULL, 0);
2853 2911 char *s;
2854 2912
2855 2913 if (guid != 0) {
2856 2914 if (nvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_GUID, &v) == 0)
2857 2915 return (v == guid);
2858 2916 } else {
2859 2917 if (nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &s) == 0)
2860 2918 return (strcmp(s, tgt) == 0);
2861 2919 }
2862 2920 return (B_FALSE);
2863 2921 }
2864 2922
2865 2923 static char *
2866 2924 find_zpool(char **target, nvlist_t **configp, int dirc, char **dirv)
2867 2925 {
2868 2926 nvlist_t *pools;
2869 2927 nvlist_t *match = NULL;
2870 2928 char *name = NULL;
2871 2929 char *sepp = NULL;
2872 2930 char sep;
2873 2931 int count = 0;
2874 2932 importargs_t args = { 0 };
2875 2933
2876 2934 args.paths = dirc;
2877 2935 args.path = dirv;
2878 2936 args.can_be_active = B_TRUE;
2879 2937
2880 2938 if ((sepp = strpbrk(*target, "/@")) != NULL) {
2881 2939 sep = *sepp;
2882 2940 *sepp = '\0';
2883 2941 }
2884 2942
2885 2943 pools = zpool_search_import(g_zfs, &args);
2886 2944
2887 2945 if (pools != NULL) {
2888 2946 nvpair_t *elem = NULL;
2889 2947 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
2890 2948 verify(nvpair_value_nvlist(elem, configp) == 0);
2891 2949 if (pool_match(*configp, *target)) {
2892 2950 count++;
2893 2951 if (match != NULL) {
2894 2952 /* print previously found config */
2895 2953 if (name != NULL) {
2896 2954 (void) printf("%s\n", name);
2897 2955 dump_nvlist(match, 8);
2898 2956 name = NULL;
2899 2957 }
2900 2958 (void) printf("%s\n",
2901 2959 nvpair_name(elem));
2902 2960 dump_nvlist(*configp, 8);
2903 2961 } else {
2904 2962 match = *configp;
2905 2963 name = nvpair_name(elem);
2906 2964 }
2907 2965 }
2908 2966 }
2909 2967 }
2910 2968 if (count > 1)
2911 2969 (void) fatal("\tMatched %d pools - use pool GUID "
2912 2970 "instead of pool name or \n"
2913 2971 "\tpool name part of a dataset name to select pool", count);
2914 2972
2915 2973 if (sepp)
2916 2974 *sepp = sep;
2917 2975 /*
2918 2976 * If pool GUID was specified for pool id, replace it with pool name
2919 2977 */
2920 2978 if (name && (strstr(*target, name) != *target)) {
2921 2979 int sz = 1 + strlen(name) + ((sepp) ? strlen(sepp) : 0);
2922 2980
2923 2981 *target = umem_alloc(sz, UMEM_NOFAIL);
2924 2982 (void) snprintf(*target, sz, "%s%s", name, sepp ? sepp : "");
2925 2983 }
2926 2984
2927 2985 *configp = name ? match : NULL;
2928 2986
2929 2987 return (name);
2930 2988 }
2931 2989
2932 2990 int
2933 2991 main(int argc, char **argv)
2934 2992 {
2935 2993 int i, c;
2936 2994 struct rlimit rl = { 1024, 1024 };
2937 2995 spa_t *spa = NULL;
2938 2996 objset_t *os = NULL;
2939 2997 int dump_all = 1;
2940 2998 int verbose = 0;
2941 2999 int error = 0;
2942 3000 char **searchdirs = NULL;
2943 3001 int nsearch = 0;
2944 3002 char *target;
2945 3003 nvlist_t *policy = NULL;
2946 3004 uint64_t max_txg = UINT64_MAX;
2947 3005 int rewind = ZPOOL_NEVER_REWIND;
2948 3006
2949 3007 (void) setrlimit(RLIMIT_NOFILE, &rl);
2950 3008 (void) enable_extended_FILE_stdio(-1, -1);
2951 3009
2952 3010 dprintf_setup(&argc, argv);
2953 3011
2954 3012 while ((c = getopt(argc, argv, "bcdhilmsuCDRSAFLXevp:t:U:P")) != -1) {
2955 3013 switch (c) {
2956 3014 case 'b':
2957 3015 case 'c':
2958 3016 case 'd':
2959 3017 case 'h':
2960 3018 case 'i':
2961 3019 case 'l':
2962 3020 case 'm':
2963 3021 case 's':
2964 3022 case 'u':
2965 3023 case 'C':
2966 3024 case 'D':
2967 3025 case 'R':
2968 3026 case 'S':
2969 3027 dump_opt[c]++;
2970 3028 dump_all = 0;
2971 3029 break;
2972 3030 case 'A':
2973 3031 case 'F':
2974 3032 case 'L':
2975 3033 case 'X':
2976 3034 case 'e':
2977 3035 case 'P':
2978 3036 dump_opt[c]++;
2979 3037 break;
2980 3038 case 'v':
2981 3039 verbose++;
2982 3040 break;
2983 3041 case 'p':
2984 3042 if (searchdirs == NULL) {
2985 3043 searchdirs = umem_alloc(sizeof (char *),
2986 3044 UMEM_NOFAIL);
2987 3045 } else {
2988 3046 char **tmp = umem_alloc((nsearch + 1) *
2989 3047 sizeof (char *), UMEM_NOFAIL);
2990 3048 bcopy(searchdirs, tmp, nsearch *
2991 3049 sizeof (char *));
2992 3050 umem_free(searchdirs,
2993 3051 nsearch * sizeof (char *));
2994 3052 searchdirs = tmp;
2995 3053 }
2996 3054 searchdirs[nsearch++] = optarg;
2997 3055 break;
2998 3056 case 't':
2999 3057 max_txg = strtoull(optarg, NULL, 0);
3000 3058 if (max_txg < TXG_INITIAL) {
3001 3059 (void) fprintf(stderr, "incorrect txg "
3002 3060 "specified: %s\n", optarg);
3003 3061 usage();
3004 3062 }
3005 3063 break;
3006 3064 case 'U':
3007 3065 spa_config_path = optarg;
3008 3066 break;
3009 3067 default:
3010 3068 usage();
3011 3069 break;
3012 3070 }
3013 3071 }
3014 3072
3015 3073 if (!dump_opt['e'] && searchdirs != NULL) {
3016 3074 (void) fprintf(stderr, "-p option requires use of -e\n");
3017 3075 usage();
3018 3076 }
3019 3077
3020 3078 kernel_init(FREAD);
3021 3079 g_zfs = libzfs_init();
3022 3080 ASSERT(g_zfs != NULL);
3023 3081
3024 3082 if (dump_all)
3025 3083 verbose = MAX(verbose, 1);
3026 3084
3027 3085 for (c = 0; c < 256; c++) {
3028 3086 if (dump_all && !strchr("elAFLRSXP", c))
3029 3087 dump_opt[c] = 1;
3030 3088 if (dump_opt[c])
3031 3089 dump_opt[c] += verbose;
3032 3090 }
3033 3091
3034 3092 aok = (dump_opt['A'] == 1) || (dump_opt['A'] > 2);
3035 3093 zfs_recover = (dump_opt['A'] > 1);
3036 3094
3037 3095 argc -= optind;
3038 3096 argv += optind;
3039 3097
3040 3098 if (argc < 2 && dump_opt['R'])
3041 3099 usage();
3042 3100 if (argc < 1) {
3043 3101 if (!dump_opt['e'] && dump_opt['C']) {
3044 3102 dump_cachefile(spa_config_path);
3045 3103 return (0);
3046 3104 }
3047 3105 usage();
3048 3106 }
3049 3107
3050 3108 if (dump_opt['l']) {
3051 3109 dump_label(argv[0]);
3052 3110 return (0);
3053 3111 }
3054 3112
3055 3113 if (dump_opt['X'] || dump_opt['F'])
3056 3114 rewind = ZPOOL_DO_REWIND |
3057 3115 (dump_opt['X'] ? ZPOOL_EXTREME_REWIND : 0);
3058 3116
3059 3117 if (nvlist_alloc(&policy, NV_UNIQUE_NAME_TYPE, 0) != 0 ||
3060 3118 nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, max_txg) != 0 ||
3061 3119 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind) != 0)
3062 3120 fatal("internal error: %s", strerror(ENOMEM));
3063 3121
3064 3122 error = 0;
3065 3123 target = argv[0];
3066 3124
3067 3125 if (dump_opt['e']) {
3068 3126 nvlist_t *cfg = NULL;
3069 3127 char *name = find_zpool(&target, &cfg, nsearch, searchdirs);
3070 3128
3071 3129 error = ENOENT;
3072 3130 if (name) {
3073 3131 if (dump_opt['C'] > 1) {
3074 3132 (void) printf("\nConfiguration for import:\n");
3075 3133 dump_nvlist(cfg, 8);
3076 3134 }
3077 3135 if (nvlist_add_nvlist(cfg,
3078 3136 ZPOOL_REWIND_POLICY, policy) != 0) {
3079 3137 fatal("can't open '%s': %s",
3080 3138 target, strerror(ENOMEM));
3081 3139 }
3082 3140 if ((error = spa_import(name, cfg, NULL,
3083 3141 ZFS_IMPORT_MISSING_LOG)) != 0) {
3084 3142 error = spa_import(name, cfg, NULL,
3085 3143 ZFS_IMPORT_VERBATIM);
3086 3144 }
3087 3145 }
3088 3146 }
3089 3147
3090 3148 if (error == 0) {
3091 3149 if (strpbrk(target, "/@") == NULL || dump_opt['R']) {
3092 3150 error = spa_open_rewind(target, &spa, FTAG, policy,
3093 3151 NULL);
3094 3152 if (error) {
3095 3153 /*
3096 3154 * If we're missing the log device then
3097 3155 * try opening the pool after clearing the
3098 3156 * log state.
3099 3157 */
3100 3158 mutex_enter(&spa_namespace_lock);
3101 3159 if ((spa = spa_lookup(target)) != NULL &&
3102 3160 spa->spa_log_state == SPA_LOG_MISSING) {
3103 3161 spa->spa_log_state = SPA_LOG_CLEAR;
3104 3162 error = 0;
3105 3163 }
3106 3164 mutex_exit(&spa_namespace_lock);
3107 3165
3108 3166 if (!error) {
3109 3167 error = spa_open_rewind(target, &spa,
3110 3168 FTAG, policy, NULL);
3111 3169 }
3112 3170 }
3113 3171 } else {
3114 3172 error = dmu_objset_own(target, DMU_OST_ANY,
3115 3173 B_TRUE, FTAG, &os);
3116 3174 }
3117 3175 }
3118 3176 nvlist_free(policy);
3119 3177
3120 3178 if (error)
3121 3179 fatal("can't open '%s': %s", target, strerror(error));
3122 3180
3123 3181 argv++;
3124 3182 argc--;
3125 3183 if (!dump_opt['R']) {
3126 3184 if (argc > 0) {
3127 3185 zopt_objects = argc;
3128 3186 zopt_object = calloc(zopt_objects, sizeof (uint64_t));
3129 3187 for (i = 0; i < zopt_objects; i++) {
3130 3188 errno = 0;
3131 3189 zopt_object[i] = strtoull(argv[i], NULL, 0);
3132 3190 if (zopt_object[i] == 0 && errno != 0)
3133 3191 fatal("bad number %s: %s",
3134 3192 argv[i], strerror(errno));
3135 3193 }
3136 3194 }
3137 3195 (os != NULL) ? dump_dir(os) : dump_zpool(spa);
3138 3196 } else {
3139 3197 flagbits['b'] = ZDB_FLAG_PRINT_BLKPTR;
3140 3198 flagbits['c'] = ZDB_FLAG_CHECKSUM;
3141 3199 flagbits['d'] = ZDB_FLAG_DECOMPRESS;
3142 3200 flagbits['e'] = ZDB_FLAG_BSWAP;
3143 3201 flagbits['g'] = ZDB_FLAG_GBH;
3144 3202 flagbits['i'] = ZDB_FLAG_INDIRECT;
3145 3203 flagbits['p'] = ZDB_FLAG_PHYS;
3146 3204 flagbits['r'] = ZDB_FLAG_RAW;
3147 3205
3148 3206 for (i = 0; i < argc; i++)
3149 3207 zdb_read_block(argv[i], spa);
3150 3208 }
3151 3209
3152 3210 (os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG);
3153 3211
3154 3212 fuid_table_destroy();
3155 3213 sa_loaded = B_FALSE;
3156 3214
3157 3215 libzfs_fini(g_zfs);
3158 3216 kernel_fini();
3159 3217
3160 3218 return (0);
3161 3219 }
|
↓ open down ↓ |
671 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX