Illumos #1748: desire support for reguid in zfs
[zfs.git] / module / zfs / spa.c
index a43b883..31ffd45 100644 (file)
@@ -21,9 +21,8 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-/*
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
  */
 
 /*
@@ -572,6 +571,43 @@ spa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
 }
 
 /*
+ * Change the GUID for the pool.  This is done so that we can later
+ * re-import a pool built from a clone of our own vdevs.  We will modify
+ * the root vdev's guid, our own pool guid, and then mark all of our
+ * vdevs dirty.  Note that we must make sure that all our vdevs are
+ * online when we do this, or else any vdevs that weren't present
+ * would be orphaned from our pool.  We are also going to issue a
+ * sysevent to update any watchers.
+ */
+int
+spa_change_guid(spa_t *spa)
+{
+       uint64_t        oldguid, newguid;
+       uint64_t        txg;
+
+       if (!(spa_mode_global & FWRITE))
+               return (EROFS);
+
+       txg = spa_vdev_enter(spa);
+
+       if (spa->spa_root_vdev->vdev_state != VDEV_STATE_HEALTHY)
+               return (spa_vdev_exit(spa, NULL, txg, ENXIO));
+
+       oldguid = spa_guid(spa);
+       newguid = spa_generate_guid(NULL);
+       ASSERT3U(oldguid, !=, newguid);
+
+       spa->spa_root_vdev->vdev_guid = newguid;
+       spa->spa_root_vdev->vdev_guid_sum += (newguid - oldguid);
+
+       vdev_config_dirty(spa->spa_root_vdev);
+
+       spa_event_notify(spa, NULL, FM_EREPORT_ZFS_POOL_REGUID);
+
+       return (spa_vdev_exit(spa, NULL, txg, 0));
+}
+
+/*
  * ==========================================================================
  * SPA state manipulation (open/create/destroy/import/export)
  * ==========================================================================
@@ -1773,7 +1809,7 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type,
            spa_guid_exists(pool_guid, 0)) {
                error = EEXIST;
        } else {
-               spa->spa_load_guid = pool_guid;
+               spa->spa_config_guid = pool_guid;
 
                if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_SPLIT,
                    &nvl) == 0) {