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