summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark J Musante <Mark.Musante@Sun.COM>2010-05-19 18:00:45 -0600
committerMark J Musante <Mark.Musante@Sun.COM>2010-05-19 18:00:45 -0600
commita8b6ddaf31808c845e00161dda0a3d1fe31ae281 (patch)
treefc2911142909e704b70a93a89622fa0005a7c752
parent783776811455d550a57536b20e93a0e306010126 (diff)
downloadillumos-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.c24
-rw-r--r--usr/src/cmd/zfs/zfs_main.c196
-rw-r--r--usr/src/cmd/zfs/zfs_util.h6
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