Print this page
2619 asynchronous destruction of ZFS file systems
2747 SPA versioning with zfs feature flags
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@delphix.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Dan McDonald <danmcd@nexenta.com>


  34 #include <libgen.h>
  35 #include <libintl.h>
  36 #include <libuutil.h>
  37 #include <locale.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <strings.h>
  42 #include <unistd.h>
  43 #include <priv.h>
  44 #include <pwd.h>
  45 #include <zone.h>
  46 #include <zfs_prop.h>
  47 #include <sys/fs/zfs.h>
  48 #include <sys/stat.h>
  49 
  50 #include <libzfs.h>
  51 
  52 #include "zpool_util.h"
  53 #include "zfs_comutil.h"

  54 
  55 #include "statcommon.h"
  56 
  57 static int zpool_do_create(int, char **);
  58 static int zpool_do_destroy(int, char **);
  59 
  60 static int zpool_do_add(int, char **);
  61 static int zpool_do_remove(int, char **);
  62 
  63 static int zpool_do_list(int, char **);
  64 static int zpool_do_iostat(int, char **);
  65 static int zpool_do_status(int, char **);
  66 
  67 static int zpool_do_online(int, char **);
  68 static int zpool_do_offline(int, char **);
  69 static int zpool_do_clear(int, char **);
  70 static int zpool_do_reopen(int, char **);
  71 
  72 static int zpool_do_reguid(int, char **);
  73 


 183 };
 184 
 185 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
 186 
 187 zpool_command_t *current_command;
 188 static char history_str[HIS_MAX_RECORD_LEN];
 189 
 190 static uint_t timestamp_fmt = NODATE;
 191 
 192 static const char *
 193 get_usage(zpool_help_t idx) {
 194         switch (idx) {
 195         case HELP_ADD:
 196                 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
 197         case HELP_ATTACH:
 198                 return (gettext("\tattach [-f] <pool> <device> "
 199                     "<new-device>\n"));
 200         case HELP_CLEAR:
 201                 return (gettext("\tclear [-nF] <pool> [device]\n"));
 202         case HELP_CREATE:
 203                 return (gettext("\tcreate [-fn] [-o property=value] ... \n"
 204                     "\t    [-O file-system-property=value] ... \n"
 205                     "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
 206         case HELP_DESTROY:
 207                 return (gettext("\tdestroy [-f] <pool>\n"));
 208         case HELP_DETACH:
 209                 return (gettext("\tdetach <pool> <device>\n"));
 210         case HELP_EXPORT:
 211                 return (gettext("\texport [-f] <pool> ...\n"));
 212         case HELP_HISTORY:
 213                 return (gettext("\thistory [-il] [<pool>] ...\n"));
 214         case HELP_IMPORT:
 215                 return (gettext("\timport [-d dir] [-D]\n"
 216                     "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
 217                     "\timport [-o mntopts] [-o property=value] ... \n"
 218                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 219                     "[-R root] [-F [-n]] -a\n"
 220                     "\timport [-o mntopts] [-o property=value] ... \n"
 221                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 222                     "[-R root] [-F [-n]]\n"
 223                     "\t    <pool | id> [newpool]\n"));


 314                 }
 315         } else {
 316                 (void) fprintf(fp, gettext("usage:\n"));
 317                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
 318         }
 319 
 320         if (current_command != NULL &&
 321             ((strcmp(current_command->name, "set") == 0) ||
 322             (strcmp(current_command->name, "get") == 0) ||
 323             (strcmp(current_command->name, "list") == 0))) {
 324 
 325                 (void) fprintf(fp,
 326                     gettext("\nthe following properties are supported:\n"));
 327 
 328                 (void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
 329                     "PROPERTY", "EDIT", "VALUES");
 330 
 331                 /* Iterate over all properties */
 332                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
 333                     ZFS_TYPE_POOL);






 334         }
 335 
 336         /*
 337          * See comments at end of main().
 338          */
 339         if (getenv("ZFS_ABORT") != NULL) {
 340                 (void) printf("dumping core by request\n");
 341                 abort();
 342         }
 343 
 344         exit(requested ? 0 : 2);
 345 }
 346 
 347 void
 348 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
 349     boolean_t print_logs)
 350 {
 351         nvlist_t **child;
 352         uint_t c, children;
 353         char *vname;


 380 static int
 381 add_prop_list(const char *propname, char *propval, nvlist_t **props,
 382     boolean_t poolprop)
 383 {
 384         zpool_prop_t prop = ZPROP_INVAL;
 385         zfs_prop_t fprop;
 386         nvlist_t *proplist;
 387         const char *normnm;
 388         char *strval;
 389 
 390         if (*props == NULL &&
 391             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
 392                 (void) fprintf(stderr,
 393                     gettext("internal error: out of memory\n"));
 394                 return (1);
 395         }
 396 
 397         proplist = *props;
 398 
 399         if (poolprop) {
 400                 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {

 401                         (void) fprintf(stderr, gettext("property '%s' is "
 402                             "not a valid pool property\n"), propname);
 403                         return (2);
 404                 }



 405                 normnm = zpool_prop_to_name(prop);
 406         } else {
 407                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
 408                         normnm = zfs_prop_to_name(fprop);
 409                 } else {
 410                         normnm = propname;
 411                 }
 412         }
 413 
 414         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
 415             prop != ZPOOL_PROP_CACHEFILE) {
 416                 (void) fprintf(stderr, gettext("property '%s' "
 417                     "specified multiple times\n"), propname);
 418                 return (2);
 419         }
 420 
 421         if (nvlist_add_string(proplist, normnm, propval) != 0) {
 422                 (void) fprintf(stderr, gettext("internal "
 423                     "error: out of memory\n"));
 424                 return (1);


 557         }
 558         if (argc < 2) {
 559                 (void) fprintf(stderr, gettext("missing device\n"));
 560                 usage(B_FALSE);
 561         }
 562 
 563         poolname = argv[0];
 564 
 565         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 566                 return (1);
 567 
 568         for (i = 1; i < argc; i++) {
 569                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
 570                         ret = 1;
 571         }
 572 
 573         return (ret);
 574 }
 575 
 576 /*
 577  * zpool create [-fn] [-o property=value] ...
 578  *              [-O file-system-property=value] ...
 579  *              [-R root] [-m mountpoint] <pool> <dev> ...
 580  *
 581  *      -f      Force creation, even if devices appear in use
 582  *      -n      Do not create the pool, but display the resulting layout if it
 583  *              were to be created.
 584  *      -R      Create a pool under an alternate root
 585  *      -m      Set default mountpoint for the root dataset.  By default it's
 586  *              '/<pool>'
 587  *      -o      Set property=value.


 588  *      -O      Set fsproperty=value in the pool's root file system
 589  *
 590  * Creates the named pool according to the given vdev specification.  The
 591  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
 592  * we get the nvlist back from get_vdev_spec(), we either print out the contents
 593  * (if '-n' was specified), or pass it to libzfs to do the creation.
 594  */
 595 int
 596 zpool_do_create(int argc, char **argv)
 597 {
 598         boolean_t force = B_FALSE;
 599         boolean_t dryrun = B_FALSE;

 600         int c;
 601         nvlist_t *nvroot = NULL;
 602         char *poolname;
 603         int ret = 1;
 604         char *altroot = NULL;
 605         char *mountpoint = NULL;
 606         nvlist_t *fsprops = NULL;
 607         nvlist_t *props = NULL;
 608         char *propval;
 609 
 610         /* check options */
 611         while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) {
 612                 switch (c) {
 613                 case 'f':
 614                         force = B_TRUE;
 615                         break;
 616                 case 'n':
 617                         dryrun = B_TRUE;
 618                         break;



 619                 case 'R':
 620                         altroot = optarg;
 621                         if (add_prop_list(zpool_prop_to_name(
 622                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
 623                                 goto errout;
 624                         if (nvlist_lookup_string(props,
 625                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
 626                             &propval) == 0)
 627                                 break;
 628                         if (add_prop_list(zpool_prop_to_name(
 629                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
 630                                 goto errout;
 631                         break;
 632                 case 'm':
 633                         mountpoint = optarg;
 634                         break;
 635                 case 'o':
 636                         if ((propval = strchr(optarg, '=')) == NULL) {
 637                                 (void) fprintf(stderr, gettext("missing "
 638                                     "'=' for -o option\n"));
 639                                 goto errout;
 640                         }
 641                         *propval = '\0';
 642                         propval++;
 643 
 644                         if (add_prop_list(optarg, propval, &props, B_TRUE))
 645                                 goto errout;















 646                         break;
 647                 case 'O':
 648                         if ((propval = strchr(optarg, '=')) == NULL) {
 649                                 (void) fprintf(stderr, gettext("missing "
 650                                     "'=' for -O option\n"));
 651                                 goto errout;
 652                         }
 653                         *propval = '\0';
 654                         propval++;
 655 
 656                         if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
 657                                 goto errout;
 658                         break;
 659                 case ':':
 660                         (void) fprintf(stderr, gettext("missing argument for "
 661                             "'%c' option\n"), optopt);
 662                         goto badusage;
 663                 case '?':
 664                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 665                             optopt);


 691                     "character '/' in pool name\n"), poolname);
 692                 (void) fprintf(stderr, gettext("use 'zfs create' to "
 693                     "create a dataset\n"));
 694                 goto errout;
 695         }
 696 
 697         /* pass off to get_vdev_spec for bulk processing */
 698         nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
 699             argc - 1, argv + 1);
 700         if (nvroot == NULL)
 701                 goto errout;
 702 
 703         /* make_root_vdev() allows 0 toplevel children if there are spares */
 704         if (!zfs_allocatable_devs(nvroot)) {
 705                 (void) fprintf(stderr, gettext("invalid vdev "
 706                     "specification: at least one toplevel vdev must be "
 707                     "specified\n"));
 708                 goto errout;
 709         }
 710 
 711 
 712         if (altroot != NULL && altroot[0] != '/') {
 713                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
 714                     "must be an absolute path\n"), altroot);
 715                 goto errout;
 716         }
 717 
 718         /*
 719          * Check the validity of the mountpoint and direct the user to use the
 720          * '-m' mountpoint option if it looks like its in use.
 721          */
 722         if (mountpoint == NULL ||
 723             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
 724             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
 725                 char buf[MAXPATHLEN];
 726                 DIR *dirp;
 727 
 728                 if (mountpoint && mountpoint[0] != '/') {
 729                         (void) fprintf(stderr, gettext("invalid mountpoint "
 730                             "'%s': must be an absolute path, 'legacy', or "
 731                             "'none'\n"), mountpoint);


 773         }
 774 
 775         if (dryrun) {
 776                 /*
 777                  * For a dry run invocation, print out a basic message and run
 778                  * through all the vdevs in the list and print out in an
 779                  * appropriate hierarchy.
 780                  */
 781                 (void) printf(gettext("would create '%s' with the "
 782                     "following layout:\n\n"), poolname);
 783 
 784                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
 785                 if (num_logs(nvroot) > 0)
 786                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
 787 
 788                 ret = 0;
 789         } else {
 790                 /*
 791                  * Hand off to libzfs.
 792                  */





















 793                 if (zpool_create(g_zfs, poolname,
 794                     nvroot, props, fsprops) == 0) {
 795                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
 796                             ZFS_TYPE_FILESYSTEM);
 797                         if (pool != NULL) {
 798                                 if (mountpoint != NULL)
 799                                         verify(zfs_prop_set(pool,
 800                                             zfs_prop_to_name(
 801                                             ZFS_PROP_MOUNTPOINT),
 802                                             mountpoint) == 0);
 803                                 if (zfs_mount(pool, NULL, 0) == 0)
 804                                         ret = zfs_shareall(pool);
 805                                 zfs_close(pool);
 806                         }
 807                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
 808                         (void) fprintf(stderr, gettext("pool name may have "
 809                             "been omitted\n"));
 810                 }
 811         }
 812 


1104         } else if (vs->vs_aux != 0) {
1105                 (void) printf("  ");
1106 
1107                 switch (vs->vs_aux) {
1108                 case VDEV_AUX_OPEN_FAILED:
1109                         (void) printf(gettext("cannot open"));
1110                         break;
1111 
1112                 case VDEV_AUX_BAD_GUID_SUM:
1113                         (void) printf(gettext("missing device"));
1114                         break;
1115 
1116                 case VDEV_AUX_NO_REPLICAS:
1117                         (void) printf(gettext("insufficient replicas"));
1118                         break;
1119 
1120                 case VDEV_AUX_VERSION_NEWER:
1121                         (void) printf(gettext("newer version"));
1122                         break;
1123 




1124                 case VDEV_AUX_SPARED:
1125                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1126                             &cb.cb_guid) == 0);
1127                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1128                                 if (strcmp(zpool_get_name(cb.cb_zhp),
1129                                     zpool_get_name(zhp)) == 0)
1130                                         (void) printf(gettext("currently in "
1131                                             "use"));
1132                                 else
1133                                         (void) printf(gettext("in use by "
1134                                             "pool '%s'"),
1135                                             zpool_get_name(cb.cb_zhp));
1136                                 zpool_close(cb.cb_zhp);
1137                         } else {
1138                                 (void) printf(gettext("currently in use"));
1139                         }
1140                         break;
1141 
1142                 case VDEV_AUX_ERR_EXCEEDED:
1143                         (void) printf(gettext("too many errors"));


1221         if (vs->vs_aux != 0) {
1222                 (void) printf("  ");
1223 
1224                 switch (vs->vs_aux) {
1225                 case VDEV_AUX_OPEN_FAILED:
1226                         (void) printf(gettext("cannot open"));
1227                         break;
1228 
1229                 case VDEV_AUX_BAD_GUID_SUM:
1230                         (void) printf(gettext("missing device"));
1231                         break;
1232 
1233                 case VDEV_AUX_NO_REPLICAS:
1234                         (void) printf(gettext("insufficient replicas"));
1235                         break;
1236 
1237                 case VDEV_AUX_VERSION_NEWER:
1238                         (void) printf(gettext("newer version"));
1239                         break;
1240 




1241                 case VDEV_AUX_ERR_EXCEEDED:
1242                         (void) printf(gettext("too many errors"));
1243                         break;
1244 
1245                 default:
1246                         (void) printf(gettext("corrupted data"));
1247                         break;
1248                 }
1249         }
1250         (void) printf("\n");
1251 
1252         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1253             &child, &children) != 0)
1254                 return;
1255 
1256         for (c = 0; c < children; c++) {
1257                 uint64_t is_log = B_FALSE;
1258 
1259                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1260                     &is_log);


1387         case ZPOOL_STATUS_OFFLINE_DEV:
1388                 (void) printf(gettext(" status: One or more devices "
1389                     "are offlined.\n"));
1390                 break;
1391 
1392         case ZPOOL_STATUS_CORRUPT_POOL:
1393                 (void) printf(gettext(" status: The pool metadata is "
1394                     "corrupted.\n"));
1395                 break;
1396 
1397         case ZPOOL_STATUS_VERSION_OLDER:
1398                 (void) printf(gettext(" status: The pool is formatted using an "
1399                     "older on-disk version.\n"));
1400                 break;
1401 
1402         case ZPOOL_STATUS_VERSION_NEWER:
1403                 (void) printf(gettext(" status: The pool is formatted using an "
1404                     "incompatible version.\n"));
1405                 break;
1406 














1407         case ZPOOL_STATUS_HOSTID_MISMATCH:
1408                 (void) printf(gettext(" status: The pool was last accessed by "
1409                     "another system.\n"));
1410                 break;
1411 
1412         case ZPOOL_STATUS_FAULTED_DEV_R:
1413         case ZPOOL_STATUS_FAULTED_DEV_NR:
1414                 (void) printf(gettext(" status: One or more devices are "
1415                     "faulted.\n"));
1416                 break;
1417 
1418         case ZPOOL_STATUS_BAD_LOG:
1419                 (void) printf(gettext(" status: An intent log record cannot be "
1420                     "read.\n"));
1421                 break;
1422 
1423         case ZPOOL_STATUS_RESILVERING:
1424                 (void) printf(gettext(" status: One or more devices were being "
1425                     "resilvered.\n"));
1426                 break;


1444                 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1445                         (void) printf(gettext(" action: The pool can be "
1446                             "imported using its name or numeric "
1447                             "identifier and\n\tthe '-f' flag.\n"));
1448                 else
1449                         (void) printf(gettext(" action: The pool can be "
1450                             "imported using its name or numeric "
1451                             "identifier.\n"));
1452         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1453                 (void) printf(gettext(" action: The pool can be imported "
1454                     "despite missing or damaged devices.  The\n\tfault "
1455                     "tolerance of the pool may be compromised if imported.\n"));
1456         } else {
1457                 switch (reason) {
1458                 case ZPOOL_STATUS_VERSION_NEWER:
1459                         (void) printf(gettext(" action: The pool cannot be "
1460                             "imported.  Access the pool on a system running "
1461                             "newer\n\tsoftware, or recreate the pool from "
1462                             "backup.\n"));
1463                         break;














1464                 case ZPOOL_STATUS_MISSING_DEV_R:
1465                 case ZPOOL_STATUS_MISSING_DEV_NR:
1466                 case ZPOOL_STATUS_BAD_GUID_SUM:
1467                         (void) printf(gettext(" action: The pool cannot be "
1468                             "imported. Attach the missing\n\tdevices and try "
1469                             "again.\n"));
1470                         break;
1471                 default:
1472                         (void) printf(gettext(" action: The pool cannot be "
1473                             "imported due to damaged devices or data.\n"));
1474                 }
1475         }
1476 
1477         /* Print the comment attached to the pool. */
1478         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1479                 (void) printf(gettext("comment: %s\n"), comment);
1480 
1481         /*
1482          * If the state is "closed" or "can't open", and the aux state
1483          * is "corrupt data":


1519  * Perform the import for the given configuration.  This passes the heavy
1520  * lifting off to zpool_import_props(), and then mounts the datasets contained
1521  * within the pool.
1522  */
1523 static int
1524 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1525     nvlist_t *props, int flags)
1526 {
1527         zpool_handle_t *zhp;
1528         char *name;
1529         uint64_t state;
1530         uint64_t version;
1531 
1532         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1533             &name) == 0);
1534 
1535         verify(nvlist_lookup_uint64(config,
1536             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1537         verify(nvlist_lookup_uint64(config,
1538             ZPOOL_CONFIG_VERSION, &version) == 0);
1539         if (version > SPA_VERSION) {
1540                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1541                     "is formatted using a newer ZFS version\n"), name);
1542                 return (1);
1543         } else if (state != POOL_STATE_EXPORTED &&
1544             !(flags & ZFS_IMPORT_ANY_HOST)) {
1545                 uint64_t hostid;
1546 
1547                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1548                     &hostid) == 0) {
1549                         if ((unsigned long)hostid != gethostid()) {
1550                                 char *hostname;
1551                                 uint64_t timestamp;
1552                                 time_t t;
1553 
1554                                 verify(nvlist_lookup_string(config,
1555                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1556                                 verify(nvlist_lookup_uint64(config,
1557                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1558                                 t = timestamp;
1559                                 (void) fprintf(stderr, gettext("cannot import "
1560                                     "'%s': pool may be in use from other "
1561                                     "system, it was last accessed by %s "


2456 
2457         pool_list_free(list);
2458 
2459         return (ret);
2460 }
2461 
2462 typedef struct list_cbdata {
2463         boolean_t       cb_verbose;
2464         int             cb_namewidth;
2465         boolean_t       cb_scripted;
2466         zprop_list_t    *cb_proplist;
2467 } list_cbdata_t;
2468 
2469 /*
2470  * Given a list of columns to display, output appropriate headers for each one.
2471  */
2472 static void
2473 print_header(list_cbdata_t *cb)
2474 {
2475         zprop_list_t *pl = cb->cb_proplist;

2476         const char *header;
2477         boolean_t first = B_TRUE;
2478         boolean_t right_justify;
2479         size_t width = 0;
2480 
2481         for (; pl != NULL; pl = pl->pl_next) {
2482                 if (pl->pl_prop == ZPROP_INVAL)
2483                         continue;
2484 
2485                 width = pl->pl_width;
2486                 if (first && cb->cb_verbose) {
2487                         /*
2488                          * Reset the width to accommodate the verbose listing
2489                          * of devices.
2490                          */
2491                         width = cb->cb_namewidth;
2492                 }
2493 
2494                 if (!first)
2495                         (void) printf("  ");
2496                 else
2497                         first = B_FALSE;
2498 


2499                 header = zpool_prop_column_name(pl->pl_prop);
2500                 right_justify = zpool_prop_align_right(pl->pl_prop);


2501 






2502                 if (pl->pl_next == NULL && !right_justify)
2503                         (void) printf("%s", header);
2504                 else if (right_justify)
2505                         (void) printf("%*s", width, header);
2506                 else
2507                         (void) printf("%-*s", width, header);
2508 
2509         }
2510 
2511         (void) printf("\n");
2512 }
2513 
2514 /*
2515  * Given a pool and a list of properties, print out all the properties according
2516  * to the described layout.
2517  */
2518 static void
2519 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2520 {
2521         zprop_list_t *pl = cb->cb_proplist;


2540                         if (cb->cb_scripted)
2541                                 (void) printf("\t");
2542                         else
2543                                 (void) printf("  ");
2544                 } else {
2545                         first = B_FALSE;
2546                 }
2547 
2548                 right_justify = B_FALSE;
2549                 if (pl->pl_prop != ZPROP_INVAL) {
2550                         if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
2551                             zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
2552                                 propstr = "-";
2553                         else if (zpool_get_prop(zhp, pl->pl_prop, property,
2554                             sizeof (property), NULL) != 0)
2555                                 propstr = "-";
2556                         else
2557                                 propstr = property;
2558 
2559                         right_justify = zpool_prop_align_right(pl->pl_prop);





2560                 } else {
2561                         propstr = "-";
2562                 }
2563 
2564 
2565                 /*
2566                  * If this is being called in scripted mode, or if this is the
2567                  * last column and it is left-justified, don't include a width
2568                  * format specifier.
2569                  */
2570                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
2571                         (void) printf("%s", propstr);
2572                 else if (right_justify)
2573                         (void) printf("%*s", width, propstr);
2574                 else
2575                         (void) printf("%-*s", width, propstr);
2576         }
2577 
2578         (void) printf("\n");
2579 }


3879                 break;
3880 
3881         case ZPOOL_STATUS_VERSION_OLDER:
3882                 (void) printf(gettext("status: The pool is formatted using an "
3883                     "older on-disk format.  The pool can\n\tstill be used, but "
3884                     "some features are unavailable.\n"));
3885                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3886                     "upgrade'.  Once this is done, the\n\tpool will no longer "
3887                     "be accessible on older software versions.\n"));
3888                 break;
3889 
3890         case ZPOOL_STATUS_VERSION_NEWER:
3891                 (void) printf(gettext("status: The pool has been upgraded to a "
3892                     "newer, incompatible on-disk version.\n\tThe pool cannot "
3893                     "be accessed on this system.\n"));
3894                 (void) printf(gettext("action: Access the pool from a system "
3895                     "running more recent software, or\n\trestore the pool from "
3896                     "backup.\n"));
3897                 break;
3898 

























3899         case ZPOOL_STATUS_FAULTED_DEV_R:
3900                 (void) printf(gettext("status: One or more devices are "
3901                     "faulted in response to persistent errors.\n\tSufficient "
3902                     "replicas exist for the pool to continue functioning "
3903                     "in a\n\tdegraded state.\n"));
3904                 (void) printf(gettext("action: Replace the faulted device, "
3905                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3906                 break;
3907 
3908         case ZPOOL_STATUS_FAULTED_DEV_NR:
3909                 (void) printf(gettext("status: One or more devices are "
3910                     "faulted in response to persistent errors.  There are "
3911                     "insufficient replicas for the pool to\n\tcontinue "
3912                     "functioning.\n"));
3913                 (void) printf(gettext("action: Destroy and re-create the pool "
3914                     "from a backup source.  Manually marking the device\n"
3915                     "\trepaired using 'zpool clear' may allow some data "
3916                     "to be recovered.\n"));
3917                 break;
3918 


4103         int     cb_all;
4104         int     cb_first;
4105         int     cb_newer;
4106         int     cb_argc;
4107         uint64_t cb_version;
4108         char    **cb_argv;
4109 } upgrade_cbdata_t;
4110 
4111 static int
4112 upgrade_cb(zpool_handle_t *zhp, void *arg)
4113 {
4114         upgrade_cbdata_t *cbp = arg;
4115         nvlist_t *config;
4116         uint64_t version;
4117         int ret = 0;
4118 
4119         config = zpool_get_config(zhp, NULL);
4120         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4121             &version) == 0);
4122 
4123         if (!cbp->cb_newer && version < SPA_VERSION) {

4124                 if (!cbp->cb_all) {
4125                         if (cbp->cb_first) {
4126                                 (void) printf(gettext("The following pools are "
4127                                     "out of date, and can be upgraded.  After "
4128                                     "being\nupgraded, these pools will no "
4129                                     "longer be accessible by older software "
4130                                     "versions.\n\n"));
4131                                 (void) printf(gettext("VER  POOL\n"));
4132                                 (void) printf(gettext("---  ------------\n"));
4133                                 cbp->cb_first = B_FALSE;
4134                         }
4135 
4136                         (void) printf("%2llu   %s\n", (u_longlong_t)version,
4137                             zpool_get_name(zhp));
4138                 } else {
4139                         cbp->cb_first = B_FALSE;
4140                         ret = zpool_upgrade(zhp, cbp->cb_version);
4141                         if (!ret) {
4142                                 (void) printf(gettext("Successfully upgraded "
4143                                     "'%s'\n\n"), zpool_get_name(zhp));
4144                         }
4145                 }
4146         } else if (cbp->cb_newer && version > SPA_VERSION) {
4147                 assert(!cbp->cb_all);
4148 
4149                 if (cbp->cb_first) {
4150                         (void) printf(gettext("The following pools are "
4151                             "formatted using a newer software version and\n"
4152                             "cannot be accessed on the current system.\n\n"));

4153                         (void) printf(gettext("VER  POOL\n"));
4154                         (void) printf(gettext("---  ------------\n"));
4155                         cbp->cb_first = B_FALSE;
4156                 }
4157 
4158                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
4159                     zpool_get_name(zhp));
4160         }
4161 
4162         zpool_close(zhp);
4163         return (ret);
4164 }
4165 
4166 /* ARGSUSED */
4167 static int
4168 upgrade_one(zpool_handle_t *zhp, void *data)
4169 {
4170         upgrade_cbdata_t *cbp = data;
4171         uint64_t cur_version;
4172         int ret;


4216 zpool_do_upgrade(int argc, char **argv)
4217 {
4218         int c;
4219         upgrade_cbdata_t cb = { 0 };
4220         int ret = 0;
4221         boolean_t showversions = B_FALSE;
4222         char *end;
4223 
4224 
4225         /* check options */
4226         while ((c = getopt(argc, argv, ":avV:")) != -1) {
4227                 switch (c) {
4228                 case 'a':
4229                         cb.cb_all = B_TRUE;
4230                         break;
4231                 case 'v':
4232                         showversions = B_TRUE;
4233                         break;
4234                 case 'V':
4235                         cb.cb_version = strtoll(optarg, &end, 10);
4236                         if (*end != '\0' || cb.cb_version > SPA_VERSION ||
4237                             cb.cb_version < SPA_VERSION_1) {
4238                                 (void) fprintf(stderr,
4239                                     gettext("invalid version '%s'\n"), optarg);
4240                                 usage(B_FALSE);
4241                         }
4242                         break;
4243                 case ':':
4244                         (void) fprintf(stderr, gettext("missing argument for "
4245                             "'%c' option\n"), optopt);
4246                         usage(B_FALSE);
4247                         break;
4248                 case '?':
4249                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4250                             optopt);
4251                         usage(B_FALSE);
4252                 }
4253         }
4254 
4255         cb.cb_argc = argc;
4256         cb.cb_argv = argv;
4257         argc -= optind;


4262         } else if (!cb.cb_all && argc == 0) {
4263                 (void) fprintf(stderr, gettext("-V option is "
4264                     "incompatible with other arguments\n"));
4265                 usage(B_FALSE);
4266         }
4267 
4268         if (showversions) {
4269                 if (cb.cb_all || argc != 0) {
4270                         (void) fprintf(stderr, gettext("-v option is "
4271                             "incompatible with other arguments\n"));
4272                         usage(B_FALSE);
4273                 }
4274         } else if (cb.cb_all) {
4275                 if (argc != 0) {
4276                         (void) fprintf(stderr, gettext("-a option should not "
4277                             "be used along with a pool name\n"));
4278                         usage(B_FALSE);
4279                 }
4280         }
4281 
4282         (void) printf(gettext("This system is currently running "
4283             "ZFS pool version %llu.\n\n"), SPA_VERSION);
4284         cb.cb_first = B_TRUE;
4285         if (showversions) {
4286                 (void) printf(gettext("The following versions are "
4287                     "supported:\n\n"));
4288                 (void) printf(gettext("VER  DESCRIPTION\n"));
4289                 (void) printf("---  -----------------------------------------"
4290                     "---------------\n");
4291                 (void) printf(gettext(" 1   Initial ZFS version\n"));
4292                 (void) printf(gettext(" 2   Ditto blocks "
4293                     "(replicated metadata)\n"));
4294                 (void) printf(gettext(" 3   Hot spares and double parity "
4295                     "RAID-Z\n"));
4296                 (void) printf(gettext(" 4   zpool history\n"));
4297                 (void) printf(gettext(" 5   Compression using the gzip "
4298                     "algorithm\n"));
4299                 (void) printf(gettext(" 6   bootfs pool property\n"));
4300                 (void) printf(gettext(" 7   Separate intent log devices\n"));
4301                 (void) printf(gettext(" 8   Delegated administration\n"));
4302                 (void) printf(gettext(" 9   refquota and refreservation "
4303                     "properties\n"));


4514 }
4515 
4516 static int
4517 get_callback(zpool_handle_t *zhp, void *data)
4518 {
4519         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
4520         char value[MAXNAMELEN];
4521         zprop_source_t srctype;
4522         zprop_list_t *pl;
4523 
4524         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
4525 
4526                 /*
4527                  * Skip the special fake placeholder. This will also skip
4528                  * over the name property when 'all' is specified.
4529                  */
4530                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
4531                     pl == cbp->cb_proplist)
4532                         continue;
4533 
4534                 if (zpool_get_prop(zhp, pl->pl_prop,
4535                     value, sizeof (value), &srctype) != 0)












4536                         continue;
4537 
4538                 zprop_print_one_property(zpool_get_name(zhp), cbp,
4539                     zpool_prop_to_name(pl->pl_prop), value, srctype, NULL,
4540                     NULL);
4541         }

4542         return (0);
4543 }
4544 
4545 int
4546 zpool_do_get(int argc, char **argv)
4547 {
4548         zprop_get_cbdata_t cb = { 0 };
4549         zprop_list_t fake_name = { 0 };
4550         int ret;
4551 
4552         if (argc < 3)


4553                 usage(B_FALSE);

4554 
4555         cb.cb_first = B_TRUE;
4556         cb.cb_sources = ZPROP_SRC_ALL;
4557         cb.cb_columns[0] = GET_COL_NAME;
4558         cb.cb_columns[1] = GET_COL_PROPERTY;
4559         cb.cb_columns[2] = GET_COL_VALUE;
4560         cb.cb_columns[3] = GET_COL_SOURCE;
4561         cb.cb_type = ZFS_TYPE_POOL;
4562 
4563         if (zprop_get_list(g_zfs, argv[1],  &cb.cb_proplist,
4564             ZFS_TYPE_POOL) != 0)
4565                 usage(B_FALSE);
4566 
4567         if (cb.cb_proplist != NULL) {
4568                 fake_name.pl_prop = ZPOOL_PROP_NAME;
4569                 fake_name.pl_width = strlen(gettext("NAME"));
4570                 fake_name.pl_next = cb.cb_proplist;
4571                 cb.cb_proplist = &fake_name;
4572         }
4573 




  34 #include <libgen.h>
  35 #include <libintl.h>
  36 #include <libuutil.h>
  37 #include <locale.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <strings.h>
  42 #include <unistd.h>
  43 #include <priv.h>
  44 #include <pwd.h>
  45 #include <zone.h>
  46 #include <zfs_prop.h>
  47 #include <sys/fs/zfs.h>
  48 #include <sys/stat.h>
  49 
  50 #include <libzfs.h>
  51 
  52 #include "zpool_util.h"
  53 #include "zfs_comutil.h"
  54 #include "zfeature_common.h"
  55 
  56 #include "statcommon.h"
  57 
  58 static int zpool_do_create(int, char **);
  59 static int zpool_do_destroy(int, char **);
  60 
  61 static int zpool_do_add(int, char **);
  62 static int zpool_do_remove(int, char **);
  63 
  64 static int zpool_do_list(int, char **);
  65 static int zpool_do_iostat(int, char **);
  66 static int zpool_do_status(int, char **);
  67 
  68 static int zpool_do_online(int, char **);
  69 static int zpool_do_offline(int, char **);
  70 static int zpool_do_clear(int, char **);
  71 static int zpool_do_reopen(int, char **);
  72 
  73 static int zpool_do_reguid(int, char **);
  74 


 184 };
 185 
 186 #define NCOMMAND        (sizeof (command_table) / sizeof (command_table[0]))
 187 
 188 zpool_command_t *current_command;
 189 static char history_str[HIS_MAX_RECORD_LEN];
 190 
 191 static uint_t timestamp_fmt = NODATE;
 192 
 193 static const char *
 194 get_usage(zpool_help_t idx) {
 195         switch (idx) {
 196         case HELP_ADD:
 197                 return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
 198         case HELP_ATTACH:
 199                 return (gettext("\tattach [-f] <pool> <device> "
 200                     "<new-device>\n"));
 201         case HELP_CLEAR:
 202                 return (gettext("\tclear [-nF] <pool> [device]\n"));
 203         case HELP_CREATE:
 204                 return (gettext("\tcreate [-fnd] [-o property=value] ... \n"
 205                     "\t    [-O file-system-property=value] ... \n"
 206                     "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
 207         case HELP_DESTROY:
 208                 return (gettext("\tdestroy [-f] <pool>\n"));
 209         case HELP_DETACH:
 210                 return (gettext("\tdetach <pool> <device>\n"));
 211         case HELP_EXPORT:
 212                 return (gettext("\texport [-f] <pool> ...\n"));
 213         case HELP_HISTORY:
 214                 return (gettext("\thistory [-il] [<pool>] ...\n"));
 215         case HELP_IMPORT:
 216                 return (gettext("\timport [-d dir] [-D]\n"
 217                     "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n"
 218                     "\timport [-o mntopts] [-o property=value] ... \n"
 219                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 220                     "[-R root] [-F [-n]] -a\n"
 221                     "\timport [-o mntopts] [-o property=value] ... \n"
 222                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
 223                     "[-R root] [-F [-n]]\n"
 224                     "\t    <pool | id> [newpool]\n"));


 315                 }
 316         } else {
 317                 (void) fprintf(fp, gettext("usage:\n"));
 318                 (void) fprintf(fp, "%s", get_usage(current_command->usage));
 319         }
 320 
 321         if (current_command != NULL &&
 322             ((strcmp(current_command->name, "set") == 0) ||
 323             (strcmp(current_command->name, "get") == 0) ||
 324             (strcmp(current_command->name, "list") == 0))) {
 325 
 326                 (void) fprintf(fp,
 327                     gettext("\nthe following properties are supported:\n"));
 328 
 329                 (void) fprintf(fp, "\n\t%-15s  %s   %s\n\n",
 330                     "PROPERTY", "EDIT", "VALUES");
 331 
 332                 /* Iterate over all properties */
 333                 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
 334                     ZFS_TYPE_POOL);
 335 
 336                 (void) fprintf(fp, "\t%-15s   ", "feature@...");
 337                 (void) fprintf(fp, "YES   disabled | enabled | active\n");
 338 
 339                 (void) fprintf(fp, gettext("\nThe feature@ properties must be "
 340                     "appended with a feature name.\nSee zpool-features(5).\n"));
 341         }
 342 
 343         /*
 344          * See comments at end of main().
 345          */
 346         if (getenv("ZFS_ABORT") != NULL) {
 347                 (void) printf("dumping core by request\n");
 348                 abort();
 349         }
 350 
 351         exit(requested ? 0 : 2);
 352 }
 353 
 354 void
 355 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
 356     boolean_t print_logs)
 357 {
 358         nvlist_t **child;
 359         uint_t c, children;
 360         char *vname;


 387 static int
 388 add_prop_list(const char *propname, char *propval, nvlist_t **props,
 389     boolean_t poolprop)
 390 {
 391         zpool_prop_t prop = ZPROP_INVAL;
 392         zfs_prop_t fprop;
 393         nvlist_t *proplist;
 394         const char *normnm;
 395         char *strval;
 396 
 397         if (*props == NULL &&
 398             nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
 399                 (void) fprintf(stderr,
 400                     gettext("internal error: out of memory\n"));
 401                 return (1);
 402         }
 403 
 404         proplist = *props;
 405 
 406         if (poolprop) {
 407                 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL &&
 408                     !zpool_prop_feature(propname)) {
 409                         (void) fprintf(stderr, gettext("property '%s' is "
 410                             "not a valid pool property\n"), propname);
 411                         return (2);
 412                 }
 413                 if (zpool_prop_feature(propname))
 414                         normnm = propname;
 415                 else
 416                         normnm = zpool_prop_to_name(prop);
 417         } else {
 418                 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) {
 419                         normnm = zfs_prop_to_name(fprop);
 420                 } else {
 421                         normnm = propname;
 422                 }
 423         }
 424 
 425         if (nvlist_lookup_string(proplist, normnm, &strval) == 0 &&
 426             prop != ZPOOL_PROP_CACHEFILE) {
 427                 (void) fprintf(stderr, gettext("property '%s' "
 428                     "specified multiple times\n"), propname);
 429                 return (2);
 430         }
 431 
 432         if (nvlist_add_string(proplist, normnm, propval) != 0) {
 433                 (void) fprintf(stderr, gettext("internal "
 434                     "error: out of memory\n"));
 435                 return (1);


 568         }
 569         if (argc < 2) {
 570                 (void) fprintf(stderr, gettext("missing device\n"));
 571                 usage(B_FALSE);
 572         }
 573 
 574         poolname = argv[0];
 575 
 576         if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
 577                 return (1);
 578 
 579         for (i = 1; i < argc; i++) {
 580                 if (zpool_vdev_remove(zhp, argv[i]) != 0)
 581                         ret = 1;
 582         }
 583 
 584         return (ret);
 585 }
 586 
 587 /*
 588  * zpool create [-fnd] [-o property=value] ...
 589  *              [-O file-system-property=value] ...
 590  *              [-R root] [-m mountpoint] <pool> <dev> ...
 591  *
 592  *      -f      Force creation, even if devices appear in use
 593  *      -n      Do not create the pool, but display the resulting layout if it
 594  *              were to be created.
 595  *      -R      Create a pool under an alternate root
 596  *      -m      Set default mountpoint for the root dataset.  By default it's
 597  *              '/<pool>'
 598  *      -o      Set property=value.
 599  *      -d      Don't automatically enable all supported pool features
 600  *              (individual features can be enabled with -o).
 601  *      -O      Set fsproperty=value in the pool's root file system
 602  *
 603  * Creates the named pool according to the given vdev specification.  The
 604  * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c.  Once
 605  * we get the nvlist back from get_vdev_spec(), we either print out the contents
 606  * (if '-n' was specified), or pass it to libzfs to do the creation.
 607  */
 608 int
 609 zpool_do_create(int argc, char **argv)
 610 {
 611         boolean_t force = B_FALSE;
 612         boolean_t dryrun = B_FALSE;
 613         boolean_t enable_all_pool_feat = B_TRUE;
 614         int c;
 615         nvlist_t *nvroot = NULL;
 616         char *poolname;
 617         int ret = 1;
 618         char *altroot = NULL;
 619         char *mountpoint = NULL;
 620         nvlist_t *fsprops = NULL;
 621         nvlist_t *props = NULL;
 622         char *propval;
 623 
 624         /* check options */
 625         while ((c = getopt(argc, argv, ":fndR:m:o:O:")) != -1) {
 626                 switch (c) {
 627                 case 'f':
 628                         force = B_TRUE;
 629                         break;
 630                 case 'n':
 631                         dryrun = B_TRUE;
 632                         break;
 633                 case 'd':
 634                         enable_all_pool_feat = B_FALSE;
 635                         break;
 636                 case 'R':
 637                         altroot = optarg;
 638                         if (add_prop_list(zpool_prop_to_name(
 639                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
 640                                 goto errout;
 641                         if (nvlist_lookup_string(props,
 642                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
 643                             &propval) == 0)
 644                                 break;
 645                         if (add_prop_list(zpool_prop_to_name(
 646                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
 647                                 goto errout;
 648                         break;
 649                 case 'm':
 650                         mountpoint = optarg;
 651                         break;
 652                 case 'o':
 653                         if ((propval = strchr(optarg, '=')) == NULL) {
 654                                 (void) fprintf(stderr, gettext("missing "
 655                                     "'=' for -o option\n"));
 656                                 goto errout;
 657                         }
 658                         *propval = '\0';
 659                         propval++;
 660 
 661                         if (add_prop_list(optarg, propval, &props, B_TRUE))
 662                                 goto errout;
 663 
 664                         /*
 665                          * If the user is creating a pool that doesn't support
 666                          * feature flags, don't enable any features.
 667                          */
 668                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
 669                                 char *end;
 670                                 u_longlong_t ver;
 671 
 672                                 ver = strtoull(propval, &end, 10);
 673                                 if (*end == '\0' &&
 674                                     ver < SPA_VERSION_FEATURES) {
 675                                         enable_all_pool_feat = B_FALSE;
 676                                 }
 677                         }
 678                         break;
 679                 case 'O':
 680                         if ((propval = strchr(optarg, '=')) == NULL) {
 681                                 (void) fprintf(stderr, gettext("missing "
 682                                     "'=' for -O option\n"));
 683                                 goto errout;
 684                         }
 685                         *propval = '\0';
 686                         propval++;
 687 
 688                         if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
 689                                 goto errout;
 690                         break;
 691                 case ':':
 692                         (void) fprintf(stderr, gettext("missing argument for "
 693                             "'%c' option\n"), optopt);
 694                         goto badusage;
 695                 case '?':
 696                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 697                             optopt);


 723                     "character '/' in pool name\n"), poolname);
 724                 (void) fprintf(stderr, gettext("use 'zfs create' to "
 725                     "create a dataset\n"));
 726                 goto errout;
 727         }
 728 
 729         /* pass off to get_vdev_spec for bulk processing */
 730         nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun,
 731             argc - 1, argv + 1);
 732         if (nvroot == NULL)
 733                 goto errout;
 734 
 735         /* make_root_vdev() allows 0 toplevel children if there are spares */
 736         if (!zfs_allocatable_devs(nvroot)) {
 737                 (void) fprintf(stderr, gettext("invalid vdev "
 738                     "specification: at least one toplevel vdev must be "
 739                     "specified\n"));
 740                 goto errout;
 741         }
 742 

 743         if (altroot != NULL && altroot[0] != '/') {
 744                 (void) fprintf(stderr, gettext("invalid alternate root '%s': "
 745                     "must be an absolute path\n"), altroot);
 746                 goto errout;
 747         }
 748 
 749         /*
 750          * Check the validity of the mountpoint and direct the user to use the
 751          * '-m' mountpoint option if it looks like its in use.
 752          */
 753         if (mountpoint == NULL ||
 754             (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
 755             strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
 756                 char buf[MAXPATHLEN];
 757                 DIR *dirp;
 758 
 759                 if (mountpoint && mountpoint[0] != '/') {
 760                         (void) fprintf(stderr, gettext("invalid mountpoint "
 761                             "'%s': must be an absolute path, 'legacy', or "
 762                             "'none'\n"), mountpoint);


 804         }
 805 
 806         if (dryrun) {
 807                 /*
 808                  * For a dry run invocation, print out a basic message and run
 809                  * through all the vdevs in the list and print out in an
 810                  * appropriate hierarchy.
 811                  */
 812                 (void) printf(gettext("would create '%s' with the "
 813                     "following layout:\n\n"), poolname);
 814 
 815                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
 816                 if (num_logs(nvroot) > 0)
 817                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
 818 
 819                 ret = 0;
 820         } else {
 821                 /*
 822                  * Hand off to libzfs.
 823                  */
 824                 if (enable_all_pool_feat) {
 825                         int i;
 826                         for (i = 0; i < SPA_FEATURES; i++) {
 827                                 char propname[MAXPATHLEN];
 828                                 zfeature_info_t *feat = &spa_feature_table[i];
 829 
 830                                 (void) snprintf(propname, sizeof (propname),
 831                                     "feature@%s", feat->fi_uname);
 832 
 833                                 /*
 834                                  * Skip feature if user specified it manually
 835                                  * on the command line.
 836                                  */
 837                                 if (nvlist_exists(props, propname))
 838                                         continue;
 839 
 840                                 if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
 841                                     &props, B_TRUE) != 0)
 842                                         goto errout;
 843                         }
 844                 }
 845                 if (zpool_create(g_zfs, poolname,
 846                     nvroot, props, fsprops) == 0) {
 847                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
 848                             ZFS_TYPE_FILESYSTEM);
 849                         if (pool != NULL) {
 850                                 if (mountpoint != NULL)
 851                                         verify(zfs_prop_set(pool,
 852                                             zfs_prop_to_name(
 853                                             ZFS_PROP_MOUNTPOINT),
 854                                             mountpoint) == 0);
 855                                 if (zfs_mount(pool, NULL, 0) == 0)
 856                                         ret = zfs_shareall(pool);
 857                                 zfs_close(pool);
 858                         }
 859                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
 860                         (void) fprintf(stderr, gettext("pool name may have "
 861                             "been omitted\n"));
 862                 }
 863         }
 864 


1156         } else if (vs->vs_aux != 0) {
1157                 (void) printf("  ");
1158 
1159                 switch (vs->vs_aux) {
1160                 case VDEV_AUX_OPEN_FAILED:
1161                         (void) printf(gettext("cannot open"));
1162                         break;
1163 
1164                 case VDEV_AUX_BAD_GUID_SUM:
1165                         (void) printf(gettext("missing device"));
1166                         break;
1167 
1168                 case VDEV_AUX_NO_REPLICAS:
1169                         (void) printf(gettext("insufficient replicas"));
1170                         break;
1171 
1172                 case VDEV_AUX_VERSION_NEWER:
1173                         (void) printf(gettext("newer version"));
1174                         break;
1175 
1176                 case VDEV_AUX_UNSUP_FEAT:
1177                         (void) printf(gettext("unsupported feature(s)"));
1178                         break;
1179 
1180                 case VDEV_AUX_SPARED:
1181                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1182                             &cb.cb_guid) == 0);
1183                         if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
1184                                 if (strcmp(zpool_get_name(cb.cb_zhp),
1185                                     zpool_get_name(zhp)) == 0)
1186                                         (void) printf(gettext("currently in "
1187                                             "use"));
1188                                 else
1189                                         (void) printf(gettext("in use by "
1190                                             "pool '%s'"),
1191                                             zpool_get_name(cb.cb_zhp));
1192                                 zpool_close(cb.cb_zhp);
1193                         } else {
1194                                 (void) printf(gettext("currently in use"));
1195                         }
1196                         break;
1197 
1198                 case VDEV_AUX_ERR_EXCEEDED:
1199                         (void) printf(gettext("too many errors"));


1277         if (vs->vs_aux != 0) {
1278                 (void) printf("  ");
1279 
1280                 switch (vs->vs_aux) {
1281                 case VDEV_AUX_OPEN_FAILED:
1282                         (void) printf(gettext("cannot open"));
1283                         break;
1284 
1285                 case VDEV_AUX_BAD_GUID_SUM:
1286                         (void) printf(gettext("missing device"));
1287                         break;
1288 
1289                 case VDEV_AUX_NO_REPLICAS:
1290                         (void) printf(gettext("insufficient replicas"));
1291                         break;
1292 
1293                 case VDEV_AUX_VERSION_NEWER:
1294                         (void) printf(gettext("newer version"));
1295                         break;
1296 
1297                 case VDEV_AUX_UNSUP_FEAT:
1298                         (void) printf(gettext("unsupported feature(s)"));
1299                         break;
1300 
1301                 case VDEV_AUX_ERR_EXCEEDED:
1302                         (void) printf(gettext("too many errors"));
1303                         break;
1304 
1305                 default:
1306                         (void) printf(gettext("corrupted data"));
1307                         break;
1308                 }
1309         }
1310         (void) printf("\n");
1311 
1312         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1313             &child, &children) != 0)
1314                 return;
1315 
1316         for (c = 0; c < children; c++) {
1317                 uint64_t is_log = B_FALSE;
1318 
1319                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1320                     &is_log);


1447         case ZPOOL_STATUS_OFFLINE_DEV:
1448                 (void) printf(gettext(" status: One or more devices "
1449                     "are offlined.\n"));
1450                 break;
1451 
1452         case ZPOOL_STATUS_CORRUPT_POOL:
1453                 (void) printf(gettext(" status: The pool metadata is "
1454                     "corrupted.\n"));
1455                 break;
1456 
1457         case ZPOOL_STATUS_VERSION_OLDER:
1458                 (void) printf(gettext(" status: The pool is formatted using an "
1459                     "older on-disk version.\n"));
1460                 break;
1461 
1462         case ZPOOL_STATUS_VERSION_NEWER:
1463                 (void) printf(gettext(" status: The pool is formatted using an "
1464                     "incompatible version.\n"));
1465                 break;
1466 
1467         case ZPOOL_STATUS_UNSUP_FEAT_READ:
1468                 (void) printf(gettext("status: The pool uses the following "
1469                     "feature(s) not supported on this sytem:\n"));
1470                 zpool_print_unsup_feat(config);
1471                 break;
1472 
1473         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1474                 (void) printf(gettext("status: The pool can only be accessed "
1475                     "in read-only mode on this system. It\n\tcannot be "
1476                     "accessed in read-write mode because it uses the "
1477                     "following\n\tfeature(s) not supported on this system:\n"));
1478                 zpool_print_unsup_feat(config);
1479                 break;
1480 
1481         case ZPOOL_STATUS_HOSTID_MISMATCH:
1482                 (void) printf(gettext(" status: The pool was last accessed by "
1483                     "another system.\n"));
1484                 break;
1485 
1486         case ZPOOL_STATUS_FAULTED_DEV_R:
1487         case ZPOOL_STATUS_FAULTED_DEV_NR:
1488                 (void) printf(gettext(" status: One or more devices are "
1489                     "faulted.\n"));
1490                 break;
1491 
1492         case ZPOOL_STATUS_BAD_LOG:
1493                 (void) printf(gettext(" status: An intent log record cannot be "
1494                     "read.\n"));
1495                 break;
1496 
1497         case ZPOOL_STATUS_RESILVERING:
1498                 (void) printf(gettext(" status: One or more devices were being "
1499                     "resilvered.\n"));
1500                 break;


1518                 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
1519                         (void) printf(gettext(" action: The pool can be "
1520                             "imported using its name or numeric "
1521                             "identifier and\n\tthe '-f' flag.\n"));
1522                 else
1523                         (void) printf(gettext(" action: The pool can be "
1524                             "imported using its name or numeric "
1525                             "identifier.\n"));
1526         } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
1527                 (void) printf(gettext(" action: The pool can be imported "
1528                     "despite missing or damaged devices.  The\n\tfault "
1529                     "tolerance of the pool may be compromised if imported.\n"));
1530         } else {
1531                 switch (reason) {
1532                 case ZPOOL_STATUS_VERSION_NEWER:
1533                         (void) printf(gettext(" action: The pool cannot be "
1534                             "imported.  Access the pool on a system running "
1535                             "newer\n\tsoftware, or recreate the pool from "
1536                             "backup.\n"));
1537                         break;
1538                 case ZPOOL_STATUS_UNSUP_FEAT_READ:
1539                         (void) printf(gettext("action: The pool cannot be "
1540                             "imported. Access the pool on a system that "
1541                             "supports\n\tthe required feature(s), or recreate "
1542                             "the pool from backup.\n"));
1543                         break;
1544                 case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
1545                         (void) printf(gettext("action: The pool cannot be "
1546                             "imported in read-write mode. Import the pool "
1547                             "with\n"
1548                             "\t\"-o readonly=on\", access the pool on a system "
1549                             "that supports the\n\trequired feature(s), or "
1550                             "recreate the pool from backup.\n"));
1551                         break;
1552                 case ZPOOL_STATUS_MISSING_DEV_R:
1553                 case ZPOOL_STATUS_MISSING_DEV_NR:
1554                 case ZPOOL_STATUS_BAD_GUID_SUM:
1555                         (void) printf(gettext(" action: The pool cannot be "
1556                             "imported. Attach the missing\n\tdevices and try "
1557                             "again.\n"));
1558                         break;
1559                 default:
1560                         (void) printf(gettext(" action: The pool cannot be "
1561                             "imported due to damaged devices or data.\n"));
1562                 }
1563         }
1564 
1565         /* Print the comment attached to the pool. */
1566         if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0)
1567                 (void) printf(gettext("comment: %s\n"), comment);
1568 
1569         /*
1570          * If the state is "closed" or "can't open", and the aux state
1571          * is "corrupt data":


1607  * Perform the import for the given configuration.  This passes the heavy
1608  * lifting off to zpool_import_props(), and then mounts the datasets contained
1609  * within the pool.
1610  */
1611 static int
1612 do_import(nvlist_t *config, const char *newname, const char *mntopts,
1613     nvlist_t *props, int flags)
1614 {
1615         zpool_handle_t *zhp;
1616         char *name;
1617         uint64_t state;
1618         uint64_t version;
1619 
1620         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1621             &name) == 0);
1622 
1623         verify(nvlist_lookup_uint64(config,
1624             ZPOOL_CONFIG_POOL_STATE, &state) == 0);
1625         verify(nvlist_lookup_uint64(config,
1626             ZPOOL_CONFIG_VERSION, &version) == 0);
1627         if (!SPA_VERSION_IS_SUPPORTED(version)) {
1628                 (void) fprintf(stderr, gettext("cannot import '%s': pool "
1629                     "is formatted using an unsupported ZFS version\n"), name);
1630                 return (1);
1631         } else if (state != POOL_STATE_EXPORTED &&
1632             !(flags & ZFS_IMPORT_ANY_HOST)) {
1633                 uint64_t hostid;
1634 
1635                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
1636                     &hostid) == 0) {
1637                         if ((unsigned long)hostid != gethostid()) {
1638                                 char *hostname;
1639                                 uint64_t timestamp;
1640                                 time_t t;
1641 
1642                                 verify(nvlist_lookup_string(config,
1643                                     ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
1644                                 verify(nvlist_lookup_uint64(config,
1645                                     ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
1646                                 t = timestamp;
1647                                 (void) fprintf(stderr, gettext("cannot import "
1648                                     "'%s': pool may be in use from other "
1649                                     "system, it was last accessed by %s "


2544 
2545         pool_list_free(list);
2546 
2547         return (ret);
2548 }
2549 
2550 typedef struct list_cbdata {
2551         boolean_t       cb_verbose;
2552         int             cb_namewidth;
2553         boolean_t       cb_scripted;
2554         zprop_list_t    *cb_proplist;
2555 } list_cbdata_t;
2556 
2557 /*
2558  * Given a list of columns to display, output appropriate headers for each one.
2559  */
2560 static void
2561 print_header(list_cbdata_t *cb)
2562 {
2563         zprop_list_t *pl = cb->cb_proplist;
2564         char headerbuf[ZPOOL_MAXPROPLEN];
2565         const char *header;
2566         boolean_t first = B_TRUE;
2567         boolean_t right_justify;
2568         size_t width = 0;
2569 
2570         for (; pl != NULL; pl = pl->pl_next) {



2571                 width = pl->pl_width;
2572                 if (first && cb->cb_verbose) {
2573                         /*
2574                          * Reset the width to accommodate the verbose listing
2575                          * of devices.
2576                          */
2577                         width = cb->cb_namewidth;
2578                 }
2579 
2580                 if (!first)
2581                         (void) printf("  ");
2582                 else
2583                         first = B_FALSE;
2584 
2585                 right_justify = B_FALSE;
2586                 if (pl->pl_prop != ZPROP_INVAL) {
2587                         header = zpool_prop_column_name(pl->pl_prop);
2588                         right_justify = zpool_prop_align_right(pl->pl_prop);
2589                 } else {
2590                         int i;
2591 
2592                         for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
2593                                 headerbuf[i] = toupper(pl->pl_user_prop[i]);
2594                         headerbuf[i] = '\0';
2595                         header = headerbuf;
2596                 }
2597 
2598                 if (pl->pl_next == NULL && !right_justify)
2599                         (void) printf("%s", header);
2600                 else if (right_justify)
2601                         (void) printf("%*s", width, header);
2602                 else
2603                         (void) printf("%-*s", width, header);
2604 
2605         }
2606 
2607         (void) printf("\n");
2608 }
2609 
2610 /*
2611  * Given a pool and a list of properties, print out all the properties according
2612  * to the described layout.
2613  */
2614 static void
2615 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
2616 {
2617         zprop_list_t *pl = cb->cb_proplist;


2636                         if (cb->cb_scripted)
2637                                 (void) printf("\t");
2638                         else
2639                                 (void) printf("  ");
2640                 } else {
2641                         first = B_FALSE;
2642                 }
2643 
2644                 right_justify = B_FALSE;
2645                 if (pl->pl_prop != ZPROP_INVAL) {
2646                         if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
2647                             zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
2648                                 propstr = "-";
2649                         else if (zpool_get_prop(zhp, pl->pl_prop, property,
2650                             sizeof (property), NULL) != 0)
2651                                 propstr = "-";
2652                         else
2653                                 propstr = property;
2654 
2655                         right_justify = zpool_prop_align_right(pl->pl_prop);
2656                 } else if ((zpool_prop_feature(pl->pl_user_prop) ||
2657                     zpool_prop_unsupported(pl->pl_user_prop)) &&
2658                     zpool_prop_get_feature(zhp, pl->pl_user_prop, property,
2659                     sizeof (property)) == 0) {
2660                         propstr = property;
2661                 } else {
2662                         propstr = "-";
2663                 }
2664 
2665 
2666                 /*
2667                  * If this is being called in scripted mode, or if this is the
2668                  * last column and it is left-justified, don't include a width
2669                  * format specifier.
2670                  */
2671                 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
2672                         (void) printf("%s", propstr);
2673                 else if (right_justify)
2674                         (void) printf("%*s", width, propstr);
2675                 else
2676                         (void) printf("%-*s", width, propstr);
2677         }
2678 
2679         (void) printf("\n");
2680 }


3980                 break;
3981 
3982         case ZPOOL_STATUS_VERSION_OLDER:
3983                 (void) printf(gettext("status: The pool is formatted using an "
3984                     "older on-disk format.  The pool can\n\tstill be used, but "
3985                     "some features are unavailable.\n"));
3986                 (void) printf(gettext("action: Upgrade the pool using 'zpool "
3987                     "upgrade'.  Once this is done, the\n\tpool will no longer "
3988                     "be accessible on older software versions.\n"));
3989                 break;
3990 
3991         case ZPOOL_STATUS_VERSION_NEWER:
3992                 (void) printf(gettext("status: The pool has been upgraded to a "
3993                     "newer, incompatible on-disk version.\n\tThe pool cannot "
3994                     "be accessed on this system.\n"));
3995                 (void) printf(gettext("action: Access the pool from a system "
3996                     "running more recent software, or\n\trestore the pool from "
3997                     "backup.\n"));
3998                 break;
3999 
4000         case ZPOOL_STATUS_UNSUP_FEAT_READ:
4001                 (void) printf(gettext("status: The pool cannot be accessed on "
4002                     "this system because it uses the\n\tfollowing feature(s) "
4003                     "not supported on this system:\n"));
4004                 zpool_print_unsup_feat(config);
4005                 (void) printf("\n");
4006                 (void) printf(gettext("action: Access the pool from a system "
4007                     "that supports the required feature(s),\n\tor restore the "
4008                     "pool from backup.\n"));
4009                 break;
4010 
4011         case ZPOOL_STATUS_UNSUP_FEAT_WRITE:
4012                 (void) printf(gettext("status: The pool can only be accessed "
4013                     "in read-only mode on this system. It\n\tcannot be "
4014                     "accessed in read-write mode because it uses the "
4015                     "following\n\tfeature(s) not supported on this system:\n"));
4016                 zpool_print_unsup_feat(config);
4017                 (void) printf("\n");
4018                 (void) printf(gettext("action: The pool cannot be accessed in "
4019                     "read-write mode. Import the pool with\n"
4020                     "\t\"-o readonly=on\", access the pool from a system that "
4021                     "supports the\n\trequired feature(s), or restore the "
4022                     "pool from backup.\n"));
4023                 break;
4024 
4025         case ZPOOL_STATUS_FAULTED_DEV_R:
4026                 (void) printf(gettext("status: One or more devices are "
4027                     "faulted in response to persistent errors.\n\tSufficient "
4028                     "replicas exist for the pool to continue functioning "
4029                     "in a\n\tdegraded state.\n"));
4030                 (void) printf(gettext("action: Replace the faulted device, "
4031                     "or use 'zpool clear' to mark the device\n\trepaired.\n"));
4032                 break;
4033 
4034         case ZPOOL_STATUS_FAULTED_DEV_NR:
4035                 (void) printf(gettext("status: One or more devices are "
4036                     "faulted in response to persistent errors.  There are "
4037                     "insufficient replicas for the pool to\n\tcontinue "
4038                     "functioning.\n"));
4039                 (void) printf(gettext("action: Destroy and re-create the pool "
4040                     "from a backup source.  Manually marking the device\n"
4041                     "\trepaired using 'zpool clear' may allow some data "
4042                     "to be recovered.\n"));
4043                 break;
4044 


4229         int     cb_all;
4230         int     cb_first;
4231         int     cb_newer;
4232         int     cb_argc;
4233         uint64_t cb_version;
4234         char    **cb_argv;
4235 } upgrade_cbdata_t;
4236 
4237 static int
4238 upgrade_cb(zpool_handle_t *zhp, void *arg)
4239 {
4240         upgrade_cbdata_t *cbp = arg;
4241         nvlist_t *config;
4242         uint64_t version;
4243         int ret = 0;
4244 
4245         config = zpool_get_config(zhp, NULL);
4246         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
4247             &version) == 0);
4248 
4249         if (!cbp->cb_newer && SPA_VERSION_IS_SUPPORTED(version) &&
4250             version != SPA_VERSION) {
4251                 if (!cbp->cb_all) {
4252                         if (cbp->cb_first) {
4253                                 (void) printf(gettext("The following pools are "
4254                                     "out of date, and can be upgraded.  After "
4255                                     "being\nupgraded, these pools will no "
4256                                     "longer be accessible by older software "
4257                                     "versions.\n\n"));
4258                                 (void) printf(gettext("VER  POOL\n"));
4259                                 (void) printf(gettext("---  ------------\n"));
4260                                 cbp->cb_first = B_FALSE;
4261                         }
4262 
4263                         (void) printf("%2llu   %s\n", (u_longlong_t)version,
4264                             zpool_get_name(zhp));
4265                 } else {
4266                         cbp->cb_first = B_FALSE;
4267                         ret = zpool_upgrade(zhp, cbp->cb_version);
4268                         if (!ret) {
4269                                 (void) printf(gettext("Successfully upgraded "
4270                                     "'%s'\n\n"), zpool_get_name(zhp));
4271                         }
4272                 }
4273         } else if (cbp->cb_newer && !SPA_VERSION_IS_SUPPORTED(version)) {
4274                 assert(!cbp->cb_all);
4275 
4276                 if (cbp->cb_first) {
4277                         (void) printf(gettext("The following pools are "
4278                             "formatted using an unsupported software version "
4279                             "and\ncannot be accessed on the current "
4280                             "system.\n\n"));
4281                         (void) printf(gettext("VER  POOL\n"));
4282                         (void) printf(gettext("---  ------------\n"));
4283                         cbp->cb_first = B_FALSE;
4284                 }
4285 
4286                 (void) printf("%2llu   %s\n", (u_longlong_t)version,
4287                     zpool_get_name(zhp));
4288         }
4289 
4290         zpool_close(zhp);
4291         return (ret);
4292 }
4293 
4294 /* ARGSUSED */
4295 static int
4296 upgrade_one(zpool_handle_t *zhp, void *data)
4297 {
4298         upgrade_cbdata_t *cbp = data;
4299         uint64_t cur_version;
4300         int ret;


4344 zpool_do_upgrade(int argc, char **argv)
4345 {
4346         int c;
4347         upgrade_cbdata_t cb = { 0 };
4348         int ret = 0;
4349         boolean_t showversions = B_FALSE;
4350         char *end;
4351 
4352 
4353         /* check options */
4354         while ((c = getopt(argc, argv, ":avV:")) != -1) {
4355                 switch (c) {
4356                 case 'a':
4357                         cb.cb_all = B_TRUE;
4358                         break;
4359                 case 'v':
4360                         showversions = B_TRUE;
4361                         break;
4362                 case 'V':
4363                         cb.cb_version = strtoll(optarg, &end, 10);
4364                         if (*end != '\0' ||
4365                             !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) {
4366                                 (void) fprintf(stderr,
4367                                     gettext("invalid version '%s'\n"), optarg);
4368                                 usage(B_FALSE);
4369                         }
4370                         break;
4371                 case ':':
4372                         (void) fprintf(stderr, gettext("missing argument for "
4373                             "'%c' option\n"), optopt);
4374                         usage(B_FALSE);
4375                         break;
4376                 case '?':
4377                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
4378                             optopt);
4379                         usage(B_FALSE);
4380                 }
4381         }
4382 
4383         cb.cb_argc = argc;
4384         cb.cb_argv = argv;
4385         argc -= optind;


4390         } else if (!cb.cb_all && argc == 0) {
4391                 (void) fprintf(stderr, gettext("-V option is "
4392                     "incompatible with other arguments\n"));
4393                 usage(B_FALSE);
4394         }
4395 
4396         if (showversions) {
4397                 if (cb.cb_all || argc != 0) {
4398                         (void) fprintf(stderr, gettext("-v option is "
4399                             "incompatible with other arguments\n"));
4400                         usage(B_FALSE);
4401                 }
4402         } else if (cb.cb_all) {
4403                 if (argc != 0) {
4404                         (void) fprintf(stderr, gettext("-a option should not "
4405                             "be used along with a pool name\n"));
4406                         usage(B_FALSE);
4407                 }
4408         }
4409 
4410         (void) printf(gettext("This system supports ZFS pool feature "
4411             "flags.\n\n"));
4412         cb.cb_first = B_TRUE;
4413         if (showversions) {
4414                 (void) printf(gettext("The following versions are "
4415                     "supported:\n\n"));
4416                 (void) printf(gettext("VER  DESCRIPTION\n"));
4417                 (void) printf("---  -----------------------------------------"
4418                     "---------------\n");
4419                 (void) printf(gettext(" 1   Initial ZFS version\n"));
4420                 (void) printf(gettext(" 2   Ditto blocks "
4421                     "(replicated metadata)\n"));
4422                 (void) printf(gettext(" 3   Hot spares and double parity "
4423                     "RAID-Z\n"));
4424                 (void) printf(gettext(" 4   zpool history\n"));
4425                 (void) printf(gettext(" 5   Compression using the gzip "
4426                     "algorithm\n"));
4427                 (void) printf(gettext(" 6   bootfs pool property\n"));
4428                 (void) printf(gettext(" 7   Separate intent log devices\n"));
4429                 (void) printf(gettext(" 8   Delegated administration\n"));
4430                 (void) printf(gettext(" 9   refquota and refreservation "
4431                     "properties\n"));


4642 }
4643 
4644 static int
4645 get_callback(zpool_handle_t *zhp, void *data)
4646 {
4647         zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
4648         char value[MAXNAMELEN];
4649         zprop_source_t srctype;
4650         zprop_list_t *pl;
4651 
4652         for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
4653 
4654                 /*
4655                  * Skip the special fake placeholder. This will also skip
4656                  * over the name property when 'all' is specified.
4657                  */
4658                 if (pl->pl_prop == ZPOOL_PROP_NAME &&
4659                     pl == cbp->cb_proplist)
4660                         continue;
4661 
4662                 if (pl->pl_prop == ZPROP_INVAL &&
4663                     (zpool_prop_feature(pl->pl_user_prop) ||
4664                     zpool_prop_unsupported(pl->pl_user_prop))) {
4665                         srctype = ZPROP_SRC_LOCAL;
4666 
4667                         if (zpool_prop_get_feature(zhp, pl->pl_user_prop,
4668                             value, sizeof (value)) == 0) {
4669                                 zprop_print_one_property(zpool_get_name(zhp),
4670                                     cbp, pl->pl_user_prop, value, srctype,
4671                                     NULL, NULL);
4672                         }
4673                 } else {
4674                         if (zpool_get_prop(zhp, pl->pl_prop, value,
4675                             sizeof (value), &srctype) != 0)
4676                                 continue;
4677 
4678                         zprop_print_one_property(zpool_get_name(zhp), cbp,
4679                             zpool_prop_to_name(pl->pl_prop), value, srctype,
4680                             NULL, NULL);
4681                 }
4682         }
4683         return (0);
4684 }
4685 
4686 int
4687 zpool_do_get(int argc, char **argv)
4688 {
4689         zprop_get_cbdata_t cb = { 0 };
4690         zprop_list_t fake_name = { 0 };
4691         int ret;
4692 
4693         if (argc < 2) {
4694                 (void) fprintf(stderr, gettext("missing property "
4695                     "argument\n"));
4696                 usage(B_FALSE);
4697         }
4698 
4699         cb.cb_first = B_TRUE;
4700         cb.cb_sources = ZPROP_SRC_ALL;
4701         cb.cb_columns[0] = GET_COL_NAME;
4702         cb.cb_columns[1] = GET_COL_PROPERTY;
4703         cb.cb_columns[2] = GET_COL_VALUE;
4704         cb.cb_columns[3] = GET_COL_SOURCE;
4705         cb.cb_type = ZFS_TYPE_POOL;
4706 
4707         if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
4708             ZFS_TYPE_POOL) != 0)
4709                 usage(B_FALSE);
4710 
4711         if (cb.cb_proplist != NULL) {
4712                 fake_name.pl_prop = ZPOOL_PROP_NAME;
4713                 fake_name.pl_width = strlen(gettext("NAME"));
4714                 fake_name.pl_next = cb.cb_proplist;
4715                 cb.cb_proplist = &fake_name;
4716         }
4717