]> git.proxmox.com Git - mirror_zfs.git/blobdiff - cmd/zpool/zpool_main.c
Illumos 4976-4984 - metaslab improvements
[mirror_zfs.git] / cmd / zpool / zpool_main.c
index d496d0c72e26647633a01fcac876a2ce9451da9d..920acc36792942d84a009b7b8083bba864a8d9d4 100644 (file)
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
  * Copyright (c) 2012 by Cyril Plisko. All rights reserved.
  */
@@ -49,6 +49,7 @@
 #include <sys/stat.h>
 #include <sys/fm/util.h>
 #include <sys/fm/protocol.h>
+#include <sys/zfs_ioctl.h>
 
 #include <libzfs.h>
 
@@ -247,8 +248,8 @@ get_usage(zpool_help_t idx) {
        case HELP_ONLINE:
                return (gettext("\tonline <pool> <device> ...\n"));
        case HELP_REPLACE:
-               return (gettext("\treplace [-f] <pool> <device> "
-                   "[new-device]\n"));
+               return (gettext("\treplace [-f] [-o property=value] "
+                   "<pool> <device> [new-device]\n"));
        case HELP_REMOVE:
                return (gettext("\tremove <pool> <device> ...\n"));
        case HELP_REOPEN:
@@ -265,7 +266,7 @@ get_usage(zpool_help_t idx) {
        case HELP_EVENTS:
                return (gettext("\tevents [-vHfc]\n"));
        case HELP_GET:
-               return (gettext("\tget [-p] <\"all\" | property[,...]> "
+               return (gettext("\tget [-pH] <\"all\" | property[,...]> "
                    "<pool> ...\n"));
        case HELP_SET:
                return (gettext("\tset <property=value> <pool> \n"));
@@ -1029,7 +1030,7 @@ zpool_do_create(int argc, char **argv)
                 * Hand off to libzfs.
                 */
                if (enable_all_pool_feat) {
-                       int i;
+                       spa_feature_t i;
                        for (i = 0; i < SPA_FEATURES; i++) {
                                char propname[MAXPATHLEN];
                                zfeature_info_t *feat = &spa_feature_table[i];
@@ -1747,6 +1748,23 @@ show_import(nvlist_t *config)
                        case ZPOOL_ERRATA_NONE:
                                break;
 
+                       case ZPOOL_ERRATA_ZOL_2094_SCRUB:
+                               (void) printf(gettext(" action: The pool can "
+                                   "be imported using its name or numeric "
+                                   "identifier,\n\thowever there is a compat"
+                                   "ibility issue which should be corrected"
+                                   "\n\tby running 'zpool scrub'\n"));
+                               break;
+
+                       case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY:
+                               (void) printf(gettext(" action: The pool can"
+                                   "not be imported with this version of ZFS "
+                                   "due to\n\tan active asynchronous destroy. "
+                                   "Revert to an earlier version\n\tand "
+                                   "allow the destroy to complete before "
+                                   "updating.\n"));
+                               break;
+
                        default:
                                /*
                                 * All errata must contain an action message.
@@ -1996,7 +2014,7 @@ zpool_do_import(int argc, char **argv)
        char *endptr;
 
        /* check options */
-       while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
+       while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:tT:VX")) != -1) {
                switch (c) {
                case 'a':
                        do_all = B_TRUE;
@@ -2058,6 +2076,10 @@ zpool_do_import(int argc, char **argv)
                            ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
                                goto error;
                        break;
+               case 't':
+                       flags |= ZFS_IMPORT_TEMP_NAME;
+                       break;
+
                case 'T':
                        errno = 0;
                        txg = strtoull(optarg, &endptr, 10);
@@ -2976,10 +2998,16 @@ print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted)
        boolean_t fixed;
        size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
 
-       zfs_nicenum(value, propval, sizeof (propval));
 
        if (prop == ZPOOL_PROP_EXPANDSZ && value == 0)
                (void) strlcpy(propval, "-", sizeof (propval));
+       else if (prop == ZPOOL_PROP_FRAGMENTATION && value == ZFS_FRAG_INVALID)
+               (void) strlcpy(propval, "-", sizeof (propval));
+       else if (prop == ZPOOL_PROP_FRAGMENTATION)
+               (void) snprintf(propval, sizeof (propval), "%llu%%",
+                   (unsigned long long)value);
+       else
+               zfs_nicenum(value, propval, sizeof (propval));
 
        if (scripted)
                (void) printf("\t%s", propval);
@@ -3012,9 +3040,9 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
                /* only toplevel vdevs have capacity stats */
                if (vs->vs_space == 0) {
                        if (scripted)
-                               (void) printf("\t-\t-\t-");
+                               (void) printf("\t-\t-\t-\t-");
                        else
-                               (void) printf("      -      -      -");
+                               (void) printf("      -      -      -      -");
                } else {
                        print_one_column(ZPOOL_PROP_SIZE, vs->vs_space,
                            scripted);
@@ -3022,6 +3050,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
                            scripted);
                        print_one_column(ZPOOL_PROP_FREE,
                            vs->vs_space - vs->vs_alloc, scripted);
+                       print_one_column(ZPOOL_PROP_FRAGMENTATION,
+                           vs->vs_fragmentation, scripted);
                }
                print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize,
                    scripted);
@@ -3106,8 +3136,8 @@ zpool_do_list(int argc, char **argv)
        int ret = 0;
        list_cbdata_t cb = { 0 };
        static char default_props[] =
-           "name,size,allocated,free,capacity,dedupratio,"
-           "health,altroot";
+           "name,size,allocated,free,fragmentation,capacity,"
+           "dedupratio,health,altroot";
        char *props = default_props;
        unsigned long interval = 0, count = 0;
        zpool_list_t *list;
@@ -4367,6 +4397,17 @@ status_callback(zpool_handle_t *zhp, void *data)
                    "'zpool clear'.\n"));
                break;
 
+       case ZPOOL_STATUS_HOSTID_MISMATCH:
+               (void) printf(gettext("status: Mismatch between pool hostid "
+                   "and system hostid on imported pool.\n\tThis pool was "
+                   "previously imported into a system with a different "
+                   "hostid,\n\tand then was verbatim imported into this "
+                   "system.\n"));
+               (void) printf(gettext("action: Export this pool on all systems "
+                   "on which it is imported.\n"
+                   "\tThen import it to correct the mismatch.\n"));
+               break;
+
        case ZPOOL_STATUS_ERRATA:
                (void) printf(gettext("status: Errata #%d detected.\n"),
                    errata);
@@ -4375,6 +4416,11 @@ status_callback(zpool_handle_t *zhp, void *data)
                case ZPOOL_ERRATA_NONE:
                        break;
 
+               case ZPOOL_ERRATA_ZOL_2094_SCRUB:
+                       (void) printf(gettext("action: To correct the issue "
+                           "run 'zpool scrub'.\n"));
+                       break;
+
                default:
                        /*
                         * All errata which allow the pool to be imported
@@ -5412,7 +5458,18 @@ zpool_do_events_nvprint(nvlist_t *nvl, int depth)
                        break;
                        }
 
-               case DATA_TYPE_STRING_ARRAY:
+               case DATA_TYPE_STRING_ARRAY: {
+                       char **str;
+                       uint_t i, nelem;
+
+                       (void) nvpair_value_string_array(nvp, &str, &nelem);
+                       for (i = 0; i < nelem; i++)
+                               printf(gettext("\"%s\" "),
+                                   str[i] ? str[i] : "<NULL>");
+
+                       break;
+                       }
+
                case DATA_TYPE_BOOLEAN_ARRAY:
                case DATA_TYPE_BYTE_ARRAY:
                case DATA_TYPE_DOUBLE:
@@ -5429,17 +5486,17 @@ static int
 zpool_do_events_next(ev_opts_t *opts)
 {
        nvlist_t *nvl;
-       int cleanup_fd, ret, dropped;
+       int zevent_fd, ret, dropped;
 
-       cleanup_fd = open(ZFS_DEV, O_RDWR);
-       VERIFY(cleanup_fd >= 0);
+       zevent_fd = open(ZFS_DEV, O_RDWR);
+       VERIFY(zevent_fd >= 0);
 
        if (!opts->scripted)
                (void) printf(gettext("%-30s %s\n"), "TIME", "CLASS");
 
        while (1) {
                ret = zpool_events_next(g_zfs, &nvl, &dropped,
-                   !!opts->follow, cleanup_fd);
+                   (opts->follow ? ZEVENT_NONE : ZEVENT_NONBLOCK), zevent_fd);
                if (ret || nvl == NULL)
                        break;
 
@@ -5457,7 +5514,7 @@ zpool_do_events_next(ev_opts_t *opts)
                nvlist_free(nvl);
        }
 
-       VERIFY(0 == close(cleanup_fd));
+       VERIFY(0 == close(zevent_fd));
 
        return (ret);
 }
@@ -5568,12 +5625,16 @@ zpool_do_get(int argc, char **argv)
        int c, ret;
 
        /* check options */
-       while ((c = getopt(argc, argv, "p")) != -1) {
+       while ((c = getopt(argc, argv, "pH")) != -1) {
                switch (c) {
                case 'p':
                        cb.cb_literal = B_TRUE;
                        break;
 
+               case 'H':
+                       cb.cb_scripted = B_TRUE;
+                       break;
+
                case '?':
                        (void) fprintf(stderr, gettext("invalid option '%c'\n"),
                            optopt);