Print this page
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/spa.c
          +++ new/usr/src/uts/common/fs/zfs/spa.c
↓ open down ↓ 2537 lines elided ↑ open up ↑
2538 2538                          spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
2539 2539  
2540 2540                  /*
2541 2541                   * Check all DTLs to see if anything needs resilvering.
2542 2542                   */
2543 2543                  if (!dsl_scan_resilvering(spa->spa_dsl_pool) &&
2544 2544                      vdev_resilver_needed(rvd, NULL, NULL))
2545 2545                          spa_async_request(spa, SPA_ASYNC_RESILVER);
2546 2546  
2547 2547                  /*
     2548 +                 * Log the fact that we booted up (so that we can detect if
     2549 +                 * we rebooted in the middle of an operation).
     2550 +                 */
     2551 +                spa_history_log_version(spa, "open");
     2552 +
     2553 +                /*
2548 2554                   * Delete any inconsistent datasets.
2549 2555                   */
2550 2556                  (void) dmu_objset_find(spa_name(spa),
2551 2557                      dsl_destroy_inconsistent, NULL, DS_FIND_CHILDREN);
2552 2558  
2553 2559                  /*
2554 2560                   * Clean up any stale temporary dataset userrefs.
2555 2561                   */
2556 2562                  dsl_pool_clean_tmp_userrefs(spa->spa_dsl_pool);
2557 2563          }
↓ open down ↓ 655 lines elided ↑ open up ↑
3213 3219                      pool != 0ULL && l2arc_vdev_present(vd))
3214 3220                          l2arc_remove_vdev(vd);
3215 3221          }
3216 3222  }
3217 3223  
3218 3224  /*
3219 3225   * Pool Creation
3220 3226   */
3221 3227  int
3222 3228  spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
3223      -    const char *history_str, nvlist_t *zplprops)
     3229 +    nvlist_t *zplprops)
3224 3230  {
3225 3231          spa_t *spa;
3226 3232          char *altroot = NULL;
3227 3233          vdev_t *rvd;
3228 3234          dsl_pool_t *dp;
3229 3235          dmu_tx_t *tx;
3230 3236          int error = 0;
3231 3237          uint64_t txg = TXG_INITIAL;
3232 3238          nvlist_t **spares, **l2cache;
3233 3239          uint_t nspares, nl2cache;
↓ open down ↓ 198 lines elided ↑ open up ↑
3432 3438          txg_sync_start(spa->spa_dsl_pool);
3433 3439  
3434 3440          /*
3435 3441           * We explicitly wait for the first transaction to complete so that our
3436 3442           * bean counters are appropriately updated.
3437 3443           */
3438 3444          txg_wait_synced(spa->spa_dsl_pool, txg);
3439 3445  
3440 3446          spa_config_sync(spa, B_FALSE, B_TRUE);
3441 3447  
3442      -        if (version >= SPA_VERSION_ZPOOL_HISTORY && history_str != NULL)
3443      -                (void) spa_history_log(spa, history_str, LOG_CMD_POOL_CREATE);
3444      -        spa_history_log_version(spa, LOG_POOL_CREATE);
     3448 +        spa_history_log_version(spa, "create");
3445 3449  
3446 3450          spa->spa_minref = refcount_count(&spa->spa_refcount);
3447 3451  
3448 3452          mutex_exit(&spa_namespace_lock);
3449 3453  
3450 3454          return (0);
3451 3455  }
3452 3456  
3453 3457  #ifdef _KERNEL
3454 3458  /*
↓ open down ↓ 179 lines elided ↑ open up ↑
3634 3638              !bvd->vdev_isspare) {
3635 3639                  cmn_err(CE_NOTE, "The boot device is currently spared. Please "
3636 3640                      "try booting from '%s'",
3637 3641                      bvd->vdev_parent->
3638 3642                      vdev_child[bvd->vdev_parent->vdev_children - 1]->vdev_path);
3639 3643                  error = EINVAL;
3640 3644                  goto out;
3641 3645          }
3642 3646  
3643 3647          error = 0;
3644      -        spa_history_log_version(spa, LOG_POOL_IMPORT);
3645 3648  out:
3646 3649          spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
3647 3650          vdev_free(rvd);
3648 3651          spa_config_exit(spa, SCL_ALL, FTAG);
3649 3652          mutex_exit(&spa_namespace_lock);
3650 3653  
3651 3654          nvlist_free(config);
3652 3655          return (error);
3653 3656  }
3654 3657  
↓ open down ↓ 41 lines elided ↑ open up ↑
3696 3699           * Verbatim import - Take a pool and insert it into the namespace
3697 3700           * as if it had been loaded at boot.
3698 3701           */
3699 3702          if (spa->spa_import_flags & ZFS_IMPORT_VERBATIM) {
3700 3703                  if (props != NULL)
3701 3704                          spa_configfile_set(spa, props, B_FALSE);
3702 3705  
3703 3706                  spa_config_sync(spa, B_FALSE, B_TRUE);
3704 3707  
3705 3708                  mutex_exit(&spa_namespace_lock);
3706      -                spa_history_log_version(spa, LOG_POOL_IMPORT);
     3709 +                spa_history_log_version(spa, "import");
3707 3710  
3708 3711                  return (0);
3709 3712          }
3710 3713  
3711 3714          spa_activate(spa, mode);
3712 3715  
3713 3716          /*
3714 3717           * Don't start async tasks until we know everything is healthy.
3715 3718           */
3716 3719          spa_async_suspend(spa);
↓ open down ↓ 110 lines elided ↑ open up ↑
3827 3830                  spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
3828 3831          }
3829 3832  
3830 3833          /*
3831 3834           * It's possible that the pool was expanded while it was exported.
3832 3835           * We kick off an async task to handle this for us.
3833 3836           */
3834 3837          spa_async_request(spa, SPA_ASYNC_AUTOEXPAND);
3835 3838  
3836 3839          mutex_exit(&spa_namespace_lock);
3837      -        spa_history_log_version(spa, LOG_POOL_IMPORT);
     3840 +        spa_history_log_version(spa, "import");
3838 3841  
3839 3842          return (0);
3840 3843  }
3841 3844  
3842 3845  nvlist_t *
3843 3846  spa_tryimport(nvlist_t *tryconfig)
3844 3847  {
3845 3848          nvlist_t *config = NULL;
3846 3849          char *poolname;
3847 3850          spa_t *spa;
↓ open down ↓ 517 lines elided ↑ open up ↑
4365 4368          /*
4366 4369           * Restart the resilver
4367 4370           */
4368 4371          dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg);
4369 4372  
4370 4373          /*
4371 4374           * Commit the config
4372 4375           */
4373 4376          (void) spa_vdev_exit(spa, newrootvd, dtl_max_txg, 0);
4374 4377  
4375      -        spa_history_log_internal(LOG_POOL_VDEV_ATTACH, spa, NULL,
     4378 +        spa_history_log_internal(spa, "vdev attach", NULL,
4376 4379              "%s vdev=%s %s vdev=%s",
4377 4380              replacing && newvd_isspare ? "spare in" :
4378 4381              replacing ? "replace" : "attach", newvdpath,
4379 4382              replacing ? "for" : "to", oldvdpath);
4380 4383  
4381 4384          spa_strfree(oldvdpath);
4382 4385          spa_strfree(newvdpath);
4383 4386  
4384 4387          if (spa->spa_bootfs)
4385 4388                  spa_event_notify(spa, newvd, ESC_ZFS_BOOTFS_VDEV_ATTACH);
↓ open down ↓ 196 lines elided ↑ open up ↑
4582 4585          vd->vdev_detached = B_TRUE;
4583 4586          vdev_dirty(tvd, VDD_DTL, vd, txg);
4584 4587  
4585 4588          spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE);
4586 4589  
4587 4590          /* hang on to the spa before we release the lock */
4588 4591          spa_open_ref(spa, FTAG);
4589 4592  
4590 4593          error = spa_vdev_exit(spa, vd, txg, 0);
4591 4594  
4592      -        spa_history_log_internal(LOG_POOL_VDEV_DETACH, spa, NULL,
     4595 +        spa_history_log_internal(spa, "detach", NULL,
4593 4596              "vdev=%s", vdpath);
4594 4597          spa_strfree(vdpath);
4595 4598  
4596 4599          /*
4597 4600           * If this was the removal of the original device in a hot spare vdev,
4598 4601           * then we want to go through and remove the device from the hot spare
4599 4602           * list of every other pool.
4600 4603           */
4601 4604          if (unspare) {
4602 4605                  spa_t *altspa = NULL;
↓ open down ↓ 248 lines elided ↑ open up ↑
4851 4854          /* finally, update the original pool's config */
4852 4855          txg = spa_vdev_config_enter(spa);
4853 4856          tx = dmu_tx_create_dd(spa_get_dsl(spa)->dp_mos_dir);
4854 4857          error = dmu_tx_assign(tx, TXG_WAIT);
4855 4858          if (error != 0)
4856 4859                  dmu_tx_abort(tx);
4857 4860          for (c = 0; c < children; c++) {
4858 4861                  if (vml[c] != NULL) {
4859 4862                          vdev_split(vml[c]);
4860 4863                          if (error == 0)
4861      -                                spa_history_log_internal(LOG_POOL_VDEV_DETACH,
4862      -                                    spa, tx, "vdev=%s",
4863      -                                    vml[c]->vdev_path);
     4864 +                                spa_history_log_internal(spa, "detach", tx,
     4865 +                                    "vdev=%s", vml[c]->vdev_path);
4864 4866                          vdev_free(vml[c]);
4865 4867                  }
4866 4868          }
4867 4869          vdev_config_dirty(spa->spa_root_vdev);
4868 4870          spa->spa_config_splitting = NULL;
4869 4871          nvlist_free(nvl);
4870 4872          if (error == 0)
4871 4873                  dmu_tx_commit(tx);
4872 4874          (void) spa_vdev_exit(spa, NULL, txg, 0);
4873 4875  
4874 4876          if (zio_injection_enabled)
4875 4877                  zio_handle_panic_injection(spa, FTAG, 3);
4876 4878  
4877 4879          /* split is complete; log a history record */
4878      -        spa_history_log_internal(LOG_POOL_SPLIT, newspa, NULL,
4879      -            "split new pool %s from pool %s", newname, spa_name(spa));
     4880 +        spa_history_log_internal(newspa, "split", NULL,
     4881 +            "from pool %s", spa_name(spa));
4880 4882  
4881 4883          kmem_free(vml, children * sizeof (vdev_t *));
4882 4884  
4883 4885          /* if we're not going to mount the filesystems in userland, export */
4884 4886          if (exp)
4885 4887                  error = spa_export_common(newname, POOL_STATE_EXPORTED, NULL,
4886 4888                      B_FALSE, B_FALSE);
4887 4889  
4888 4890          return (error);
4889 4891  
↓ open down ↓ 565 lines elided ↑ open up ↑
5455 5457                  old_space = metaslab_class_get_space(spa_normal_class(spa));
5456 5458                  spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
5457 5459                  new_space = metaslab_class_get_space(spa_normal_class(spa));
5458 5460                  mutex_exit(&spa_namespace_lock);
5459 5461  
5460 5462                  /*
5461 5463                   * If the pool grew as a result of the config update,
5462 5464                   * then log an internal history event.
5463 5465                   */
5464 5466                  if (new_space != old_space) {
5465      -                        spa_history_log_internal(LOG_POOL_VDEV_ONLINE,
5466      -                            spa, NULL,
     5467 +                        spa_history_log_internal(spa, "vdev online", NULL,
5467 5468                              "pool '%s' size: %llu(+%llu)",
5468 5469                              spa_name(spa), new_space, new_space - old_space);
5469 5470                  }
5470 5471          }
5471 5472  
5472 5473          /*
5473 5474           * See if any devices need to be marked REMOVED.
5474 5475           */
5475 5476          if (tasks & SPA_ASYNC_REMOVE) {
5476 5477                  spa_vdev_state_enter(spa, SCL_NONE);
↓ open down ↓ 215 lines elided ↑ open up ↑
5692 5693          /*
5693 5694           * Setting the version is special cased when first creating the pool.
5694 5695           */
5695 5696          ASSERT(tx->tx_txg != TXG_INITIAL);
5696 5697  
5697 5698          ASSERT(version <= SPA_VERSION);
5698 5699          ASSERT(version >= spa_version(spa));
5699 5700  
5700 5701          spa->spa_uberblock.ub_version = version;
5701 5702          vdev_config_dirty(spa->spa_root_vdev);
     5703 +        spa_history_log_internal(spa, "set", tx, "version=%lld", version);
5702 5704  }
5703 5705  
5704 5706  /*
5705 5707   * Set zpool properties.
5706 5708   */
5707 5709  static void
5708 5710  spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
5709 5711  {
5710 5712          spa_t *spa = arg1;
5711 5713          objset_t *mos = spa->spa_meta_objset;
↓ open down ↓ 14 lines elided ↑ open up ↑
5726 5728                  case ZPROP_INVAL:
5727 5729                          /*
5728 5730                           * We checked this earlier in spa_prop_validate().
5729 5731                           */
5730 5732                          ASSERT(zpool_prop_feature(nvpair_name(elem)));
5731 5733  
5732 5734                          fname = strchr(nvpair_name(elem), '@') + 1;
5733 5735                          VERIFY3U(0, ==, zfeature_lookup_name(fname, &feature));
5734 5736  
5735 5737                          spa_feature_enable(spa, feature, tx);
     5738 +                        spa_history_log_internal(spa, "set", tx,
     5739 +                            "%s=enabled", nvpair_name(elem));
5736 5740                          break;
5737 5741  
5738 5742                  case ZPOOL_PROP_VERSION:
5739 5743                          VERIFY(nvpair_value_uint64(elem, &intval) == 0);
5740 5744                          /*
5741 5745                           * The version is synced seperatly before other
5742 5746                           * properties and should be correct by now.
5743 5747                           */
5744 5748                          ASSERT3U(spa_version(spa), >=, intval);
5745 5749                          break;
↓ open down ↓ 19 lines elided ↑ open up ↑
5765 5769                                  spa_strfree(spa->spa_comment);
5766 5770                          spa->spa_comment = spa_strdup(strval);
5767 5771                          /*
5768 5772                           * We need to dirty the configuration on all the vdevs
5769 5773                           * so that their labels get updated.  It's unnecessary
5770 5774                           * to do this for pool creation since the vdev's
5771 5775                           * configuratoin has already been dirtied.
5772 5776                           */
5773 5777                          if (tx->tx_txg != TXG_INITIAL)
5774 5778                                  vdev_config_dirty(spa->spa_root_vdev);
     5779 +                        spa_history_log_internal(spa, "set", tx,
     5780 +                            "%s=%s", nvpair_name(elem), strval);
5775 5781                          break;
5776 5782                  default:
5777 5783                          /*
5778 5784                           * Set pool property values in the poolprops mos object.
5779 5785                           */
5780 5786                          if (spa->spa_pool_props_object == 0) {
5781 5787                                  spa->spa_pool_props_object =
5782 5788                                      zap_create_link(mos, DMU_OT_POOL_PROPS,
5783 5789                                      DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS,
5784 5790                                      tx);
↓ open down ↓ 2 lines elided ↑ open up ↑
5787 5793                          /* normalize the property name */
5788 5794                          propname = zpool_prop_to_name(prop);
5789 5795                          proptype = zpool_prop_get_type(prop);
5790 5796  
5791 5797                          if (nvpair_type(elem) == DATA_TYPE_STRING) {
5792 5798                                  ASSERT(proptype == PROP_TYPE_STRING);
5793 5799                                  VERIFY(nvpair_value_string(elem, &strval) == 0);
5794 5800                                  VERIFY(zap_update(mos,
5795 5801                                      spa->spa_pool_props_object, propname,
5796 5802                                      1, strlen(strval) + 1, strval, tx) == 0);
5797      -
     5803 +                                spa_history_log_internal(spa, "set", tx,
     5804 +                                    "%s=%s", nvpair_name(elem), strval);
5798 5805                          } else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
5799 5806                                  VERIFY(nvpair_value_uint64(elem, &intval) == 0);
5800 5807  
5801 5808                                  if (proptype == PROP_TYPE_INDEX) {
5802 5809                                          const char *unused;
5803 5810                                          VERIFY(zpool_prop_index_to_string(
5804 5811                                              prop, intval, &unused) == 0);
5805 5812                                  }
5806 5813                                  VERIFY(zap_update(mos,
5807 5814                                      spa->spa_pool_props_object, propname,
5808 5815                                      8, 1, &intval, tx) == 0);
     5816 +                                spa_history_log_internal(spa, "set", tx,
     5817 +                                    "%s=%lld", nvpair_name(elem), intval);
5809 5818                          } else {
5810 5819                                  ASSERT(0); /* not allowed */
5811 5820                          }
5812 5821  
5813 5822                          switch (prop) {
5814 5823                          case ZPOOL_PROP_DELEGATION:
5815 5824                                  spa->spa_delegation = intval;
5816 5825                                  break;
5817 5826                          case ZPOOL_PROP_BOOTFS:
5818 5827                                  spa->spa_bootfs = intval;
↓ open down ↓ 8 lines elided ↑ open up ↑
5827 5836                                              SPA_ASYNC_AUTOEXPAND);
5828 5837                                  break;
5829 5838                          case ZPOOL_PROP_DEDUPDITTO:
5830 5839                                  spa->spa_dedup_ditto = intval;
5831 5840                                  break;
5832 5841                          default:
5833 5842                                  break;
5834 5843                          }
5835 5844                  }
5836 5845  
5837      -                /* log internal history if this is not a zpool create */
5838      -                if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY &&
5839      -                    tx->tx_txg != TXG_INITIAL) {
5840      -                        spa_history_log_internal(LOG_POOL_PROPSET,
5841      -                            spa, tx, "%s %lld %s",
5842      -                            nvpair_name(elem), intval, spa_name(spa));
5843      -                }
5844 5846          }
5845 5847  
5846 5848          mutex_exit(&spa->spa_props_lock);
5847 5849  }
5848 5850  
5849 5851  /*
5850 5852   * Perform one-time upgrade on-disk changes.  spa_version() does not
5851 5853   * reflect the new version this txg, so there must be no changes this
5852 5854   * txg to anything that the upgrade code depends on after it executes.
5853 5855   * Therefore this must be called after dsl_pool_sync() does the sync
↓ open down ↓ 471 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX