summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zfs
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2018-05-16 11:14:46 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2018-05-16 11:14:46 +0000
commitc884631e9c751a35384a284fea0975fe5174262d (patch)
tree4d47f3e8853bf814a777e423c1eeb5ae997ec2dd /usr/src/cmd/zfs
parentc596bb2c28271ba1ba0b6af4ef4a3244b32bbfe1 (diff)
parent0b2e8253986c5c761129b58cfdac46d204903de1 (diff)
downloadillumos-joyent-c884631e9c751a35384a284fea0975fe5174262d.tar.gz
[illumos-gate merge]
commit 0b2e8253986c5c761129b58cfdac46d204903de1 9512 zfs remap poolname@snapname coredumps commit 591e0e133f9980083db5d64ac33a30bcc3382ff7 8115 parallel zfs mount commit b4bf0cf0458759c67920a031021a9d96cd683cfe 9426 metaslab size can exceed offset addressable by spacemap commit b1da084b97cda9a2d087205b95c45a54ad654453 9309 mdb: this statement may fall through Conflicts: usr/src/lib/Makefile
Diffstat (limited to 'usr/src/cmd/zfs')
-rw-r--r--usr/src/cmd/zfs/zfs_main.c140
1 files changed, 102 insertions, 38 deletions
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c
index 7dac2f2237..d9f253fbf8 100644
--- a/usr/src/cmd/zfs/zfs_main.c
+++ b/usr/src/cmd/zfs/zfs_main.c
@@ -60,6 +60,7 @@
#include <sys/fs/zfs.h>
#include <sys/types.h>
#include <time.h>
+#include <synch.h>
#include <libzfs.h>
#include <libzfs_core.h>
@@ -5839,7 +5840,12 @@ zfs_do_holds(int argc, char **argv)
#define CHECK_SPINNER 30
#define SPINNER_TIME 3 /* seconds */
-#define MOUNT_TIME 5 /* seconds */
+#define MOUNT_TIME 1 /* seconds */
+
+typedef struct get_all_state {
+ boolean_t ga_verbose;
+ get_all_cb_t *ga_cbp;
+} get_all_state_t;
static int
get_one_dataset(zfs_handle_t *zhp, void *data)
@@ -5848,10 +5854,10 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
static int spinval = 0;
static int spincheck = 0;
static time_t last_spin_time = (time_t)0;
- get_all_cb_t *cbp = data;
+ get_all_state_t *state = data;
zfs_type_t type = zfs_get_type(zhp);
- if (cbp->cb_verbose) {
+ if (state->ga_verbose) {
if (--spincheck < 0) {
time_t now = time(NULL);
if (last_spin_time + SPINNER_TIME < now) {
@@ -5877,25 +5883,23 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
zfs_close(zhp);
return (0);
}
- libzfs_add_handle(cbp, zhp);
- assert(cbp->cb_used <= cbp->cb_alloc);
+ libzfs_add_handle(state->ga_cbp, zhp);
+ assert(state->ga_cbp->cb_used <= state->ga_cbp->cb_alloc);
return (0);
}
static void
-get_all_datasets(zfs_handle_t ***dslist, size_t *count, boolean_t verbose)
+get_all_datasets(get_all_cb_t *cbp, boolean_t verbose)
{
- get_all_cb_t cb = { 0 };
- cb.cb_verbose = verbose;
- cb.cb_getone = get_one_dataset;
+ get_all_state_t state = {
+ .ga_verbose = verbose,
+ .ga_cbp = cbp
+ };
if (verbose)
set_progress_header(gettext("Reading ZFS config"));
- (void) zfs_iter_root(g_zfs, get_one_dataset, &cb);
-
- *dslist = cb.cb_handles;
- *count = cb.cb_used;
+ (void) zfs_iter_root(g_zfs, get_one_dataset, &state);
if (verbose)
finish_progress(gettext("done."));
@@ -5906,8 +5910,19 @@ get_all_datasets(zfs_handle_t ***dslist, size_t *count, boolean_t verbose)
* similar, we have a common function with an extra parameter to determine which
* mode we are using.
*/
-#define OP_SHARE 0x1
-#define OP_MOUNT 0x2
+typedef enum { OP_SHARE, OP_MOUNT } share_mount_op_t;
+
+typedef struct share_mount_state {
+ share_mount_op_t sm_op;
+ boolean_t sm_verbose;
+ int sm_flags;
+ char *sm_options;
+ char *sm_proto; /* only valid for OP_SHARE */
+ mutex_t sm_lock; /* protects the remaining fields */
+ uint_t sm_total; /* number of filesystems to process */
+ uint_t sm_done; /* number of filesystems processed */
+ int sm_status; /* -1 if any of the share/mount operations failed */
+} share_mount_state_t;
/*
* Share or mount a dataset.
@@ -6149,6 +6164,29 @@ report_mount_progress(int current, int total)
update_progress(info);
}
+/*
+ * zfs_foreach_mountpoint() callback that mounts or shares one filesystem and
+ * updates the progress meter.
+ */
+static int
+share_mount_one_cb(zfs_handle_t *zhp, void *arg)
+{
+ share_mount_state_t *sms = arg;
+ int ret;
+
+ ret = share_mount_one(zhp, sms->sm_op, sms->sm_flags, sms->sm_proto,
+ B_FALSE, sms->sm_options);
+
+ mutex_enter(&sms->sm_lock);
+ if (ret != 0)
+ sms->sm_status = ret;
+ sms->sm_done++;
+ if (sms->sm_verbose)
+ report_mount_progress(sms->sm_done, sms->sm_total);
+ mutex_exit(&sms->sm_lock);
+ return (ret);
+}
+
static void
append_options(char *mntopts, char *newopts)
{
@@ -6221,8 +6259,6 @@ share_mount(int op, int argc, char **argv)
/* check number of arguments */
if (do_all) {
- zfs_handle_t **dslist = NULL;
- size_t i, count = 0;
char *protocol = NULL;
if (op == OP_SHARE && argc > 0) {
@@ -6243,33 +6279,44 @@ share_mount(int op, int argc, char **argv)
}
start_progress_timer();
- get_all_datasets(&dslist, &count, verbose);
+ get_all_cb_t cb = { 0 };
+ get_all_datasets(&cb, verbose);
- if (count == 0)
+ if (cb.cb_used == 0)
return (0);
- qsort(dslist, count, sizeof (void *), libzfs_dataset_cmp);
- sa_init_selective_arg_t sharearg;
- sharearg.zhandle_arr = dslist;
- sharearg.zhandle_len = count;
- if ((ret = zfs_init_libshare_arg(zfs_get_handle(dslist[0]),
- SA_INIT_SHARE_API_SELECTIVE, &sharearg)) != SA_OK) {
- (void) fprintf(stderr,
- gettext("Could not initialize libshare, %d"), ret);
- return (ret);
+ if (op == OP_SHARE) {
+ sa_init_selective_arg_t sharearg;
+ sharearg.zhandle_arr = cb.cb_handles;
+ sharearg.zhandle_len = cb.cb_used;
+ if ((ret = zfs_init_libshare_arg(g_zfs,
+ SA_INIT_SHARE_API_SELECTIVE, &sharearg)) != SA_OK) {
+ (void) fprintf(stderr, gettext(
+ "Could not initialize libshare, %d"), ret);
+ return (ret);
+ }
}
- for (i = 0; i < count; i++) {
- if (verbose)
- report_mount_progress(i, count);
-
- if (share_mount_one(dslist[i], op, flags, protocol,
- B_FALSE, options) != 0)
- ret = 1;
- zfs_close(dslist[i]);
- }
+ share_mount_state_t share_mount_state = { 0 };
+ share_mount_state.sm_op = op;
+ share_mount_state.sm_verbose = verbose;
+ share_mount_state.sm_flags = flags;
+ share_mount_state.sm_options = options;
+ share_mount_state.sm_proto = protocol;
+ share_mount_state.sm_total = cb.cb_used;
+ (void) mutex_init(&share_mount_state.sm_lock,
+ LOCK_NORMAL | LOCK_ERRORCHECK, NULL);
+ /*
+ * libshare isn't mt-safe, so only do the operation in parallel
+ * if we're mounting.
+ */
+ zfs_foreach_mountpoint(g_zfs, cb.cb_handles, cb.cb_used,
+ share_mount_one_cb, &share_mount_state, op == OP_MOUNT);
+ ret = share_mount_state.sm_status;
- free(dslist);
+ for (int i = 0; i < cb.cb_used; i++)
+ zfs_close(cb.cb_handles[i]);
+ free(cb.cb_handles);
} else if (argc == 0) {
struct mnttab entry;
@@ -6984,11 +7031,28 @@ zfs_do_diff(int argc, char **argv)
return (err != 0);
}
+/*
+ * zfs remap <filesystem | volume>
+ *
+ * Remap the indirect blocks in the given fileystem or volume.
+ */
static int
zfs_do_remap(int argc, char **argv)
{
const char *fsname;
int err = 0;
+ int c;
+
+ /* check options */
+ while ((c = getopt(argc, argv, "")) != -1) {
+ switch (c) {
+ case '?':
+ (void) fprintf(stderr,
+ gettext("invalid option '%c'\n"), optopt);
+ usage(B_FALSE);
+ }
+ }
+
if (argc != 2) {
(void) fprintf(stderr, gettext("wrong number of arguments\n"));
usage(B_FALSE);