summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/zfs/arc.c10
-rw-r--r--module/zfs/spa.c42
-rw-r--r--module/zfs/spa_misc.c16
-rw-r--r--module/zfs/vdev.c3
-rw-r--r--module/zfs/zfs_ioctl.c22
5 files changed, 83 insertions, 10 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index 7aa23ca15..aad37a39b 100644
--- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -20,6 +20,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.
*/
/*
@@ -1284,7 +1286,7 @@ arc_buf_alloc(spa_t *spa, int size, void *tag, arc_buf_contents_t type)
ASSERT(BUF_EMPTY(hdr));
hdr->b_size = size;
hdr->b_type = type;
- hdr->b_spa = spa_guid(spa);
+ hdr->b_spa = spa_load_guid(spa);
hdr->b_state = arc_anon;
hdr->b_arc_access = 0;
buf = kmem_cache_alloc(buf_cache, KM_PUSHPAGE);
@@ -2056,7 +2058,7 @@ arc_flush(spa_t *spa)
uint64_t guid = 0;
if (spa)
- guid = spa_guid(spa);
+ guid = spa_load_guid(spa);
while (list_head(&arc_mru->arcs_list[ARC_BUFC_DATA])) {
(void) arc_evict(arc_mru, guid, -1, FALSE, ARC_BUFC_DATA);
@@ -2887,7 +2889,7 @@ arc_read_nolock(zio_t *pio, spa_t *spa, const blkptr_t *bp,
arc_buf_t *buf = NULL;
kmutex_t *hash_lock;
zio_t *rzio;
- uint64_t guid = spa_guid(spa);
+ uint64_t guid = spa_load_guid(spa);
top:
hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
@@ -4522,7 +4524,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
boolean_t have_lock, full;
l2arc_write_callback_t *cb;
zio_t *pio, *wzio;
- uint64_t guid = spa_guid(spa);
+ uint64_t guid = spa_load_guid(spa);
int try;
ASSERT(dev->l2ad_vdev != NULL);
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index a43b88338..31ffd453f 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -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) {
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index 1016ac7be..c82dca6c5 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -1290,13 +1291,24 @@ spa_guid(spa_t *spa)
/*
* If we fail to parse the config during spa_load(), we can go through
* the error path (which posts an ereport) and end up here with no root
- * vdev. We stash the original pool guid in 'spa_load_guid' to handle
+ * vdev. We stash the original pool guid in 'spa_config_guid' to handle
* this case.
*/
if (spa->spa_root_vdev != NULL)
return (spa->spa_root_vdev->vdev_guid);
else
- return (spa->spa_load_guid);
+ return (spa->spa_config_guid);
+}
+
+uint64_t
+spa_load_guid(spa_t *spa)
+{
+ /*
+ * This is a GUID that exists solely as a reference for the
+ * purposes of the arc. It is generated at load time, and
+ * is never written to persistent storage.
+ */
+ return (spa->spa_load_guid);
}
uint64_t
diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c
index 1630d2fae..18d2d5ca6 100644
--- a/module/zfs/vdev.c
+++ b/module/zfs/vdev.c
@@ -21,6 +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.
*/
#include <sys/zfs_context.h>
@@ -291,6 +293,7 @@ vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid, vdev_ops_t *ops)
if (spa->spa_root_vdev == NULL) {
ASSERT(ops == &vdev_root_ops);
spa->spa_root_vdev = vd;
+ spa->spa_load_guid = spa_generate_guid(NULL);
}
if (guid == 0 && ops != &vdev_hole_ops) {
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index a232ed0d5..65b0a1975 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -24,6 +24,10 @@
* Portions Copyright 2012 Pawel Jakub Dawidek <[email protected]>
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/param.h>
@@ -1428,6 +1432,20 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
}
static int
+zfs_ioc_pool_reguid(zfs_cmd_t *zc)
+{
+ spa_t *spa;
+ int error;
+
+ error = spa_open(zc->zc_name, &spa, FTAG);
+ if (error == 0) {
+ error = spa_change_guid(spa);
+ spa_close(spa, FTAG);
+ }
+ return (error);
+}
+
+static int
zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
{
int error;
@@ -4698,10 +4716,12 @@ static zfs_ioc_vec_t zfs_ioc_vec[] = {
B_FALSE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
{ zfs_ioc_obj_to_stats, zfs_secpolicy_diff, DATASET_NAME, B_FALSE,
POOL_CHECK_SUSPENDED },
+ { zfs_ioc_pool_reguid, zfs_secpolicy_config, POOL_NAME, B_TRUE,
+ POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY },
{ zfs_ioc_events_next, zfs_secpolicy_config, NO_NAME, B_FALSE,
POOL_CHECK_NONE },
{ zfs_ioc_events_clear, zfs_secpolicy_config, NO_NAME, B_FALSE,
- POOL_CHECK_NONE },
+ POOL_CHECK_NONE }
};
int