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