Print this page
4168 ztest assertion failure in dbuf_undirty
4169 verbatim import causes zdb to segfault
4170 zhack leaves pool in ACTIVE state
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Eric Schrock <eric.schrock@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zhack/zhack.c
          +++ new/usr/src/cmd/zhack/zhack.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  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) 2012 by Delphix. All rights reserved.
       23 + * Copyright (c) 2013 by Delphix. All rights reserved.
  24   24   * Copyright (c) 2013 Steven Hartland. All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * zhack is a debugging tool that can write changes to ZFS pool using libzpool
  29   29   * for testing purposes. Altering pools with zhack is unsupported and may
  30   30   * result in corrupted pools.
  31   31   */
  32   32  
  33   33  #include <stdio.h>
↓ open down ↓ 44 lines elided ↑ open up ↑
  78   78              "        change the refcount on the given feature\n"
  79   79              "        -d decrease instead of increase the refcount\n"
  80   80              "        -m add the feature to the label if increasing refcount\n"
  81   81              "\n"
  82   82              "    <feature> : should be a feature guid\n");
  83   83          exit(1);
  84   84  }
  85   85  
  86   86  
  87   87  static void
  88      -fatal(const char *fmt, ...)
       88 +fatal(spa_t *spa, void *tag, const char *fmt, ...)
  89   89  {
  90   90          va_list ap;
  91   91  
       92 +        if (spa != NULL) {
       93 +                spa_close(spa, tag);
       94 +                (void) spa_export(g_pool, NULL, B_TRUE, B_FALSE);
       95 +        }
       96 +
  92   97          va_start(ap, fmt);
  93   98          (void) fprintf(stderr, "%s: ", cmdname);
  94   99          (void) vfprintf(stderr, fmt, ap);
  95  100          va_end(ap);
  96  101          (void) fprintf(stderr, "\n");
  97  102  
  98  103          exit(1);
  99  104  }
 100  105  
 101  106  /* ARGSUSED */
↓ open down ↓ 50 lines elided ↑ open up ↑
 152  157          if ((sepp = strpbrk(g_pool, "/@")) != NULL)
 153  158                  *sepp = '\0';
 154  159          g_importargs.poolname = g_pool;
 155  160          pools = zpool_search_import(g_zfs, &g_importargs);
 156  161  
 157  162          if (nvlist_empty(pools)) {
 158  163                  if (!g_importargs.can_be_active) {
 159  164                          g_importargs.can_be_active = B_TRUE;
 160  165                          if (zpool_search_import(g_zfs, &g_importargs) != NULL ||
 161  166                              spa_open(target, &spa, FTAG) == 0) {
 162      -                                fatal("cannot import '%s': pool is active; run "
 163      -                                    "\"zpool export %s\" first\n",
 164      -                                    g_pool, g_pool);
      167 +                                fatal(spa, FTAG, "cannot import '%s': pool is "
      168 +                                    "active; run " "\"zpool export %s\" "
      169 +                                    "first\n", g_pool, g_pool);
 165  170                          }
 166  171                  }
 167  172  
 168      -                fatal("cannot import '%s': no such pool available\n", g_pool);
      173 +                fatal(NULL, FTAG, "cannot import '%s': no such pool "
      174 +                    "available\n", g_pool);
 169  175          }
 170  176  
 171  177          elem = nvlist_next_nvpair(pools, NULL);
 172  178          name = nvpair_name(elem);
 173  179          verify(nvpair_value_nvlist(elem, &config) == 0);
 174  180  
 175  181          props = NULL;
 176  182          if (readonly) {
 177  183                  verify(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
 178  184                  verify(nvlist_add_uint64(props,
 179  185                      zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0);
 180  186          }
 181  187  
 182  188          zfeature_checks_disable = B_TRUE;
 183  189          error = spa_import(name, config, props, ZFS_IMPORT_NORMAL);
 184  190          zfeature_checks_disable = B_FALSE;
 185  191          if (error == EEXIST)
 186  192                  error = 0;
 187  193  
 188  194          if (error)
 189      -                fatal("can't import '%s': %s", name, strerror(error));
      195 +                fatal(NULL, FTAG, "can't import '%s': %s", name,
      196 +                    strerror(error));
 190  197  }
 191  198  
 192  199  static void
 193  200  zhack_spa_open(const char *target, boolean_t readonly, void *tag, spa_t **spa)
 194  201  {
 195  202          int err;
 196  203  
 197  204          import_pool(target, readonly);
 198  205  
 199  206          zfeature_checks_disable = B_TRUE;
 200  207          err = spa_open(target, spa, tag);
 201  208          zfeature_checks_disable = B_FALSE;
 202  209  
 203  210          if (err != 0)
 204      -                fatal("cannot open '%s': %s", target, strerror(err));
      211 +                fatal(*spa, FTAG, "cannot open '%s': %s", target,
      212 +                    strerror(err));
 205  213          if (spa_version(*spa) < SPA_VERSION_FEATURES) {
 206      -                fatal("'%s' has version %d, features not enabled", target,
 207      -                    (int)spa_version(*spa));
      214 +                fatal(*spa, FTAG, "'%s' has version %d, features not enabled",
      215 +                    target, (int)spa_version(*spa));
 208  216          }
 209  217  }
 210  218  
 211  219  static void
 212  220  dump_obj(objset_t *os, uint64_t obj, const char *name)
 213  221  {
 214  222          zap_cursor_t zc;
 215  223          zap_attribute_t za;
 216  224  
 217  225          (void) printf("%s_obj:\n", name);
↓ open down ↓ 111 lines elided ↑ open up ↑
 329  337          argv += optind;
 330  338  
 331  339          if (argc < 2) {
 332  340                  (void) fprintf(stderr, "error: missing feature or pool name\n");
 333  341                  usage();
 334  342          }
 335  343          target = argv[0];
 336  344          feature.fi_guid = argv[1];
 337  345  
 338  346          if (!zfeature_is_valid_guid(feature.fi_guid))
 339      -                fatal("invalid feature guid: %s", feature.fi_guid);
      347 +                fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
 340  348  
 341  349          zhack_spa_open(target, B_FALSE, FTAG, &spa);
 342  350          mos = spa->spa_meta_objset;
 343  351  
 344  352          if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
 345      -                fatal("'%s' is a real feature, will not enable");
      353 +                fatal(spa, FTAG, "'%s' is a real feature, will not enable");
 346  354          if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
 347      -                fatal("feature already enabled: %s", feature.fi_guid);
      355 +                fatal(spa, FTAG, "feature already enabled: %s",
      356 +                    feature.fi_guid);
 348  357  
 349  358          VERIFY0(dsl_sync_task(spa_name(spa), NULL,
 350  359              feature_enable_sync, &feature, 5));
 351  360  
 352  361          spa_close(spa, FTAG);
 353  362  
 354  363          free(desc);
 355  364  }
 356  365  
 357  366  static void
↓ open down ↓ 58 lines elided ↑ open up ↑
 416  425          argv += optind;
 417  426  
 418  427          if (argc < 2) {
 419  428                  (void) fprintf(stderr, "error: missing feature or pool name\n");
 420  429                  usage();
 421  430          }
 422  431          target = argv[0];
 423  432          feature.fi_guid = argv[1];
 424  433  
 425  434          if (!zfeature_is_valid_guid(feature.fi_guid))
 426      -                fatal("invalid feature guid: %s", feature.fi_guid);
      435 +                fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
 427  436  
 428  437          zhack_spa_open(target, B_FALSE, FTAG, &spa);
 429  438          mos = spa->spa_meta_objset;
 430  439  
 431  440          if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
 432      -                fatal("'%s' is a real feature, will not change refcount");
      441 +                fatal(spa, FTAG, "'%s' is a real feature, will not change "
      442 +                    "refcount");
 433  443  
 434  444          if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
 435  445              feature.fi_guid)) {
 436  446                  feature.fi_can_readonly = B_FALSE;
 437  447          } else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
 438  448              feature.fi_guid)) {
 439  449                  feature.fi_can_readonly = B_TRUE;
 440  450          } else {
 441      -                fatal("feature is not enabled: %s", feature.fi_guid);
      451 +                fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
 442  452          }
 443  453  
 444  454          if (decr && !spa_feature_is_active(spa, &feature))
 445      -                fatal("feature refcount already 0: %s", feature.fi_guid);
      455 +                fatal(spa, FTAG, "feature refcount already 0: %s",
      456 +                    feature.fi_guid);
 446  457  
 447  458          VERIFY0(dsl_sync_task(spa_name(spa), NULL,
 448  459              decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
 449  460  
 450  461          spa_close(spa, FTAG);
 451  462  }
 452  463  
 453  464  static int
 454  465  zhack_do_feature(int argc, char **argv)
 455  466  {
↓ open down ↓ 67 lines elided ↑ open up ↑
 523  534          subcommand = argv[0];
 524  535  
 525  536          if (strcmp(subcommand, "feature") == 0) {
 526  537                  rv = zhack_do_feature(argc, argv);
 527  538          } else {
 528  539                  (void) fprintf(stderr, "error: unknown subcommand: %s\n",
 529  540                      subcommand);
 530  541                  usage();
 531  542          }
 532  543  
 533      -        if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_TRUE) != 0) {
 534      -                fatal("pool export failed; "
      544 +        if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_FALSE) != 0) {
      545 +                fatal(NULL, FTAG, "pool export failed; "
 535  546                      "changes may not be committed to disk\n");
 536  547          }
 537  548  
 538  549          libzfs_fini(g_zfs);
 539  550          kernel_fini();
 540  551  
 541  552          return (rv);
 542  553  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX