X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=cmd%2Fzpool%2Fzpool_main.c;h=3679b4ee2d659a63f9908f6df80b79b59a324053;hb=ea1fdf46e2d37e9eb048f9add0fb06e77e9ee6e2;hp=3859bf737a382287f493ebdb5463b75acd89bb0a;hpb=9b020fd97a3dc449a94baec028b30b1fe3c2d5bc;p=zfs.git diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 3859bf7..3679b4e 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -21,6 +21,9 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2012 by Frederik Wessels. All rights reserved. */ #include @@ -66,6 +69,8 @@ static int zpool_do_online(int, char **); static int zpool_do_offline(int, char **); static int zpool_do_clear(int, char **); +static int zpool_do_reguid(int, char **); + static int zpool_do_attach(int, char **); static int zpool_do_detach(int, char **); static int zpool_do_replace(int, char **); @@ -125,7 +130,8 @@ typedef enum { HELP_EVENTS, HELP_GET, HELP_SET, - HELP_SPLIT + HELP_SPLIT, + HELP_REGUID } zpool_help_t; @@ -169,6 +175,7 @@ static zpool_command_t command_table[] = { { "import", zpool_do_import, HELP_IMPORT }, { "export", zpool_do_export, HELP_EXPORT }, { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, + { "reguid", zpool_do_reguid, HELP_REGUID }, { NULL }, { "history", zpool_do_history, HELP_HISTORY }, { "events", zpool_do_events, HELP_EVENTS }, @@ -241,7 +248,7 @@ get_usage(zpool_help_t idx) { "\tupgrade -v\n" "\tupgrade [-V version] <-a | pool ...>\n")); case HELP_EVENTS: - return (gettext("\tevents [-vfc]\n")); + return (gettext("\tevents [-vHfc]\n")); case HELP_GET: return (gettext("\tget <\"all\" | property[,...]> " " ...\n")); @@ -251,6 +258,8 @@ get_usage(zpool_help_t idx) { return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n" "\t [-o property=value] " "[ ...]\n")); + case HELP_REGUID: + return (gettext("\treguid \n")); } abort(); @@ -488,7 +497,7 @@ zpool_do_add(int argc, char **argv) } /* pass off to get_vdev_spec for processing */ - nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, + nvroot = make_root_vdev(zhp, NULL, force, !force, B_FALSE, dryrun, argc, argv); if (nvroot == NULL) { zpool_close(zhp); @@ -688,7 +697,7 @@ zpool_do_create(int argc, char **argv) } /* pass off to get_vdev_spec for bulk processing */ - nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, + nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun, argc - 1, argv + 1); if (nvroot == NULL) goto errout; @@ -716,9 +725,7 @@ zpool_do_create(int argc, char **argv) (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { char buf[MAXPATHLEN]; -#ifdef HAVE_ZPL DIR *dirp; -#endif if (mountpoint && mountpoint[0] != '/') { (void) fprintf(stderr, gettext("invalid mountpoint " @@ -743,7 +750,6 @@ zpool_do_create(int argc, char **argv) mountpoint); } -#ifdef HAVE_ZPL if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { (void) fprintf(stderr, gettext("mountpoint '%s' : " "%s\n"), buf, strerror(errno)); @@ -766,7 +772,6 @@ zpool_do_create(int argc, char **argv) goto errout; } } -#endif /* HAVE_ZPL */ } if (dryrun) { @@ -797,12 +802,8 @@ zpool_do_create(int argc, char **argv) zfs_prop_to_name( ZFS_PROP_MOUNTPOINT), mountpoint) == 0); -#ifdef HAVE_ZPL if (zfs_mount(pool, NULL, 0) == 0) ret = zfs_shareall(pool); -#else - ret = 0; -#endif /* HAVE_ZPL */ zfs_close(pool); } } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { @@ -1490,7 +1491,7 @@ show_import(nvlist_t *config) } if (msgid != NULL) - (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), + (void) printf(gettext(" see: http://zfsonlinux.org/msg/%s\n"), msgid); (void) printf(gettext("config:\n\n")); @@ -1541,7 +1542,9 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid) == 0) { - if ((unsigned long)hostid != gethostid()) { + unsigned long system_hostid = gethostid() & 0xffffffff; + + if ((unsigned long)hostid != system_hostid) { char *hostname; uint64_t timestamp; time_t t; @@ -1579,14 +1582,12 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts, if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) return (1); -#if HAVE_ZPL if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && !(flags & ZFS_IMPORT_ONLY) && zpool_enable_datasets(zhp, mntopts, 0) != 0) { zpool_close(zhp); return (1); } -#endif /* HAVE_ZPL */ zpool_close(zhp); return (0); @@ -2094,10 +2095,15 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, return; for (c = 0; c < children; c++) { - uint64_t ishole = B_FALSE; + uint64_t ishole = B_FALSE, islog = B_FALSE; + + (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, + &ishole); + + (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, + &islog); - if (nvlist_lookup_uint64(newchild[c], - ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) + if (ishole || islog) continue; vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE); @@ -2107,6 +2113,31 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, } /* + * Log device section + */ + + if (num_logs(newnv) > 0) { + (void) printf("%-*s - - - - - " + "-\n", cb->cb_namewidth, "logs"); + + for (c = 0; c < children; c++) { + uint64_t islog = B_FALSE; + (void) nvlist_lookup_uint64(newchild[c], + ZPOOL_CONFIG_IS_LOG, &islog); + + if (islog) { + vname = zpool_vdev_name(g_zfs, zhp, newchild[c], + B_FALSE); + print_vdev_stats(zhp, vname, oldnv ? + oldchild[c] : NULL, newchild[c], + cb, depth + 2); + free(vname); + } + } + + } + + /* * Include level 2 ARC devices in iostat output */ if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, @@ -2183,11 +2214,30 @@ print_iostat(zpool_handle_t *zhp, void *data) return (0); } +static int +get_columns(void) +{ + struct winsize ws; + int columns = 80; + int error; + + if (isatty(STDOUT_FILENO)) { + error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); + if (error == 0) + columns = ws.ws_col; + } else { + columns = 999; + } + + return columns; +} + int get_namewidth(zpool_handle_t *zhp, void *data) { iostat_cbdata_t *cb = data; nvlist_t *config, *nvroot; + int columns; if ((config = zpool_get_config(zhp, NULL)) != NULL) { verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, @@ -2195,17 +2245,20 @@ get_namewidth(zpool_handle_t *zhp, void *data) if (!cb->cb_verbose) cb->cb_namewidth = strlen(zpool_get_name(zhp)); else - cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); + cb->cb_namewidth = max_width(zhp, nvroot, 0, + cb->cb_namewidth); } /* - * The width must fall into the range [10,38]. The upper limit is the - * maximum we can have and still fit in 80 columns. + * The width must be at least 10, but may be as large as the + * column width - 42 so that we can still fit in one line. */ + columns = get_columns(); + if (cb->cb_namewidth < 10) cb->cb_namewidth = 10; - if (cb->cb_namewidth > 38) - cb->cb_namewidth = 38; + if (cb->cb_namewidth > columns - 42) + cb->cb_namewidth = columns - 42; return (0); } @@ -2366,42 +2419,48 @@ zpool_do_iostat(int argc, char **argv) pool_list_update(list); if ((npools = pool_list_count(list)) == 0) - break; + (void) fprintf(stderr, gettext("no pools available\n")); + else { + /* + * Refresh all statistics. This is done as an + * explicit step before calculating the maximum name + * width, so that any * configuration changes are + * properly accounted for. + */ + (void) pool_list_iter(list, B_FALSE, refresh_iostat, + &cb); - /* - * Refresh all statistics. This is done as an explicit step - * before calculating the maximum name width, so that any - * configuration changes are properly accounted for. - */ - (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); + /* + * Iterate over all pools to determine the maximum width + * for the pool / device name column across all pools. + */ + cb.cb_namewidth = 0; + (void) pool_list_iter(list, B_FALSE, get_namewidth, + &cb); - /* - * Iterate over all pools to determine the maximum width - * for the pool / device name column across all pools. - */ - cb.cb_namewidth = 0; - (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); + if (timestamp_fmt != NODATE) + print_timestamp(timestamp_fmt); - if (timestamp_fmt != NODATE) - print_timestamp(timestamp_fmt); - - /* - * If it's the first time, or verbose mode, print the header. - */ - if (++cb.cb_iteration == 1 || verbose) - print_iostat_header(&cb); + /* + * If it's the first time, or verbose mode, print the + * header. + */ + if (++cb.cb_iteration == 1 || verbose) + print_iostat_header(&cb); - (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); + (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); - /* - * If there's more than one pool, and we're not in verbose mode - * (which prints a separator for us), then print a separator. - */ - if (npools > 1 && !verbose) - print_iostat_separator(&cb); + /* + * If there's more than one pool, and we're not in + * verbose mode (which prints a separator for us), + * then print a separator. + */ + if (npools > 1 && !verbose) + print_iostat_separator(&cb); - if (verbose) - (void) printf("\n"); + if (verbose) + (void) printf("\n"); + } /* * Flush the output so that redirection to a file isn't buffered @@ -2600,10 +2659,12 @@ zpool_do_list(int argc, char **argv) ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, list_callback, &cb); - if (argc == 0 && cb.cb_first && !cb.cb_scripted) { - (void) printf(gettext("no pools available\n")); + if (argc == 0 && cb.cb_first) + (void) fprintf(stderr, gettext("no pools available\n")); + else if (argc && cb.cb_first) { + /* cannot open the given pool */ zprop_free_list(cb.cb_proplist); - return (0); + return (1); } if (interval == 0) @@ -2691,7 +2752,7 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing) return (1); } - nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, + nvroot = make_root_vdev(zhp, NULL, force, B_FALSE, replacing, B_FALSE, argc, argv); if (nvroot == NULL) { zpool_close(zhp); @@ -3151,6 +3212,52 @@ zpool_do_clear(int argc, char **argv) return (ret); } +/* + * zpool reguid + */ +int +zpool_do_reguid(int argc, char **argv) +{ + int c; + char *poolname; + zpool_handle_t *zhp; + int ret = 0; + + /* check options */ + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + case '?': + (void) fprintf(stderr, gettext("invalid option '%c'\n"), + optopt); + usage(B_FALSE); + } + } + + argc -= optind; + argv += optind; + + /* get pool name and check number of arguments */ + if (argc < 1) { + (void) fprintf(stderr, gettext("missing pool name\n")); + usage(B_FALSE); + } + + if (argc > 1) { + (void) fprintf(stderr, gettext("too many arguments\n")); + usage(B_FALSE); + } + + poolname = argv[0]; + if ((zhp = zpool_open(g_zfs, poolname)) == NULL) + return (1); + + ret = zpool_reguid(zhp); + + zpool_close(zhp); + return (ret); +} + + typedef struct scrub_cbdata { int cb_type; int cb_argc; @@ -3448,7 +3555,7 @@ print_dedup_stats(nvlist_t *config) * pool: tank * status: DEGRADED * reason: One or more devices ... - * see: http://www.sun.com/msg/ZFS-xxxx-01 + * see: http://zfsonlinux.org/msg/ZFS-xxxx-01 * config: * mirror DEGRADED * c1t0d0 OK @@ -3656,7 +3763,7 @@ status_callback(zpool_handle_t *zhp, void *data) } if (msgid != NULL) - (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), + (void) printf(gettext(" see: http://zfsonlinux.org/msg/%s\n"), msgid); if (config != NULL) { @@ -3793,7 +3900,7 @@ zpool_do_status(int argc, char **argv) status_callback, &cb); if (argc == 0 && cb.cb_count == 0) - (void) printf(gettext("no pools available\n")); + (void) fprintf(stderr, gettext("no pools available\n")); else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) (void) printf(gettext("all pools are healthy\n")); @@ -4219,7 +4326,7 @@ zpool_do_history(int argc, char **argv) &cbdata); if (argc == 0 && cbdata.first == B_TRUE) { - (void) printf(gettext("no pools available\n")); + (void) fprintf(stderr, gettext("no pools available\n")); return (0); } @@ -4228,6 +4335,7 @@ zpool_do_history(int argc, char **argv) typedef struct ev_opts { int verbose; + int scripted; int follow; int clear; } ev_opts_t; @@ -4342,7 +4450,7 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth) printf(gettext("(embedded nvlist)\n")); (void) nvpair_value_nvlist(nvp, &cnv); zpool_do_events_nvprint(cnv, depth + 8); - printf(gettext("%*s(end %s)\n"), depth, "", name); + printf(gettext("%*s(end %s)"), depth, "", name); break; case DATA_TYPE_NVLIST_ARRAY: { @@ -4472,7 +4580,8 @@ zpool_do_events_next(ev_opts_t *opts) cleanup_fd = open(ZFS_DEV, O_RDWR); VERIFY(cleanup_fd >= 0); - (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS"); + if (!opts->scripted) + (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS"); while (1) { ret = zpool_events_next(g_zfs, &nvl, &dropped, @@ -4523,11 +4632,14 @@ zpool_do_events(int argc, char **argv) int c; /* check options */ - while ((c = getopt(argc, argv, "vfc")) != -1) { + while ((c = getopt(argc, argv, "vHfc")) != -1) { switch (c) { case 'v': opts.verbose = 1; break; + case 'H': + opts.scripted = 1; + break; case 'f': opts.follow = 1; break;