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