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_RESILVERING: 3122 (void) printf(gettext("status: One or more devices is " 3123 "currently being resilvered. The pool will\n\tcontinue " 3124 "to function, possibly in a degraded state.\n")); 3125 (void) printf(gettext("action: Wait for the resilver to " 3126 "complete.\n")); 3127 break; 3128 3129 case ZPOOL_STATUS_CORRUPT_DATA: 3130 (void) printf(gettext("status: One or more devices has " 3131 "experienced an error resulting in data\n\tcorruption. " 3132 "Applications may be affected.\n")); 3133 (void) printf(gettext("action: Restore the file in question " 3134 "if possible. Otherwise restore the\n\tentire pool from " 3135 "backup.\n")); 3136 break; 3137 3138 case ZPOOL_STATUS_CORRUPT_POOL: 3139 (void) printf(gettext("status: The pool metadata is corrupted " 3140 "and the pool cannot be opened.\n")); 3141 (void) printf(gettext("action: Destroy and re-create the pool " 3142 "from a backup source.\n")); 3143 break; 3144 3145 case ZPOOL_STATUS_VERSION_OLDER: 3146 (void) printf(gettext("status: The pool is formatted using an " 3147 "older on-disk format. The pool can\n\tstill be used, but " 3148 "some features are unavailable.\n")); 3149 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3150 "upgrade'. Once this is done, the\n\tpool will no longer " 3151 "be accessible on older software versions.\n")); 3152 break; 3153 3154 case ZPOOL_STATUS_VERSION_NEWER: 3155 (void) printf(gettext("status: The pool has been upgraded to a " 3156 "newer, incompatible on-disk version.\n\tThe pool cannot " 3157 "be accessed on this system.\n")); 3158 (void) printf(gettext("action: Access the pool from a system " 3159 "running more recent software, or\n\trestore the pool from " 3160 "backup.\n")); 3161 break; 3162 3163 case ZPOOL_STATUS_FAULTED_DEV_R: 3164 (void) printf(gettext("status: One or more devices are " 3165 "faulted in response to persistent errors.\n\tSufficient " 3166 "replicas exist for the pool to continue functioning " 3167 "in a\n\tdegraded state.\n")); 3168 (void) printf(gettext("action: Replace the faulted device, " 3169 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3170 break; 3171 3172 case ZPOOL_STATUS_FAULTED_DEV_NR: 3173 (void) printf(gettext("status: One or more devices are " 3174 "faulted in response to persistent errors. There are " 3175 "insufficient replicas for the pool to\n\tcontinue " 3176 "functioning.\n")); 3177 (void) printf(gettext("action: Destroy and re-create the pool " 3178 "from a backup source. Manually marking the device\n" 3179 "\trepaired using 'zpool clear' may allow some data " 3180 "to be recovered.\n")); 3181 break; 3182 3183 case ZPOOL_STATUS_IO_FAILURE_WAIT: 3184 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 3185 (void) printf(gettext("status: One or more devices are " 3186 "faulted in response to IO failures.\n")); 3187 (void) printf(gettext("action: Make sure the affected devices " 3188 "are connected, then run 'zpool clear'.\n")); 3189 break; 3190 3191 case ZPOOL_STATUS_BAD_LOG: 3192 (void) printf(gettext("status: An intent log record " 3193 "could not be read.\n" 3194 "\tWaiting for adminstrator intervention to fix the " 3195 "faulted pool.\n")); 3196 (void) printf(gettext("action: Either restore the affected " 3197 "device(s) and run 'zpool online',\n" 3198 "\tor ignore the intent log records by running " 3199 "'zpool clear'.\n")); 3200 break; 3201 3202 default: 3203 /* 3204 * The remaining errors can't actually be generated, yet. 3205 */ 3206 assert(reason == ZPOOL_STATUS_OK); 3207 } 3208 3209 if (msgid != NULL) 3210 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3211 msgid); 3212 3213 if (config != NULL) { 3214 int namewidth; 3215 uint64_t nerr; 3216 nvlist_t **spares, **l2cache; 3217 uint_t nspares, nl2cache; 3218 3219 3220 (void) printf(gettext(" scrub: ")); 3221 print_scrub_status(nvroot); 3222 3223 namewidth = max_width(zhp, nvroot, 0, 0); 3224 if (namewidth < 10) 3225 namewidth = 10; 3226 3227 (void) printf(gettext("config:\n\n")); 3228 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3229 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3230 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3231 namewidth, 0, B_FALSE); 3232 3233 if (num_logs(nvroot) > 0) 3234 print_logs(zhp, nvroot, namewidth, B_TRUE); 3235 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3236 &l2cache, &nl2cache) == 0) 3237 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3238 3239 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3240 &spares, &nspares) == 0) 3241 print_spares(zhp, spares, nspares, namewidth); 3242 3243 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3244 &nerr) == 0) { 3245 nvlist_t *nverrlist = NULL; 3246 3247 /* 3248 * If the approximate error count is small, get a 3249 * precise count by fetching the entire log and 3250 * uniquifying the results. 3251 */ 3252 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3253 zpool_get_errlog(zhp, &nverrlist) == 0) { 3254 nvpair_t *elem; 3255 3256 elem = NULL; 3257 nerr = 0; 3258 while ((elem = nvlist_next_nvpair(nverrlist, 3259 elem)) != NULL) { 3260 nerr++; 3261 } 3262 } 3263 nvlist_free(nverrlist); 3264 3265 (void) printf("\n"); 3266 3267 if (nerr == 0) 3268 (void) printf(gettext("errors: No known data " 3269 "errors\n")); 3270 else if (!cbp->cb_verbose) 3271 (void) printf(gettext("errors: %llu data " 3272 "errors, use '-v' for a list\n"), 3273 (u_longlong_t)nerr); 3274 else 3275 print_error_log(zhp); 3276 } 3277 } else { 3278 (void) printf(gettext("config: The configuration cannot be " 3279 "determined.\n")); 3280 } 3281 3282 return (0); 3283 } 3284 3285 /* 3286 * zpool status [-vx] [pool] ... 3287 * 3288 * -v Display complete error logs 3289 * -x Display only pools with potential problems 3290 * 3291 * Describes the health status of all pools or some subset. 3292 */ 3293 int 3294 zpool_do_status(int argc, char **argv) 3295 { 3296 int c; 3297 int ret; 3298 status_cbdata_t cb = { 0 }; 3299 3300 /* check options */ 3301 while ((c = getopt(argc, argv, "vx")) != -1) { 3302 switch (c) { 3303 case 'v': 3304 cb.cb_verbose = B_TRUE; 3305 break; 3306 case 'x': 3307 cb.cb_explain = B_TRUE; 3308 break; 3309 case '?': 3310 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3311 optopt); 3312 usage(B_FALSE); 3313 } 3314 } 3315 3316 argc -= optind; 3317 argv += optind; 3318 3319 cb.cb_first = B_TRUE; 3320 3321 if (argc == 0) 3322 cb.cb_allpools = B_TRUE; 3323 3324 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3325 3326 if (argc == 0 && cb.cb_count == 0) 3327 (void) printf(gettext("no pools available\n")); 3328 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3329 (void) printf(gettext("all pools are healthy\n")); 3330 3331 return (ret); 3332 } 3333 3334 typedef struct upgrade_cbdata { 3335 int cb_all; 3336 int cb_first; 3337 int cb_newer; 3338 int cb_argc; 3339 uint64_t cb_version; 3340 char **cb_argv; 3341 } upgrade_cbdata_t; 3342 3343 static int 3344 upgrade_cb(zpool_handle_t *zhp, void *arg) 3345 { 3346 upgrade_cbdata_t *cbp = arg; 3347 nvlist_t *config; 3348 uint64_t version; 3349 int ret = 0; 3350 3351 config = zpool_get_config(zhp, NULL); 3352 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3353 &version) == 0); 3354 3355 if (!cbp->cb_newer && version < SPA_VERSION) { 3356 if (!cbp->cb_all) { 3357 if (cbp->cb_first) { 3358 (void) printf(gettext("The following pools are " 3359 "out of date, and can be upgraded. After " 3360 "being\nupgraded, these pools will no " 3361 "longer be accessible by older software " 3362 "versions.\n\n")); 3363 (void) printf(gettext("VER POOL\n")); 3364 (void) printf(gettext("--- ------------\n")); 3365 cbp->cb_first = B_FALSE; 3366 } 3367 3368 (void) printf("%2llu %s\n", (u_longlong_t)version, 3369 zpool_get_name(zhp)); 3370 } else { 3371 cbp->cb_first = B_FALSE; 3372 ret = zpool_upgrade(zhp, cbp->cb_version); 3373 if (!ret) { 3374 (void) printf(gettext("Successfully upgraded " 3375 "'%s'\n\n"), zpool_get_name(zhp)); 3376 } 3377 } 3378 } else if (cbp->cb_newer && version > SPA_VERSION) { 3379 assert(!cbp->cb_all); 3380 3381 if (cbp->cb_first) { 3382 (void) printf(gettext("The following pools are " 3383 "formatted using a newer software version and\n" 3384 "cannot be accessed on the current system.\n\n")); 3385 (void) printf(gettext("VER POOL\n")); 3386 (void) printf(gettext("--- ------------\n")); 3387 cbp->cb_first = B_FALSE; 3388 } 3389 3390 (void) printf("%2llu %s\n", (u_longlong_t)version, 3391 zpool_get_name(zhp)); 3392 } 3393 3394 zpool_close(zhp); 3395 return (ret); 3396 } 3397 3398 /* ARGSUSED */ 3399 static int 3400 upgrade_one(zpool_handle_t *zhp, void *data) 3401 { 3402 upgrade_cbdata_t *cbp = data; 3403 uint64_t cur_version; 3404 int ret; 3405 3406 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3407 (void) printf(gettext("'log' is now a reserved word\n" 3408 "Pool 'log' must be renamed using export and import" 3409 " to upgrade.\n")); 3410 return (1); 3411 } 3412 3413 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3414 if (cur_version > cbp->cb_version) { 3415 (void) printf(gettext("Pool '%s' is already formatted " 3416 "using more current version '%llu'.\n"), 3417 zpool_get_name(zhp), cur_version); 3418 return (0); 3419 } 3420 if (cur_version == cbp->cb_version) { 3421 (void) printf(gettext("Pool '%s' is already formatted " 3422 "using the current version.\n"), zpool_get_name(zhp)); 3423 return (0); 3424 } 3425 3426 ret = zpool_upgrade(zhp, cbp->cb_version); 3427 3428 if (!ret) { 3429 (void) printf(gettext("Successfully upgraded '%s' " 3430 "from version %llu to version %llu\n\n"), 3431 zpool_get_name(zhp), (u_longlong_t)cur_version, 3432 (u_longlong_t)cbp->cb_version); 3433 } 3434 3435 return (ret != 0); 3436 } 3437 3438 /* 3439 * zpool upgrade 3440 * zpool upgrade -v 3441 * zpool upgrade [-V version] <-a | pool ...> 3442 * 3443 * With no arguments, display downrev'd ZFS pool available for upgrade. 3444 * Individual pools can be upgraded by specifying the pool, and '-a' will 3445 * upgrade all pools. 3446 */ 3447 int 3448 zpool_do_upgrade(int argc, char **argv) 3449 { 3450 int c; 3451 upgrade_cbdata_t cb = { 0 }; 3452 int ret = 0; 3453 boolean_t showversions = B_FALSE; 3454 char *end; 3455 3456 3457 /* check options */ 3458 while ((c = getopt(argc, argv, ":avV:")) != -1) { 3459 switch (c) { 3460 case 'a': 3461 cb.cb_all = B_TRUE; 3462 break; 3463 case 'v': 3464 showversions = B_TRUE; 3465 break; 3466 case 'V': 3467 cb.cb_version = strtoll(optarg, &end, 10); 3468 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3469 cb.cb_version < SPA_VERSION_1) { 3470 (void) fprintf(stderr, 3471 gettext("invalid version '%s'\n"), optarg); 3472 usage(B_FALSE); 3473 } 3474 break; 3475 case ':': 3476 (void) fprintf(stderr, gettext("missing argument for " 3477 "'%c' option\n"), optopt); 3478 usage(B_FALSE); 3479 break; 3480 case '?': 3481 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3482 optopt); 3483 usage(B_FALSE); 3484 } 3485 } 3486 3487 cb.cb_argc = argc; 3488 cb.cb_argv = argv; 3489 argc -= optind; 3490 argv += optind; 3491 3492 if (cb.cb_version == 0) { 3493 cb.cb_version = SPA_VERSION; 3494 } else if (!cb.cb_all && argc == 0) { 3495 (void) fprintf(stderr, gettext("-V option is " 3496 "incompatible with other arguments\n")); 3497 usage(B_FALSE); 3498 } 3499 3500 if (showversions) { 3501 if (cb.cb_all || argc != 0) { 3502 (void) fprintf(stderr, gettext("-v option is " 3503 "incompatible with other arguments\n")); 3504 usage(B_FALSE); 3505 } 3506 } else if (cb.cb_all) { 3507 if (argc != 0) { 3508 (void) fprintf(stderr, gettext("-a option should not " 3509 "be used along with a pool name\n")); 3510 usage(B_FALSE); 3511 } 3512 } 3513 3514 (void) printf(gettext("This system is currently running " 3515 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3516 cb.cb_first = B_TRUE; 3517 if (showversions) { 3518 (void) printf(gettext("The following versions are " 3519 "supported:\n\n")); 3520 (void) printf(gettext("VER DESCRIPTION\n")); 3521 (void) printf("--- -----------------------------------------" 3522 "---------------\n"); 3523 (void) printf(gettext(" 1 Initial ZFS version\n")); 3524 (void) printf(gettext(" 2 Ditto blocks " 3525 "(replicated metadata)\n")); 3526 (void) printf(gettext(" 3 Hot spares and double parity " 3527 "RAID-Z\n")); 3528 (void) printf(gettext(" 4 zpool history\n")); 3529 (void) printf(gettext(" 5 Compression using the gzip " 3530 "algorithm\n")); 3531 (void) printf(gettext(" 6 bootfs pool property\n")); 3532 (void) printf(gettext(" 7 Separate intent log devices\n")); 3533 (void) printf(gettext(" 8 Delegated administration\n")); 3534 (void) printf(gettext(" 9 refquota and refreservation " 3535 "properties\n")); 3536 (void) printf(gettext(" 10 Cache devices\n")); 3537 (void) printf(gettext(" 11 Improved scrub performance\n")); 3538 (void) printf(gettext(" 12 Snapshot properties\n")); 3539 (void) printf(gettext(" 13 snapused property\n")); 3540 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 3541 (void) printf(gettext(" 15 user/group space accounting\n")); 3542 (void) printf(gettext(" 16 stmf property support\n")); 3543 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 3544 (void) printf(gettext("For more information on a particular " 3545 "version, including supported releases, see:\n\n")); 3546 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3547 "version/N\n\n"); 3548 (void) printf(gettext("Where 'N' is the version number.\n")); 3549 } else if (argc == 0) { 3550 int notfound; 3551 3552 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3553 notfound = cb.cb_first; 3554 3555 if (!cb.cb_all && ret == 0) { 3556 if (!cb.cb_first) 3557 (void) printf("\n"); 3558 cb.cb_first = B_TRUE; 3559 cb.cb_newer = B_TRUE; 3560 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3561 if (!cb.cb_first) { 3562 notfound = B_FALSE; 3563 (void) printf("\n"); 3564 } 3565 } 3566 3567 if (ret == 0) { 3568 if (notfound) 3569 (void) printf(gettext("All pools are formatted " 3570 "using this version.\n")); 3571 else if (!cb.cb_all) 3572 (void) printf(gettext("Use 'zpool upgrade -v' " 3573 "for a list of available versions and " 3574 "their associated\nfeatures.\n")); 3575 } 3576 } else { 3577 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3578 upgrade_one, &cb); 3579 } 3580 3581 return (ret); 3582 } 3583 3584 typedef struct hist_cbdata { 3585 boolean_t first; 3586 int longfmt; 3587 int internal; 3588 } hist_cbdata_t; 3589 3590 char *hist_event_table[LOG_END] = { 3591 "invalid event", 3592 "pool create", 3593 "vdev add", 3594 "pool remove", 3595 "pool destroy", 3596 "pool export", 3597 "pool import", 3598 "vdev attach", 3599 "vdev replace", 3600 "vdev detach", 3601 "vdev online", 3602 "vdev offline", 3603 "vdev upgrade", 3604 "pool clear", 3605 "pool scrub", 3606 "pool property set", 3607 "create", 3608 "clone", 3609 "destroy", 3610 "destroy_begin_sync", 3611 "inherit", 3612 "property set", 3613 "quota set", 3614 "permission update", 3615 "permission remove", 3616 "permission who remove", 3617 "promote", 3618 "receive", 3619 "rename", 3620 "reservation set", 3621 "replay_inc_sync", 3622 "replay_full_sync", 3623 "rollback", 3624 "snapshot", 3625 "filesystem version upgrade", 3626 "refquota set", 3627 "refreservation set", 3628 "pool scrub done", 3629 }; 3630 3631 /* 3632 * Print out the command history for a specific pool. 3633 */ 3634 static int 3635 get_history_one(zpool_handle_t *zhp, void *data) 3636 { 3637 nvlist_t *nvhis; 3638 nvlist_t **records; 3639 uint_t numrecords; 3640 char *cmdstr; 3641 char *pathstr; 3642 uint64_t dst_time; 3643 time_t tsec; 3644 struct tm t; 3645 char tbuf[30]; 3646 int ret, i; 3647 uint64_t who; 3648 struct passwd *pwd; 3649 char *hostname; 3650 char *zonename; 3651 char internalstr[MAXPATHLEN]; 3652 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3653 uint64_t txg; 3654 uint64_t ievent; 3655 3656 cb->first = B_FALSE; 3657 3658 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3659 3660 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3661 return (ret); 3662 3663 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3664 &records, &numrecords) == 0); 3665 for (i = 0; i < numrecords; i++) { 3666 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3667 &dst_time) != 0) 3668 continue; 3669 3670 /* is it an internal event or a standard event? */ 3671 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3672 &cmdstr) != 0) { 3673 if (cb->internal == 0) 3674 continue; 3675 3676 if (nvlist_lookup_uint64(records[i], 3677 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3678 continue; 3679 verify(nvlist_lookup_uint64(records[i], 3680 ZPOOL_HIST_TXG, &txg) == 0); 3681 verify(nvlist_lookup_string(records[i], 3682 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3683 if (ievent >= LOG_END) 3684 continue; 3685 (void) snprintf(internalstr, 3686 sizeof (internalstr), 3687 "[internal %s txg:%lld] %s", 3688 hist_event_table[ievent], txg, 3689 pathstr); 3690 cmdstr = internalstr; 3691 } 3692 tsec = dst_time; 3693 (void) localtime_r(&tsec, &t); 3694 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3695 (void) printf("%s %s", tbuf, cmdstr); 3696 3697 if (!cb->longfmt) { 3698 (void) printf("\n"); 3699 continue; 3700 } 3701 (void) printf(" ["); 3702 if (nvlist_lookup_uint64(records[i], 3703 ZPOOL_HIST_WHO, &who) == 0) { 3704 pwd = getpwuid((uid_t)who); 3705 if (pwd) 3706 (void) printf("user %s on", 3707 pwd->pw_name); 3708 else 3709 (void) printf("user %d on", 3710 (int)who); 3711 } else { 3712 (void) printf(gettext("no info]\n")); 3713 continue; 3714 } 3715 if (nvlist_lookup_string(records[i], 3716 ZPOOL_HIST_HOST, &hostname) == 0) { 3717 (void) printf(" %s", hostname); 3718 } 3719 if (nvlist_lookup_string(records[i], 3720 ZPOOL_HIST_ZONE, &zonename) == 0) { 3721 (void) printf(":%s", zonename); 3722 } 3723 3724 (void) printf("]"); 3725 (void) printf("\n"); 3726 } 3727 (void) printf("\n"); 3728 nvlist_free(nvhis); 3729 3730 return (ret); 3731 } 3732 3733 /* 3734 * zpool history <pool> 3735 * 3736 * Displays the history of commands that modified pools. 3737 */ 3738 3739 3740 int 3741 zpool_do_history(int argc, char **argv) 3742 { 3743 hist_cbdata_t cbdata = { 0 }; 3744 int ret; 3745 int c; 3746 3747 cbdata.first = B_TRUE; 3748 /* check options */ 3749 while ((c = getopt(argc, argv, "li")) != -1) { 3750 switch (c) { 3751 case 'l': 3752 cbdata.longfmt = 1; 3753 break; 3754 case 'i': 3755 cbdata.internal = 1; 3756 break; 3757 case '?': 3758 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3759 optopt); 3760 usage(B_FALSE); 3761 } 3762 } 3763 argc -= optind; 3764 argv += optind; 3765 3766 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3767 &cbdata); 3768 3769 if (argc == 0 && cbdata.first == B_TRUE) { 3770 (void) printf(gettext("no pools available\n")); 3771 return (0); 3772 } 3773 3774 return (ret); 3775 } 3776 3777 static int 3778 get_callback(zpool_handle_t *zhp, void *data) 3779 { 3780 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3781 char value[MAXNAMELEN]; 3782 zprop_source_t srctype; 3783 zprop_list_t *pl; 3784 3785 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3786 3787 /* 3788 * Skip the special fake placeholder. This will also skip 3789 * over the name property when 'all' is specified. 3790 */ 3791 if (pl->pl_prop == ZPOOL_PROP_NAME && 3792 pl == cbp->cb_proplist) 3793 continue; 3794 3795 if (zpool_get_prop(zhp, pl->pl_prop, 3796 value, sizeof (value), &srctype) != 0) 3797 continue; 3798 3799 zprop_print_one_property(zpool_get_name(zhp), cbp, 3800 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3801 } 3802 return (0); 3803 } 3804 3805 int 3806 zpool_do_get(int argc, char **argv) 3807 { 3808 zprop_get_cbdata_t cb = { 0 }; 3809 zprop_list_t fake_name = { 0 }; 3810 int ret; 3811 3812 if (argc < 3) 3813 usage(B_FALSE); 3814 3815 cb.cb_first = B_TRUE; 3816 cb.cb_sources = ZPROP_SRC_ALL; 3817 cb.cb_columns[0] = GET_COL_NAME; 3818 cb.cb_columns[1] = GET_COL_PROPERTY; 3819 cb.cb_columns[2] = GET_COL_VALUE; 3820 cb.cb_columns[3] = GET_COL_SOURCE; 3821 cb.cb_type = ZFS_TYPE_POOL; 3822 3823 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3824 ZFS_TYPE_POOL) != 0) 3825 usage(B_FALSE); 3826 3827 if (cb.cb_proplist != NULL) { 3828 fake_name.pl_prop = ZPOOL_PROP_NAME; 3829 fake_name.pl_width = strlen(gettext("NAME")); 3830 fake_name.pl_next = cb.cb_proplist; 3831 cb.cb_proplist = &fake_name; 3832 } 3833 3834 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3835 get_callback, &cb); 3836 3837 if (cb.cb_proplist == &fake_name) 3838 zprop_free_list(fake_name.pl_next); 3839 else 3840 zprop_free_list(cb.cb_proplist); 3841 3842 return (ret); 3843 } 3844 3845 typedef struct set_cbdata { 3846 char *cb_propname; 3847 char *cb_value; 3848 boolean_t cb_any_successful; 3849 } set_cbdata_t; 3850 3851 int 3852 set_callback(zpool_handle_t *zhp, void *data) 3853 { 3854 int error; 3855 set_cbdata_t *cb = (set_cbdata_t *)data; 3856 3857 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3858 3859 if (!error) 3860 cb->cb_any_successful = B_TRUE; 3861 3862 return (error); 3863 } 3864 3865 int 3866 zpool_do_set(int argc, char **argv) 3867 { 3868 set_cbdata_t cb = { 0 }; 3869 int error; 3870 3871 if (argc > 1 && argv[1][0] == '-') { 3872 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3873 argv[1][1]); 3874 usage(B_FALSE); 3875 } 3876 3877 if (argc < 2) { 3878 (void) fprintf(stderr, gettext("missing property=value " 3879 "argument\n")); 3880 usage(B_FALSE); 3881 } 3882 3883 if (argc < 3) { 3884 (void) fprintf(stderr, gettext("missing pool name\n")); 3885 usage(B_FALSE); 3886 } 3887 3888 if (argc > 3) { 3889 (void) fprintf(stderr, gettext("too many pool names\n")); 3890 usage(B_FALSE); 3891 } 3892 3893 cb.cb_propname = argv[1]; 3894 cb.cb_value = strchr(cb.cb_propname, '='); 3895 if (cb.cb_value == NULL) { 3896 (void) fprintf(stderr, gettext("missing value in " 3897 "property=value argument\n")); 3898 usage(B_FALSE); 3899 } 3900 3901 *(cb.cb_value) = '\0'; 3902 cb.cb_value++; 3903 3904 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3905 set_callback, &cb); 3906 3907 return (error); 3908 } 3909 3910 static int 3911 find_command_idx(char *command, int *idx) 3912 { 3913 int i; 3914 3915 for (i = 0; i < NCOMMAND; i++) { 3916 if (command_table[i].name == NULL) 3917 continue; 3918 3919 if (strcmp(command, command_table[i].name) == 0) { 3920 *idx = i; 3921 return (0); 3922 } 3923 } 3924 return (1); 3925 } 3926 3927 int 3928 main(int argc, char **argv) 3929 { 3930 int ret; 3931 int i; 3932 char *cmdname; 3933 3934 (void) setlocale(LC_ALL, ""); 3935 (void) textdomain(TEXT_DOMAIN); 3936 3937 if ((g_zfs = libzfs_init()) == NULL) { 3938 (void) fprintf(stderr, gettext("internal error: failed to " 3939 "initialize ZFS library\n")); 3940 return (1); 3941 } 3942 3943 libzfs_print_on_error(g_zfs, B_TRUE); 3944 3945 opterr = 0; 3946 3947 /* 3948 * Make sure the user has specified some command. 3949 */ 3950 if (argc < 2) { 3951 (void) fprintf(stderr, gettext("missing command\n")); 3952 usage(B_FALSE); 3953 } 3954 3955 cmdname = argv[1]; 3956 3957 /* 3958 * Special case '-?' 3959 */ 3960 if (strcmp(cmdname, "-?") == 0) 3961 usage(B_TRUE); 3962 3963 zpool_set_history_str("zpool", argc, argv, history_str); 3964 verify(zpool_stage_history(g_zfs, history_str) == 0); 3965 3966 /* 3967 * Run the appropriate command. 3968 */ 3969 if (find_command_idx(cmdname, &i) == 0) { 3970 current_command = &command_table[i]; 3971 ret = command_table[i].func(argc - 1, argv + 1); 3972 } else if (strchr(cmdname, '=')) { 3973 verify(find_command_idx("set", &i) == 0); 3974 current_command = &command_table[i]; 3975 ret = command_table[i].func(argc, argv); 3976 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3977 /* 3978 * 'freeze' is a vile debugging abomination, so we treat 3979 * it as such. 3980 */ 3981 char buf[16384]; 3982 int fd = open(ZFS_DEV, O_RDWR); 3983 (void) strcpy((void *)buf, argv[2]); 3984 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3985 } else { 3986 (void) fprintf(stderr, gettext("unrecognized " 3987 "command '%s'\n"), cmdname); 3988 usage(B_FALSE); 3989 } 3990 3991 libzfs_fini(g_zfs); 3992 3993 /* 3994 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3995 * for the purposes of running ::findleaks. 3996 */ 3997 if (getenv("ZFS_ABORT") != NULL) { 3998 (void) printf("dumping core by request\n"); 3999 abort(); 4000 } 4001 4002 return (ret); 4003 } 4004