1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2011, 2018 by Delphix. All rights reserved. 25 * Copyright (c) 2012 by Frederik Wessels. All rights reserved. 26 * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. 27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>. 28 * Copyright 2016 Nexenta Systems, Inc. 29 * Copyright (c) 2017 Datto Inc. 30 */ 31 32 #include <assert.h> 33 #include <ctype.h> 34 #include <dirent.h> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <libgen.h> 38 #include <libintl.h> 39 #include <libuutil.h> 40 #include <locale.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <strings.h> 45 #include <unistd.h> 46 #include <priv.h> 47 #include <pwd.h> 48 #include <zone.h> 49 #include <zfs_prop.h> 50 #include <sys/fs/zfs.h> 51 #include <sys/stat.h> 52 53 #include <libzfs.h> 54 55 #include "zpool_util.h" 56 #include "zfs_comutil.h" 57 #include "zfeature_common.h" 58 59 #include "statcommon.h" 60 61 static int zpool_do_create(int, char **); 62 static int zpool_do_destroy(int, char **); 63 64 static int zpool_do_add(int, char **); 65 static int zpool_do_remove(int, char **); 66 static int zpool_do_labelclear(int, char **); 67 68 static int zpool_do_list(int, char **); 69 static int zpool_do_iostat(int, char **); 70 static int zpool_do_status(int, char **); 71 72 static int zpool_do_online(int, char **); 73 static int zpool_do_offline(int, char **); 74 static int zpool_do_clear(int, char **); 75 static int zpool_do_reopen(int, char **); 76 77 static int zpool_do_reguid(int, char **); 78 79 static int zpool_do_attach(int, char **); 80 static int zpool_do_detach(int, char **); 81 static int zpool_do_replace(int, char **); 82 static int zpool_do_split(int, char **); 83 84 static int zpool_do_scrub(int, char **); 85 86 static int zpool_do_import(int, char **); 87 static int zpool_do_export(int, char **); 88 89 static int zpool_do_upgrade(int, char **); 90 91 static int zpool_do_history(int, char **); 92 93 static int zpool_do_get(int, char **); 94 static int zpool_do_set(int, char **); 95 96 /* 97 * These libumem hooks provide a reasonable set of defaults for the allocator's 98 * debugging facilities. 99 */ 100 101 #ifdef DEBUG 102 const char * 103 _umem_debug_init(void) 104 { 105 return ("default,verbose"); /* $UMEM_DEBUG setting */ 106 } 107 108 const char * 109 _umem_logging_init(void) 110 { 111 return ("fail,contents"); /* $UMEM_LOGGING setting */ 112 } 113 #endif 114 115 typedef enum { 116 HELP_ADD, 117 HELP_ATTACH, 118 HELP_CLEAR, 119 HELP_CREATE, 120 HELP_DESTROY, 121 HELP_DETACH, 122 HELP_EXPORT, 123 HELP_HISTORY, 124 HELP_IMPORT, 125 HELP_IOSTAT, 126 HELP_LABELCLEAR, 127 HELP_LIST, 128 HELP_OFFLINE, 129 HELP_ONLINE, 130 HELP_REPLACE, 131 HELP_REMOVE, 132 HELP_SCRUB, 133 HELP_STATUS, 134 HELP_UPGRADE, 135 HELP_GET, 136 HELP_SET, 137 HELP_SPLIT, 138 HELP_REGUID, 139 HELP_REOPEN 140 } zpool_help_t; 141 142 143 typedef struct zpool_command { 144 const char *name; 145 int (*func)(int, char **); 146 zpool_help_t usage; 147 } zpool_command_t; 148 149 /* 150 * Master command table. Each ZFS command has a name, associated function, and 151 * usage message. The usage messages need to be internationalized, so we have 152 * to have a function to return the usage message based on a command index. 153 * 154 * These commands are organized according to how they are displayed in the usage 155 * message. An empty command (one with a NULL name) indicates an empty line in 156 * the generic usage message. 157 */ 158 static zpool_command_t command_table[] = { 159 { "create", zpool_do_create, HELP_CREATE }, 160 { "destroy", zpool_do_destroy, HELP_DESTROY }, 161 { NULL }, 162 { "add", zpool_do_add, HELP_ADD }, 163 { "remove", zpool_do_remove, HELP_REMOVE }, 164 { NULL }, 165 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, 166 { NULL }, 167 { "list", zpool_do_list, HELP_LIST }, 168 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 169 { "status", zpool_do_status, HELP_STATUS }, 170 { NULL }, 171 { "online", zpool_do_online, HELP_ONLINE }, 172 { "offline", zpool_do_offline, HELP_OFFLINE }, 173 { "clear", zpool_do_clear, HELP_CLEAR }, 174 { "reopen", zpool_do_reopen, HELP_REOPEN }, 175 { NULL }, 176 { "attach", zpool_do_attach, HELP_ATTACH }, 177 { "detach", zpool_do_detach, HELP_DETACH }, 178 { "replace", zpool_do_replace, HELP_REPLACE }, 179 { "split", zpool_do_split, HELP_SPLIT }, 180 { NULL }, 181 { "scrub", zpool_do_scrub, HELP_SCRUB }, 182 { NULL }, 183 { "import", zpool_do_import, HELP_IMPORT }, 184 { "export", zpool_do_export, HELP_EXPORT }, 185 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 186 { "reguid", zpool_do_reguid, HELP_REGUID }, 187 { NULL }, 188 { "history", zpool_do_history, HELP_HISTORY }, 189 { "get", zpool_do_get, HELP_GET }, 190 { "set", zpool_do_set, HELP_SET }, 191 }; 192 193 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 194 195 static zpool_command_t *current_command; 196 static char history_str[HIS_MAX_RECORD_LEN]; 197 static boolean_t log_history = B_TRUE; 198 static uint_t timestamp_fmt = NODATE; 199 200 static const char * 201 get_usage(zpool_help_t idx) 202 { 203 switch (idx) { 204 case HELP_ADD: 205 return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 206 case HELP_ATTACH: 207 return (gettext("\tattach [-f] <pool> <device> " 208 "<new-device>\n")); 209 case HELP_CLEAR: 210 return (gettext("\tclear [-nF] <pool> [device]\n")); 211 case HELP_CREATE: 212 return (gettext("\tcreate [-fnd] [-B] " 213 "[-o property=value] ... \n" 214 "\t [-O file-system-property=value] ... \n" 215 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 216 case HELP_DESTROY: 217 return (gettext("\tdestroy [-f] <pool>\n")); 218 case HELP_DETACH: 219 return (gettext("\tdetach <pool> <device>\n")); 220 case HELP_EXPORT: 221 return (gettext("\texport [-f] <pool> ...\n")); 222 case HELP_HISTORY: 223 return (gettext("\thistory [-il] [<pool>] ...\n")); 224 case HELP_IMPORT: 225 return (gettext("\timport [-d dir] [-D]\n" 226 "\timport [-d dir | -c cachefile] [-F [-n]] <pool | id>\n" 227 "\timport [-o mntopts] [-o property=value] ... \n" 228 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 229 "[-R root] [-F [-n]] -a\n" 230 "\timport [-o mntopts] [-o property=value] ... \n" 231 "\t [-d dir | -c cachefile] [-D] [-f] [-m] [-N] " 232 "[-R root] [-F [-n]]\n" 233 "\t <pool | id> [newpool]\n")); 234 case HELP_IOSTAT: 235 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval " 236 "[count]]\n")); 237 case HELP_LABELCLEAR: 238 return (gettext("\tlabelclear [-f] <vdev>\n")); 239 case HELP_LIST: 240 return (gettext("\tlist [-Hp] [-o property[,...]] " 241 "[-T d|u] [pool] ... [interval [count]]\n")); 242 case HELP_OFFLINE: 243 return (gettext("\toffline [-t] <pool> <device> ...\n")); 244 case HELP_ONLINE: 245 return (gettext("\tonline <pool> <device> ...\n")); 246 case HELP_REPLACE: 247 return (gettext("\treplace [-f] <pool> <device> " 248 "[new-device]\n")); 249 case HELP_REMOVE: 250 return (gettext("\tremove [-nps] <pool> <device> ...\n")); 251 case HELP_REOPEN: 252 return (gettext("\treopen <pool>\n")); 253 case HELP_SCRUB: 254 return (gettext("\tscrub [-s | -p] <pool> ...\n")); 255 case HELP_STATUS: 256 return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval " 257 "[count]]\n")); 258 case HELP_UPGRADE: 259 return (gettext("\tupgrade\n" 260 "\tupgrade -v\n" 261 "\tupgrade [-V version] <-a | pool ...>\n")); 262 case HELP_GET: 263 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " 264 "<\"all\" | property[,...]> <pool> ...\n")); 265 case HELP_SET: 266 return (gettext("\tset <property=value> <pool> \n")); 267 case HELP_SPLIT: 268 return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n" 269 "\t [-o property=value] <pool> <newpool> " 270 "[<device> ...]\n")); 271 case HELP_REGUID: 272 return (gettext("\treguid <pool>\n")); 273 } 274 275 abort(); 276 /* NOTREACHED */ 277 } 278 279 280 /* 281 * Callback routine that will print out a pool property value. 282 */ 283 static int 284 print_prop_cb(int prop, void *cb) 285 { 286 FILE *fp = cb; 287 288 (void) fprintf(fp, "\t%-15s ", zpool_prop_to_name(prop)); 289 290 if (zpool_prop_readonly(prop)) 291 (void) fprintf(fp, " NO "); 292 else 293 (void) fprintf(fp, " YES "); 294 295 if (zpool_prop_values(prop) == NULL) 296 (void) fprintf(fp, "-\n"); 297 else 298 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 299 300 return (ZPROP_CONT); 301 } 302 303 /* 304 * Display usage message. If we're inside a command, display only the usage for 305 * that command. Otherwise, iterate over the entire command table and display 306 * a complete usage message. 307 */ 308 void 309 usage(boolean_t requested) 310 { 311 FILE *fp = requested ? stdout : stderr; 312 313 if (current_command == NULL) { 314 int i; 315 316 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 317 (void) fprintf(fp, 318 gettext("where 'command' is one of the following:\n\n")); 319 320 for (i = 0; i < NCOMMAND; i++) { 321 if (command_table[i].name == NULL) 322 (void) fprintf(fp, "\n"); 323 else 324 (void) fprintf(fp, "%s", 325 get_usage(command_table[i].usage)); 326 } 327 } else { 328 (void) fprintf(fp, gettext("usage:\n")); 329 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 330 } 331 332 if (current_command != NULL && 333 ((strcmp(current_command->name, "set") == 0) || 334 (strcmp(current_command->name, "get") == 0) || 335 (strcmp(current_command->name, "list") == 0))) { 336 337 (void) fprintf(fp, 338 gettext("\nthe following properties are supported:\n")); 339 340 (void) fprintf(fp, "\n\t%-15s %s %s\n\n", 341 "PROPERTY", "EDIT", "VALUES"); 342 343 /* Iterate over all properties */ 344 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 345 ZFS_TYPE_POOL); 346 347 (void) fprintf(fp, "\t%-15s ", "feature@..."); 348 (void) fprintf(fp, "YES disabled | enabled | active\n"); 349 350 (void) fprintf(fp, gettext("\nThe feature@ properties must be " 351 "appended with a feature name.\nSee zpool-features(5).\n")); 352 } 353 354 /* 355 * See comments at end of main(). 356 */ 357 if (getenv("ZFS_ABORT") != NULL) { 358 (void) printf("dumping core by request\n"); 359 abort(); 360 } 361 362 exit(requested ? 0 : 2); 363 } 364 365 void 366 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 367 boolean_t print_logs) 368 { 369 nvlist_t **child; 370 uint_t c, children; 371 char *vname; 372 373 if (name != NULL) 374 (void) printf("\t%*s%s\n", indent, "", name); 375 376 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 377 &child, &children) != 0) 378 return; 379 380 for (c = 0; c < children; c++) { 381 uint64_t is_log = B_FALSE; 382 383 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 384 &is_log); 385 if ((is_log && !print_logs) || (!is_log && print_logs)) 386 continue; 387 388 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 389 print_vdev_tree(zhp, vname, child[c], indent + 2, 390 B_FALSE); 391 free(vname); 392 } 393 } 394 395 static boolean_t 396 prop_list_contains_feature(nvlist_t *proplist) 397 { 398 nvpair_t *nvp; 399 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp; 400 nvp = nvlist_next_nvpair(proplist, nvp)) { 401 if (zpool_prop_feature(nvpair_name(nvp))) 402 return (B_TRUE); 403 } 404 return (B_FALSE); 405 } 406 407 /* 408 * Add a property pair (name, string-value) into a property nvlist. 409 */ 410 static int 411 add_prop_list(const char *propname, char *propval, nvlist_t **props, 412 boolean_t poolprop) 413 { 414 zpool_prop_t prop = ZPOOL_PROP_INVAL; 415 zfs_prop_t fprop; 416 nvlist_t *proplist; 417 const char *normnm; 418 char *strval; 419 420 if (*props == NULL && 421 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 422 (void) fprintf(stderr, 423 gettext("internal error: out of memory\n")); 424 return (1); 425 } 426 427 proplist = *props; 428 429 if (poolprop) { 430 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); 431 432 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL && 433 !zpool_prop_feature(propname)) { 434 (void) fprintf(stderr, gettext("property '%s' is " 435 "not a valid pool property\n"), propname); 436 return (2); 437 } 438 439 /* 440 * feature@ properties and version should not be specified 441 * at the same time. 442 */ 443 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) && 444 nvlist_exists(proplist, vname)) || 445 (prop == ZPOOL_PROP_VERSION && 446 prop_list_contains_feature(proplist))) { 447 (void) fprintf(stderr, gettext("'feature@' and " 448 "'version' properties cannot be specified " 449 "together\n")); 450 return (2); 451 } 452 453 454 if (zpool_prop_feature(propname)) 455 normnm = propname; 456 else 457 normnm = zpool_prop_to_name(prop); 458 } else { 459 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) { 460 normnm = zfs_prop_to_name(fprop); 461 } else { 462 normnm = propname; 463 } 464 } 465 466 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 467 prop != ZPOOL_PROP_CACHEFILE) { 468 (void) fprintf(stderr, gettext("property '%s' " 469 "specified multiple times\n"), propname); 470 return (2); 471 } 472 473 if (nvlist_add_string(proplist, normnm, propval) != 0) { 474 (void) fprintf(stderr, gettext("internal " 475 "error: out of memory\n")); 476 return (1); 477 } 478 479 return (0); 480 } 481 482 /* 483 * zpool add [-fn] <pool> <vdev> ... 484 * 485 * -f Force addition of devices, even if they appear in use 486 * -n Do not add the devices, but display the resulting layout if 487 * they were to be added. 488 * 489 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 490 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 491 * libzfs. 492 */ 493 int 494 zpool_do_add(int argc, char **argv) 495 { 496 boolean_t force = B_FALSE; 497 boolean_t dryrun = B_FALSE; 498 int c; 499 nvlist_t *nvroot; 500 char *poolname; 501 zpool_boot_label_t boot_type; 502 uint64_t boot_size; 503 int ret; 504 zpool_handle_t *zhp; 505 nvlist_t *config; 506 507 /* check options */ 508 while ((c = getopt(argc, argv, "fn")) != -1) { 509 switch (c) { 510 case 'f': 511 force = B_TRUE; 512 break; 513 case 'n': 514 dryrun = B_TRUE; 515 break; 516 case '?': 517 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 518 optopt); 519 usage(B_FALSE); 520 } 521 } 522 523 argc -= optind; 524 argv += optind; 525 526 /* get pool name and check number of arguments */ 527 if (argc < 1) { 528 (void) fprintf(stderr, gettext("missing pool name argument\n")); 529 usage(B_FALSE); 530 } 531 if (argc < 2) { 532 (void) fprintf(stderr, gettext("missing vdev specification\n")); 533 usage(B_FALSE); 534 } 535 536 poolname = argv[0]; 537 538 argc--; 539 argv++; 540 541 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 542 return (1); 543 544 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 545 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 546 poolname); 547 zpool_close(zhp); 548 return (1); 549 } 550 551 if (zpool_is_bootable(zhp)) 552 boot_type = ZPOOL_COPY_BOOT_LABEL; 553 else 554 boot_type = ZPOOL_NO_BOOT_LABEL; 555 556 /* pass off to get_vdev_spec for processing */ 557 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 558 nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, 559 boot_type, boot_size, argc, argv); 560 if (nvroot == NULL) { 561 zpool_close(zhp); 562 return (1); 563 } 564 565 if (dryrun) { 566 nvlist_t *poolnvroot; 567 568 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 569 &poolnvroot) == 0); 570 571 (void) printf(gettext("would update '%s' to the following " 572 "configuration:\n"), zpool_get_name(zhp)); 573 574 /* print original main pool and new tree */ 575 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE); 576 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE); 577 578 /* Do the same for the logs */ 579 if (num_logs(poolnvroot) > 0) { 580 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE); 581 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE); 582 } else if (num_logs(nvroot) > 0) { 583 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE); 584 } 585 586 ret = 0; 587 } else { 588 ret = (zpool_add(zhp, nvroot) != 0); 589 } 590 591 nvlist_free(nvroot); 592 zpool_close(zhp); 593 594 return (ret); 595 } 596 597 /* 598 * zpool remove <pool> <vdev> ... 599 * 600 * Removes the given vdev from the pool. 601 */ 602 int 603 zpool_do_remove(int argc, char **argv) 604 { 605 char *poolname; 606 int i, ret = 0; 607 zpool_handle_t *zhp; 608 boolean_t stop = B_FALSE; 609 boolean_t noop = B_FALSE; 610 boolean_t parsable = B_FALSE; 611 char c; 612 613 /* check options */ 614 while ((c = getopt(argc, argv, "nps")) != -1) { 615 switch (c) { 616 case 'n': 617 noop = B_TRUE; 618 break; 619 case 'p': 620 parsable = B_TRUE; 621 break; 622 case 's': 623 stop = B_TRUE; 624 break; 625 case '?': 626 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 627 optopt); 628 usage(B_FALSE); 629 } 630 } 631 632 argc -= optind; 633 argv += optind; 634 635 /* get pool name and check number of arguments */ 636 if (argc < 1) { 637 (void) fprintf(stderr, gettext("missing pool name argument\n")); 638 usage(B_FALSE); 639 } 640 641 poolname = argv[0]; 642 643 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 644 return (1); 645 646 if (stop && noop) { 647 (void) fprintf(stderr, gettext("stop request ignored\n")); 648 return (0); 649 } 650 651 if (stop) { 652 if (argc > 1) { 653 (void) fprintf(stderr, gettext("too many arguments\n")); 654 usage(B_FALSE); 655 } 656 if (zpool_vdev_remove_cancel(zhp) != 0) 657 ret = 1; 658 } else { 659 if (argc < 2) { 660 (void) fprintf(stderr, gettext("missing device\n")); 661 usage(B_FALSE); 662 } 663 664 for (i = 1; i < argc; i++) { 665 if (noop) { 666 uint64_t size; 667 668 if (zpool_vdev_indirect_size(zhp, argv[i], 669 &size) != 0) { 670 ret = 1; 671 break; 672 } 673 if (parsable) { 674 (void) printf("%s %llu\n", 675 argv[i], size); 676 } else { 677 char valstr[32]; 678 zfs_nicenum(size, valstr, 679 sizeof (valstr)); 680 (void) printf("Memory that will be " 681 "used after removing %s: %s\n", 682 argv[i], valstr); 683 } 684 } else { 685 if (zpool_vdev_remove(zhp, argv[i]) != 0) 686 ret = 1; 687 } 688 } 689 } 690 691 return (ret); 692 } 693 694 /* 695 * zpool labelclear [-f] <vdev> 696 * 697 * -f Force clearing the label for the vdevs which are members of 698 * the exported or foreign pools. 699 * 700 * Verifies that the vdev is not active and zeros out the label information 701 * on the device. 702 */ 703 int 704 zpool_do_labelclear(int argc, char **argv) 705 { 706 char vdev[MAXPATHLEN]; 707 char *name = NULL; 708 struct stat st; 709 int c, fd, ret = 0; 710 nvlist_t *config; 711 pool_state_t state; 712 boolean_t inuse = B_FALSE; 713 boolean_t force = B_FALSE; 714 715 /* check options */ 716 while ((c = getopt(argc, argv, "f")) != -1) { 717 switch (c) { 718 case 'f': 719 force = B_TRUE; 720 break; 721 default: 722 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 723 optopt); 724 usage(B_FALSE); 725 } 726 } 727 728 argc -= optind; 729 argv += optind; 730 731 /* get vdev name */ 732 if (argc < 1) { 733 (void) fprintf(stderr, gettext("missing vdev name\n")); 734 usage(B_FALSE); 735 } 736 if (argc > 1) { 737 (void) fprintf(stderr, gettext("too many arguments\n")); 738 usage(B_FALSE); 739 } 740 741 /* 742 * Check if we were given absolute path and use it as is. 743 * Otherwise if the provided vdev name doesn't point to a file, 744 * try prepending dsk path and appending s0. 745 */ 746 (void) strlcpy(vdev, argv[0], sizeof (vdev)); 747 if (vdev[0] != '/' && stat(vdev, &st) != 0) { 748 char *s; 749 750 (void) snprintf(vdev, sizeof (vdev), "%s/%s", 751 ZFS_DISK_ROOT, argv[0]); 752 if ((s = strrchr(argv[0], 's')) == NULL || 753 !isdigit(*(s + 1))) 754 (void) strlcat(vdev, "s0", sizeof (vdev)); 755 if (stat(vdev, &st) != 0) { 756 (void) fprintf(stderr, gettext( 757 "failed to find device %s, try specifying absolute " 758 "path instead\n"), argv[0]); 759 return (1); 760 } 761 } 762 763 if ((fd = open(vdev, O_RDWR)) < 0) { 764 (void) fprintf(stderr, gettext("failed to open %s: %s\n"), 765 vdev, strerror(errno)); 766 return (1); 767 } 768 769 if (zpool_read_label(fd, &config) != 0) { 770 (void) fprintf(stderr, 771 gettext("failed to read label from %s\n"), vdev); 772 return (1); 773 } 774 nvlist_free(config); 775 776 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse); 777 if (ret != 0) { 778 (void) fprintf(stderr, 779 gettext("failed to check state for %s\n"), vdev); 780 return (1); 781 } 782 783 if (!inuse) 784 goto wipe_label; 785 786 switch (state) { 787 default: 788 case POOL_STATE_ACTIVE: 789 case POOL_STATE_SPARE: 790 case POOL_STATE_L2CACHE: 791 (void) fprintf(stderr, gettext( 792 "%s is a member (%s) of pool \"%s\"\n"), 793 vdev, zpool_pool_state_to_name(state), name); 794 ret = 1; 795 goto errout; 796 797 case POOL_STATE_EXPORTED: 798 if (force) 799 break; 800 (void) fprintf(stderr, gettext( 801 "use '-f' to override the following error:\n" 802 "%s is a member of exported pool \"%s\"\n"), 803 vdev, name); 804 ret = 1; 805 goto errout; 806 807 case POOL_STATE_POTENTIALLY_ACTIVE: 808 if (force) 809 break; 810 (void) fprintf(stderr, gettext( 811 "use '-f' to override the following error:\n" 812 "%s is a member of potentially active pool \"%s\"\n"), 813 vdev, name); 814 ret = 1; 815 goto errout; 816 817 case POOL_STATE_DESTROYED: 818 /* inuse should never be set for a destroyed pool */ 819 assert(0); 820 break; 821 } 822 823 wipe_label: 824 ret = zpool_clear_label(fd); 825 if (ret != 0) { 826 (void) fprintf(stderr, 827 gettext("failed to clear label for %s\n"), vdev); 828 } 829 830 errout: 831 free(name); 832 (void) close(fd); 833 834 return (ret); 835 } 836 837 /* 838 * zpool create [-fnd] [-B] [-o property=value] ... 839 * [-O file-system-property=value] ... 840 * [-R root] [-m mountpoint] <pool> <dev> ... 841 * 842 * -B Create boot partition. 843 * -f Force creation, even if devices appear in use 844 * -n Do not create the pool, but display the resulting layout if it 845 * were to be created. 846 * -R Create a pool under an alternate root 847 * -m Set default mountpoint for the root dataset. By default it's 848 * '/<pool>' 849 * -o Set property=value. 850 * -d Don't automatically enable all supported pool features 851 * (individual features can be enabled with -o). 852 * -O Set fsproperty=value in the pool's root file system 853 * 854 * Creates the named pool according to the given vdev specification. The 855 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 856 * we get the nvlist back from get_vdev_spec(), we either print out the contents 857 * (if '-n' was specified), or pass it to libzfs to do the creation. 858 */ 859 860 #define SYSTEM256 (256 * 1024 * 1024) 861 int 862 zpool_do_create(int argc, char **argv) 863 { 864 boolean_t force = B_FALSE; 865 boolean_t dryrun = B_FALSE; 866 boolean_t enable_all_pool_feat = B_TRUE; 867 zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL; 868 uint64_t boot_size = 0; 869 int c; 870 nvlist_t *nvroot = NULL; 871 char *poolname; 872 int ret = 1; 873 char *altroot = NULL; 874 char *mountpoint = NULL; 875 nvlist_t *fsprops = NULL; 876 nvlist_t *props = NULL; 877 char *propval; 878 879 /* check options */ 880 while ((c = getopt(argc, argv, ":fndBR:m:o:O:")) != -1) { 881 switch (c) { 882 case 'f': 883 force = B_TRUE; 884 break; 885 case 'n': 886 dryrun = B_TRUE; 887 break; 888 case 'd': 889 enable_all_pool_feat = B_FALSE; 890 break; 891 case 'B': 892 /* 893 * We should create the system partition. 894 * Also make sure the size is set. 895 */ 896 boot_type = ZPOOL_CREATE_BOOT_LABEL; 897 if (boot_size == 0) 898 boot_size = SYSTEM256; 899 break; 900 case 'R': 901 altroot = optarg; 902 if (add_prop_list(zpool_prop_to_name( 903 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 904 goto errout; 905 if (nvlist_lookup_string(props, 906 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 907 &propval) == 0) 908 break; 909 if (add_prop_list(zpool_prop_to_name( 910 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 911 goto errout; 912 break; 913 case 'm': 914 /* Equivalent to -O mountpoint=optarg */ 915 mountpoint = optarg; 916 break; 917 case 'o': 918 if ((propval = strchr(optarg, '=')) == NULL) { 919 (void) fprintf(stderr, gettext("missing " 920 "'=' for -o option\n")); 921 goto errout; 922 } 923 *propval = '\0'; 924 propval++; 925 926 if (add_prop_list(optarg, propval, &props, B_TRUE)) 927 goto errout; 928 929 /* 930 * Get bootsize value for make_root_vdev(). 931 */ 932 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) { 933 if (zfs_nicestrtonum(g_zfs, propval, 934 &boot_size) < 0 || boot_size == 0) { 935 (void) fprintf(stderr, 936 gettext("bad boot partition size " 937 "'%s': %s\n"), propval, 938 libzfs_error_description(g_zfs)); 939 goto errout; 940 } 941 } 942 943 /* 944 * If the user is creating a pool that doesn't support 945 * feature flags, don't enable any features. 946 */ 947 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) { 948 char *end; 949 u_longlong_t ver; 950 951 ver = strtoull(propval, &end, 10); 952 if (*end == '\0' && 953 ver < SPA_VERSION_FEATURES) { 954 enable_all_pool_feat = B_FALSE; 955 } 956 } 957 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT) 958 altroot = propval; 959 break; 960 case 'O': 961 if ((propval = strchr(optarg, '=')) == NULL) { 962 (void) fprintf(stderr, gettext("missing " 963 "'=' for -O option\n")); 964 goto errout; 965 } 966 *propval = '\0'; 967 propval++; 968 969 /* 970 * Mountpoints are checked and then added later. 971 * Uniquely among properties, they can be specified 972 * more than once, to avoid conflict with -m. 973 */ 974 if (0 == strcmp(optarg, 975 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) { 976 mountpoint = propval; 977 } else if (add_prop_list(optarg, propval, &fsprops, 978 B_FALSE)) { 979 goto errout; 980 } 981 break; 982 case ':': 983 (void) fprintf(stderr, gettext("missing argument for " 984 "'%c' option\n"), optopt); 985 goto badusage; 986 case '?': 987 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 988 optopt); 989 goto badusage; 990 } 991 } 992 993 argc -= optind; 994 argv += optind; 995 996 /* get pool name and check number of arguments */ 997 if (argc < 1) { 998 (void) fprintf(stderr, gettext("missing pool name argument\n")); 999 goto badusage; 1000 } 1001 if (argc < 2) { 1002 (void) fprintf(stderr, gettext("missing vdev specification\n")); 1003 goto badusage; 1004 } 1005 1006 poolname = argv[0]; 1007 1008 /* 1009 * As a special case, check for use of '/' in the name, and direct the 1010 * user to use 'zfs create' instead. 1011 */ 1012 if (strchr(poolname, '/') != NULL) { 1013 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 1014 "character '/' in pool name\n"), poolname); 1015 (void) fprintf(stderr, gettext("use 'zfs create' to " 1016 "create a dataset\n")); 1017 goto errout; 1018 } 1019 1020 /* 1021 * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used, 1022 * and not set otherwise. 1023 */ 1024 if (boot_type == ZPOOL_CREATE_BOOT_LABEL) { 1025 const char *propname; 1026 char *strptr, *buf = NULL; 1027 int rv; 1028 1029 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1030 if (nvlist_lookup_string(props, propname, &strptr) != 0) { 1031 (void) asprintf(&buf, "%" PRIu64, boot_size); 1032 if (buf == NULL) { 1033 (void) fprintf(stderr, 1034 gettext("internal error: out of memory\n")); 1035 goto errout; 1036 } 1037 rv = add_prop_list(propname, buf, &props, B_TRUE); 1038 free(buf); 1039 if (rv != 0) 1040 goto errout; 1041 } 1042 } else { 1043 const char *propname; 1044 char *strptr; 1045 1046 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1047 if (nvlist_lookup_string(props, propname, &strptr) == 0) { 1048 (void) fprintf(stderr, gettext("error: setting boot " 1049 "partition size requires option '-B'\n")); 1050 goto errout; 1051 } 1052 } 1053 1054 /* pass off to get_vdev_spec for bulk processing */ 1055 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, 1056 boot_type, boot_size, argc - 1, argv + 1); 1057 if (nvroot == NULL) 1058 goto errout; 1059 1060 /* make_root_vdev() allows 0 toplevel children if there are spares */ 1061 if (!zfs_allocatable_devs(nvroot)) { 1062 (void) fprintf(stderr, gettext("invalid vdev " 1063 "specification: at least one toplevel vdev must be " 1064 "specified\n")); 1065 goto errout; 1066 } 1067 1068 if (altroot != NULL && altroot[0] != '/') { 1069 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 1070 "must be an absolute path\n"), altroot); 1071 goto errout; 1072 } 1073 1074 /* 1075 * Check the validity of the mountpoint and direct the user to use the 1076 * '-m' mountpoint option if it looks like its in use. 1077 */ 1078 if (mountpoint == NULL || 1079 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 1080 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 1081 char buf[MAXPATHLEN]; 1082 DIR *dirp; 1083 1084 if (mountpoint && mountpoint[0] != '/') { 1085 (void) fprintf(stderr, gettext("invalid mountpoint " 1086 "'%s': must be an absolute path, 'legacy', or " 1087 "'none'\n"), mountpoint); 1088 goto errout; 1089 } 1090 1091 if (mountpoint == NULL) { 1092 if (altroot != NULL) 1093 (void) snprintf(buf, sizeof (buf), "%s/%s", 1094 altroot, poolname); 1095 else 1096 (void) snprintf(buf, sizeof (buf), "/%s", 1097 poolname); 1098 } else { 1099 if (altroot != NULL) 1100 (void) snprintf(buf, sizeof (buf), "%s%s", 1101 altroot, mountpoint); 1102 else 1103 (void) snprintf(buf, sizeof (buf), "%s", 1104 mountpoint); 1105 } 1106 1107 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 1108 (void) fprintf(stderr, gettext("mountpoint '%s' : " 1109 "%s\n"), buf, strerror(errno)); 1110 (void) fprintf(stderr, gettext("use '-m' " 1111 "option to provide a different default\n")); 1112 goto errout; 1113 } else if (dirp) { 1114 int count = 0; 1115 1116 while (count < 3 && readdir(dirp) != NULL) 1117 count++; 1118 (void) closedir(dirp); 1119 1120 if (count > 2) { 1121 (void) fprintf(stderr, gettext("mountpoint " 1122 "'%s' exists and is not empty\n"), buf); 1123 (void) fprintf(stderr, gettext("use '-m' " 1124 "option to provide a " 1125 "different default\n")); 1126 goto errout; 1127 } 1128 } 1129 } 1130 1131 /* 1132 * Now that the mountpoint's validity has been checked, ensure that 1133 * the property is set appropriately prior to creating the pool. 1134 */ 1135 if (mountpoint != NULL) { 1136 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1137 mountpoint, &fsprops, B_FALSE); 1138 if (ret != 0) 1139 goto errout; 1140 } 1141 1142 ret = 1; 1143 if (dryrun) { 1144 /* 1145 * For a dry run invocation, print out a basic message and run 1146 * through all the vdevs in the list and print out in an 1147 * appropriate hierarchy. 1148 */ 1149 (void) printf(gettext("would create '%s' with the " 1150 "following layout:\n\n"), poolname); 1151 1152 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE); 1153 if (num_logs(nvroot) > 0) 1154 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE); 1155 1156 ret = 0; 1157 } else { 1158 /* 1159 * Hand off to libzfs. 1160 */ 1161 if (enable_all_pool_feat) { 1162 spa_feature_t i; 1163 for (i = 0; i < SPA_FEATURES; i++) { 1164 char propname[MAXPATHLEN]; 1165 zfeature_info_t *feat = &spa_feature_table[i]; 1166 1167 (void) snprintf(propname, sizeof (propname), 1168 "feature@%s", feat->fi_uname); 1169 1170 /* 1171 * Skip feature if user specified it manually 1172 * on the command line. 1173 */ 1174 if (nvlist_exists(props, propname)) 1175 continue; 1176 1177 ret = add_prop_list(propname, 1178 ZFS_FEATURE_ENABLED, &props, B_TRUE); 1179 if (ret != 0) 1180 goto errout; 1181 } 1182 } 1183 1184 ret = 1; 1185 if (zpool_create(g_zfs, poolname, 1186 nvroot, props, fsprops) == 0) { 1187 zfs_handle_t *pool = zfs_open(g_zfs, poolname, 1188 ZFS_TYPE_FILESYSTEM); 1189 if (pool != NULL) { 1190 if (zfs_mount(pool, NULL, 0) == 0) 1191 ret = zfs_shareall(pool); 1192 zfs_close(pool); 1193 } 1194 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 1195 (void) fprintf(stderr, gettext("pool name may have " 1196 "been omitted\n")); 1197 } 1198 } 1199 1200 errout: 1201 nvlist_free(nvroot); 1202 nvlist_free(fsprops); 1203 nvlist_free(props); 1204 return (ret); 1205 badusage: 1206 nvlist_free(fsprops); 1207 nvlist_free(props); 1208 usage(B_FALSE); 1209 return (2); 1210 } 1211 1212 /* 1213 * zpool destroy <pool> 1214 * 1215 * -f Forcefully unmount any datasets 1216 * 1217 * Destroy the given pool. Automatically unmounts any datasets in the pool. 1218 */ 1219 int 1220 zpool_do_destroy(int argc, char **argv) 1221 { 1222 boolean_t force = B_FALSE; 1223 int c; 1224 char *pool; 1225 zpool_handle_t *zhp; 1226 int ret; 1227 1228 /* check options */ 1229 while ((c = getopt(argc, argv, "f")) != -1) { 1230 switch (c) { 1231 case 'f': 1232 force = B_TRUE; 1233 break; 1234 case '?': 1235 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1236 optopt); 1237 usage(B_FALSE); 1238 } 1239 } 1240 1241 argc -= optind; 1242 argv += optind; 1243 1244 /* check arguments */ 1245 if (argc < 1) { 1246 (void) fprintf(stderr, gettext("missing pool argument\n")); 1247 usage(B_FALSE); 1248 } 1249 if (argc > 1) { 1250 (void) fprintf(stderr, gettext("too many arguments\n")); 1251 usage(B_FALSE); 1252 } 1253 1254 pool = argv[0]; 1255 1256 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 1257 /* 1258 * As a special case, check for use of '/' in the name, and 1259 * direct the user to use 'zfs destroy' instead. 1260 */ 1261 if (strchr(pool, '/') != NULL) 1262 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 1263 "destroy a dataset\n")); 1264 return (1); 1265 } 1266 1267 if (zpool_disable_datasets(zhp, force) != 0) { 1268 (void) fprintf(stderr, gettext("could not destroy '%s': " 1269 "could not unmount datasets\n"), zpool_get_name(zhp)); 1270 return (1); 1271 } 1272 1273 /* The history must be logged as part of the export */ 1274 log_history = B_FALSE; 1275 1276 ret = (zpool_destroy(zhp, history_str) != 0); 1277 1278 zpool_close(zhp); 1279 1280 return (ret); 1281 } 1282 1283 /* 1284 * zpool export [-f] <pool> ... 1285 * 1286 * -f Forcefully unmount datasets 1287 * 1288 * Export the given pools. By default, the command will attempt to cleanly 1289 * unmount any active datasets within the pool. If the '-f' flag is specified, 1290 * then the datasets will be forcefully unmounted. 1291 */ 1292 int 1293 zpool_do_export(int argc, char **argv) 1294 { 1295 boolean_t force = B_FALSE; 1296 boolean_t hardforce = B_FALSE; 1297 int c; 1298 zpool_handle_t *zhp; 1299 int ret; 1300 int i; 1301 1302 /* check options */ 1303 while ((c = getopt(argc, argv, "fF")) != -1) { 1304 switch (c) { 1305 case 'f': 1306 force = B_TRUE; 1307 break; 1308 case 'F': 1309 hardforce = B_TRUE; 1310 break; 1311 case '?': 1312 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1313 optopt); 1314 usage(B_FALSE); 1315 } 1316 } 1317 1318 argc -= optind; 1319 argv += optind; 1320 1321 /* check arguments */ 1322 if (argc < 1) { 1323 (void) fprintf(stderr, gettext("missing pool argument\n")); 1324 usage(B_FALSE); 1325 } 1326 1327 ret = 0; 1328 for (i = 0; i < argc; i++) { 1329 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 1330 ret = 1; 1331 continue; 1332 } 1333 1334 if (zpool_disable_datasets(zhp, force) != 0) { 1335 ret = 1; 1336 zpool_close(zhp); 1337 continue; 1338 } 1339 1340 /* The history must be logged as part of the export */ 1341 log_history = B_FALSE; 1342 1343 if (hardforce) { 1344 if (zpool_export_force(zhp, history_str) != 0) 1345 ret = 1; 1346 } else if (zpool_export(zhp, force, history_str) != 0) { 1347 ret = 1; 1348 } 1349 1350 zpool_close(zhp); 1351 } 1352 1353 return (ret); 1354 } 1355 1356 /* 1357 * Given a vdev configuration, determine the maximum width needed for the device 1358 * name column. 1359 */ 1360 static int 1361 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max) 1362 { 1363 char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE); 1364 nvlist_t **child; 1365 uint_t c, children; 1366 int ret; 1367 1368 if (strlen(name) + depth > max) 1369 max = strlen(name) + depth; 1370 1371 free(name); 1372 1373 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1374 &child, &children) == 0) { 1375 for (c = 0; c < children; c++) 1376 if ((ret = max_width(zhp, child[c], depth + 2, 1377 max)) > max) 1378 max = ret; 1379 } 1380 1381 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1382 &child, &children) == 0) { 1383 for (c = 0; c < children; c++) 1384 if ((ret = max_width(zhp, child[c], depth + 2, 1385 max)) > max) 1386 max = ret; 1387 } 1388 1389 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1390 &child, &children) == 0) { 1391 for (c = 0; c < children; c++) 1392 if ((ret = max_width(zhp, child[c], depth + 2, 1393 max)) > max) 1394 max = ret; 1395 } 1396 1397 1398 return (max); 1399 } 1400 1401 typedef struct spare_cbdata { 1402 uint64_t cb_guid; 1403 zpool_handle_t *cb_zhp; 1404 } spare_cbdata_t; 1405 1406 static boolean_t 1407 find_vdev(nvlist_t *nv, uint64_t search) 1408 { 1409 uint64_t guid; 1410 nvlist_t **child; 1411 uint_t c, children; 1412 1413 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 1414 search == guid) 1415 return (B_TRUE); 1416 1417 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1418 &child, &children) == 0) { 1419 for (c = 0; c < children; c++) 1420 if (find_vdev(child[c], search)) 1421 return (B_TRUE); 1422 } 1423 1424 return (B_FALSE); 1425 } 1426 1427 static int 1428 find_spare(zpool_handle_t *zhp, void *data) 1429 { 1430 spare_cbdata_t *cbp = data; 1431 nvlist_t *config, *nvroot; 1432 1433 config = zpool_get_config(zhp, NULL); 1434 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1435 &nvroot) == 0); 1436 1437 if (find_vdev(nvroot, cbp->cb_guid)) { 1438 cbp->cb_zhp = zhp; 1439 return (1); 1440 } 1441 1442 zpool_close(zhp); 1443 return (0); 1444 } 1445 1446 /* 1447 * Print out configuration state as requested by status_callback. 1448 */ 1449 void 1450 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 1451 int namewidth, int depth, boolean_t isspare) 1452 { 1453 nvlist_t **child; 1454 uint_t c, children; 1455 pool_scan_stat_t *ps = NULL; 1456 vdev_stat_t *vs; 1457 char rbuf[6], wbuf[6], cbuf[6]; 1458 char *vname; 1459 uint64_t notpresent; 1460 spare_cbdata_t cb; 1461 const char *state; 1462 char *type; 1463 1464 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1465 &child, &children) != 0) 1466 children = 0; 1467 1468 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1469 (uint64_t **)&vs, &c) == 0); 1470 1471 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1472 1473 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) 1474 return; 1475 1476 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1477 if (isspare) { 1478 /* 1479 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 1480 * online drives. 1481 */ 1482 if (vs->vs_aux == VDEV_AUX_SPARED) 1483 state = "INUSE"; 1484 else if (vs->vs_state == VDEV_STATE_HEALTHY) 1485 state = "AVAIL"; 1486 } 1487 1488 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 1489 name, state); 1490 1491 if (!isspare) { 1492 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 1493 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 1494 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 1495 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 1496 } 1497 1498 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1499 ¬present) == 0) { 1500 char *path; 1501 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1502 (void) printf(" was %s", path); 1503 } else if (vs->vs_aux != 0) { 1504 (void) printf(" "); 1505 1506 switch (vs->vs_aux) { 1507 case VDEV_AUX_OPEN_FAILED: 1508 (void) printf(gettext("cannot open")); 1509 break; 1510 1511 case VDEV_AUX_BAD_GUID_SUM: 1512 (void) printf(gettext("missing device")); 1513 break; 1514 1515 case VDEV_AUX_NO_REPLICAS: 1516 (void) printf(gettext("insufficient replicas")); 1517 break; 1518 1519 case VDEV_AUX_VERSION_NEWER: 1520 (void) printf(gettext("newer version")); 1521 break; 1522 1523 case VDEV_AUX_UNSUP_FEAT: 1524 (void) printf(gettext("unsupported feature(s)")); 1525 break; 1526 1527 case VDEV_AUX_SPARED: 1528 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1529 &cb.cb_guid) == 0); 1530 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 1531 if (strcmp(zpool_get_name(cb.cb_zhp), 1532 zpool_get_name(zhp)) == 0) 1533 (void) printf(gettext("currently in " 1534 "use")); 1535 else 1536 (void) printf(gettext("in use by " 1537 "pool '%s'"), 1538 zpool_get_name(cb.cb_zhp)); 1539 zpool_close(cb.cb_zhp); 1540 } else { 1541 (void) printf(gettext("currently in use")); 1542 } 1543 break; 1544 1545 case VDEV_AUX_ERR_EXCEEDED: 1546 (void) printf(gettext("too many errors")); 1547 break; 1548 1549 case VDEV_AUX_IO_FAILURE: 1550 (void) printf(gettext("experienced I/O failures")); 1551 break; 1552 1553 case VDEV_AUX_BAD_LOG: 1554 (void) printf(gettext("bad intent log")); 1555 break; 1556 1557 case VDEV_AUX_EXTERNAL: 1558 (void) printf(gettext("external device fault")); 1559 break; 1560 1561 case VDEV_AUX_SPLIT_POOL: 1562 (void) printf(gettext("split into new pool")); 1563 break; 1564 1565 case VDEV_AUX_CHILDREN_OFFLINE: 1566 (void) printf(gettext("all children offline")); 1567 break; 1568 1569 default: 1570 (void) printf(gettext("corrupted data")); 1571 break; 1572 } 1573 } 1574 1575 (void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS, 1576 (uint64_t **)&ps, &c); 1577 1578 if (ps && ps->pss_state == DSS_SCANNING && 1579 vs->vs_scan_processed != 0 && children == 0) { 1580 (void) printf(gettext(" (%s)"), 1581 (ps->pss_func == POOL_SCAN_RESILVER) ? 1582 "resilvering" : "repairing"); 1583 } 1584 1585 (void) printf("\n"); 1586 1587 for (c = 0; c < children; c++) { 1588 uint64_t islog = B_FALSE, ishole = B_FALSE; 1589 1590 /* Don't print logs or holes here */ 1591 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1592 &islog); 1593 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 1594 &ishole); 1595 if (islog || ishole) 1596 continue; 1597 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE); 1598 print_status_config(zhp, vname, child[c], 1599 namewidth, depth + 2, isspare); 1600 free(vname); 1601 } 1602 } 1603 1604 1605 /* 1606 * Print the configuration of an exported pool. Iterate over all vdevs in the 1607 * pool, printing out the name and status for each one. 1608 */ 1609 void 1610 print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth) 1611 { 1612 nvlist_t **child; 1613 uint_t c, children; 1614 vdev_stat_t *vs; 1615 char *type, *vname; 1616 1617 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1618 if (strcmp(type, VDEV_TYPE_MISSING) == 0 || 1619 strcmp(type, VDEV_TYPE_HOLE) == 0) 1620 return; 1621 1622 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1623 (uint64_t **)&vs, &c) == 0); 1624 1625 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name); 1626 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 1627 1628 if (vs->vs_aux != 0) { 1629 (void) printf(" "); 1630 1631 switch (vs->vs_aux) { 1632 case VDEV_AUX_OPEN_FAILED: 1633 (void) printf(gettext("cannot open")); 1634 break; 1635 1636 case VDEV_AUX_BAD_GUID_SUM: 1637 (void) printf(gettext("missing device")); 1638 break; 1639 1640 case VDEV_AUX_NO_REPLICAS: 1641 (void) printf(gettext("insufficient replicas")); 1642 break; 1643 1644 case VDEV_AUX_VERSION_NEWER: 1645 (void) printf(gettext("newer version")); 1646 break; 1647 1648 case VDEV_AUX_UNSUP_FEAT: 1649 (void) printf(gettext("unsupported feature(s)")); 1650 break; 1651 1652 case VDEV_AUX_ERR_EXCEEDED: 1653 (void) printf(gettext("too many errors")); 1654 break; 1655 1656 case VDEV_AUX_CHILDREN_OFFLINE: 1657 (void) printf(gettext("all children offline")); 1658 break; 1659 1660 default: 1661 (void) printf(gettext("corrupted data")); 1662 break; 1663 } 1664 } 1665 (void) printf("\n"); 1666 1667 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1668 &child, &children) != 0) 1669 return; 1670 1671 for (c = 0; c < children; c++) { 1672 uint64_t is_log = B_FALSE; 1673 1674 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1675 &is_log); 1676 if (is_log) 1677 continue; 1678 1679 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE); 1680 print_import_config(vname, child[c], namewidth, depth + 2); 1681 free(vname); 1682 } 1683 1684 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1685 &child, &children) == 0) { 1686 (void) printf(gettext("\tcache\n")); 1687 for (c = 0; c < children; c++) { 1688 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE); 1689 (void) printf("\t %s\n", vname); 1690 free(vname); 1691 } 1692 } 1693 1694 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1695 &child, &children) == 0) { 1696 (void) printf(gettext("\tspares\n")); 1697 for (c = 0; c < children; c++) { 1698 vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE); 1699 (void) printf("\t %s\n", vname); 1700 free(vname); 1701 } 1702 } 1703 } 1704 1705 /* 1706 * Print log vdevs. 1707 * Logs are recorded as top level vdevs in the main pool child array 1708 * but with "is_log" set to 1. We use either print_status_config() or 1709 * print_import_config() to print the top level logs then any log 1710 * children (eg mirrored slogs) are printed recursively - which 1711 * works because only the top level vdev is marked "is_log" 1712 */ 1713 static void 1714 print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose) 1715 { 1716 uint_t c, children; 1717 nvlist_t **child; 1718 1719 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, 1720 &children) != 0) 1721 return; 1722 1723 (void) printf(gettext("\tlogs\n")); 1724 1725 for (c = 0; c < children; c++) { 1726 uint64_t is_log = B_FALSE; 1727 char *name; 1728 1729 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1730 &is_log); 1731 if (!is_log) 1732 continue; 1733 name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE); 1734 if (verbose) 1735 print_status_config(zhp, name, child[c], namewidth, 1736 2, B_FALSE); 1737 else 1738 print_import_config(name, child[c], namewidth, 2); 1739 free(name); 1740 } 1741 } 1742 1743 /* 1744 * Display the status for the given pool. 1745 */ 1746 static void 1747 show_import(nvlist_t *config) 1748 { 1749 uint64_t pool_state; 1750 vdev_stat_t *vs; 1751 char *name; 1752 uint64_t guid; 1753 char *msgid; 1754 nvlist_t *nvroot; 1755 int reason; 1756 const char *health; 1757 uint_t vsc; 1758 int namewidth; 1759 char *comment; 1760 1761 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1762 &name) == 0); 1763 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 1764 &guid) == 0); 1765 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1766 &pool_state) == 0); 1767 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1768 &nvroot) == 0); 1769 1770 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 1771 (uint64_t **)&vs, &vsc) == 0); 1772 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1773 1774 reason = zpool_import_status(config, &msgid); 1775 1776 (void) printf(gettext(" pool: %s\n"), name); 1777 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 1778 (void) printf(gettext(" state: %s"), health); 1779 if (pool_state == POOL_STATE_DESTROYED) 1780 (void) printf(gettext(" (DESTROYED)")); 1781 (void) printf("\n"); 1782 1783 switch (reason) { 1784 case ZPOOL_STATUS_MISSING_DEV_R: 1785 case ZPOOL_STATUS_MISSING_DEV_NR: 1786 case ZPOOL_STATUS_BAD_GUID_SUM: 1787 (void) printf(gettext(" status: One or more devices are " 1788 "missing from the system.\n")); 1789 break; 1790 1791 case ZPOOL_STATUS_CORRUPT_LABEL_R: 1792 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 1793 (void) printf(gettext(" status: One or more devices contains " 1794 "corrupted data.\n")); 1795 break; 1796 1797 case ZPOOL_STATUS_CORRUPT_DATA: 1798 (void) printf( 1799 gettext(" status: The pool data is corrupted.\n")); 1800 break; 1801 1802 case ZPOOL_STATUS_OFFLINE_DEV: 1803 (void) printf(gettext(" status: One or more devices " 1804 "are offlined.\n")); 1805 break; 1806 1807 case ZPOOL_STATUS_CORRUPT_POOL: 1808 (void) printf(gettext(" status: The pool metadata is " 1809 "corrupted.\n")); 1810 break; 1811 1812 case ZPOOL_STATUS_VERSION_OLDER: 1813 (void) printf(gettext(" status: The pool is formatted using a " 1814 "legacy on-disk version.\n")); 1815 break; 1816 1817 case ZPOOL_STATUS_VERSION_NEWER: 1818 (void) printf(gettext(" status: The pool is formatted using an " 1819 "incompatible version.\n")); 1820 break; 1821 1822 case ZPOOL_STATUS_FEAT_DISABLED: 1823 (void) printf(gettext(" status: Some supported features are " 1824 "not enabled on the pool.\n")); 1825 break; 1826 1827 case ZPOOL_STATUS_UNSUP_FEAT_READ: 1828 (void) printf(gettext("status: The pool uses the following " 1829 "feature(s) not supported on this system:\n")); 1830 zpool_print_unsup_feat(config); 1831 break; 1832 1833 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 1834 (void) printf(gettext("status: The pool can only be accessed " 1835 "in read-only mode on this system. It\n\tcannot be " 1836 "accessed in read-write mode because it uses the " 1837 "following\n\tfeature(s) not supported on this system:\n")); 1838 zpool_print_unsup_feat(config); 1839 break; 1840 1841 case ZPOOL_STATUS_HOSTID_MISMATCH: 1842 (void) printf(gettext(" status: The pool was last accessed by " 1843 "another system.\n")); 1844 break; 1845 1846 case ZPOOL_STATUS_FAULTED_DEV_R: 1847 case ZPOOL_STATUS_FAULTED_DEV_NR: 1848 (void) printf(gettext(" status: One or more devices are " 1849 "faulted.\n")); 1850 break; 1851 1852 case ZPOOL_STATUS_BAD_LOG: 1853 (void) printf(gettext(" status: An intent log record cannot be " 1854 "read.\n")); 1855 break; 1856 1857 case ZPOOL_STATUS_RESILVERING: 1858 (void) printf(gettext(" status: One or more devices were being " 1859 "resilvered.\n")); 1860 break; 1861 1862 default: 1863 /* 1864 * No other status can be seen when importing pools. 1865 */ 1866 assert(reason == ZPOOL_STATUS_OK); 1867 } 1868 1869 /* 1870 * Print out an action according to the overall state of the pool. 1871 */ 1872 if (vs->vs_state == VDEV_STATE_HEALTHY) { 1873 if (reason == ZPOOL_STATUS_VERSION_OLDER || 1874 reason == ZPOOL_STATUS_FEAT_DISABLED) { 1875 (void) printf(gettext(" action: The pool can be " 1876 "imported using its name or numeric identifier, " 1877 "though\n\tsome features will not be available " 1878 "without an explicit 'zpool upgrade'.\n")); 1879 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) { 1880 (void) printf(gettext(" action: The pool can be " 1881 "imported using its name or numeric " 1882 "identifier and\n\tthe '-f' flag.\n")); 1883 } else { 1884 (void) printf(gettext(" action: The pool can be " 1885 "imported using its name or numeric " 1886 "identifier.\n")); 1887 } 1888 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 1889 (void) printf(gettext(" action: The pool can be imported " 1890 "despite missing or damaged devices. The\n\tfault " 1891 "tolerance of the pool may be compromised if imported.\n")); 1892 } else { 1893 switch (reason) { 1894 case ZPOOL_STATUS_VERSION_NEWER: 1895 (void) printf(gettext(" action: The pool cannot be " 1896 "imported. Access the pool on a system running " 1897 "newer\n\tsoftware, or recreate the pool from " 1898 "backup.\n")); 1899 break; 1900 case ZPOOL_STATUS_UNSUP_FEAT_READ: 1901 (void) printf(gettext("action: The pool cannot be " 1902 "imported. Access the pool on a system that " 1903 "supports\n\tthe required feature(s), or recreate " 1904 "the pool from backup.\n")); 1905 break; 1906 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 1907 (void) printf(gettext("action: The pool cannot be " 1908 "imported in read-write mode. Import the pool " 1909 "with\n" 1910 "\t\"-o readonly=on\", access the pool on a system " 1911 "that supports the\n\trequired feature(s), or " 1912 "recreate the pool from backup.\n")); 1913 break; 1914 case ZPOOL_STATUS_MISSING_DEV_R: 1915 case ZPOOL_STATUS_MISSING_DEV_NR: 1916 case ZPOOL_STATUS_BAD_GUID_SUM: 1917 (void) printf(gettext(" action: The pool cannot be " 1918 "imported. Attach the missing\n\tdevices and try " 1919 "again.\n")); 1920 break; 1921 default: 1922 (void) printf(gettext(" action: The pool cannot be " 1923 "imported due to damaged devices or data.\n")); 1924 } 1925 } 1926 1927 /* Print the comment attached to the pool. */ 1928 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) 1929 (void) printf(gettext("comment: %s\n"), comment); 1930 1931 /* 1932 * If the state is "closed" or "can't open", and the aux state 1933 * is "corrupt data": 1934 */ 1935 if (((vs->vs_state == VDEV_STATE_CLOSED) || 1936 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 1937 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 1938 if (pool_state == POOL_STATE_DESTROYED) 1939 (void) printf(gettext("\tThe pool was destroyed, " 1940 "but can be imported using the '-Df' flags.\n")); 1941 else if (pool_state != POOL_STATE_EXPORTED) 1942 (void) printf(gettext("\tThe pool may be active on " 1943 "another system, but can be imported using\n\t" 1944 "the '-f' flag.\n")); 1945 } 1946 1947 if (msgid != NULL) 1948 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 1949 msgid); 1950 1951 (void) printf(gettext(" config:\n\n")); 1952 1953 namewidth = max_width(NULL, nvroot, 0, 0); 1954 if (namewidth < 10) 1955 namewidth = 10; 1956 1957 print_import_config(name, nvroot, namewidth, 0); 1958 if (num_logs(nvroot) > 0) 1959 print_logs(NULL, nvroot, namewidth, B_FALSE); 1960 1961 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 1962 (void) printf(gettext("\n\tAdditional devices are known to " 1963 "be part of this pool, though their\n\texact " 1964 "configuration cannot be determined.\n")); 1965 } 1966 } 1967 1968 /* 1969 * Perform the import for the given configuration. This passes the heavy 1970 * lifting off to zpool_import_props(), and then mounts the datasets contained 1971 * within the pool. 1972 */ 1973 static int 1974 do_import(nvlist_t *config, const char *newname, const char *mntopts, 1975 nvlist_t *props, int flags) 1976 { 1977 zpool_handle_t *zhp; 1978 char *name; 1979 uint64_t state; 1980 uint64_t version; 1981 1982 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1983 &name) == 0); 1984 1985 verify(nvlist_lookup_uint64(config, 1986 ZPOOL_CONFIG_POOL_STATE, &state) == 0); 1987 verify(nvlist_lookup_uint64(config, 1988 ZPOOL_CONFIG_VERSION, &version) == 0); 1989 if (!SPA_VERSION_IS_SUPPORTED(version)) { 1990 (void) fprintf(stderr, gettext("cannot import '%s': pool " 1991 "is formatted using an unsupported ZFS version\n"), name); 1992 return (1); 1993 } else if (state != POOL_STATE_EXPORTED && 1994 !(flags & ZFS_IMPORT_ANY_HOST)) { 1995 uint64_t hostid; 1996 1997 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, 1998 &hostid) == 0) { 1999 if ((unsigned long)hostid != gethostid()) { 2000 char *hostname; 2001 uint64_t timestamp; 2002 time_t t; 2003 2004 verify(nvlist_lookup_string(config, 2005 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); 2006 verify(nvlist_lookup_uint64(config, 2007 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0); 2008 t = timestamp; 2009 (void) fprintf(stderr, gettext("cannot import " 2010 "'%s': pool may be in use from other " 2011 "system, it was last accessed by %s " 2012 "(hostid: 0x%lx) on %s"), name, hostname, 2013 (unsigned long)hostid, 2014 asctime(localtime(&t))); 2015 (void) fprintf(stderr, gettext("use '-f' to " 2016 "import anyway\n")); 2017 return (1); 2018 } 2019 } else { 2020 (void) fprintf(stderr, gettext("cannot import '%s': " 2021 "pool may be in use from other system\n"), name); 2022 (void) fprintf(stderr, gettext("use '-f' to import " 2023 "anyway\n")); 2024 return (1); 2025 } 2026 } 2027 2028 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) 2029 return (1); 2030 2031 if (newname != NULL) 2032 name = (char *)newname; 2033 2034 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) 2035 return (1); 2036 2037 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 2038 !(flags & ZFS_IMPORT_ONLY) && 2039 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 2040 zpool_close(zhp); 2041 return (1); 2042 } 2043 2044 zpool_close(zhp); 2045 return (0); 2046 } 2047 2048 /* 2049 * zpool import [-d dir] [-D] 2050 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 2051 * [-d dir | -c cachefile] [-f] -a 2052 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 2053 * [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool] 2054 * 2055 * -c Read pool information from a cachefile instead of searching 2056 * devices. 2057 * 2058 * -d Scan in a specific directory, other than /dev/dsk. More than 2059 * one directory can be specified using multiple '-d' options. 2060 * 2061 * -D Scan for previously destroyed pools or import all or only 2062 * specified destroyed pools. 2063 * 2064 * -R Temporarily import the pool, with all mountpoints relative to 2065 * the given root. The pool will remain exported when the machine 2066 * is rebooted. 2067 * 2068 * -V Import even in the presence of faulted vdevs. This is an 2069 * intentionally undocumented option for testing purposes, and 2070 * treats the pool configuration as complete, leaving any bad 2071 * vdevs in the FAULTED state. In other words, it does verbatim 2072 * import. 2073 * 2074 * -f Force import, even if it appears that the pool is active. 2075 * 2076 * -F Attempt rewind if necessary. 2077 * 2078 * -n See if rewind would work, but don't actually rewind. 2079 * 2080 * -N Import the pool but don't mount datasets. 2081 * 2082 * -T Specify a starting txg to use for import. This option is 2083 * intentionally undocumented option for testing purposes. 2084 * 2085 * -a Import all pools found. 2086 * 2087 * -o Set property=value and/or temporary mount options (without '='). 2088 * 2089 * The import command scans for pools to import, and import pools based on pool 2090 * name and GUID. The pool can also be renamed as part of the import process. 2091 */ 2092 int 2093 zpool_do_import(int argc, char **argv) 2094 { 2095 char **searchdirs = NULL; 2096 int nsearch = 0; 2097 int c; 2098 int err = 0; 2099 nvlist_t *pools = NULL; 2100 boolean_t do_all = B_FALSE; 2101 boolean_t do_destroyed = B_FALSE; 2102 char *mntopts = NULL; 2103 nvpair_t *elem; 2104 nvlist_t *config; 2105 uint64_t searchguid = 0; 2106 char *searchname = NULL; 2107 char *propval; 2108 nvlist_t *found_config; 2109 nvlist_t *policy = NULL; 2110 nvlist_t *props = NULL; 2111 boolean_t first; 2112 int flags = ZFS_IMPORT_NORMAL; 2113 uint32_t rewind_policy = ZPOOL_NO_REWIND; 2114 boolean_t dryrun = B_FALSE; 2115 boolean_t do_rewind = B_FALSE; 2116 boolean_t xtreme_rewind = B_FALSE; 2117 uint64_t pool_state, txg = -1ULL; 2118 char *cachefile = NULL; 2119 importargs_t idata = { 0 }; 2120 char *endptr; 2121 2122 /* check options */ 2123 while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) { 2124 switch (c) { 2125 case 'a': 2126 do_all = B_TRUE; 2127 break; 2128 case 'c': 2129 cachefile = optarg; 2130 break; 2131 case 'd': 2132 if (searchdirs == NULL) { 2133 searchdirs = safe_malloc(sizeof (char *)); 2134 } else { 2135 char **tmp = safe_malloc((nsearch + 1) * 2136 sizeof (char *)); 2137 bcopy(searchdirs, tmp, nsearch * 2138 sizeof (char *)); 2139 free(searchdirs); 2140 searchdirs = tmp; 2141 } 2142 searchdirs[nsearch++] = optarg; 2143 break; 2144 case 'D': 2145 do_destroyed = B_TRUE; 2146 break; 2147 case 'f': 2148 flags |= ZFS_IMPORT_ANY_HOST; 2149 break; 2150 case 'F': 2151 do_rewind = B_TRUE; 2152 break; 2153 case 'm': 2154 flags |= ZFS_IMPORT_MISSING_LOG; 2155 break; 2156 case 'n': 2157 dryrun = B_TRUE; 2158 break; 2159 case 'N': 2160 flags |= ZFS_IMPORT_ONLY; 2161 break; 2162 case 'o': 2163 if ((propval = strchr(optarg, '=')) != NULL) { 2164 *propval = '\0'; 2165 propval++; 2166 if (add_prop_list(optarg, propval, 2167 &props, B_TRUE)) 2168 goto error; 2169 } else { 2170 mntopts = optarg; 2171 } 2172 break; 2173 case 'R': 2174 if (add_prop_list(zpool_prop_to_name( 2175 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 2176 goto error; 2177 if (nvlist_lookup_string(props, 2178 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 2179 &propval) == 0) 2180 break; 2181 if (add_prop_list(zpool_prop_to_name( 2182 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 2183 goto error; 2184 break; 2185 case 'T': 2186 errno = 0; 2187 txg = strtoull(optarg, &endptr, 0); 2188 if (errno != 0 || *endptr != '\0') { 2189 (void) fprintf(stderr, 2190 gettext("invalid txg value\n")); 2191 usage(B_FALSE); 2192 } 2193 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND; 2194 break; 2195 case 'V': 2196 flags |= ZFS_IMPORT_VERBATIM; 2197 break; 2198 case 'X': 2199 xtreme_rewind = B_TRUE; 2200 break; 2201 case ':': 2202 (void) fprintf(stderr, gettext("missing argument for " 2203 "'%c' option\n"), optopt); 2204 usage(B_FALSE); 2205 break; 2206 case '?': 2207 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2208 optopt); 2209 usage(B_FALSE); 2210 } 2211 } 2212 2213 argc -= optind; 2214 argv += optind; 2215 2216 if (cachefile && nsearch != 0) { 2217 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 2218 usage(B_FALSE); 2219 } 2220 2221 if ((dryrun || xtreme_rewind) && !do_rewind) { 2222 (void) fprintf(stderr, 2223 gettext("-n or -X only meaningful with -F\n")); 2224 usage(B_FALSE); 2225 } 2226 if (dryrun) 2227 rewind_policy = ZPOOL_TRY_REWIND; 2228 else if (do_rewind) 2229 rewind_policy = ZPOOL_DO_REWIND; 2230 if (xtreme_rewind) 2231 rewind_policy |= ZPOOL_EXTREME_REWIND; 2232 2233 /* In the future, we can capture further policy and include it here */ 2234 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 2235 nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 || 2236 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) 2237 goto error; 2238 2239 if (searchdirs == NULL) { 2240 searchdirs = safe_malloc(sizeof (char *)); 2241 searchdirs[0] = ZFS_DISK_ROOT; 2242 nsearch = 1; 2243 } 2244 2245 /* check argument count */ 2246 if (do_all) { 2247 if (argc != 0) { 2248 (void) fprintf(stderr, gettext("too many arguments\n")); 2249 usage(B_FALSE); 2250 } 2251 } else { 2252 if (argc > 2) { 2253 (void) fprintf(stderr, gettext("too many arguments\n")); 2254 usage(B_FALSE); 2255 } 2256 2257 /* 2258 * Check for the SYS_CONFIG privilege. We do this explicitly 2259 * here because otherwise any attempt to discover pools will 2260 * silently fail. 2261 */ 2262 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 2263 (void) fprintf(stderr, gettext("cannot " 2264 "discover pools: permission denied\n")); 2265 free(searchdirs); 2266 nvlist_free(policy); 2267 return (1); 2268 } 2269 } 2270 2271 /* 2272 * Depending on the arguments given, we do one of the following: 2273 * 2274 * <none> Iterate through all pools and display information about 2275 * each one. 2276 * 2277 * -a Iterate through all pools and try to import each one. 2278 * 2279 * <id> Find the pool that corresponds to the given GUID/pool 2280 * name and import that one. 2281 * 2282 * -D Above options applies only to destroyed pools. 2283 */ 2284 if (argc != 0) { 2285 char *endptr; 2286 2287 errno = 0; 2288 searchguid = strtoull(argv[0], &endptr, 10); 2289 if (errno != 0 || *endptr != '\0') { 2290 searchname = argv[0]; 2291 searchguid = 0; 2292 } 2293 found_config = NULL; 2294 2295 /* 2296 * User specified a name or guid. Ensure it's unique. 2297 */ 2298 idata.unique = B_TRUE; 2299 } 2300 2301 2302 idata.path = searchdirs; 2303 idata.paths = nsearch; 2304 idata.poolname = searchname; 2305 idata.guid = searchguid; 2306 idata.cachefile = cachefile; 2307 idata.policy = policy; 2308 2309 pools = zpool_search_import(g_zfs, &idata); 2310 2311 if (pools != NULL && idata.exists && 2312 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 2313 (void) fprintf(stderr, gettext("cannot import '%s': " 2314 "a pool with that name already exists\n"), 2315 argv[0]); 2316 (void) fprintf(stderr, gettext("use the form '%s " 2317 "<pool | id> <newpool>' to give it a new name\n"), 2318 "zpool import"); 2319 err = 1; 2320 } else if (pools == NULL && idata.exists) { 2321 (void) fprintf(stderr, gettext("cannot import '%s': " 2322 "a pool with that name is already created/imported,\n"), 2323 argv[0]); 2324 (void) fprintf(stderr, gettext("and no additional pools " 2325 "with that name were found\n")); 2326 err = 1; 2327 } else if (pools == NULL) { 2328 if (argc != 0) { 2329 (void) fprintf(stderr, gettext("cannot import '%s': " 2330 "no such pool available\n"), argv[0]); 2331 } 2332 err = 1; 2333 } 2334 2335 if (err == 1) { 2336 free(searchdirs); 2337 nvlist_free(policy); 2338 return (1); 2339 } 2340 2341 /* 2342 * At this point we have a list of import candidate configs. Even if 2343 * we were searching by pool name or guid, we still need to 2344 * post-process the list to deal with pool state and possible 2345 * duplicate names. 2346 */ 2347 err = 0; 2348 elem = NULL; 2349 first = B_TRUE; 2350 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 2351 2352 verify(nvpair_value_nvlist(elem, &config) == 0); 2353 2354 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2355 &pool_state) == 0); 2356 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 2357 continue; 2358 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 2359 continue; 2360 2361 verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY, 2362 policy) == 0); 2363 2364 if (argc == 0) { 2365 if (first) 2366 first = B_FALSE; 2367 else if (!do_all) 2368 (void) printf("\n"); 2369 2370 if (do_all) { 2371 err |= do_import(config, NULL, mntopts, 2372 props, flags); 2373 } else { 2374 show_import(config); 2375 } 2376 } else if (searchname != NULL) { 2377 char *name; 2378 2379 /* 2380 * We are searching for a pool based on name. 2381 */ 2382 verify(nvlist_lookup_string(config, 2383 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 2384 2385 if (strcmp(name, searchname) == 0) { 2386 if (found_config != NULL) { 2387 (void) fprintf(stderr, gettext( 2388 "cannot import '%s': more than " 2389 "one matching pool\n"), searchname); 2390 (void) fprintf(stderr, gettext( 2391 "import by numeric ID instead\n")); 2392 err = B_TRUE; 2393 } 2394 found_config = config; 2395 } 2396 } else { 2397 uint64_t guid; 2398 2399 /* 2400 * Search for a pool by guid. 2401 */ 2402 verify(nvlist_lookup_uint64(config, 2403 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 2404 2405 if (guid == searchguid) 2406 found_config = config; 2407 } 2408 } 2409 2410 /* 2411 * If we were searching for a specific pool, verify that we found a 2412 * pool, and then do the import. 2413 */ 2414 if (argc != 0 && err == 0) { 2415 if (found_config == NULL) { 2416 (void) fprintf(stderr, gettext("cannot import '%s': " 2417 "no such pool available\n"), argv[0]); 2418 err = B_TRUE; 2419 } else { 2420 err |= do_import(found_config, argc == 1 ? NULL : 2421 argv[1], mntopts, props, flags); 2422 } 2423 } 2424 2425 /* 2426 * If we were just looking for pools, report an error if none were 2427 * found. 2428 */ 2429 if (argc == 0 && first) 2430 (void) fprintf(stderr, 2431 gettext("no pools available to import\n")); 2432 2433 error: 2434 nvlist_free(props); 2435 nvlist_free(pools); 2436 nvlist_free(policy); 2437 free(searchdirs); 2438 2439 return (err ? 1 : 0); 2440 } 2441 2442 typedef struct iostat_cbdata { 2443 boolean_t cb_verbose; 2444 int cb_namewidth; 2445 int cb_iteration; 2446 zpool_list_t *cb_list; 2447 } iostat_cbdata_t; 2448 2449 static void 2450 print_iostat_separator(iostat_cbdata_t *cb) 2451 { 2452 int i = 0; 2453 2454 for (i = 0; i < cb->cb_namewidth; i++) 2455 (void) printf("-"); 2456 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 2457 } 2458 2459 static void 2460 print_iostat_header(iostat_cbdata_t *cb) 2461 { 2462 (void) printf("%*s capacity operations bandwidth\n", 2463 cb->cb_namewidth, ""); 2464 (void) printf("%-*s alloc free read write read write\n", 2465 cb->cb_namewidth, "pool"); 2466 print_iostat_separator(cb); 2467 } 2468 2469 /* 2470 * Display a single statistic. 2471 */ 2472 static void 2473 print_one_stat(uint64_t value) 2474 { 2475 char buf[64]; 2476 2477 zfs_nicenum(value, buf, sizeof (buf)); 2478 (void) printf(" %5s", buf); 2479 } 2480 2481 /* 2482 * Print out all the statistics for the given vdev. This can either be the 2483 * toplevel configuration, or called recursively. If 'name' is NULL, then this 2484 * is a verbose output, and we don't want to display the toplevel pool stats. 2485 */ 2486 void 2487 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 2488 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 2489 { 2490 nvlist_t **oldchild, **newchild; 2491 uint_t c, children; 2492 vdev_stat_t *oldvs, *newvs; 2493 vdev_stat_t zerovs = { 0 }; 2494 uint64_t tdelta; 2495 double scale; 2496 char *vname; 2497 2498 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 2499 return; 2500 2501 if (oldnv != NULL) { 2502 verify(nvlist_lookup_uint64_array(oldnv, 2503 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 2504 } else { 2505 oldvs = &zerovs; 2506 } 2507 2508 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 2509 (uint64_t **)&newvs, &c) == 0); 2510 2511 if (strlen(name) + depth > cb->cb_namewidth) 2512 (void) printf("%*s%s", depth, "", name); 2513 else 2514 (void) printf("%*s%s%*s", depth, "", name, 2515 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 2516 2517 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 2518 2519 if (tdelta == 0) 2520 scale = 1.0; 2521 else 2522 scale = (double)NANOSEC / tdelta; 2523 2524 /* only toplevel vdevs have capacity stats */ 2525 if (newvs->vs_space == 0) { 2526 (void) printf(" - -"); 2527 } else { 2528 print_one_stat(newvs->vs_alloc); 2529 print_one_stat(newvs->vs_space - newvs->vs_alloc); 2530 } 2531 2532 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 2533 oldvs->vs_ops[ZIO_TYPE_READ]))); 2534 2535 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 2536 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 2537 2538 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 2539 oldvs->vs_bytes[ZIO_TYPE_READ]))); 2540 2541 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 2542 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 2543 2544 (void) printf("\n"); 2545 2546 if (!cb->cb_verbose) 2547 return; 2548 2549 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 2550 &newchild, &children) != 0) 2551 return; 2552 2553 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 2554 &oldchild, &c) != 0) 2555 return; 2556 2557 for (c = 0; c < children; c++) { 2558 uint64_t ishole = B_FALSE, islog = B_FALSE; 2559 2560 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 2561 &ishole); 2562 2563 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 2564 &islog); 2565 2566 if (ishole || islog) 2567 continue; 2568 2569 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE); 2570 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2571 newchild[c], cb, depth + 2); 2572 free(vname); 2573 } 2574 2575 /* 2576 * Log device section 2577 */ 2578 2579 if (num_logs(newnv) > 0) { 2580 (void) printf("%-*s - - - - - " 2581 "-\n", cb->cb_namewidth, "logs"); 2582 2583 for (c = 0; c < children; c++) { 2584 uint64_t islog = B_FALSE; 2585 (void) nvlist_lookup_uint64(newchild[c], 2586 ZPOOL_CONFIG_IS_LOG, &islog); 2587 2588 if (islog) { 2589 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2590 B_FALSE); 2591 print_vdev_stats(zhp, vname, oldnv ? 2592 oldchild[c] : NULL, newchild[c], 2593 cb, depth + 2); 2594 free(vname); 2595 } 2596 } 2597 2598 } 2599 2600 /* 2601 * Include level 2 ARC devices in iostat output 2602 */ 2603 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 2604 &newchild, &children) != 0) 2605 return; 2606 2607 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 2608 &oldchild, &c) != 0) 2609 return; 2610 2611 if (children > 0) { 2612 (void) printf("%-*s - - - - - " 2613 "-\n", cb->cb_namewidth, "cache"); 2614 for (c = 0; c < children; c++) { 2615 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 2616 B_FALSE); 2617 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 2618 newchild[c], cb, depth + 2); 2619 free(vname); 2620 } 2621 } 2622 } 2623 2624 static int 2625 refresh_iostat(zpool_handle_t *zhp, void *data) 2626 { 2627 iostat_cbdata_t *cb = data; 2628 boolean_t missing; 2629 2630 /* 2631 * If the pool has disappeared, remove it from the list and continue. 2632 */ 2633 if (zpool_refresh_stats(zhp, &missing) != 0) 2634 return (-1); 2635 2636 if (missing) 2637 pool_list_remove(cb->cb_list, zhp); 2638 2639 return (0); 2640 } 2641 2642 /* 2643 * Callback to print out the iostats for the given pool. 2644 */ 2645 int 2646 print_iostat(zpool_handle_t *zhp, void *data) 2647 { 2648 iostat_cbdata_t *cb = data; 2649 nvlist_t *oldconfig, *newconfig; 2650 nvlist_t *oldnvroot, *newnvroot; 2651 2652 newconfig = zpool_get_config(zhp, &oldconfig); 2653 2654 if (cb->cb_iteration == 1) 2655 oldconfig = NULL; 2656 2657 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 2658 &newnvroot) == 0); 2659 2660 if (oldconfig == NULL) 2661 oldnvroot = NULL; 2662 else 2663 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 2664 &oldnvroot) == 0); 2665 2666 /* 2667 * Print out the statistics for the pool. 2668 */ 2669 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 2670 2671 if (cb->cb_verbose) 2672 print_iostat_separator(cb); 2673 2674 return (0); 2675 } 2676 2677 int 2678 get_namewidth(zpool_handle_t *zhp, void *data) 2679 { 2680 iostat_cbdata_t *cb = data; 2681 nvlist_t *config, *nvroot; 2682 2683 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 2684 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2685 &nvroot) == 0); 2686 if (!cb->cb_verbose) 2687 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 2688 else 2689 cb->cb_namewidth = max_width(zhp, nvroot, 0, 2690 cb->cb_namewidth); 2691 } 2692 2693 /* 2694 * The width must fall into the range [10,38]. The upper limit is the 2695 * maximum we can have and still fit in 80 columns. 2696 */ 2697 if (cb->cb_namewidth < 10) 2698 cb->cb_namewidth = 10; 2699 if (cb->cb_namewidth > 38) 2700 cb->cb_namewidth = 38; 2701 2702 return (0); 2703 } 2704 2705 /* 2706 * Parse the input string, get the 'interval' and 'count' value if there is one. 2707 */ 2708 static void 2709 get_interval_count(int *argcp, char **argv, unsigned long *iv, 2710 unsigned long *cnt) 2711 { 2712 unsigned long interval = 0, count = 0; 2713 int argc = *argcp, errno; 2714 2715 /* 2716 * Determine if the last argument is an integer or a pool name 2717 */ 2718 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2719 char *end; 2720 2721 errno = 0; 2722 interval = strtoul(argv[argc - 1], &end, 10); 2723 2724 if (*end == '\0' && errno == 0) { 2725 if (interval == 0) { 2726 (void) fprintf(stderr, gettext("interval " 2727 "cannot be zero\n")); 2728 usage(B_FALSE); 2729 } 2730 /* 2731 * Ignore the last parameter 2732 */ 2733 argc--; 2734 } else { 2735 /* 2736 * If this is not a valid number, just plow on. The 2737 * user will get a more informative error message later 2738 * on. 2739 */ 2740 interval = 0; 2741 } 2742 } 2743 2744 /* 2745 * If the last argument is also an integer, then we have both a count 2746 * and an interval. 2747 */ 2748 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2749 char *end; 2750 2751 errno = 0; 2752 count = interval; 2753 interval = strtoul(argv[argc - 1], &end, 10); 2754 2755 if (*end == '\0' && errno == 0) { 2756 if (interval == 0) { 2757 (void) fprintf(stderr, gettext("interval " 2758 "cannot be zero\n")); 2759 usage(B_FALSE); 2760 } 2761 2762 /* 2763 * Ignore the last parameter 2764 */ 2765 argc--; 2766 } else { 2767 interval = 0; 2768 } 2769 } 2770 2771 *iv = interval; 2772 *cnt = count; 2773 *argcp = argc; 2774 } 2775 2776 static void 2777 get_timestamp_arg(char c) 2778 { 2779 if (c == 'u') 2780 timestamp_fmt = UDATE; 2781 else if (c == 'd') 2782 timestamp_fmt = DDATE; 2783 else 2784 usage(B_FALSE); 2785 } 2786 2787 /* 2788 * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]] 2789 * 2790 * -v Display statistics for individual vdevs 2791 * -T Display a timestamp in date(1) or Unix format 2792 * 2793 * This command can be tricky because we want to be able to deal with pool 2794 * creation/destruction as well as vdev configuration changes. The bulk of this 2795 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 2796 * on pool_list_update() to detect the addition of new pools. Configuration 2797 * changes are all handled within libzfs. 2798 */ 2799 int 2800 zpool_do_iostat(int argc, char **argv) 2801 { 2802 int c; 2803 int ret; 2804 int npools; 2805 unsigned long interval = 0, count = 0; 2806 zpool_list_t *list; 2807 boolean_t verbose = B_FALSE; 2808 iostat_cbdata_t cb; 2809 2810 /* check options */ 2811 while ((c = getopt(argc, argv, "T:v")) != -1) { 2812 switch (c) { 2813 case 'T': 2814 get_timestamp_arg(*optarg); 2815 break; 2816 case 'v': 2817 verbose = B_TRUE; 2818 break; 2819 case '?': 2820 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2821 optopt); 2822 usage(B_FALSE); 2823 } 2824 } 2825 2826 argc -= optind; 2827 argv += optind; 2828 2829 get_interval_count(&argc, argv, &interval, &count); 2830 2831 /* 2832 * Construct the list of all interesting pools. 2833 */ 2834 ret = 0; 2835 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 2836 return (1); 2837 2838 if (pool_list_count(list) == 0 && argc != 0) { 2839 pool_list_free(list); 2840 return (1); 2841 } 2842 2843 if (pool_list_count(list) == 0 && interval == 0) { 2844 pool_list_free(list); 2845 (void) fprintf(stderr, gettext("no pools available\n")); 2846 return (1); 2847 } 2848 2849 /* 2850 * Enter the main iostat loop. 2851 */ 2852 cb.cb_list = list; 2853 cb.cb_verbose = verbose; 2854 cb.cb_iteration = 0; 2855 cb.cb_namewidth = 0; 2856 2857 for (;;) { 2858 pool_list_update(list); 2859 2860 if ((npools = pool_list_count(list)) == 0) 2861 break; 2862 2863 /* 2864 * Refresh all statistics. This is done as an explicit step 2865 * before calculating the maximum name width, so that any 2866 * configuration changes are properly accounted for. 2867 */ 2868 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 2869 2870 /* 2871 * Iterate over all pools to determine the maximum width 2872 * for the pool / device name column across all pools. 2873 */ 2874 cb.cb_namewidth = 0; 2875 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2876 2877 if (timestamp_fmt != NODATE) 2878 print_timestamp(timestamp_fmt); 2879 2880 /* 2881 * If it's the first time, or verbose mode, print the header. 2882 */ 2883 if (++cb.cb_iteration == 1 || verbose) 2884 print_iostat_header(&cb); 2885 2886 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2887 2888 /* 2889 * If there's more than one pool, and we're not in verbose mode 2890 * (which prints a separator for us), then print a separator. 2891 */ 2892 if (npools > 1 && !verbose) 2893 print_iostat_separator(&cb); 2894 2895 if (verbose) 2896 (void) printf("\n"); 2897 2898 /* 2899 * Flush the output so that redirection to a file isn't buffered 2900 * indefinitely. 2901 */ 2902 (void) fflush(stdout); 2903 2904 if (interval == 0) 2905 break; 2906 2907 if (count != 0 && --count == 0) 2908 break; 2909 2910 (void) sleep(interval); 2911 } 2912 2913 pool_list_free(list); 2914 2915 return (ret); 2916 } 2917 2918 typedef struct list_cbdata { 2919 boolean_t cb_verbose; 2920 int cb_namewidth; 2921 boolean_t cb_scripted; 2922 zprop_list_t *cb_proplist; 2923 boolean_t cb_literal; 2924 } list_cbdata_t; 2925 2926 /* 2927 * Given a list of columns to display, output appropriate headers for each one. 2928 */ 2929 static void 2930 print_header(list_cbdata_t *cb) 2931 { 2932 zprop_list_t *pl = cb->cb_proplist; 2933 char headerbuf[ZPOOL_MAXPROPLEN]; 2934 const char *header; 2935 boolean_t first = B_TRUE; 2936 boolean_t right_justify; 2937 size_t width = 0; 2938 2939 for (; pl != NULL; pl = pl->pl_next) { 2940 width = pl->pl_width; 2941 if (first && cb->cb_verbose) { 2942 /* 2943 * Reset the width to accommodate the verbose listing 2944 * of devices. 2945 */ 2946 width = cb->cb_namewidth; 2947 } 2948 2949 if (!first) 2950 (void) printf(" "); 2951 else 2952 first = B_FALSE; 2953 2954 right_justify = B_FALSE; 2955 if (pl->pl_prop != ZPROP_INVAL) { 2956 header = zpool_prop_column_name(pl->pl_prop); 2957 right_justify = zpool_prop_align_right(pl->pl_prop); 2958 } else { 2959 int i; 2960 2961 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 2962 headerbuf[i] = toupper(pl->pl_user_prop[i]); 2963 headerbuf[i] = '\0'; 2964 header = headerbuf; 2965 } 2966 2967 if (pl->pl_next == NULL && !right_justify) 2968 (void) printf("%s", header); 2969 else if (right_justify) 2970 (void) printf("%*s", width, header); 2971 else 2972 (void) printf("%-*s", width, header); 2973 2974 } 2975 2976 (void) printf("\n"); 2977 } 2978 2979 /* 2980 * Given a pool and a list of properties, print out all the properties according 2981 * to the described layout. 2982 */ 2983 static void 2984 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 2985 { 2986 zprop_list_t *pl = cb->cb_proplist; 2987 boolean_t first = B_TRUE; 2988 char property[ZPOOL_MAXPROPLEN]; 2989 char *propstr; 2990 boolean_t right_justify; 2991 size_t width; 2992 2993 for (; pl != NULL; pl = pl->pl_next) { 2994 2995 width = pl->pl_width; 2996 if (first && cb->cb_verbose) { 2997 /* 2998 * Reset the width to accommodate the verbose listing 2999 * of devices. 3000 */ 3001 width = cb->cb_namewidth; 3002 } 3003 3004 if (!first) { 3005 if (cb->cb_scripted) 3006 (void) printf("\t"); 3007 else 3008 (void) printf(" "); 3009 } else { 3010 first = B_FALSE; 3011 } 3012 3013 right_justify = B_FALSE; 3014 if (pl->pl_prop != ZPROP_INVAL) { 3015 if (zpool_get_prop(zhp, pl->pl_prop, property, 3016 sizeof (property), NULL, cb->cb_literal) != 0) 3017 propstr = "-"; 3018 else 3019 propstr = property; 3020 3021 right_justify = zpool_prop_align_right(pl->pl_prop); 3022 } else if ((zpool_prop_feature(pl->pl_user_prop) || 3023 zpool_prop_unsupported(pl->pl_user_prop)) && 3024 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 3025 sizeof (property)) == 0) { 3026 propstr = property; 3027 } else { 3028 propstr = "-"; 3029 } 3030 3031 3032 /* 3033 * If this is being called in scripted mode, or if this is the 3034 * last column and it is left-justified, don't include a width 3035 * format specifier. 3036 */ 3037 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 3038 (void) printf("%s", propstr); 3039 else if (right_justify) 3040 (void) printf("%*s", width, propstr); 3041 else 3042 (void) printf("%-*s", width, propstr); 3043 } 3044 3045 (void) printf("\n"); 3046 } 3047 3048 static void 3049 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted, 3050 boolean_t valid) 3051 { 3052 char propval[64]; 3053 boolean_t fixed; 3054 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 3055 3056 switch (prop) { 3057 case ZPOOL_PROP_EXPANDSZ: 3058 if (value == 0) 3059 (void) strlcpy(propval, "-", sizeof (propval)); 3060 else 3061 zfs_nicenum(value, propval, sizeof (propval)); 3062 break; 3063 case ZPOOL_PROP_FRAGMENTATION: 3064 if (value == ZFS_FRAG_INVALID) { 3065 (void) strlcpy(propval, "-", sizeof (propval)); 3066 } else { 3067 (void) snprintf(propval, sizeof (propval), "%llu%%", 3068 value); 3069 } 3070 break; 3071 case ZPOOL_PROP_CAPACITY: 3072 (void) snprintf(propval, sizeof (propval), "%llu%%", value); 3073 break; 3074 default: 3075 zfs_nicenum(value, propval, sizeof (propval)); 3076 } 3077 3078 if (!valid) 3079 (void) strlcpy(propval, "-", sizeof (propval)); 3080 3081 if (scripted) 3082 (void) printf("\t%s", propval); 3083 else 3084 (void) printf(" %*s", width, propval); 3085 } 3086 3087 void 3088 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 3089 list_cbdata_t *cb, int depth) 3090 { 3091 nvlist_t **child; 3092 vdev_stat_t *vs; 3093 uint_t c, children; 3094 char *vname; 3095 boolean_t scripted = cb->cb_scripted; 3096 uint64_t islog = B_FALSE; 3097 boolean_t haslog = B_FALSE; 3098 char *dashes = "%-*s - - - - - -\n"; 3099 3100 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 3101 (uint64_t **)&vs, &c) == 0); 3102 3103 if (name != NULL) { 3104 boolean_t toplevel = (vs->vs_space != 0); 3105 uint64_t cap; 3106 3107 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 3108 return; 3109 3110 if (scripted) 3111 (void) printf("\t%s", name); 3112 else if (strlen(name) + depth > cb->cb_namewidth) 3113 (void) printf("%*s%s", depth, "", name); 3114 else 3115 (void) printf("%*s%s%*s", depth, "", name, 3116 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 3117 3118 /* 3119 * Print the properties for the individual vdevs. Some 3120 * properties are only applicable to toplevel vdevs. The 3121 * 'toplevel' boolean value is passed to the print_one_column() 3122 * to indicate that the value is valid. 3123 */ 3124 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted, 3125 toplevel); 3126 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted, 3127 toplevel); 3128 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 3129 scripted, toplevel); 3130 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted, 3131 B_TRUE); 3132 print_one_column(ZPOOL_PROP_FRAGMENTATION, 3133 vs->vs_fragmentation, scripted, 3134 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel)); 3135 cap = (vs->vs_space == 0) ? 0 : 3136 (vs->vs_alloc * 100 / vs->vs_space); 3137 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel); 3138 (void) printf("\n"); 3139 } 3140 3141 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 3142 &child, &children) != 0) 3143 return; 3144 3145 for (c = 0; c < children; c++) { 3146 uint64_t ishole = B_FALSE; 3147 3148 if (nvlist_lookup_uint64(child[c], 3149 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 3150 continue; 3151 3152 if (nvlist_lookup_uint64(child[c], 3153 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) { 3154 haslog = B_TRUE; 3155 continue; 3156 } 3157 3158 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3159 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3160 free(vname); 3161 } 3162 3163 if (haslog == B_TRUE) { 3164 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3165 (void) printf(dashes, cb->cb_namewidth, "log"); 3166 for (c = 0; c < children; c++) { 3167 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 3168 &islog) != 0 || !islog) 3169 continue; 3170 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3171 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3172 free(vname); 3173 } 3174 } 3175 3176 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 3177 &child, &children) == 0 && children > 0) { 3178 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3179 (void) printf(dashes, cb->cb_namewidth, "cache"); 3180 for (c = 0; c < children; c++) { 3181 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3182 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3183 free(vname); 3184 } 3185 } 3186 3187 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 3188 &children) == 0 && children > 0) { 3189 /* LINTED E_SEC_PRINTF_VAR_FMT */ 3190 (void) printf(dashes, cb->cb_namewidth, "spare"); 3191 for (c = 0; c < children; c++) { 3192 vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE); 3193 print_list_stats(zhp, vname, child[c], cb, depth + 2); 3194 free(vname); 3195 } 3196 } 3197 } 3198 3199 3200 /* 3201 * Generic callback function to list a pool. 3202 */ 3203 int 3204 list_callback(zpool_handle_t *zhp, void *data) 3205 { 3206 list_cbdata_t *cbp = data; 3207 nvlist_t *config; 3208 nvlist_t *nvroot; 3209 3210 config = zpool_get_config(zhp, NULL); 3211 3212 print_pool(zhp, cbp); 3213 if (!cbp->cb_verbose) 3214 return (0); 3215 3216 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3217 &nvroot) == 0); 3218 print_list_stats(zhp, NULL, nvroot, cbp, 0); 3219 3220 return (0); 3221 } 3222 3223 /* 3224 * zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 3225 * 3226 * -H Scripted mode. Don't display headers, and separate properties 3227 * by a single tab. 3228 * -o List of properties to display. Defaults to 3229 * "name,size,allocated,free,expandsize,fragmentation,capacity," 3230 * "dedupratio,health,altroot" 3231 * -p Diplay values in parsable (exact) format. 3232 * -T Display a timestamp in date(1) or Unix format 3233 * 3234 * List all pools in the system, whether or not they're healthy. Output space 3235 * statistics for each one, as well as health status summary. 3236 */ 3237 int 3238 zpool_do_list(int argc, char **argv) 3239 { 3240 int c; 3241 int ret; 3242 list_cbdata_t cb = { 0 }; 3243 static char default_props[] = 3244 "name,size,allocated,free,expandsize,fragmentation,capacity," 3245 "dedupratio,health,altroot"; 3246 char *props = default_props; 3247 unsigned long interval = 0, count = 0; 3248 zpool_list_t *list; 3249 boolean_t first = B_TRUE; 3250 3251 /* check options */ 3252 while ((c = getopt(argc, argv, ":Ho:pT:v")) != -1) { 3253 switch (c) { 3254 case 'H': 3255 cb.cb_scripted = B_TRUE; 3256 break; 3257 case 'o': 3258 props = optarg; 3259 break; 3260 case 'p': 3261 cb.cb_literal = B_TRUE; 3262 break; 3263 case 'T': 3264 get_timestamp_arg(*optarg); 3265 break; 3266 case 'v': 3267 cb.cb_verbose = B_TRUE; 3268 break; 3269 case ':': 3270 (void) fprintf(stderr, gettext("missing argument for " 3271 "'%c' option\n"), optopt); 3272 usage(B_FALSE); 3273 break; 3274 case '?': 3275 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3276 optopt); 3277 usage(B_FALSE); 3278 } 3279 } 3280 3281 argc -= optind; 3282 argv += optind; 3283 3284 get_interval_count(&argc, argv, &interval, &count); 3285 3286 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 3287 usage(B_FALSE); 3288 3289 for (;;) { 3290 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 3291 &ret)) == NULL) 3292 return (1); 3293 3294 if (pool_list_count(list) == 0) 3295 break; 3296 3297 cb.cb_namewidth = 0; 3298 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 3299 3300 if (timestamp_fmt != NODATE) 3301 print_timestamp(timestamp_fmt); 3302 3303 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 3304 print_header(&cb); 3305 first = B_FALSE; 3306 } 3307 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 3308 3309 if (interval == 0) 3310 break; 3311 3312 if (count != 0 && --count == 0) 3313 break; 3314 3315 pool_list_free(list); 3316 (void) sleep(interval); 3317 } 3318 3319 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 3320 (void) printf(gettext("no pools available\n")); 3321 ret = 0; 3322 } 3323 3324 pool_list_free(list); 3325 zprop_free_list(cb.cb_proplist); 3326 return (ret); 3327 } 3328 3329 static int 3330 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 3331 { 3332 boolean_t force = B_FALSE; 3333 int c; 3334 nvlist_t *nvroot; 3335 char *poolname, *old_disk, *new_disk; 3336 zpool_handle_t *zhp; 3337 zpool_boot_label_t boot_type; 3338 uint64_t boot_size; 3339 int ret; 3340 3341 /* check options */ 3342 while ((c = getopt(argc, argv, "f")) != -1) { 3343 switch (c) { 3344 case 'f': 3345 force = B_TRUE; 3346 break; 3347 case '?': 3348 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3349 optopt); 3350 usage(B_FALSE); 3351 } 3352 } 3353 3354 argc -= optind; 3355 argv += optind; 3356 3357 /* get pool name and check number of arguments */ 3358 if (argc < 1) { 3359 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3360 usage(B_FALSE); 3361 } 3362 3363 poolname = argv[0]; 3364 3365 if (argc < 2) { 3366 (void) fprintf(stderr, 3367 gettext("missing <device> specification\n")); 3368 usage(B_FALSE); 3369 } 3370 3371 old_disk = argv[1]; 3372 3373 if (argc < 3) { 3374 if (!replacing) { 3375 (void) fprintf(stderr, 3376 gettext("missing <new_device> specification\n")); 3377 usage(B_FALSE); 3378 } 3379 new_disk = old_disk; 3380 argc -= 1; 3381 argv += 1; 3382 } else { 3383 new_disk = argv[2]; 3384 argc -= 2; 3385 argv += 2; 3386 } 3387 3388 if (argc > 1) { 3389 (void) fprintf(stderr, gettext("too many arguments\n")); 3390 usage(B_FALSE); 3391 } 3392 3393 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3394 return (1); 3395 3396 if (zpool_get_config(zhp, NULL) == NULL) { 3397 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 3398 poolname); 3399 zpool_close(zhp); 3400 return (1); 3401 } 3402 3403 if (zpool_is_bootable(zhp)) 3404 boot_type = ZPOOL_COPY_BOOT_LABEL; 3405 else 3406 boot_type = ZPOOL_NO_BOOT_LABEL; 3407 3408 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 3409 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 3410 boot_type, boot_size, argc, argv); 3411 if (nvroot == NULL) { 3412 zpool_close(zhp); 3413 return (1); 3414 } 3415 3416 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 3417 3418 nvlist_free(nvroot); 3419 zpool_close(zhp); 3420 3421 return (ret); 3422 } 3423 3424 /* 3425 * zpool replace [-f] <pool> <device> <new_device> 3426 * 3427 * -f Force attach, even if <new_device> appears to be in use. 3428 * 3429 * Replace <device> with <new_device>. 3430 */ 3431 /* ARGSUSED */ 3432 int 3433 zpool_do_replace(int argc, char **argv) 3434 { 3435 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 3436 } 3437 3438 /* 3439 * zpool attach [-f] <pool> <device> <new_device> 3440 * 3441 * -f Force attach, even if <new_device> appears to be in use. 3442 * 3443 * Attach <new_device> to the mirror containing <device>. If <device> is not 3444 * part of a mirror, then <device> will be transformed into a mirror of 3445 * <device> and <new_device>. In either case, <new_device> will begin life 3446 * with a DTL of [0, now], and will immediately begin to resilver itself. 3447 */ 3448 int 3449 zpool_do_attach(int argc, char **argv) 3450 { 3451 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 3452 } 3453 3454 /* 3455 * zpool detach [-f] <pool> <device> 3456 * 3457 * -f Force detach of <device>, even if DTLs argue against it 3458 * (not supported yet) 3459 * 3460 * Detach a device from a mirror. The operation will be refused if <device> 3461 * is the last device in the mirror, or if the DTLs indicate that this device 3462 * has the only valid copy of some data. 3463 */ 3464 /* ARGSUSED */ 3465 int 3466 zpool_do_detach(int argc, char **argv) 3467 { 3468 int c; 3469 char *poolname, *path; 3470 zpool_handle_t *zhp; 3471 int ret; 3472 3473 /* check options */ 3474 while ((c = getopt(argc, argv, "f")) != -1) { 3475 switch (c) { 3476 case 'f': 3477 case '?': 3478 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3479 optopt); 3480 usage(B_FALSE); 3481 } 3482 } 3483 3484 argc -= optind; 3485 argv += optind; 3486 3487 /* get pool name and check number of arguments */ 3488 if (argc < 1) { 3489 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3490 usage(B_FALSE); 3491 } 3492 3493 if (argc < 2) { 3494 (void) fprintf(stderr, 3495 gettext("missing <device> specification\n")); 3496 usage(B_FALSE); 3497 } 3498 3499 poolname = argv[0]; 3500 path = argv[1]; 3501 3502 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3503 return (1); 3504 3505 ret = zpool_vdev_detach(zhp, path); 3506 3507 zpool_close(zhp); 3508 3509 return (ret); 3510 } 3511 3512 /* 3513 * zpool split [-n] [-o prop=val] ... 3514 * [-o mntopt] ... 3515 * [-R altroot] <pool> <newpool> [<device> ...] 3516 * 3517 * -n Do not split the pool, but display the resulting layout if 3518 * it were to be split. 3519 * -o Set property=value, or set mount options. 3520 * -R Mount the split-off pool under an alternate root. 3521 * 3522 * Splits the named pool and gives it the new pool name. Devices to be split 3523 * off may be listed, provided that no more than one device is specified 3524 * per top-level vdev mirror. The newly split pool is left in an exported 3525 * state unless -R is specified. 3526 * 3527 * Restrictions: the top-level of the pool pool must only be made up of 3528 * mirrors; all devices in the pool must be healthy; no device may be 3529 * undergoing a resilvering operation. 3530 */ 3531 int 3532 zpool_do_split(int argc, char **argv) 3533 { 3534 char *srcpool, *newpool, *propval; 3535 char *mntopts = NULL; 3536 splitflags_t flags; 3537 int c, ret = 0; 3538 zpool_handle_t *zhp; 3539 nvlist_t *config, *props = NULL; 3540 3541 flags.dryrun = B_FALSE; 3542 flags.import = B_FALSE; 3543 3544 /* check options */ 3545 while ((c = getopt(argc, argv, ":R:no:")) != -1) { 3546 switch (c) { 3547 case 'R': 3548 flags.import = B_TRUE; 3549 if (add_prop_list( 3550 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 3551 &props, B_TRUE) != 0) { 3552 nvlist_free(props); 3553 usage(B_FALSE); 3554 } 3555 break; 3556 case 'n': 3557 flags.dryrun = B_TRUE; 3558 break; 3559 case 'o': 3560 if ((propval = strchr(optarg, '=')) != NULL) { 3561 *propval = '\0'; 3562 propval++; 3563 if (add_prop_list(optarg, propval, 3564 &props, B_TRUE) != 0) { 3565 nvlist_free(props); 3566 usage(B_FALSE); 3567 } 3568 } else { 3569 mntopts = optarg; 3570 } 3571 break; 3572 case ':': 3573 (void) fprintf(stderr, gettext("missing argument for " 3574 "'%c' option\n"), optopt); 3575 usage(B_FALSE); 3576 break; 3577 case '?': 3578 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3579 optopt); 3580 usage(B_FALSE); 3581 break; 3582 } 3583 } 3584 3585 if (!flags.import && mntopts != NULL) { 3586 (void) fprintf(stderr, gettext("setting mntopts is only " 3587 "valid when importing the pool\n")); 3588 usage(B_FALSE); 3589 } 3590 3591 argc -= optind; 3592 argv += optind; 3593 3594 if (argc < 1) { 3595 (void) fprintf(stderr, gettext("Missing pool name\n")); 3596 usage(B_FALSE); 3597 } 3598 if (argc < 2) { 3599 (void) fprintf(stderr, gettext("Missing new pool name\n")); 3600 usage(B_FALSE); 3601 } 3602 3603 srcpool = argv[0]; 3604 newpool = argv[1]; 3605 3606 argc -= 2; 3607 argv += 2; 3608 3609 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 3610 return (1); 3611 3612 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 3613 if (config == NULL) { 3614 ret = 1; 3615 } else { 3616 if (flags.dryrun) { 3617 (void) printf(gettext("would create '%s' with the " 3618 "following layout:\n\n"), newpool); 3619 print_vdev_tree(NULL, newpool, config, 0, B_FALSE); 3620 } 3621 nvlist_free(config); 3622 } 3623 3624 zpool_close(zhp); 3625 3626 if (ret != 0 || flags.dryrun || !flags.import) 3627 return (ret); 3628 3629 /* 3630 * The split was successful. Now we need to open the new 3631 * pool and import it. 3632 */ 3633 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 3634 return (1); 3635 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 3636 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 3637 ret = 1; 3638 (void) fprintf(stderr, gettext("Split was successful, but " 3639 "the datasets could not all be mounted\n")); 3640 (void) fprintf(stderr, gettext("Try doing '%s' with a " 3641 "different altroot\n"), "zpool import"); 3642 } 3643 zpool_close(zhp); 3644 3645 return (ret); 3646 } 3647 3648 3649 3650 /* 3651 * zpool online <pool> <device> ... 3652 */ 3653 int 3654 zpool_do_online(int argc, char **argv) 3655 { 3656 int c, i; 3657 char *poolname; 3658 zpool_handle_t *zhp; 3659 int ret = 0; 3660 vdev_state_t newstate; 3661 int flags = 0; 3662 3663 /* check options */ 3664 while ((c = getopt(argc, argv, "et")) != -1) { 3665 switch (c) { 3666 case 'e': 3667 flags |= ZFS_ONLINE_EXPAND; 3668 break; 3669 case 't': 3670 case '?': 3671 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3672 optopt); 3673 usage(B_FALSE); 3674 } 3675 } 3676 3677 argc -= optind; 3678 argv += optind; 3679 3680 /* get pool name and check number of arguments */ 3681 if (argc < 1) { 3682 (void) fprintf(stderr, gettext("missing pool name\n")); 3683 usage(B_FALSE); 3684 } 3685 if (argc < 2) { 3686 (void) fprintf(stderr, gettext("missing device name\n")); 3687 usage(B_FALSE); 3688 } 3689 3690 poolname = argv[0]; 3691 3692 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3693 return (1); 3694 3695 for (i = 1; i < argc; i++) { 3696 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 3697 if (newstate != VDEV_STATE_HEALTHY) { 3698 (void) printf(gettext("warning: device '%s' " 3699 "onlined, but remains in faulted state\n"), 3700 argv[i]); 3701 if (newstate == VDEV_STATE_FAULTED) 3702 (void) printf(gettext("use 'zpool " 3703 "clear' to restore a faulted " 3704 "device\n")); 3705 else 3706 (void) printf(gettext("use 'zpool " 3707 "replace' to replace devices " 3708 "that are no longer present\n")); 3709 } 3710 } else { 3711 ret = 1; 3712 } 3713 } 3714 3715 zpool_close(zhp); 3716 3717 return (ret); 3718 } 3719 3720 /* 3721 * zpool offline [-ft] <pool> <device> ... 3722 * 3723 * -f Force the device into the offline state, even if doing 3724 * so would appear to compromise pool availability. 3725 * (not supported yet) 3726 * 3727 * -t Only take the device off-line temporarily. The offline 3728 * state will not be persistent across reboots. 3729 */ 3730 /* ARGSUSED */ 3731 int 3732 zpool_do_offline(int argc, char **argv) 3733 { 3734 int c, i; 3735 char *poolname; 3736 zpool_handle_t *zhp; 3737 int ret = 0; 3738 boolean_t istmp = B_FALSE; 3739 3740 /* check options */ 3741 while ((c = getopt(argc, argv, "ft")) != -1) { 3742 switch (c) { 3743 case 't': 3744 istmp = B_TRUE; 3745 break; 3746 case 'f': 3747 case '?': 3748 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3749 optopt); 3750 usage(B_FALSE); 3751 } 3752 } 3753 3754 argc -= optind; 3755 argv += optind; 3756 3757 /* get pool name and check number of arguments */ 3758 if (argc < 1) { 3759 (void) fprintf(stderr, gettext("missing pool name\n")); 3760 usage(B_FALSE); 3761 } 3762 if (argc < 2) { 3763 (void) fprintf(stderr, gettext("missing device name\n")); 3764 usage(B_FALSE); 3765 } 3766 3767 poolname = argv[0]; 3768 3769 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3770 return (1); 3771 3772 for (i = 1; i < argc; i++) { 3773 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 3774 ret = 1; 3775 } 3776 3777 zpool_close(zhp); 3778 3779 return (ret); 3780 } 3781 3782 /* 3783 * zpool clear <pool> [device] 3784 * 3785 * Clear all errors associated with a pool or a particular device. 3786 */ 3787 int 3788 zpool_do_clear(int argc, char **argv) 3789 { 3790 int c; 3791 int ret = 0; 3792 boolean_t dryrun = B_FALSE; 3793 boolean_t do_rewind = B_FALSE; 3794 boolean_t xtreme_rewind = B_FALSE; 3795 uint32_t rewind_policy = ZPOOL_NO_REWIND; 3796 nvlist_t *policy = NULL; 3797 zpool_handle_t *zhp; 3798 char *pool, *device; 3799 3800 /* check options */ 3801 while ((c = getopt(argc, argv, "FnX")) != -1) { 3802 switch (c) { 3803 case 'F': 3804 do_rewind = B_TRUE; 3805 break; 3806 case 'n': 3807 dryrun = B_TRUE; 3808 break; 3809 case 'X': 3810 xtreme_rewind = B_TRUE; 3811 break; 3812 case '?': 3813 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3814 optopt); 3815 usage(B_FALSE); 3816 } 3817 } 3818 3819 argc -= optind; 3820 argv += optind; 3821 3822 if (argc < 1) { 3823 (void) fprintf(stderr, gettext("missing pool name\n")); 3824 usage(B_FALSE); 3825 } 3826 3827 if (argc > 2) { 3828 (void) fprintf(stderr, gettext("too many arguments\n")); 3829 usage(B_FALSE); 3830 } 3831 3832 if ((dryrun || xtreme_rewind) && !do_rewind) { 3833 (void) fprintf(stderr, 3834 gettext("-n or -X only meaningful with -F\n")); 3835 usage(B_FALSE); 3836 } 3837 if (dryrun) 3838 rewind_policy = ZPOOL_TRY_REWIND; 3839 else if (do_rewind) 3840 rewind_policy = ZPOOL_DO_REWIND; 3841 if (xtreme_rewind) 3842 rewind_policy |= ZPOOL_EXTREME_REWIND; 3843 3844 /* In future, further rewind policy choices can be passed along here */ 3845 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 3846 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) 3847 return (1); 3848 3849 pool = argv[0]; 3850 device = argc == 2 ? argv[1] : NULL; 3851 3852 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 3853 nvlist_free(policy); 3854 return (1); 3855 } 3856 3857 if (zpool_clear(zhp, device, policy) != 0) 3858 ret = 1; 3859 3860 zpool_close(zhp); 3861 3862 nvlist_free(policy); 3863 3864 return (ret); 3865 } 3866 3867 /* 3868 * zpool reguid <pool> 3869 */ 3870 int 3871 zpool_do_reguid(int argc, char **argv) 3872 { 3873 int c; 3874 char *poolname; 3875 zpool_handle_t *zhp; 3876 int ret = 0; 3877 3878 /* check options */ 3879 while ((c = getopt(argc, argv, "")) != -1) { 3880 switch (c) { 3881 case '?': 3882 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3883 optopt); 3884 usage(B_FALSE); 3885 } 3886 } 3887 3888 argc -= optind; 3889 argv += optind; 3890 3891 /* get pool name and check number of arguments */ 3892 if (argc < 1) { 3893 (void) fprintf(stderr, gettext("missing pool name\n")); 3894 usage(B_FALSE); 3895 } 3896 3897 if (argc > 1) { 3898 (void) fprintf(stderr, gettext("too many arguments\n")); 3899 usage(B_FALSE); 3900 } 3901 3902 poolname = argv[0]; 3903 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3904 return (1); 3905 3906 ret = zpool_reguid(zhp); 3907 3908 zpool_close(zhp); 3909 return (ret); 3910 } 3911 3912 3913 /* 3914 * zpool reopen <pool> 3915 * 3916 * Reopen the pool so that the kernel can update the sizes of all vdevs. 3917 */ 3918 int 3919 zpool_do_reopen(int argc, char **argv) 3920 { 3921 int c; 3922 int ret = 0; 3923 zpool_handle_t *zhp; 3924 char *pool; 3925 3926 /* check options */ 3927 while ((c = getopt(argc, argv, "")) != -1) { 3928 switch (c) { 3929 case '?': 3930 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3931 optopt); 3932 usage(B_FALSE); 3933 } 3934 } 3935 3936 argc--; 3937 argv++; 3938 3939 if (argc < 1) { 3940 (void) fprintf(stderr, gettext("missing pool name\n")); 3941 usage(B_FALSE); 3942 } 3943 3944 if (argc > 1) { 3945 (void) fprintf(stderr, gettext("too many arguments\n")); 3946 usage(B_FALSE); 3947 } 3948 3949 pool = argv[0]; 3950 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 3951 return (1); 3952 3953 ret = zpool_reopen(zhp); 3954 zpool_close(zhp); 3955 return (ret); 3956 } 3957 3958 typedef struct scrub_cbdata { 3959 int cb_type; 3960 int cb_argc; 3961 char **cb_argv; 3962 pool_scrub_cmd_t cb_scrub_cmd; 3963 } scrub_cbdata_t; 3964 3965 int 3966 scrub_callback(zpool_handle_t *zhp, void *data) 3967 { 3968 scrub_cbdata_t *cb = data; 3969 int err; 3970 3971 /* 3972 * Ignore faulted pools. 3973 */ 3974 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 3975 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 3976 "currently unavailable\n"), zpool_get_name(zhp)); 3977 return (1); 3978 } 3979 3980 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 3981 3982 return (err != 0); 3983 } 3984 3985 /* 3986 * zpool scrub [-s | -p] <pool> ... 3987 * 3988 * -s Stop. Stops any in-progress scrub. 3989 * -p Pause. Pause in-progress scrub. 3990 */ 3991 int 3992 zpool_do_scrub(int argc, char **argv) 3993 { 3994 int c; 3995 scrub_cbdata_t cb; 3996 3997 cb.cb_type = POOL_SCAN_SCRUB; 3998 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 3999 4000 /* check options */ 4001 while ((c = getopt(argc, argv, "sp")) != -1) { 4002 switch (c) { 4003 case 's': 4004 cb.cb_type = POOL_SCAN_NONE; 4005 break; 4006 case 'p': 4007 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 4008 break; 4009 case '?': 4010 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4011 optopt); 4012 usage(B_FALSE); 4013 } 4014 } 4015 4016 if (cb.cb_type == POOL_SCAN_NONE && 4017 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 4018 (void) fprintf(stderr, gettext("invalid option combination: " 4019 "-s and -p are mutually exclusive\n")); 4020 usage(B_FALSE); 4021 } 4022 4023 cb.cb_argc = argc; 4024 cb.cb_argv = argv; 4025 argc -= optind; 4026 argv += optind; 4027 4028 if (argc < 1) { 4029 (void) fprintf(stderr, gettext("missing pool name argument\n")); 4030 usage(B_FALSE); 4031 } 4032 4033 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 4034 } 4035 4036 typedef struct status_cbdata { 4037 int cb_count; 4038 boolean_t cb_allpools; 4039 boolean_t cb_verbose; 4040 boolean_t cb_explain; 4041 boolean_t cb_first; 4042 boolean_t cb_dedup_stats; 4043 } status_cbdata_t; 4044 4045 /* 4046 * Print out detailed scrub status. 4047 */ 4048 static void 4049 print_scan_status(pool_scan_stat_t *ps) 4050 { 4051 time_t start, end, pause; 4052 uint64_t elapsed, mins_left, hours_left; 4053 uint64_t pass_exam, examined, total; 4054 uint_t rate; 4055 double fraction_done; 4056 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 4057 4058 (void) printf(gettext(" scan: ")); 4059 4060 /* If there's never been a scan, there's not much to say. */ 4061 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 4062 ps->pss_func >= POOL_SCAN_FUNCS) { 4063 (void) printf(gettext("none requested\n")); 4064 return; 4065 } 4066 4067 start = ps->pss_start_time; 4068 end = ps->pss_end_time; 4069 pause = ps->pss_pass_scrub_pause; 4070 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 4071 4072 assert(ps->pss_func == POOL_SCAN_SCRUB || 4073 ps->pss_func == POOL_SCAN_RESILVER); 4074 /* 4075 * Scan is finished or canceled. 4076 */ 4077 if (ps->pss_state == DSS_FINISHED) { 4078 uint64_t minutes_taken = (end - start) / 60; 4079 char *fmt = NULL; 4080 4081 if (ps->pss_func == POOL_SCAN_SCRUB) { 4082 fmt = gettext("scrub repaired %s in %lluh%um with " 4083 "%llu errors on %s"); 4084 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4085 fmt = gettext("resilvered %s in %lluh%um with " 4086 "%llu errors on %s"); 4087 } 4088 /* LINTED */ 4089 (void) printf(fmt, processed_buf, 4090 (u_longlong_t)(minutes_taken / 60), 4091 (uint_t)(minutes_taken % 60), 4092 (u_longlong_t)ps->pss_errors, 4093 ctime((time_t *)&end)); 4094 return; 4095 } else if (ps->pss_state == DSS_CANCELED) { 4096 if (ps->pss_func == POOL_SCAN_SCRUB) { 4097 (void) printf(gettext("scrub canceled on %s"), 4098 ctime(&end)); 4099 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4100 (void) printf(gettext("resilver canceled on %s"), 4101 ctime(&end)); 4102 } 4103 return; 4104 } 4105 4106 assert(ps->pss_state == DSS_SCANNING); 4107 4108 /* 4109 * Scan is in progress. 4110 */ 4111 if (ps->pss_func == POOL_SCAN_SCRUB) { 4112 if (pause == 0) { 4113 (void) printf(gettext("scrub in progress since %s"), 4114 ctime(&start)); 4115 } else { 4116 char buf[32]; 4117 struct tm *p = localtime(&pause); 4118 (void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p); 4119 (void) printf(gettext("scrub paused since %s\n"), buf); 4120 (void) printf(gettext("\tscrub started on %s"), 4121 ctime(&start)); 4122 } 4123 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 4124 (void) printf(gettext("resilver in progress since %s"), 4125 ctime(&start)); 4126 } 4127 4128 examined = ps->pss_examined ? ps->pss_examined : 1; 4129 total = ps->pss_to_examine; 4130 fraction_done = (double)examined / total; 4131 4132 /* elapsed time for this pass */ 4133 elapsed = time(NULL) - ps->pss_pass_start; 4134 elapsed -= ps->pss_pass_scrub_spent_paused; 4135 elapsed = elapsed ? elapsed : 1; 4136 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1; 4137 rate = pass_exam / elapsed; 4138 rate = rate ? rate : 1; 4139 mins_left = ((total - examined) / rate) / 60; 4140 hours_left = mins_left / 60; 4141 4142 zfs_nicenum(examined, examined_buf, sizeof (examined_buf)); 4143 zfs_nicenum(total, total_buf, sizeof (total_buf)); 4144 4145 /* 4146 * do not print estimated time if hours_left is more than 30 days 4147 * or we have a paused scrub 4148 */ 4149 if (pause == 0) { 4150 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 4151 (void) printf(gettext("\t%s scanned out of %s at %s/s"), 4152 examined_buf, total_buf, rate_buf); 4153 if (hours_left < (30 * 24)) { 4154 (void) printf(gettext(", %lluh%um to go\n"), 4155 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 4156 } else { 4157 (void) printf(gettext( 4158 ", (scan is slow, no estimated time)\n")); 4159 } 4160 } else { 4161 (void) printf(gettext("\t%s scanned out of %s\n"), 4162 examined_buf, total_buf); 4163 } 4164 4165 if (ps->pss_func == POOL_SCAN_RESILVER) { 4166 (void) printf(gettext(" %s resilvered, %.2f%% done\n"), 4167 processed_buf, 100 * fraction_done); 4168 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 4169 (void) printf(gettext(" %s repaired, %.2f%% done\n"), 4170 processed_buf, 100 * fraction_done); 4171 } 4172 } 4173 4174 /* 4175 * Print out detailed removal status. 4176 */ 4177 static void 4178 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 4179 { 4180 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 4181 time_t start, end; 4182 nvlist_t *config, *nvroot; 4183 nvlist_t **child; 4184 uint_t children; 4185 char *vdev_name; 4186 4187 if (prs == NULL || prs->prs_state == DSS_NONE) 4188 return; 4189 4190 /* 4191 * Determine name of vdev. 4192 */ 4193 config = zpool_get_config(zhp, NULL); 4194 nvroot = fnvlist_lookup_nvlist(config, 4195 ZPOOL_CONFIG_VDEV_TREE); 4196 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 4197 &child, &children) == 0); 4198 assert(prs->prs_removing_vdev < children); 4199 vdev_name = zpool_vdev_name(g_zfs, zhp, 4200 child[prs->prs_removing_vdev], B_TRUE); 4201 4202 (void) printf(gettext("remove: ")); 4203 4204 start = prs->prs_start_time; 4205 end = prs->prs_end_time; 4206 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 4207 4208 /* 4209 * Removal is finished or canceled. 4210 */ 4211 if (prs->prs_state == DSS_FINISHED) { 4212 uint64_t minutes_taken = (end - start) / 60; 4213 4214 (void) printf(gettext("Removal of vdev %llu copied %s " 4215 "in %lluh%um, completed on %s"), 4216 (longlong_t)prs->prs_removing_vdev, 4217 copied_buf, 4218 (u_longlong_t)(minutes_taken / 60), 4219 (uint_t)(minutes_taken % 60), 4220 ctime((time_t *)&end)); 4221 } else if (prs->prs_state == DSS_CANCELED) { 4222 (void) printf(gettext("Removal of %s canceled on %s"), 4223 vdev_name, ctime(&end)); 4224 } else { 4225 uint64_t copied, total, elapsed, mins_left, hours_left; 4226 double fraction_done; 4227 uint_t rate; 4228 4229 assert(prs->prs_state == DSS_SCANNING); 4230 4231 /* 4232 * Removal is in progress. 4233 */ 4234 (void) printf(gettext( 4235 "Evacuation of %s in progress since %s"), 4236 vdev_name, ctime(&start)); 4237 4238 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 4239 total = prs->prs_to_copy; 4240 fraction_done = (double)copied / total; 4241 4242 /* elapsed time for this pass */ 4243 elapsed = time(NULL) - prs->prs_start_time; 4244 elapsed = elapsed > 0 ? elapsed : 1; 4245 rate = copied / elapsed; 4246 rate = rate > 0 ? rate : 1; 4247 mins_left = ((total - copied) / rate) / 60; 4248 hours_left = mins_left / 60; 4249 4250 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 4251 zfs_nicenum(total, total_buf, sizeof (total_buf)); 4252 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 4253 4254 /* 4255 * do not print estimated time if hours_left is more than 4256 * 30 days 4257 */ 4258 (void) printf(gettext(" %s copied out of %s at %s/s, " 4259 "%.2f%% done"), 4260 examined_buf, total_buf, rate_buf, 100 * fraction_done); 4261 if (hours_left < (30 * 24)) { 4262 (void) printf(gettext(", %lluh%um to go\n"), 4263 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 4264 } else { 4265 (void) printf(gettext( 4266 ", (copy is slow, no estimated time)\n")); 4267 } 4268 } 4269 4270 if (prs->prs_mapping_memory > 0) { 4271 char mem_buf[7]; 4272 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 4273 (void) printf(gettext(" %s memory used for " 4274 "removed device mappings\n"), 4275 mem_buf); 4276 } 4277 } 4278 4279 static void 4280 print_error_log(zpool_handle_t *zhp) 4281 { 4282 nvlist_t *nverrlist = NULL; 4283 nvpair_t *elem; 4284 char *pathname; 4285 size_t len = MAXPATHLEN * 2; 4286 4287 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 4288 (void) printf("errors: List of errors unavailable " 4289 "(insufficient privileges)\n"); 4290 return; 4291 } 4292 4293 (void) printf("errors: Permanent errors have been " 4294 "detected in the following files:\n\n"); 4295 4296 pathname = safe_malloc(len); 4297 elem = NULL; 4298 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 4299 nvlist_t *nv; 4300 uint64_t dsobj, obj; 4301 4302 verify(nvpair_value_nvlist(elem, &nv) == 0); 4303 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 4304 &dsobj) == 0); 4305 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 4306 &obj) == 0); 4307 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 4308 (void) printf("%7s %s\n", "", pathname); 4309 } 4310 free(pathname); 4311 nvlist_free(nverrlist); 4312 } 4313 4314 static void 4315 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 4316 int namewidth) 4317 { 4318 uint_t i; 4319 char *name; 4320 4321 if (nspares == 0) 4322 return; 4323 4324 (void) printf(gettext("\tspares\n")); 4325 4326 for (i = 0; i < nspares; i++) { 4327 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE); 4328 print_status_config(zhp, name, spares[i], 4329 namewidth, 2, B_TRUE); 4330 free(name); 4331 } 4332 } 4333 4334 static void 4335 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 4336 int namewidth) 4337 { 4338 uint_t i; 4339 char *name; 4340 4341 if (nl2cache == 0) 4342 return; 4343 4344 (void) printf(gettext("\tcache\n")); 4345 4346 for (i = 0; i < nl2cache; i++) { 4347 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE); 4348 print_status_config(zhp, name, l2cache[i], 4349 namewidth, 2, B_FALSE); 4350 free(name); 4351 } 4352 } 4353 4354 static void 4355 print_dedup_stats(nvlist_t *config) 4356 { 4357 ddt_histogram_t *ddh; 4358 ddt_stat_t *dds; 4359 ddt_object_t *ddo; 4360 uint_t c; 4361 4362 /* 4363 * If the pool was faulted then we may not have been able to 4364 * obtain the config. Otherwise, if we have anything in the dedup 4365 * table continue processing the stats. 4366 */ 4367 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 4368 (uint64_t **)&ddo, &c) != 0) 4369 return; 4370 4371 (void) printf("\n"); 4372 (void) printf(gettext(" dedup: ")); 4373 if (ddo->ddo_count == 0) { 4374 (void) printf(gettext("no DDT entries\n")); 4375 return; 4376 } 4377 4378 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 4379 (u_longlong_t)ddo->ddo_count, 4380 (u_longlong_t)ddo->ddo_dspace, 4381 (u_longlong_t)ddo->ddo_mspace); 4382 4383 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 4384 (uint64_t **)&dds, &c) == 0); 4385 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 4386 (uint64_t **)&ddh, &c) == 0); 4387 zpool_dump_ddt(dds, ddh); 4388 } 4389 4390 /* 4391 * Display a summary of pool status. Displays a summary such as: 4392 * 4393 * pool: tank 4394 * status: DEGRADED 4395 * reason: One or more devices ... 4396 * see: http://illumos.org/msg/ZFS-xxxx-01 4397 * config: 4398 * mirror DEGRADED 4399 * c1t0d0 OK 4400 * c2t0d0 UNAVAIL 4401 * 4402 * When given the '-v' option, we print out the complete config. If the '-e' 4403 * option is specified, then we print out error rate information as well. 4404 */ 4405 int 4406 status_callback(zpool_handle_t *zhp, void *data) 4407 { 4408 status_cbdata_t *cbp = data; 4409 nvlist_t *config, *nvroot; 4410 char *msgid; 4411 int reason; 4412 const char *health; 4413 uint_t c; 4414 vdev_stat_t *vs; 4415 4416 config = zpool_get_config(zhp, NULL); 4417 reason = zpool_get_status(zhp, &msgid); 4418 4419 cbp->cb_count++; 4420 4421 /* 4422 * If we were given 'zpool status -x', only report those pools with 4423 * problems. 4424 */ 4425 if (cbp->cb_explain && 4426 (reason == ZPOOL_STATUS_OK || 4427 reason == ZPOOL_STATUS_VERSION_OLDER || 4428 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 4429 if (!cbp->cb_allpools) { 4430 (void) printf(gettext("pool '%s' is healthy\n"), 4431 zpool_get_name(zhp)); 4432 if (cbp->cb_first) 4433 cbp->cb_first = B_FALSE; 4434 } 4435 return (0); 4436 } 4437 4438 if (cbp->cb_first) 4439 cbp->cb_first = B_FALSE; 4440 else 4441 (void) printf("\n"); 4442 4443 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 4444 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 4445 (uint64_t **)&vs, &c) == 0); 4446 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 4447 4448 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 4449 (void) printf(gettext(" state: %s\n"), health); 4450 4451 switch (reason) { 4452 case ZPOOL_STATUS_MISSING_DEV_R: 4453 (void) printf(gettext("status: One or more devices could not " 4454 "be opened. Sufficient replicas exist for\n\tthe pool to " 4455 "continue functioning in a degraded state.\n")); 4456 (void) printf(gettext("action: Attach the missing device and " 4457 "online it using 'zpool online'.\n")); 4458 break; 4459 4460 case ZPOOL_STATUS_MISSING_DEV_NR: 4461 (void) printf(gettext("status: One or more devices could not " 4462 "be opened. There are insufficient\n\treplicas for the " 4463 "pool to continue functioning.\n")); 4464 (void) printf(gettext("action: Attach the missing device and " 4465 "online it using 'zpool online'.\n")); 4466 break; 4467 4468 case ZPOOL_STATUS_CORRUPT_LABEL_R: 4469 (void) printf(gettext("status: One or more devices could not " 4470 "be used because the label is missing or\n\tinvalid. " 4471 "Sufficient replicas exist for the pool to continue\n\t" 4472 "functioning in a degraded state.\n")); 4473 (void) printf(gettext("action: Replace the device using " 4474 "'zpool replace'.\n")); 4475 break; 4476 4477 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 4478 (void) printf(gettext("status: One or more devices could not " 4479 "be used because the label is missing \n\tor invalid. " 4480 "There are insufficient replicas for the pool to " 4481 "continue\n\tfunctioning.\n")); 4482 zpool_explain_recover(zpool_get_handle(zhp), 4483 zpool_get_name(zhp), reason, config); 4484 break; 4485 4486 case ZPOOL_STATUS_FAILING_DEV: 4487 (void) printf(gettext("status: One or more devices has " 4488 "experienced an unrecoverable error. An\n\tattempt was " 4489 "made to correct the error. Applications are " 4490 "unaffected.\n")); 4491 (void) printf(gettext("action: Determine if the device needs " 4492 "to be replaced, and clear the errors\n\tusing " 4493 "'zpool clear' or replace the device with 'zpool " 4494 "replace'.\n")); 4495 break; 4496 4497 case ZPOOL_STATUS_OFFLINE_DEV: 4498 (void) printf(gettext("status: One or more devices has " 4499 "been taken offline by the administrator.\n\tSufficient " 4500 "replicas exist for the pool to continue functioning in " 4501 "a\n\tdegraded state.\n")); 4502 (void) printf(gettext("action: Online the device using " 4503 "'zpool online' or replace the device with\n\t'zpool " 4504 "replace'.\n")); 4505 break; 4506 4507 case ZPOOL_STATUS_REMOVED_DEV: 4508 (void) printf(gettext("status: One or more devices has " 4509 "been removed by the administrator.\n\tSufficient " 4510 "replicas exist for the pool to continue functioning in " 4511 "a\n\tdegraded state.\n")); 4512 (void) printf(gettext("action: Online the device using " 4513 "'zpool online' or replace the device with\n\t'zpool " 4514 "replace'.\n")); 4515 break; 4516 4517 case ZPOOL_STATUS_RESILVERING: 4518 (void) printf(gettext("status: One or more devices is " 4519 "currently being resilvered. The pool will\n\tcontinue " 4520 "to function, possibly in a degraded state.\n")); 4521 (void) printf(gettext("action: Wait for the resilver to " 4522 "complete.\n")); 4523 break; 4524 4525 case ZPOOL_STATUS_CORRUPT_DATA: 4526 (void) printf(gettext("status: One or more devices has " 4527 "experienced an error resulting in data\n\tcorruption. " 4528 "Applications may be affected.\n")); 4529 (void) printf(gettext("action: Restore the file in question " 4530 "if possible. Otherwise restore the\n\tentire pool from " 4531 "backup.\n")); 4532 break; 4533 4534 case ZPOOL_STATUS_CORRUPT_POOL: 4535 (void) printf(gettext("status: The pool metadata is corrupted " 4536 "and the pool cannot be opened.\n")); 4537 zpool_explain_recover(zpool_get_handle(zhp), 4538 zpool_get_name(zhp), reason, config); 4539 break; 4540 4541 case ZPOOL_STATUS_VERSION_OLDER: 4542 (void) printf(gettext("status: The pool is formatted using a " 4543 "legacy on-disk format. The pool can\n\tstill be used, " 4544 "but some features are unavailable.\n")); 4545 (void) printf(gettext("action: Upgrade the pool using 'zpool " 4546 "upgrade'. Once this is done, the\n\tpool will no longer " 4547 "be accessible on software that does not support feature\n" 4548 "\tflags.\n")); 4549 break; 4550 4551 case ZPOOL_STATUS_VERSION_NEWER: 4552 (void) printf(gettext("status: The pool has been upgraded to a " 4553 "newer, incompatible on-disk version.\n\tThe pool cannot " 4554 "be accessed on this system.\n")); 4555 (void) printf(gettext("action: Access the pool from a system " 4556 "running more recent software, or\n\trestore the pool from " 4557 "backup.\n")); 4558 break; 4559 4560 case ZPOOL_STATUS_FEAT_DISABLED: 4561 (void) printf(gettext("status: Some supported features are not " 4562 "enabled on the pool. The pool can\n\tstill be used, but " 4563 "some features are unavailable.\n")); 4564 (void) printf(gettext("action: Enable all features using " 4565 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 4566 "longer be accessible by software that does not support\n\t" 4567 "the features. See zpool-features(5) for details.\n")); 4568 break; 4569 4570 case ZPOOL_STATUS_UNSUP_FEAT_READ: 4571 (void) printf(gettext("status: The pool cannot be accessed on " 4572 "this system because it uses the\n\tfollowing feature(s) " 4573 "not supported on this system:\n")); 4574 zpool_print_unsup_feat(config); 4575 (void) printf("\n"); 4576 (void) printf(gettext("action: Access the pool from a system " 4577 "that supports the required feature(s),\n\tor restore the " 4578 "pool from backup.\n")); 4579 break; 4580 4581 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 4582 (void) printf(gettext("status: The pool can only be accessed " 4583 "in read-only mode on this system. It\n\tcannot be " 4584 "accessed in read-write mode because it uses the " 4585 "following\n\tfeature(s) not supported on this system:\n")); 4586 zpool_print_unsup_feat(config); 4587 (void) printf("\n"); 4588 (void) printf(gettext("action: The pool cannot be accessed in " 4589 "read-write mode. Import the pool with\n" 4590 "\t\"-o readonly=on\", access the pool from a system that " 4591 "supports the\n\trequired feature(s), or restore the " 4592 "pool from backup.\n")); 4593 break; 4594 4595 case ZPOOL_STATUS_FAULTED_DEV_R: 4596 (void) printf(gettext("status: One or more devices are " 4597 "faulted in response to persistent errors.\n\tSufficient " 4598 "replicas exist for the pool to continue functioning " 4599 "in a\n\tdegraded state.\n")); 4600 (void) printf(gettext("action: Replace the faulted device, " 4601 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 4602 break; 4603 4604 case ZPOOL_STATUS_FAULTED_DEV_NR: 4605 (void) printf(gettext("status: One or more devices are " 4606 "faulted in response to persistent errors. There are " 4607 "insufficient replicas for the pool to\n\tcontinue " 4608 "functioning.\n")); 4609 (void) printf(gettext("action: Destroy and re-create the pool " 4610 "from a backup source. Manually marking the device\n" 4611 "\trepaired using 'zpool clear' may allow some data " 4612 "to be recovered.\n")); 4613 break; 4614 4615 case ZPOOL_STATUS_IO_FAILURE_WAIT: 4616 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 4617 (void) printf(gettext("status: One or more devices are " 4618 "faulted in response to IO failures.\n")); 4619 (void) printf(gettext("action: Make sure the affected devices " 4620 "are connected, then run 'zpool clear'.\n")); 4621 break; 4622 4623 case ZPOOL_STATUS_BAD_LOG: 4624 (void) printf(gettext("status: An intent log record " 4625 "could not be read.\n" 4626 "\tWaiting for adminstrator intervention to fix the " 4627 "faulted pool.\n")); 4628 (void) printf(gettext("action: Either restore the affected " 4629 "device(s) and run 'zpool online',\n" 4630 "\tor ignore the intent log records by running " 4631 "'zpool clear'.\n")); 4632 break; 4633 4634 default: 4635 /* 4636 * The remaining errors can't actually be generated, yet. 4637 */ 4638 assert(reason == ZPOOL_STATUS_OK); 4639 } 4640 4641 if (msgid != NULL) 4642 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 4643 msgid); 4644 4645 if (config != NULL) { 4646 int namewidth; 4647 uint64_t nerr; 4648 nvlist_t **spares, **l2cache; 4649 uint_t nspares, nl2cache; 4650 pool_scan_stat_t *ps = NULL; 4651 pool_removal_stat_t *prs = NULL; 4652 4653 (void) nvlist_lookup_uint64_array(nvroot, 4654 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 4655 print_scan_status(ps); 4656 4657 (void) nvlist_lookup_uint64_array(nvroot, 4658 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 4659 print_removal_status(zhp, prs); 4660 4661 namewidth = max_width(zhp, nvroot, 0, 0); 4662 if (namewidth < 10) 4663 namewidth = 10; 4664 4665 (void) printf(gettext("config:\n\n")); 4666 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 4667 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 4668 print_status_config(zhp, zpool_get_name(zhp), nvroot, 4669 namewidth, 0, B_FALSE); 4670 4671 if (num_logs(nvroot) > 0) 4672 print_logs(zhp, nvroot, namewidth, B_TRUE); 4673 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 4674 &l2cache, &nl2cache) == 0) 4675 print_l2cache(zhp, l2cache, nl2cache, namewidth); 4676 4677 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 4678 &spares, &nspares) == 0) 4679 print_spares(zhp, spares, nspares, namewidth); 4680 4681 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 4682 &nerr) == 0) { 4683 nvlist_t *nverrlist = NULL; 4684 4685 /* 4686 * If the approximate error count is small, get a 4687 * precise count by fetching the entire log and 4688 * uniquifying the results. 4689 */ 4690 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 4691 zpool_get_errlog(zhp, &nverrlist) == 0) { 4692 nvpair_t *elem; 4693 4694 elem = NULL; 4695 nerr = 0; 4696 while ((elem = nvlist_next_nvpair(nverrlist, 4697 elem)) != NULL) { 4698 nerr++; 4699 } 4700 } 4701 nvlist_free(nverrlist); 4702 4703 (void) printf("\n"); 4704 4705 if (nerr == 0) 4706 (void) printf(gettext("errors: No known data " 4707 "errors\n")); 4708 else if (!cbp->cb_verbose) 4709 (void) printf(gettext("errors: %llu data " 4710 "errors, use '-v' for a list\n"), 4711 (u_longlong_t)nerr); 4712 else 4713 print_error_log(zhp); 4714 } 4715 4716 if (cbp->cb_dedup_stats) 4717 print_dedup_stats(config); 4718 } else { 4719 (void) printf(gettext("config: The configuration cannot be " 4720 "determined.\n")); 4721 } 4722 4723 return (0); 4724 } 4725 4726 /* 4727 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]] 4728 * 4729 * -v Display complete error logs 4730 * -x Display only pools with potential problems 4731 * -D Display dedup status (undocumented) 4732 * -T Display a timestamp in date(1) or Unix format 4733 * 4734 * Describes the health status of all pools or some subset. 4735 */ 4736 int 4737 zpool_do_status(int argc, char **argv) 4738 { 4739 int c; 4740 int ret; 4741 unsigned long interval = 0, count = 0; 4742 status_cbdata_t cb = { 0 }; 4743 4744 /* check options */ 4745 while ((c = getopt(argc, argv, "vxDT:")) != -1) { 4746 switch (c) { 4747 case 'v': 4748 cb.cb_verbose = B_TRUE; 4749 break; 4750 case 'x': 4751 cb.cb_explain = B_TRUE; 4752 break; 4753 case 'D': 4754 cb.cb_dedup_stats = B_TRUE; 4755 break; 4756 case 'T': 4757 get_timestamp_arg(*optarg); 4758 break; 4759 case '?': 4760 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4761 optopt); 4762 usage(B_FALSE); 4763 } 4764 } 4765 4766 argc -= optind; 4767 argv += optind; 4768 4769 get_interval_count(&argc, argv, &interval, &count); 4770 4771 if (argc == 0) 4772 cb.cb_allpools = B_TRUE; 4773 4774 cb.cb_first = B_TRUE; 4775 4776 for (;;) { 4777 if (timestamp_fmt != NODATE) 4778 print_timestamp(timestamp_fmt); 4779 4780 ret = for_each_pool(argc, argv, B_TRUE, NULL, 4781 status_callback, &cb); 4782 4783 if (argc == 0 && cb.cb_count == 0) 4784 (void) printf(gettext("no pools available\n")); 4785 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 4786 (void) printf(gettext("all pools are healthy\n")); 4787 4788 if (ret != 0) 4789 return (ret); 4790 4791 if (interval == 0) 4792 break; 4793 4794 if (count != 0 && --count == 0) 4795 break; 4796 4797 (void) sleep(interval); 4798 } 4799 4800 return (0); 4801 } 4802 4803 typedef struct upgrade_cbdata { 4804 int cb_first; 4805 int cb_argc; 4806 uint64_t cb_version; 4807 char **cb_argv; 4808 } upgrade_cbdata_t; 4809 4810 static int 4811 upgrade_version(zpool_handle_t *zhp, uint64_t version) 4812 { 4813 int ret; 4814 nvlist_t *config; 4815 uint64_t oldversion; 4816 4817 config = zpool_get_config(zhp, NULL); 4818 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4819 &oldversion) == 0); 4820 4821 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 4822 assert(oldversion < version); 4823 4824 ret = zpool_upgrade(zhp, version); 4825 if (ret != 0) 4826 return (ret); 4827 4828 if (version >= SPA_VERSION_FEATURES) { 4829 (void) printf(gettext("Successfully upgraded " 4830 "'%s' from version %llu to feature flags.\n"), 4831 zpool_get_name(zhp), oldversion); 4832 } else { 4833 (void) printf(gettext("Successfully upgraded " 4834 "'%s' from version %llu to version %llu.\n"), 4835 zpool_get_name(zhp), oldversion, version); 4836 } 4837 4838 return (0); 4839 } 4840 4841 static int 4842 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 4843 { 4844 int i, ret, count; 4845 boolean_t firstff = B_TRUE; 4846 nvlist_t *enabled = zpool_get_features(zhp); 4847 4848 count = 0; 4849 for (i = 0; i < SPA_FEATURES; i++) { 4850 const char *fname = spa_feature_table[i].fi_uname; 4851 const char *fguid = spa_feature_table[i].fi_guid; 4852 if (!nvlist_exists(enabled, fguid)) { 4853 char *propname; 4854 verify(-1 != asprintf(&propname, "feature@%s", fname)); 4855 ret = zpool_set_prop(zhp, propname, 4856 ZFS_FEATURE_ENABLED); 4857 if (ret != 0) { 4858 free(propname); 4859 return (ret); 4860 } 4861 count++; 4862 4863 if (firstff) { 4864 (void) printf(gettext("Enabled the " 4865 "following features on '%s':\n"), 4866 zpool_get_name(zhp)); 4867 firstff = B_FALSE; 4868 } 4869 (void) printf(gettext(" %s\n"), fname); 4870 free(propname); 4871 } 4872 } 4873 4874 if (countp != NULL) 4875 *countp = count; 4876 return (0); 4877 } 4878 4879 static int 4880 upgrade_cb(zpool_handle_t *zhp, void *arg) 4881 { 4882 upgrade_cbdata_t *cbp = arg; 4883 nvlist_t *config; 4884 uint64_t version; 4885 boolean_t printnl = B_FALSE; 4886 int ret; 4887 4888 config = zpool_get_config(zhp, NULL); 4889 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4890 &version) == 0); 4891 4892 assert(SPA_VERSION_IS_SUPPORTED(version)); 4893 4894 if (version < cbp->cb_version) { 4895 cbp->cb_first = B_FALSE; 4896 ret = upgrade_version(zhp, cbp->cb_version); 4897 if (ret != 0) 4898 return (ret); 4899 printnl = B_TRUE; 4900 4901 /* 4902 * If they did "zpool upgrade -a", then we could 4903 * be doing ioctls to different pools. We need 4904 * to log this history once to each pool, and bypass 4905 * the normal history logging that happens in main(). 4906 */ 4907 (void) zpool_log_history(g_zfs, history_str); 4908 log_history = B_FALSE; 4909 } 4910 4911 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 4912 int count; 4913 ret = upgrade_enable_all(zhp, &count); 4914 if (ret != 0) 4915 return (ret); 4916 4917 if (count > 0) { 4918 cbp->cb_first = B_FALSE; 4919 printnl = B_TRUE; 4920 } 4921 } 4922 4923 if (printnl) { 4924 (void) printf(gettext("\n")); 4925 } 4926 4927 return (0); 4928 } 4929 4930 static int 4931 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 4932 { 4933 upgrade_cbdata_t *cbp = arg; 4934 nvlist_t *config; 4935 uint64_t version; 4936 4937 config = zpool_get_config(zhp, NULL); 4938 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4939 &version) == 0); 4940 4941 assert(SPA_VERSION_IS_SUPPORTED(version)); 4942 4943 if (version < SPA_VERSION_FEATURES) { 4944 if (cbp->cb_first) { 4945 (void) printf(gettext("The following pools are " 4946 "formatted with legacy version numbers and can\n" 4947 "be upgraded to use feature flags. After " 4948 "being upgraded, these pools\nwill no " 4949 "longer be accessible by software that does not " 4950 "support feature\nflags.\n\n")); 4951 (void) printf(gettext("VER POOL\n")); 4952 (void) printf(gettext("--- ------------\n")); 4953 cbp->cb_first = B_FALSE; 4954 } 4955 4956 (void) printf("%2llu %s\n", (u_longlong_t)version, 4957 zpool_get_name(zhp)); 4958 } 4959 4960 return (0); 4961 } 4962 4963 static int 4964 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 4965 { 4966 upgrade_cbdata_t *cbp = arg; 4967 nvlist_t *config; 4968 uint64_t version; 4969 4970 config = zpool_get_config(zhp, NULL); 4971 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4972 &version) == 0); 4973 4974 if (version >= SPA_VERSION_FEATURES) { 4975 int i; 4976 boolean_t poolfirst = B_TRUE; 4977 nvlist_t *enabled = zpool_get_features(zhp); 4978 4979 for (i = 0; i < SPA_FEATURES; i++) { 4980 const char *fguid = spa_feature_table[i].fi_guid; 4981 const char *fname = spa_feature_table[i].fi_uname; 4982 if (!nvlist_exists(enabled, fguid)) { 4983 if (cbp->cb_first) { 4984 (void) printf(gettext("\nSome " 4985 "supported features are not " 4986 "enabled on the following pools. " 4987 "Once a\nfeature is enabled the " 4988 "pool may become incompatible with " 4989 "software\nthat does not support " 4990 "the feature. See " 4991 "zpool-features(5) for " 4992 "details.\n\n")); 4993 (void) printf(gettext("POOL " 4994 "FEATURE\n")); 4995 (void) printf(gettext("------" 4996 "---------\n")); 4997 cbp->cb_first = B_FALSE; 4998 } 4999 5000 if (poolfirst) { 5001 (void) printf(gettext("%s\n"), 5002 zpool_get_name(zhp)); 5003 poolfirst = B_FALSE; 5004 } 5005 5006 (void) printf(gettext(" %s\n"), fname); 5007 } 5008 } 5009 } 5010 5011 return (0); 5012 } 5013 5014 /* ARGSUSED */ 5015 static int 5016 upgrade_one(zpool_handle_t *zhp, void *data) 5017 { 5018 boolean_t printnl = B_FALSE; 5019 upgrade_cbdata_t *cbp = data; 5020 uint64_t cur_version; 5021 int ret; 5022 5023 if (strcmp("log", zpool_get_name(zhp)) == 0) { 5024 (void) printf(gettext("'log' is now a reserved word\n" 5025 "Pool 'log' must be renamed using export and import" 5026 " to upgrade.\n")); 5027 return (1); 5028 } 5029 5030 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 5031 if (cur_version > cbp->cb_version) { 5032 (void) printf(gettext("Pool '%s' is already formatted " 5033 "using more current version '%llu'.\n\n"), 5034 zpool_get_name(zhp), cur_version); 5035 return (0); 5036 } 5037 5038 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 5039 (void) printf(gettext("Pool '%s' is already formatted " 5040 "using version %llu.\n\n"), zpool_get_name(zhp), 5041 cbp->cb_version); 5042 return (0); 5043 } 5044 5045 if (cur_version != cbp->cb_version) { 5046 printnl = B_TRUE; 5047 ret = upgrade_version(zhp, cbp->cb_version); 5048 if (ret != 0) 5049 return (ret); 5050 } 5051 5052 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 5053 int count = 0; 5054 ret = upgrade_enable_all(zhp, &count); 5055 if (ret != 0) 5056 return (ret); 5057 5058 if (count != 0) { 5059 printnl = B_TRUE; 5060 } else if (cur_version == SPA_VERSION) { 5061 (void) printf(gettext("Pool '%s' already has all " 5062 "supported features enabled.\n"), 5063 zpool_get_name(zhp)); 5064 } 5065 } 5066 5067 if (printnl) { 5068 (void) printf(gettext("\n")); 5069 } 5070 5071 return (0); 5072 } 5073 5074 /* 5075 * zpool upgrade 5076 * zpool upgrade -v 5077 * zpool upgrade [-V version] <-a | pool ...> 5078 * 5079 * With no arguments, display downrev'd ZFS pool available for upgrade. 5080 * Individual pools can be upgraded by specifying the pool, and '-a' will 5081 * upgrade all pools. 5082 */ 5083 int 5084 zpool_do_upgrade(int argc, char **argv) 5085 { 5086 int c; 5087 upgrade_cbdata_t cb = { 0 }; 5088 int ret = 0; 5089 boolean_t showversions = B_FALSE; 5090 boolean_t upgradeall = B_FALSE; 5091 char *end; 5092 5093 5094 /* check options */ 5095 while ((c = getopt(argc, argv, ":avV:")) != -1) { 5096 switch (c) { 5097 case 'a': 5098 upgradeall = B_TRUE; 5099 break; 5100 case 'v': 5101 showversions = B_TRUE; 5102 break; 5103 case 'V': 5104 cb.cb_version = strtoll(optarg, &end, 10); 5105 if (*end != '\0' || 5106 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 5107 (void) fprintf(stderr, 5108 gettext("invalid version '%s'\n"), optarg); 5109 usage(B_FALSE); 5110 } 5111 break; 5112 case ':': 5113 (void) fprintf(stderr, gettext("missing argument for " 5114 "'%c' option\n"), optopt); 5115 usage(B_FALSE); 5116 break; 5117 case '?': 5118 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5119 optopt); 5120 usage(B_FALSE); 5121 } 5122 } 5123 5124 cb.cb_argc = argc; 5125 cb.cb_argv = argv; 5126 argc -= optind; 5127 argv += optind; 5128 5129 if (cb.cb_version == 0) { 5130 cb.cb_version = SPA_VERSION; 5131 } else if (!upgradeall && argc == 0) { 5132 (void) fprintf(stderr, gettext("-V option is " 5133 "incompatible with other arguments\n")); 5134 usage(B_FALSE); 5135 } 5136 5137 if (showversions) { 5138 if (upgradeall || argc != 0) { 5139 (void) fprintf(stderr, gettext("-v option is " 5140 "incompatible with other arguments\n")); 5141 usage(B_FALSE); 5142 } 5143 } else if (upgradeall) { 5144 if (argc != 0) { 5145 (void) fprintf(stderr, gettext("-a option should not " 5146 "be used along with a pool name\n")); 5147 usage(B_FALSE); 5148 } 5149 } 5150 5151 (void) printf(gettext("This system supports ZFS pool feature " 5152 "flags.\n\n")); 5153 if (showversions) { 5154 int i; 5155 5156 (void) printf(gettext("The following features are " 5157 "supported:\n\n")); 5158 (void) printf(gettext("FEAT DESCRIPTION\n")); 5159 (void) printf("----------------------------------------------" 5160 "---------------\n"); 5161 for (i = 0; i < SPA_FEATURES; i++) { 5162 zfeature_info_t *fi = &spa_feature_table[i]; 5163 const char *ro = 5164 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 5165 " (read-only compatible)" : ""; 5166 5167 (void) printf("%-37s%s\n", fi->fi_uname, ro); 5168 (void) printf(" %s\n", fi->fi_desc); 5169 } 5170 (void) printf("\n"); 5171 5172 (void) printf(gettext("The following legacy versions are also " 5173 "supported:\n\n")); 5174 (void) printf(gettext("VER DESCRIPTION\n")); 5175 (void) printf("--- -----------------------------------------" 5176 "---------------\n"); 5177 (void) printf(gettext(" 1 Initial ZFS version\n")); 5178 (void) printf(gettext(" 2 Ditto blocks " 5179 "(replicated metadata)\n")); 5180 (void) printf(gettext(" 3 Hot spares and double parity " 5181 "RAID-Z\n")); 5182 (void) printf(gettext(" 4 zpool history\n")); 5183 (void) printf(gettext(" 5 Compression using the gzip " 5184 "algorithm\n")); 5185 (void) printf(gettext(" 6 bootfs pool property\n")); 5186 (void) printf(gettext(" 7 Separate intent log devices\n")); 5187 (void) printf(gettext(" 8 Delegated administration\n")); 5188 (void) printf(gettext(" 9 refquota and refreservation " 5189 "properties\n")); 5190 (void) printf(gettext(" 10 Cache devices\n")); 5191 (void) printf(gettext(" 11 Improved scrub performance\n")); 5192 (void) printf(gettext(" 12 Snapshot properties\n")); 5193 (void) printf(gettext(" 13 snapused property\n")); 5194 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 5195 (void) printf(gettext(" 15 user/group space accounting\n")); 5196 (void) printf(gettext(" 16 stmf property support\n")); 5197 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 5198 (void) printf(gettext(" 18 Snapshot user holds\n")); 5199 (void) printf(gettext(" 19 Log device removal\n")); 5200 (void) printf(gettext(" 20 Compression using zle " 5201 "(zero-length encoding)\n")); 5202 (void) printf(gettext(" 21 Deduplication\n")); 5203 (void) printf(gettext(" 22 Received properties\n")); 5204 (void) printf(gettext(" 23 Slim ZIL\n")); 5205 (void) printf(gettext(" 24 System attributes\n")); 5206 (void) printf(gettext(" 25 Improved scrub stats\n")); 5207 (void) printf(gettext(" 26 Improved snapshot deletion " 5208 "performance\n")); 5209 (void) printf(gettext(" 27 Improved snapshot creation " 5210 "performance\n")); 5211 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 5212 (void) printf(gettext("\nFor more information on a particular " 5213 "version, including supported releases,\n")); 5214 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 5215 } else if (argc == 0 && upgradeall) { 5216 cb.cb_first = B_TRUE; 5217 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 5218 if (ret == 0 && cb.cb_first) { 5219 if (cb.cb_version == SPA_VERSION) { 5220 (void) printf(gettext("All pools are already " 5221 "formatted using feature flags.\n\n")); 5222 (void) printf(gettext("Every feature flags " 5223 "pool already has all supported features " 5224 "enabled.\n")); 5225 } else { 5226 (void) printf(gettext("All pools are already " 5227 "formatted with version %llu or higher.\n"), 5228 cb.cb_version); 5229 } 5230 } 5231 } else if (argc == 0) { 5232 cb.cb_first = B_TRUE; 5233 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 5234 assert(ret == 0); 5235 5236 if (cb.cb_first) { 5237 (void) printf(gettext("All pools are formatted " 5238 "using feature flags.\n\n")); 5239 } else { 5240 (void) printf(gettext("\nUse 'zpool upgrade -v' " 5241 "for a list of available legacy versions.\n")); 5242 } 5243 5244 cb.cb_first = B_TRUE; 5245 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 5246 assert(ret == 0); 5247 5248 if (cb.cb_first) { 5249 (void) printf(gettext("Every feature flags pool has " 5250 "all supported features enabled.\n")); 5251 } else { 5252 (void) printf(gettext("\n")); 5253 } 5254 } else { 5255 ret = for_each_pool(argc, argv, B_FALSE, NULL, 5256 upgrade_one, &cb); 5257 } 5258 5259 return (ret); 5260 } 5261 5262 typedef struct hist_cbdata { 5263 boolean_t first; 5264 boolean_t longfmt; 5265 boolean_t internal; 5266 } hist_cbdata_t; 5267 5268 /* 5269 * Print out the command history for a specific pool. 5270 */ 5271 static int 5272 get_history_one(zpool_handle_t *zhp, void *data) 5273 { 5274 nvlist_t *nvhis; 5275 nvlist_t **records; 5276 uint_t numrecords; 5277 int ret, i; 5278 hist_cbdata_t *cb = (hist_cbdata_t *)data; 5279 5280 cb->first = B_FALSE; 5281 5282 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 5283 5284 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 5285 return (ret); 5286 5287 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 5288 &records, &numrecords) == 0); 5289 for (i = 0; i < numrecords; i++) { 5290 nvlist_t *rec = records[i]; 5291 char tbuf[30] = ""; 5292 5293 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 5294 time_t tsec; 5295 struct tm t; 5296 5297 tsec = fnvlist_lookup_uint64(records[i], 5298 ZPOOL_HIST_TIME); 5299 (void) localtime_r(&tsec, &t); 5300 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 5301 } 5302 5303 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 5304 (void) printf("%s %s", tbuf, 5305 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 5306 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 5307 int ievent = 5308 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 5309 if (!cb->internal) 5310 continue; 5311 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 5312 (void) printf("%s unrecognized record:\n", 5313 tbuf); 5314 dump_nvlist(rec, 4); 5315 continue; 5316 } 5317 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 5318 zfs_history_event_names[ievent], 5319 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 5320 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 5321 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 5322 if (!cb->internal) 5323 continue; 5324 (void) printf("%s [txg:%lld] %s", tbuf, 5325 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 5326 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 5327 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 5328 (void) printf(" %s (%llu)", 5329 fnvlist_lookup_string(rec, 5330 ZPOOL_HIST_DSNAME), 5331 fnvlist_lookup_uint64(rec, 5332 ZPOOL_HIST_DSID)); 5333 } 5334 (void) printf(" %s", fnvlist_lookup_string(rec, 5335 ZPOOL_HIST_INT_STR)); 5336 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 5337 if (!cb->internal) 5338 continue; 5339 (void) printf("%s ioctl %s\n", tbuf, 5340 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 5341 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 5342 (void) printf(" input:\n"); 5343 dump_nvlist(fnvlist_lookup_nvlist(rec, 5344 ZPOOL_HIST_INPUT_NVL), 8); 5345 } 5346 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 5347 (void) printf(" output:\n"); 5348 dump_nvlist(fnvlist_lookup_nvlist(rec, 5349 ZPOOL_HIST_OUTPUT_NVL), 8); 5350 } 5351 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 5352 (void) printf(" errno: %lld\n", 5353 fnvlist_lookup_int64(rec, 5354 ZPOOL_HIST_ERRNO)); 5355 } 5356 } else { 5357 if (!cb->internal) 5358 continue; 5359 (void) printf("%s unrecognized record:\n", tbuf); 5360 dump_nvlist(rec, 4); 5361 } 5362 5363 if (!cb->longfmt) { 5364 (void) printf("\n"); 5365 continue; 5366 } 5367 (void) printf(" ["); 5368 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 5369 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 5370 struct passwd *pwd = getpwuid(who); 5371 (void) printf("user %d ", (int)who); 5372 if (pwd != NULL) 5373 (void) printf("(%s) ", pwd->pw_name); 5374 } 5375 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 5376 (void) printf("on %s", 5377 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 5378 } 5379 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 5380 (void) printf(":%s", 5381 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 5382 } 5383 (void) printf("]"); 5384 (void) printf("\n"); 5385 } 5386 (void) printf("\n"); 5387 nvlist_free(nvhis); 5388 5389 return (ret); 5390 } 5391 5392 /* 5393 * zpool history <pool> 5394 * 5395 * Displays the history of commands that modified pools. 5396 */ 5397 int 5398 zpool_do_history(int argc, char **argv) 5399 { 5400 hist_cbdata_t cbdata = { 0 }; 5401 int ret; 5402 int c; 5403 5404 cbdata.first = B_TRUE; 5405 /* check options */ 5406 while ((c = getopt(argc, argv, "li")) != -1) { 5407 switch (c) { 5408 case 'l': 5409 cbdata.longfmt = B_TRUE; 5410 break; 5411 case 'i': 5412 cbdata.internal = B_TRUE; 5413 break; 5414 case '?': 5415 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5416 optopt); 5417 usage(B_FALSE); 5418 } 5419 } 5420 argc -= optind; 5421 argv += optind; 5422 5423 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 5424 &cbdata); 5425 5426 if (argc == 0 && cbdata.first == B_TRUE) { 5427 (void) printf(gettext("no pools available\n")); 5428 return (0); 5429 } 5430 5431 return (ret); 5432 } 5433 5434 static int 5435 get_callback(zpool_handle_t *zhp, void *data) 5436 { 5437 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 5438 char value[MAXNAMELEN]; 5439 zprop_source_t srctype; 5440 zprop_list_t *pl; 5441 5442 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 5443 5444 /* 5445 * Skip the special fake placeholder. This will also skip 5446 * over the name property when 'all' is specified. 5447 */ 5448 if (pl->pl_prop == ZPOOL_PROP_NAME && 5449 pl == cbp->cb_proplist) 5450 continue; 5451 5452 if (pl->pl_prop == ZPROP_INVAL && 5453 (zpool_prop_feature(pl->pl_user_prop) || 5454 zpool_prop_unsupported(pl->pl_user_prop))) { 5455 srctype = ZPROP_SRC_LOCAL; 5456 5457 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 5458 value, sizeof (value)) == 0) { 5459 zprop_print_one_property(zpool_get_name(zhp), 5460 cbp, pl->pl_user_prop, value, srctype, 5461 NULL, NULL); 5462 } 5463 } else { 5464 if (zpool_get_prop(zhp, pl->pl_prop, value, 5465 sizeof (value), &srctype, cbp->cb_literal) != 0) 5466 continue; 5467 5468 zprop_print_one_property(zpool_get_name(zhp), cbp, 5469 zpool_prop_to_name(pl->pl_prop), value, srctype, 5470 NULL, NULL); 5471 } 5472 } 5473 return (0); 5474 } 5475 5476 /* 5477 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 5478 * 5479 * -H Scripted mode. Don't display headers, and separate properties 5480 * by a single tab. 5481 * -o List of columns to display. Defaults to 5482 * "name,property,value,source". 5483 * -p Diplay values in parsable (exact) format. 5484 * 5485 * Get properties of pools in the system. Output space statistics 5486 * for each one as well as other attributes. 5487 */ 5488 int 5489 zpool_do_get(int argc, char **argv) 5490 { 5491 zprop_get_cbdata_t cb = { 0 }; 5492 zprop_list_t fake_name = { 0 }; 5493 int ret; 5494 int c, i; 5495 char *value; 5496 5497 cb.cb_first = B_TRUE; 5498 5499 /* 5500 * Set up default columns and sources. 5501 */ 5502 cb.cb_sources = ZPROP_SRC_ALL; 5503 cb.cb_columns[0] = GET_COL_NAME; 5504 cb.cb_columns[1] = GET_COL_PROPERTY; 5505 cb.cb_columns[2] = GET_COL_VALUE; 5506 cb.cb_columns[3] = GET_COL_SOURCE; 5507 cb.cb_type = ZFS_TYPE_POOL; 5508 5509 /* check options */ 5510 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 5511 switch (c) { 5512 case 'p': 5513 cb.cb_literal = B_TRUE; 5514 break; 5515 case 'H': 5516 cb.cb_scripted = B_TRUE; 5517 break; 5518 case 'o': 5519 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 5520 i = 0; 5521 while (*optarg != '\0') { 5522 static char *col_subopts[] = 5523 { "name", "property", "value", "source", 5524 "all", NULL }; 5525 5526 if (i == ZFS_GET_NCOLS) { 5527 (void) fprintf(stderr, gettext("too " 5528 "many fields given to -o " 5529 "option\n")); 5530 usage(B_FALSE); 5531 } 5532 5533 switch (getsubopt(&optarg, col_subopts, 5534 &value)) { 5535 case 0: 5536 cb.cb_columns[i++] = GET_COL_NAME; 5537 break; 5538 case 1: 5539 cb.cb_columns[i++] = GET_COL_PROPERTY; 5540 break; 5541 case 2: 5542 cb.cb_columns[i++] = GET_COL_VALUE; 5543 break; 5544 case 3: 5545 cb.cb_columns[i++] = GET_COL_SOURCE; 5546 break; 5547 case 4: 5548 if (i > 0) { 5549 (void) fprintf(stderr, 5550 gettext("\"all\" conflicts " 5551 "with specific fields " 5552 "given to -o option\n")); 5553 usage(B_FALSE); 5554 } 5555 cb.cb_columns[0] = GET_COL_NAME; 5556 cb.cb_columns[1] = GET_COL_PROPERTY; 5557 cb.cb_columns[2] = GET_COL_VALUE; 5558 cb.cb_columns[3] = GET_COL_SOURCE; 5559 i = ZFS_GET_NCOLS; 5560 break; 5561 default: 5562 (void) fprintf(stderr, 5563 gettext("invalid column name " 5564 "'%s'\n"), value); 5565 usage(B_FALSE); 5566 } 5567 } 5568 break; 5569 case '?': 5570 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5571 optopt); 5572 usage(B_FALSE); 5573 } 5574 } 5575 5576 argc -= optind; 5577 argv += optind; 5578 5579 if (argc < 1) { 5580 (void) fprintf(stderr, gettext("missing property " 5581 "argument\n")); 5582 usage(B_FALSE); 5583 } 5584 5585 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 5586 ZFS_TYPE_POOL) != 0) 5587 usage(B_FALSE); 5588 5589 argc--; 5590 argv++; 5591 5592 if (cb.cb_proplist != NULL) { 5593 fake_name.pl_prop = ZPOOL_PROP_NAME; 5594 fake_name.pl_width = strlen(gettext("NAME")); 5595 fake_name.pl_next = cb.cb_proplist; 5596 cb.cb_proplist = &fake_name; 5597 } 5598 5599 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 5600 get_callback, &cb); 5601 5602 if (cb.cb_proplist == &fake_name) 5603 zprop_free_list(fake_name.pl_next); 5604 else 5605 zprop_free_list(cb.cb_proplist); 5606 5607 return (ret); 5608 } 5609 5610 typedef struct set_cbdata { 5611 char *cb_propname; 5612 char *cb_value; 5613 boolean_t cb_any_successful; 5614 } set_cbdata_t; 5615 5616 int 5617 set_callback(zpool_handle_t *zhp, void *data) 5618 { 5619 int error; 5620 set_cbdata_t *cb = (set_cbdata_t *)data; 5621 5622 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 5623 5624 if (!error) 5625 cb->cb_any_successful = B_TRUE; 5626 5627 return (error); 5628 } 5629 5630 int 5631 zpool_do_set(int argc, char **argv) 5632 { 5633 set_cbdata_t cb = { 0 }; 5634 int error; 5635 5636 if (argc > 1 && argv[1][0] == '-') { 5637 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5638 argv[1][1]); 5639 usage(B_FALSE); 5640 } 5641 5642 if (argc < 2) { 5643 (void) fprintf(stderr, gettext("missing property=value " 5644 "argument\n")); 5645 usage(B_FALSE); 5646 } 5647 5648 if (argc < 3) { 5649 (void) fprintf(stderr, gettext("missing pool name\n")); 5650 usage(B_FALSE); 5651 } 5652 5653 if (argc > 3) { 5654 (void) fprintf(stderr, gettext("too many pool names\n")); 5655 usage(B_FALSE); 5656 } 5657 5658 cb.cb_propname = argv[1]; 5659 cb.cb_value = strchr(cb.cb_propname, '='); 5660 if (cb.cb_value == NULL) { 5661 (void) fprintf(stderr, gettext("missing value in " 5662 "property=value argument\n")); 5663 usage(B_FALSE); 5664 } 5665 5666 *(cb.cb_value) = '\0'; 5667 cb.cb_value++; 5668 5669 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 5670 set_callback, &cb); 5671 5672 return (error); 5673 } 5674 5675 static int 5676 find_command_idx(char *command, int *idx) 5677 { 5678 int i; 5679 5680 for (i = 0; i < NCOMMAND; i++) { 5681 if (command_table[i].name == NULL) 5682 continue; 5683 5684 if (strcmp(command, command_table[i].name) == 0) { 5685 *idx = i; 5686 return (0); 5687 } 5688 } 5689 return (1); 5690 } 5691 5692 int 5693 main(int argc, char **argv) 5694 { 5695 int ret = 0; 5696 int i; 5697 char *cmdname; 5698 5699 (void) setlocale(LC_ALL, ""); 5700 (void) textdomain(TEXT_DOMAIN); 5701 5702 if ((g_zfs = libzfs_init()) == NULL) { 5703 (void) fprintf(stderr, gettext("internal error: failed to " 5704 "initialize ZFS library\n")); 5705 return (1); 5706 } 5707 5708 libzfs_print_on_error(g_zfs, B_TRUE); 5709 5710 opterr = 0; 5711 5712 /* 5713 * Make sure the user has specified some command. 5714 */ 5715 if (argc < 2) { 5716 (void) fprintf(stderr, gettext("missing command\n")); 5717 usage(B_FALSE); 5718 } 5719 5720 cmdname = argv[1]; 5721 5722 /* 5723 * Special case '-?' 5724 */ 5725 if (strcmp(cmdname, "-?") == 0) 5726 usage(B_TRUE); 5727 5728 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 5729 5730 /* 5731 * Run the appropriate command. 5732 */ 5733 if (find_command_idx(cmdname, &i) == 0) { 5734 current_command = &command_table[i]; 5735 ret = command_table[i].func(argc - 1, argv + 1); 5736 } else if (strchr(cmdname, '=')) { 5737 verify(find_command_idx("set", &i) == 0); 5738 current_command = &command_table[i]; 5739 ret = command_table[i].func(argc, argv); 5740 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 5741 /* 5742 * 'freeze' is a vile debugging abomination, so we treat 5743 * it as such. 5744 */ 5745 char buf[16384]; 5746 int fd = open(ZFS_DEV, O_RDWR); 5747 (void) strcpy((void *)buf, argv[2]); 5748 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 5749 } else { 5750 (void) fprintf(stderr, gettext("unrecognized " 5751 "command '%s'\n"), cmdname); 5752 usage(B_FALSE); 5753 } 5754 5755 if (ret == 0 && log_history) 5756 (void) zpool_log_history(g_zfs, history_str); 5757 5758 libzfs_fini(g_zfs); 5759 5760 /* 5761 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 5762 * for the purposes of running ::findleaks. 5763 */ 5764 if (getenv("ZFS_ABORT") != NULL) { 5765 (void) printf("dumping core by request\n"); 5766 abort(); 5767 } 5768 5769 return (ret); 5770 } 5771