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, ×tamp) == 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, ×tamp) == 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
|