diff options
author | Mark J Musante <Mark.Musante@Sun.COM> | 2010-05-19 18:00:45 -0600 |
---|---|---|
committer | Mark J Musante <Mark.Musante@Sun.COM> | 2010-05-19 18:00:45 -0600 |
commit | a8b6ddaf31808c845e00161dda0a3d1fe31ae281 (patch) | |
tree | fc2911142909e704b70a93a89622fa0005a7c752 | |
parent | 783776811455d550a57536b20e93a0e306010126 (diff) | |
download | illumos-gate-a8b6ddaf31808c845e00161dda0a3d1fe31ae281.tar.gz |
6608465 zfs mount -v should only report progress if progress is slow
-rw-r--r-- | usr/src/cmd/zfs/zfs_iter.c | 24 | ||||
-rw-r--r-- | usr/src/cmd/zfs/zfs_main.c | 196 | ||||
-rw-r--r-- | usr/src/cmd/zfs/zfs_util.h | 6 |
3 files changed, 120 insertions, 106 deletions
diff --git a/usr/src/cmd/zfs/zfs_iter.c b/usr/src/cmd/zfs/zfs_iter.c index f70bebe00b..e2ab90eaf1 100644 --- a/usr/src/cmd/zfs/zfs_iter.c +++ b/usr/src/cmd/zfs/zfs_iter.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <libintl.h> @@ -351,11 +350,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT); - if (avl_pool == NULL) { - (void) fprintf(stderr, - gettext("internal error: out of memory\n")); - exit(1); - } + if (avl_pool == NULL) + nomem(); cb.cb_sortcol = sortcol; cb.cb_flags = flags; @@ -400,11 +396,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, sizeof (cb.cb_props_table)); } - if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) { - (void) fprintf(stderr, - gettext("internal error: out of memory\n")); - exit(1); - } + if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) + nomem(); if (argc == 0) { /* @@ -454,11 +447,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, /* * Finally, clean up the AVL tree. */ - if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) { - (void) fprintf(stderr, - gettext("internal error: out of memory")); - exit(1); - } + if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) + nomem(); while ((node = uu_avl_walk_next(walk)) != NULL) { uu_avl_remove(cb.cb_avl, node); diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c index de2051bd13..353fd4fa62 100644 --- a/usr/src/cmd/zfs/zfs_main.c +++ b/usr/src/cmd/zfs/zfs_main.c @@ -46,6 +46,8 @@ #include <sys/mount.h> #include <sys/stat.h> #include <sys/fs/zfs.h> +#include <sys/types.h> +#include <time.h> #include <libzfs.h> #include <libuutil.h> @@ -287,22 +289,39 @@ get_usage(zfs_help_t idx) /* NOTREACHED */ } +void +nomem(void) +{ + (void) fprintf(stderr, gettext("internal error: out of memory\n")); + exit(1); +} + /* * Utility function to guarantee malloc() success. */ + void * safe_malloc(size_t size) { void *data; - if ((data = calloc(1, size)) == NULL) { - (void) fprintf(stderr, "internal error: out of memory\n"); - exit(1); - } + if ((data = calloc(1, size)) == NULL) + nomem(); return (data); } +static char * +safe_strdup(char *str) +{ + char *dupstr = strdup(str); + + if (dupstr == NULL) + nomem(); + + return (dupstr); +} + /* * Callback routine that will print out information for each of * the properties. @@ -441,11 +460,8 @@ parseprop(nvlist_t *props) "specified multiple times\n"), propname); return (-1); } - if (nvlist_add_string(props, propname, propval) != 0) { - (void) fprintf(stderr, gettext("internal " - "error: out of memory\n")); - return (-1); - } + if (nvlist_add_string(props, propname, propval) != 0) + nomem(); return (0); } @@ -470,6 +486,59 @@ parse_depth(char *opt, int *flags) return (depth); } +#define PROGRESS_DELAY 2 /* seconds */ + +static char *pt_reverse = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; +static time_t pt_begin; +static char *pt_header = NULL; +static boolean_t pt_shown; + +static void +start_progress_timer(void) +{ + pt_begin = time(NULL) + PROGRESS_DELAY; + pt_shown = B_FALSE; +} + +static void +set_progress_header(char *header) +{ + assert(pt_header == NULL); + pt_header = safe_strdup(header); + if (pt_shown) { + (void) printf("%s: ", header); + (void) fflush(stdout); + } +} + +static void +update_progress(char *update) +{ + if (!pt_shown && time(NULL) > pt_begin) { + int len = strlen(update); + + (void) printf("%s: %s%*.*s", pt_header, update, len, len, + pt_reverse); + (void) fflush(stdout); + pt_shown = B_TRUE; + } else if (pt_shown) { + int len = strlen(update); + + (void) printf("%s%*.*s", update, len, len, pt_reverse); + (void) fflush(stdout); + } +} + +static void +finish_progress(char *done) +{ + if (pt_shown) { + (void) printf("%s\n", done); + (void) fflush(stdout); + } + free(pt_header); + pt_header = NULL; +} /* * zfs clone [-p] [-o prop=value] ... <snap> <fs | vol> * @@ -489,11 +558,8 @@ zfs_do_clone(int argc, char **argv) int ret; int c; - if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { - (void) fprintf(stderr, gettext("internal error: " - "out of memory\n")); - return (1); - } + if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) + nomem(); /* check options */ while ((c = getopt(argc, argv, "o:p")) != -1) { @@ -607,11 +673,8 @@ zfs_do_create(int argc, char **argv) uint64_t intval; int canmount; - if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { - (void) fprintf(stderr, gettext("internal error: " - "out of memory\n")); - return (1); - } + if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) + nomem(); /* check options */ while ((c = getopt(argc, argv, ":V:b:so:p")) != -1) { @@ -626,12 +689,8 @@ zfs_do_create(int argc, char **argv) } if (nvlist_add_uint64(props, - zfs_prop_to_name(ZFS_PROP_VOLSIZE), - intval) != 0) { - (void) fprintf(stderr, gettext("internal " - "error: out of memory\n")); - goto error; - } + zfs_prop_to_name(ZFS_PROP_VOLSIZE), intval) != 0) + nomem(); volsize = intval; break; case 'p': @@ -648,11 +707,8 @@ zfs_do_create(int argc, char **argv) if (nvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), - intval) != 0) { - (void) fprintf(stderr, gettext("internal " - "error: out of memory\n")); - goto error; - } + intval) != 0) + nomem(); break; case 'o': if (parseprop(props)) @@ -720,10 +776,8 @@ zfs_do_create(int argc, char **argv) &strval) != 0) { if (nvlist_add_uint64(props, zfs_prop_to_name(resv_prop), volsize) != 0) { - (void) fprintf(stderr, gettext("internal " - "error: out of memory\n")); nvlist_free(props); - return (1); + nomem(); } } } @@ -2507,11 +2561,8 @@ zfs_do_snapshot(int argc, char **argv) char c; nvlist_t *props; - if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) { - (void) fprintf(stderr, gettext("internal error: " - "out of memory\n")); - return (1); - } + if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) + nomem(); /* check options */ while ((c = getopt(argc, argv, "ro:")) != -1) { @@ -2891,7 +2942,7 @@ typedef struct get_all_cbdata { static int get_one_dataset(zfs_handle_t *zhp, void *data) { - static char spin[] = { '-', '\\', '|', '/' }; + static char *spin[] = { "-", "\\", "|", "/" }; static int spinval = 0; static int spincheck = 0; static time_t last_spin_time = (time_t)0; @@ -2902,8 +2953,7 @@ get_one_dataset(zfs_handle_t *zhp, void *data) if (--spincheck < 0) { time_t now = time(NULL); if (last_spin_time + SPINNER_TIME < now) { - (void) printf("\b%c", spin[spinval++ % 4]); - (void) fflush(stdout); + update_progress(spin[spinval++ % 4]); last_spin_time = now; } spincheck = CHECK_SPINNER; @@ -2959,19 +3009,16 @@ get_all_datasets(uint_t types, zfs_handle_t ***dslist, size_t *count, cb.cb_types = types; cb.cb_verbose = verbose; - if (verbose) { - (void) printf("%s: *", gettext("Reading ZFS config")); - (void) fflush(stdout); - } + 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; - if (verbose) { - (void) printf("\b%s\n", gettext("done.")); - } + if (verbose) + finish_progress(gettext("done.")); } static int @@ -3210,19 +3257,16 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol, static void report_mount_progress(int current, int total) { - static int len; - static char *reverse = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" - "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; - static time_t last_progress_time; + static time_t last_progress_time = 0; time_t now = time(NULL); + char info[32]; /* report 1..n instead of 0..n-1 */ ++current; /* display header if we're here for the first time */ if (current == 1) { - (void) printf(gettext("Mounting ZFS filesystems: ")); - len = 0; + set_progress_header(gettext("Mounting ZFS filesystems")); } else if (current != total && last_progress_time + MOUNT_TIME >= now) { /* too soon to report again */ return; @@ -3230,13 +3274,12 @@ report_mount_progress(int current, int total) last_progress_time = now; - /* back up to prepare for overwriting */ - if (len) - (void) printf("%*.*s", len, len, reverse); + (void) sprintf(info, "(%d/%d)", current, total); - /* We put a newline at the end if this is the last one. */ - len = printf("(%d/%d)%s", current, total, current == total ? "\n" : ""); - (void) fflush(stdout); + if (current == total) + finish_progress(info); + else + update_progress(info); } static void @@ -3338,6 +3381,7 @@ share_mount(int op, int argc, char **argv) usage(B_FALSE); } + start_progress_timer(); get_all_datasets(types, &dslist, &count, verbose); if (count == 0) @@ -3623,21 +3667,12 @@ unshare_unmount(int op, int argc, char **argv) usage(B_FALSE); } - if ((pool = uu_avl_pool_create("unmount_pool", + if (((pool = uu_avl_pool_create("unmount_pool", sizeof (unshare_unmount_node_t), offsetof(unshare_unmount_node_t, un_avlnode), - unshare_unmount_compare, - UU_DEFAULT)) == NULL) { - (void) fprintf(stderr, gettext("internal error: " - "out of memory\n")); - exit(1); - } - - if ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL) { - (void) fprintf(stderr, gettext("internal error: " - "out of memory\n")); - exit(1); - } + unshare_unmount_compare, UU_DEFAULT)) == NULL) || + ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL)) + nomem(); rewind(mnttab_file); while (getmntent(mnttab_file, &entry) == 0) { @@ -3689,13 +3724,7 @@ unshare_unmount(int op, int argc, char **argv) node = safe_malloc(sizeof (unshare_unmount_node_t)); node->un_zhp = zhp; - - if ((node->un_mountp = strdup(entry.mnt_mountp)) == - NULL) { - (void) fprintf(stderr, gettext("internal error:" - " out of memory\n")); - exit(1); - } + node->un_mountp = safe_strdup(entry.mnt_mountp); uu_avl_node_init(node, &node->un_avlnode, pool); @@ -3713,11 +3742,8 @@ unshare_unmount(int op, int argc, char **argv) * removing it from the AVL tree in the process. */ if ((walk = uu_avl_walk_start(tree, - UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL) { - (void) fprintf(stderr, - gettext("internal error: out of memory")); - exit(1); - } + UU_WALK_REVERSE | UU_WALK_ROBUST)) == NULL) + nomem(); while ((node = uu_avl_walk_next(walk)) != NULL) { uu_avl_remove(tree, node); diff --git a/usr/src/cmd/zfs/zfs_util.h b/usr/src/cmd/zfs/zfs_util.h index c7f2f16186..3ddff9e22d 100644 --- a/usr/src/cmd/zfs/zfs_util.h +++ b/usr/src/cmd/zfs/zfs_util.h @@ -19,15 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _ZFS_UTIL_H #define _ZFS_UTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libzfs.h> #ifdef __cplusplus @@ -35,6 +32,7 @@ extern "C" { #endif void * safe_malloc(size_t size); +void nomem(void); libzfs_handle_t *g_zfs; #ifdef __cplusplus |