case HELP_DETACH:
return (gettext("\tdetach <pool> <device>\n"));
case HELP_EXPORT:
- return (gettext("\texport [-f] <pool> ...\n"));
+ return (gettext("\texport [-af] <pool> ...\n"));
case HELP_HISTORY:
return (gettext("\thistory [-il] [<pool>] ...\n"));
case HELP_IMPORT:
return (ret);
}
+typedef struct export_cbdata {
+ boolean_t force;
+ boolean_t hardforce;
+} export_cbdata_t;
+
+/*
+ * Export one pool
+ */
+int
+zpool_export_one(zpool_handle_t *zhp, void *data)
+{
+ export_cbdata_t *cb = data;
+
+ if (zpool_disable_datasets(zhp, cb->force) != 0)
+ return (1);
+
+ /* The history must be logged as part of the export */
+ log_history = B_FALSE;
+
+ if (cb->hardforce) {
+ if (zpool_export_force(zhp, history_str) != 0)
+ return (1);
+ } else if (zpool_export(zhp, cb->force, history_str) != 0) {
+ return (1);
+ }
+
+ return (0);
+}
+
/*
* zpool export [-f] <pool> ...
*
+ * -a Export all pools
* -f Forcefully unmount datasets
*
* Export the given pools. By default, the command will attempt to cleanly
int
zpool_do_export(int argc, char **argv)
{
+ export_cbdata_t cb;
+ boolean_t do_all = B_FALSE;
boolean_t force = B_FALSE;
boolean_t hardforce = B_FALSE;
- int c;
- zpool_handle_t *zhp;
- int ret;
- int i;
+ int c, ret;
/* check options */
- while ((c = getopt(argc, argv, "fF")) != -1) {
+ while ((c = getopt(argc, argv, "afF")) != -1) {
switch (c) {
+ case 'a':
+ do_all = B_TRUE;
+ break;
case 'f':
force = B_TRUE;
break;
}
}
+ cb.force = force;
+ cb.hardforce = hardforce;
argc -= optind;
argv += optind;
+ if (do_all) {
+ if (argc != 0) {
+ (void) fprintf(stderr, gettext("too many arguments\n"));
+ usage(B_FALSE);
+ }
+
+ return (for_each_pool(argc, argv, B_TRUE, NULL,
+ zpool_export_one, &cb));
+ }
+
/* check arguments */
if (argc < 1) {
(void) fprintf(stderr, gettext("missing pool argument\n"));
usage(B_FALSE);
}
- ret = 0;
- for (i = 0; i < argc; i++) {
- if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
- ret = 1;
- continue;
- }
-
- if (zpool_disable_datasets(zhp, force) != 0) {
- ret = 1;
- zpool_close(zhp);
- continue;
- }
-
- /* The history must be logged as part of the export */
- log_history = B_FALSE;
-
- if (hardforce) {
- if (zpool_export_force(zhp, history_str) != 0)
- ret = 1;
- } else if (zpool_export(zhp, force, history_str) != 0) {
- ret = 1;
- }
-
- zpool_close(zhp);
- }
+ ret = for_each_pool(argc, argv, B_TRUE, NULL, zpool_export_one, &cb);
return (ret);
}
.LP
.nf
-\fBzpool export\fR [\fB-f\fR] \fIpool\fR ...
+\fBzpool export\fR [\fB-a\fR] [\fB-f\fR] \fIpool\fR ...
.fi
.LP
Detaches \fIdevice\fR from a mirror. The operation is refused if there are no other valid replicas of the data. If \fIdevice\fR may be re-added to the pool later on then consider the "\fBzpool offline\fR" command instead.
.RE
+.RE
+
.sp
.ne 2
.mk
.na
-\fB\fBzpool export\fR [\fB-f\fR] \fIpool\fR ...\fR
+\fB\fBzpool export\fR [\fB-a\fR] [\fB-f\fR] \fIpool\fR ...\fR
.ad
.sp .6
.RS 4n
Before exporting the pool, all datasets within the pool are unmounted. A pool can not be exported if it has a shared spare that is currently being used.
.sp
For pools to be portable, you must give the \fBzpool\fR command whole disks, not just partitions, so that \fBZFS\fR can label the disks with portable \fBEFI\fR labels. Otherwise, disk drivers on platforms of different endianness will not recognize the disks.
+.sp
+.ne 2
+.mk
+.na
+\fB\fB-a\fR\fR
+.ad
+.RS 6n
+.rt
+Exports all pools imported on the system.
+.RE
+
.sp
.ne 2
.mk
\fB\fB-f\fR\fR
.ad
.RS 6n
-.rt
+.rt
Forcefully unmount all datasets, using the "\fBunmount -f\fR" command.
.sp
This command will forcefully export the pool even if it has a shared spare that is currently being used. This may lead to potential data corruption.