summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorGeorge Wilson <George.Wilson@Sun.COM>2008-11-24 16:10:21 -0800
committerGeorge Wilson <George.Wilson@Sun.COM>2008-11-24 16:10:21 -0800
commit394ab0cbe9de0b3be5bf232d9224a9d050999ae5 (patch)
treeb61cca2d34a4d884a55bcc7f166dcc9951cc421e /usr
parent1cd8b493b0a45858d806ce12a9ce6efdc1426827 (diff)
downloadillumos-joyent-394ab0cbe9de0b3be5bf232d9224a9d050999ae5.tar.gz
6775357 ZFS should have a way to export a pool without touching anything
Diffstat (limited to 'usr')
-rw-r--r--usr/src/cmd/zpool/zpool_main.c12
-rw-r--r--usr/src/cmd/ztest/ztest.c2
-rw-r--r--usr/src/lib/libzfs/common/libzfs.h1
-rw-r--r--usr/src/lib/libzfs/common/libzfs_pool.c15
-rw-r--r--usr/src/lib/libzfs/common/mapfile-vers1
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c21
-rw-r--r--usr/src/uts/common/fs/zfs/sys/spa.h3
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c3
8 files changed, 44 insertions, 14 deletions
diff --git a/usr/src/cmd/zpool/zpool_main.c b/usr/src/cmd/zpool/zpool_main.c
index 54bba8645c..1bca45c80f 100644
--- a/usr/src/cmd/zpool/zpool_main.c
+++ b/usr/src/cmd/zpool/zpool_main.c
@@ -877,17 +877,21 @@ int
zpool_do_export(int argc, char **argv)
{
boolean_t force = B_FALSE;
+ boolean_t hardforce = B_FALSE;
int c;
zpool_handle_t *zhp;
int ret;
int i;
/* check options */
- while ((c = getopt(argc, argv, "f")) != -1) {
+ while ((c = getopt(argc, argv, "fF")) != -1) {
switch (c) {
case 'f':
force = B_TRUE;
break;
+ case 'F':
+ hardforce = B_TRUE;
+ break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@@ -917,8 +921,12 @@ zpool_do_export(int argc, char **argv)
continue;
}
- if (zpool_export(zhp, force) != 0)
+ if (hardforce) {
+ if (zpool_export_force(zhp) != 0)
+ ret = 1;
+ } else if (zpool_export(zhp, force) != 0) {
ret = 1;
+ }
zpool_close(zhp);
}
diff --git a/usr/src/cmd/ztest/ztest.c b/usr/src/cmd/ztest/ztest.c
index 53cc6c7093..dceb04e937 100644
--- a/usr/src/cmd/ztest/ztest.c
+++ b/usr/src/cmd/ztest/ztest.c
@@ -2883,7 +2883,7 @@ ztest_spa_import_export(char *oldname, char *newname)
/*
* Export it.
*/
- error = spa_export(oldname, &config, B_FALSE);
+ error = spa_export(oldname, &config, B_FALSE, B_FALSE);
if (error)
fatal(0, "spa_export('%s') = %d", oldname, error);
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h
index c650865f30..b587521a31 100644
--- a/usr/src/lib/libzfs/common/libzfs.h
+++ b/usr/src/lib/libzfs/common/libzfs.h
@@ -289,6 +289,7 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
* Import and export functions
*/
extern int zpool_export(zpool_handle_t *, boolean_t);
+extern int zpool_export_force(zpool_handle_t *);
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
char *altroot);
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c
index 18ceb48596..9cb5d76421 100644
--- a/usr/src/lib/libzfs/common/libzfs_pool.c
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c
@@ -1127,7 +1127,7 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
* mounted datasets in the pool.
*/
int
-zpool_export(zpool_handle_t *zhp, boolean_t force)
+zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
{
zfs_cmd_t zc = { 0 };
char msg[1024];
@@ -1140,6 +1140,7 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
zc.zc_cookie = force;
+ zc.zc_guid = hardforce;
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
switch (errno) {
@@ -1160,6 +1161,18 @@ zpool_export(zpool_handle_t *zhp, boolean_t force)
return (0);
}
+int
+zpool_export(zpool_handle_t *zhp, boolean_t force)
+{
+ return (zpool_export_common(zhp, force, B_FALSE));
+}
+
+int
+zpool_export_force(zpool_handle_t *zhp)
+{
+ return (zpool_export_common(zhp, B_TRUE, B_TRUE));
+}
+
/*
* zpool_import() is a contracted interface. Should be kept the same
* if possible.
diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers
index 6ddffbcf1a..20c9b3fa45 100644
--- a/usr/src/lib/libzfs/common/mapfile-vers
+++ b/usr/src/lib/libzfs/common/mapfile-vers
@@ -121,6 +121,7 @@ SUNWprivate_1.1 {
zpool_enable_datasets;
zpool_expand_proplist;
zpool_export;
+ zpool_export_force;
zpool_find_import;
zpool_find_import_activeok;
zpool_find_import_byguid;
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c
index fb1b96f8b8..5a03db234b 100644
--- a/usr/src/uts/common/fs/zfs/spa.c
+++ b/usr/src/uts/common/fs/zfs/spa.c
@@ -2563,11 +2563,12 @@ spa_tryimport(nvlist_t *tryconfig)
* The act of destroying or exporting a pool is very simple. We make sure there
* is no more pending I/O and any references to the pool are gone. Then, we
* update the pool state and sync all the labels to disk, removing the
- * configuration from the cache afterwards.
+ * configuration from the cache afterwards. If the 'hardforce' flag is set, then
+ * we don't sync the labels or remove the configuration cache.
*/
static int
spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
- boolean_t force)
+ boolean_t force, boolean_t hardforce)
{
spa_t *spa;
@@ -2635,7 +2636,7 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
* so mark them all dirty. spa_unload() will do the
* final sync that pushes these changes out.
*/
- if (new_state != POOL_STATE_UNINITIALIZED) {
+ if (new_state != POOL_STATE_UNINITIALIZED && !hardforce) {
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
spa->spa_state = new_state;
spa->spa_final_txg = spa_last_synced_txg(spa) + 1;
@@ -2655,7 +2656,8 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0);
if (new_state != POOL_STATE_UNINITIALIZED) {
- spa_config_sync(spa, B_TRUE, B_TRUE);
+ if (!hardforce)
+ spa_config_sync(spa, B_TRUE, B_TRUE);
spa_remove(spa);
}
mutex_exit(&spa_namespace_lock);
@@ -2669,16 +2671,19 @@ spa_export_common(char *pool, int new_state, nvlist_t **oldconfig,
int
spa_destroy(char *pool)
{
- return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL, B_FALSE));
+ return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL,
+ B_FALSE, B_FALSE));
}
/*
* Export a storage pool.
*/
int
-spa_export(char *pool, nvlist_t **oldconfig, boolean_t force)
+spa_export(char *pool, nvlist_t **oldconfig, boolean_t force,
+ boolean_t hardforce)
{
- return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig, force));
+ return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig,
+ force, hardforce));
}
/*
@@ -2689,7 +2694,7 @@ int
spa_reset(char *pool)
{
return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL,
- B_FALSE));
+ B_FALSE, B_FALSE));
}
/*
diff --git a/usr/src/uts/common/fs/zfs/sys/spa.h b/usr/src/uts/common/fs/zfs/sys/spa.h
index 24b3ca4476..c3b40a4192 100644
--- a/usr/src/uts/common/fs/zfs/sys/spa.h
+++ b/usr/src/uts/common/fs/zfs/sys/spa.h
@@ -332,7 +332,8 @@ extern int spa_import(const char *pool, nvlist_t *config, nvlist_t *props);
extern int spa_import_faulted(const char *, nvlist_t *, nvlist_t *);
extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
extern int spa_destroy(char *pool);
-extern int spa_export(char *pool, nvlist_t **oldconfig, boolean_t force);
+extern int spa_export(char *pool, nvlist_t **oldconfig, boolean_t force,
+ boolean_t hardforce);
extern int spa_reset(char *pool);
extern void spa_async_request(spa_t *spa, int flag);
extern void spa_async_unrequest(spa_t *spa, int flag);
diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index c77892f90a..b8d87890ee 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -856,9 +856,10 @@ zfs_ioc_pool_export(zfs_cmd_t *zc)
{
int error;
boolean_t force = (boolean_t)zc->zc_cookie;
+ boolean_t hardforce = (boolean_t)zc->zc_guid;
zfs_log_history(zc);
- error = spa_export(zc->zc_name, NULL, force);
+ error = spa_export(zc->zc_name, NULL, force, hardforce);
return (error);
}