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