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