diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-05-16 11:14:46 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-05-16 11:14:46 +0000 |
| commit | c884631e9c751a35384a284fea0975fe5174262d (patch) | |
| tree | 4d47f3e8853bf814a777e423c1eeb5ae997ec2dd /usr/src/cmd/zfs | |
| parent | c596bb2c28271ba1ba0b6af4ef4a3244b32bbfe1 (diff) | |
| parent | 0b2e8253986c5c761129b58cfdac46d204903de1 (diff) | |
| download | illumos-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.c | 140 |
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); |
