19 * CDDL HEADER END |
19 * CDDL HEADER END |
20 */ |
20 */ |
21 |
21 |
22 /* |
22 /* |
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
24 * Copyright (c) 2012 by Delphix. All rights reserved. |
24 * Copyright (c) 2013 by Delphix. All rights reserved. |
25 */ |
25 */ |
26 |
26 |
27 #include <stdio.h> |
27 #include <stdio.h> |
|
28 #include <unistd.h> |
28 #include <stdio_ext.h> |
29 #include <stdio_ext.h> |
29 #include <stdlib.h> |
30 #include <stdlib.h> |
30 #include <ctype.h> |
31 #include <ctype.h> |
31 #include <sys/zfs_context.h> |
32 #include <sys/zfs_context.h> |
32 #include <sys/spa.h> |
33 #include <sys/spa.h> |
239 (void) sprintf(buf, "%llu", (longlong_t)num); |
240 (void) sprintf(buf, "%llu", (longlong_t)num); |
240 else |
241 else |
241 nicenum(num, buf); |
242 nicenum(num, buf); |
242 } |
243 } |
243 |
244 |
244 const char dump_zap_stars[] = "****************************************"; |
245 const char histo_stars[] = "****************************************"; |
245 const int dump_zap_width = sizeof (dump_zap_stars) - 1; |
246 const int histo_width = sizeof (histo_stars) - 1; |
246 |
247 |
247 static void |
248 static void |
248 dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE]) |
249 dump_histogram(const uint64_t *histo, int size) |
249 { |
250 { |
250 int i; |
251 int i; |
251 int minidx = ZAP_HISTOGRAM_SIZE - 1; |
252 int minidx = size - 1; |
252 int maxidx = 0; |
253 int maxidx = 0; |
253 uint64_t max = 0; |
254 uint64_t max = 0; |
254 |
255 |
255 for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) { |
256 for (i = 0; i < size; i++) { |
256 if (histo[i] > max) |
257 if (histo[i] > max) |
257 max = histo[i]; |
258 max = histo[i]; |
258 if (histo[i] > 0 && i > maxidx) |
259 if (histo[i] > 0 && i > maxidx) |
259 maxidx = i; |
260 maxidx = i; |
260 if (histo[i] > 0 && i < minidx) |
261 if (histo[i] > 0 && i < minidx) |
261 minidx = i; |
262 minidx = i; |
262 } |
263 } |
263 |
264 |
264 if (max < dump_zap_width) |
265 if (max < histo_width) |
265 max = dump_zap_width; |
266 max = histo_width; |
266 |
267 |
267 for (i = minidx; i <= maxidx; i++) |
268 for (i = minidx; i <= maxidx; i++) { |
268 (void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i], |
269 (void) printf("\t\t\t%3u: %6llu %s\n", |
269 &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]); |
270 i, (u_longlong_t)histo[i], |
|
271 &histo_stars[(max - histo[i]) * histo_width / max]); |
|
272 } |
270 } |
273 } |
271 |
274 |
272 static void |
275 static void |
273 dump_zap_stats(objset_t *os, uint64_t object) |
276 dump_zap_stats(objset_t *os, uint64_t object) |
274 { |
277 { |
315 (u_longlong_t)zs.zs_magic); |
318 (u_longlong_t)zs.zs_magic); |
316 (void) printf("\t\tzap_salt: 0x%llx\n", |
319 (void) printf("\t\tzap_salt: 0x%llx\n", |
317 (u_longlong_t)zs.zs_salt); |
320 (u_longlong_t)zs.zs_salt); |
318 |
321 |
319 (void) printf("\t\tLeafs with 2^n pointers:\n"); |
322 (void) printf("\t\tLeafs with 2^n pointers:\n"); |
320 dump_zap_histogram(zs.zs_leafs_with_2n_pointers); |
323 dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE); |
321 |
324 |
322 (void) printf("\t\tBlocks with n*5 entries:\n"); |
325 (void) printf("\t\tBlocks with n*5 entries:\n"); |
323 dump_zap_histogram(zs.zs_blocks_with_n5_entries); |
326 dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE); |
324 |
327 |
325 (void) printf("\t\tBlocks n/10 full:\n"); |
328 (void) printf("\t\tBlocks n/10 full:\n"); |
326 dump_zap_histogram(zs.zs_blocks_n_tenths_full); |
329 dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE); |
327 |
330 |
328 (void) printf("\t\tEntries with n chunks:\n"); |
331 (void) printf("\t\tEntries with n chunks:\n"); |
329 dump_zap_histogram(zs.zs_entries_using_n_chunks); |
332 dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE); |
330 |
333 |
331 (void) printf("\t\tBuckets with n entries:\n"); |
334 (void) printf("\t\tBuckets with n entries:\n"); |
332 dump_zap_histogram(zs.zs_buckets_with_n_entries); |
335 dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE); |
333 } |
336 } |
334 |
337 |
335 /*ARGSUSED*/ |
338 /*ARGSUSED*/ |
336 static void |
339 static void |
337 dump_none(objset_t *os, uint64_t object, void *data, size_t size) |
340 dump_none(objset_t *os, uint64_t object, void *data, size_t size) |
947 sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp) |
950 sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp) |
948 { |
951 { |
949 const dva_t *dva = bp->blk_dva; |
952 const dva_t *dva = bp->blk_dva; |
950 int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1; |
953 int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1; |
951 |
954 |
952 if (dump_opt['b'] >= 5) { |
955 if (dump_opt['b'] >= 6) { |
953 sprintf_blkptr(blkbuf, bp); |
956 sprintf_blkptr(blkbuf, bp); |
954 return; |
957 return; |
955 } |
958 } |
956 |
959 |
957 blkbuf[0] = '\0'; |
960 blkbuf[0] = '\0'; |
2014 |
2019 |
2015 typedef struct zdb_cb { |
2020 typedef struct zdb_cb { |
2016 zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1]; |
2021 zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1]; |
2017 uint64_t zcb_dedup_asize; |
2022 uint64_t zcb_dedup_asize; |
2018 uint64_t zcb_dedup_blocks; |
2023 uint64_t zcb_dedup_blocks; |
|
2024 uint64_t zcb_start; |
|
2025 uint64_t zcb_lastprint; |
|
2026 uint64_t zcb_totalasize; |
2019 uint64_t zcb_errors[256]; |
2027 uint64_t zcb_errors[256]; |
2020 int zcb_readfails; |
2028 int zcb_readfails; |
2021 int zcb_haderrors; |
2029 int zcb_haderrors; |
2022 spa_t *zcb_spa; |
2030 spa_t *zcb_spa; |
2023 } zdb_cb_t; |
2031 } zdb_cb_t; |
2149 zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb)); |
2158 zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb)); |
2150 } |
2159 } |
2151 |
2160 |
2152 zcb->zcb_readfails = 0; |
2161 zcb->zcb_readfails = 0; |
2153 |
2162 |
2154 if (dump_opt['b'] >= 4) { |
2163 if (dump_opt['b'] >= 5) { |
2155 sprintf_blkptr(blkbuf, bp); |
2164 sprintf_blkptr(blkbuf, bp); |
2156 (void) printf("objset %llu object %llu " |
2165 (void) printf("objset %llu object %llu " |
2157 "level %lld offset 0x%llx %s\n", |
2166 "level %lld offset 0x%llx %s\n", |
2158 (u_longlong_t)zb->zb_objset, |
2167 (u_longlong_t)zb->zb_objset, |
2159 (u_longlong_t)zb->zb_object, |
2168 (u_longlong_t)zb->zb_object, |
2160 (longlong_t)zb->zb_level, |
2169 (longlong_t)zb->zb_level, |
2161 (u_longlong_t)blkid2offset(dnp, bp, zb), |
2170 (u_longlong_t)blkid2offset(dnp, bp, zb), |
2162 blkbuf); |
2171 blkbuf); |
|
2172 } |
|
2173 |
|
2174 if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) && |
|
2175 gethrtime() > zcb->zcb_lastprint + NANOSEC) { |
|
2176 uint64_t now = gethrtime(); |
|
2177 char buf[10]; |
|
2178 uint64_t bytes = zcb->zcb_type[ZB_TOTAL][ZDB_OT_TOTAL].zb_asize; |
|
2179 int kb_per_sec = |
|
2180 1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000)); |
|
2181 int sec_remaining = |
|
2182 (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec; |
|
2183 |
|
2184 zfs_nicenum(bytes, buf, sizeof (buf)); |
|
2185 (void) fprintf(stderr, |
|
2186 "\r%5s completed (%4dMB/s) " |
|
2187 "estimated time remaining: %uhr %02umin %02usec ", |
|
2188 buf, kb_per_sec / 1024, |
|
2189 sec_remaining / 60 / 60, |
|
2190 sec_remaining / 60 % 60, |
|
2191 sec_remaining % 60); |
|
2192 |
|
2193 zcb->zcb_lastprint = now; |
2163 } |
2194 } |
2164 |
2195 |
2165 return (0); |
2196 return (0); |
2166 } |
2197 } |
2167 |
2198 |
2291 static int |
2322 static int |
2292 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) |
2323 count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) |
2293 { |
2324 { |
2294 zdb_cb_t *zcb = arg; |
2325 zdb_cb_t *zcb = arg; |
2295 |
2326 |
2296 if (dump_opt['b'] >= 4) { |
2327 if (dump_opt['b'] >= 5) { |
2297 char blkbuf[BP_SPRINTF_LEN]; |
2328 char blkbuf[BP_SPRINTF_LEN]; |
2298 sprintf_blkptr(blkbuf, bp); |
2329 sprintf_blkptr(blkbuf, bp); |
2299 (void) printf("[%s] %s\n", |
2330 (void) printf("[%s] %s\n", |
2300 "deferred free", blkbuf); |
2331 "deferred free", blkbuf); |
2301 } |
2332 } |
2310 zdb_blkstats_t *zb, *tzb; |
2341 zdb_blkstats_t *zb, *tzb; |
2311 uint64_t norm_alloc, norm_space, total_alloc, total_found; |
2342 uint64_t norm_alloc, norm_space, total_alloc, total_found; |
2312 int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD; |
2343 int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD; |
2313 int leaks = 0; |
2344 int leaks = 0; |
2314 |
2345 |
2315 (void) printf("\nTraversing all blocks %s%s%s%s%s...\n", |
2346 (void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n", |
2316 (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "", |
2347 (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "", |
2317 (dump_opt['c'] == 1) ? "metadata " : "", |
2348 (dump_opt['c'] == 1) ? "metadata " : "", |
2318 dump_opt['c'] ? "checksums " : "", |
2349 dump_opt['c'] ? "checksums " : "", |
2319 (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "", |
2350 (dump_opt['c'] && !dump_opt['L']) ? "and verify " : "", |
2320 !dump_opt['L'] ? "nothing leaked " : ""); |
2351 !dump_opt['L'] ? "nothing leaked " : ""); |
2346 } |
2377 } |
2347 |
2378 |
2348 if (dump_opt['c'] > 1) |
2379 if (dump_opt['c'] > 1) |
2349 flags |= TRAVERSE_PREFETCH_DATA; |
2380 flags |= TRAVERSE_PREFETCH_DATA; |
2350 |
2381 |
|
2382 zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa)); |
|
2383 zcb.zcb_start = zcb.zcb_lastprint = gethrtime(); |
2351 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); |
2384 zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); |
2352 |
2385 |
2353 /* |
2386 /* |
2354 * If we've traversed the data blocks then we need to wait for those |
2387 * If we've traversed the data blocks then we need to wait for those |
2355 * I/Os to complete. We leverage "The Godfather" zio to wait on |
2388 * I/Os to complete. We leverage "The Godfather" zio to wait on |
2485 if (level == ZB_TOTAL) |
2518 if (level == ZB_TOTAL) |
2486 (void) printf("%s\n", typename); |
2519 (void) printf("%s\n", typename); |
2487 else |
2520 else |
2488 (void) printf(" L%d %s\n", |
2521 (void) printf(" L%d %s\n", |
2489 level, typename); |
2522 level, typename); |
|
2523 |
|
2524 if (dump_opt['b'] >= 4) { |
|
2525 (void) printf("psize " |
|
2526 "(in 512-byte sectors): " |
|
2527 "number of blocks\n"); |
|
2528 dump_histogram(zb->zb_psize_histogram, |
|
2529 PSIZE_HISTO_SIZE); |
|
2530 } |
2490 } |
2531 } |
2491 } |
2532 } |
2492 } |
2533 } |
2493 |
2534 |
2494 (void) printf("\n"); |
2535 (void) printf("\n"); |