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 allowfaulted) 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, 1526 allowfaulted) != 0) 1527 return (1); 1528 1529 if (newname != NULL) 1530 name = (char *)newname; 1531 1532 verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL); 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. 1570 * 1571 * -a Import all pools found. 1572 * 1573 * -o Set property=value and/or temporary mount options (without '='). 1574 * 1575 * The import command scans for pools to import, and import pools based on pool 1576 * name and GUID. The pool can also be renamed as part of the import process. 1577 */ 1578 int 1579 zpool_do_import(int argc, char **argv) 1580 { 1581 char **searchdirs = NULL; 1582 int nsearch = 0; 1583 int c; 1584 int err; 1585 nvlist_t *pools = NULL; 1586 boolean_t do_all = B_FALSE; 1587 boolean_t do_destroyed = B_FALSE; 1588 char *mntopts = NULL; 1589 boolean_t do_force = B_FALSE; 1590 nvpair_t *elem; 1591 nvlist_t *config; 1592 uint64_t searchguid = 0; 1593 char *searchname = NULL; 1594 char *propval; 1595 nvlist_t *found_config; 1596 nvlist_t *props = NULL; 1597 boolean_t first; 1598 boolean_t allow_faulted = B_FALSE; 1599 uint64_t pool_state; 1600 char *cachefile = NULL; 1601 1602 /* check options */ 1603 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) { 1604 switch (c) { 1605 case 'a': 1606 do_all = B_TRUE; 1607 break; 1608 case 'c': 1609 cachefile = optarg; 1610 break; 1611 case 'd': 1612 if (searchdirs == NULL) { 1613 searchdirs = safe_malloc(sizeof (char *)); 1614 } else { 1615 char **tmp = safe_malloc((nsearch + 1) * 1616 sizeof (char *)); 1617 bcopy(searchdirs, tmp, nsearch * 1618 sizeof (char *)); 1619 free(searchdirs); 1620 searchdirs = tmp; 1621 } 1622 searchdirs[nsearch++] = optarg; 1623 break; 1624 case 'D': 1625 do_destroyed = B_TRUE; 1626 break; 1627 case 'f': 1628 do_force = B_TRUE; 1629 break; 1630 case 'F': 1631 allow_faulted = B_TRUE; 1632 break; 1633 case 'o': 1634 if ((propval = strchr(optarg, '=')) != NULL) { 1635 *propval = '\0'; 1636 propval++; 1637 if (add_prop_list(optarg, propval, 1638 &props, B_TRUE)) 1639 goto error; 1640 } else { 1641 mntopts = optarg; 1642 } 1643 break; 1644 case 'R': 1645 if (add_prop_list(zpool_prop_to_name( 1646 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1647 goto error; 1648 if (nvlist_lookup_string(props, 1649 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 1650 &propval) == 0) 1651 break; 1652 if (add_prop_list(zpool_prop_to_name( 1653 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1654 goto error; 1655 break; 1656 case ':': 1657 (void) fprintf(stderr, gettext("missing argument for " 1658 "'%c' option\n"), optopt); 1659 usage(B_FALSE); 1660 break; 1661 case '?': 1662 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1663 optopt); 1664 usage(B_FALSE); 1665 } 1666 } 1667 1668 argc -= optind; 1669 argv += optind; 1670 1671 if (cachefile && nsearch != 0) { 1672 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 1673 usage(B_FALSE); 1674 } 1675 1676 if (searchdirs == NULL) { 1677 searchdirs = safe_malloc(sizeof (char *)); 1678 searchdirs[0] = "/dev/dsk"; 1679 nsearch = 1; 1680 } 1681 1682 /* check argument count */ 1683 if (do_all) { 1684 if (argc != 0) { 1685 (void) fprintf(stderr, gettext("too many arguments\n")); 1686 usage(B_FALSE); 1687 } 1688 } else { 1689 if (argc > 2) { 1690 (void) fprintf(stderr, gettext("too many arguments\n")); 1691 usage(B_FALSE); 1692 } 1693 1694 /* 1695 * Check for the SYS_CONFIG privilege. We do this explicitly 1696 * here because otherwise any attempt to discover pools will 1697 * silently fail. 1698 */ 1699 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 1700 (void) fprintf(stderr, gettext("cannot " 1701 "discover pools: permission denied\n")); 1702 free(searchdirs); 1703 return (1); 1704 } 1705 } 1706 1707 /* 1708 * Depending on the arguments given, we do one of the following: 1709 * 1710 * <none> Iterate through all pools and display information about 1711 * each one. 1712 * 1713 * -a Iterate through all pools and try to import each one. 1714 * 1715 * <id> Find the pool that corresponds to the given GUID/pool 1716 * name and import that one. 1717 * 1718 * -D Above options applies only to destroyed pools. 1719 */ 1720 if (argc != 0) { 1721 char *endptr; 1722 1723 errno = 0; 1724 searchguid = strtoull(argv[0], &endptr, 10); 1725 if (errno != 0 || *endptr != '\0') 1726 searchname = argv[0]; 1727 found_config = NULL; 1728 } 1729 1730 if (cachefile) { 1731 pools = zpool_find_import_cached(g_zfs, cachefile, searchname, 1732 searchguid); 1733 } else if (searchname != NULL) { 1734 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs, 1735 searchname); 1736 } else { 1737 /* 1738 * It's OK to search by guid even if searchguid is 0. 1739 */ 1740 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs, 1741 searchguid); 1742 } 1743 1744 if (pools == NULL) { 1745 if (argc != 0) { 1746 (void) fprintf(stderr, gettext("cannot import '%s': " 1747 "no such pool available\n"), argv[0]); 1748 } 1749 free(searchdirs); 1750 return (1); 1751 } 1752 1753 /* 1754 * At this point we have a list of import candidate configs. Even if 1755 * we were searching by pool name or guid, we still need to 1756 * post-process the list to deal with pool state and possible 1757 * duplicate names. 1758 */ 1759 err = 0; 1760 elem = NULL; 1761 first = B_TRUE; 1762 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 1763 1764 verify(nvpair_value_nvlist(elem, &config) == 0); 1765 1766 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1767 &pool_state) == 0); 1768 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 1769 continue; 1770 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 1771 continue; 1772 1773 if (argc == 0) { 1774 if (first) 1775 first = B_FALSE; 1776 else if (!do_all) 1777 (void) printf("\n"); 1778 1779 if (do_all) 1780 err |= do_import(config, NULL, mntopts, 1781 do_force, props, allow_faulted); 1782 else 1783 show_import(config); 1784 } else if (searchname != NULL) { 1785 char *name; 1786 1787 /* 1788 * We are searching for a pool based on name. 1789 */ 1790 verify(nvlist_lookup_string(config, 1791 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 1792 1793 if (strcmp(name, searchname) == 0) { 1794 if (found_config != NULL) { 1795 (void) fprintf(stderr, gettext( 1796 "cannot import '%s': more than " 1797 "one matching pool\n"), searchname); 1798 (void) fprintf(stderr, gettext( 1799 "import by numeric ID instead\n")); 1800 err = B_TRUE; 1801 } 1802 found_config = config; 1803 } 1804 } else { 1805 uint64_t guid; 1806 1807 /* 1808 * Search for a pool by guid. 1809 */ 1810 verify(nvlist_lookup_uint64(config, 1811 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 1812 1813 if (guid == searchguid) 1814 found_config = config; 1815 } 1816 } 1817 1818 /* 1819 * If we were searching for a specific pool, verify that we found a 1820 * pool, and then do the import. 1821 */ 1822 if (argc != 0 && err == 0) { 1823 if (found_config == NULL) { 1824 (void) fprintf(stderr, gettext("cannot import '%s': " 1825 "no such pool available\n"), argv[0]); 1826 err = B_TRUE; 1827 } else { 1828 err |= do_import(found_config, argc == 1 ? NULL : 1829 argv[1], mntopts, do_force, props, allow_faulted); 1830 } 1831 } 1832 1833 /* 1834 * If we were just looking for pools, report an error if none were 1835 * found. 1836 */ 1837 if (argc == 0 && first) 1838 (void) fprintf(stderr, 1839 gettext("no pools available to import\n")); 1840 1841 error: 1842 nvlist_free(props); 1843 nvlist_free(pools); 1844 free(searchdirs); 1845 1846 return (err ? 1 : 0); 1847 } 1848 1849 typedef struct iostat_cbdata { 1850 zpool_list_t *cb_list; 1851 int cb_verbose; 1852 int cb_iteration; 1853 int cb_namewidth; 1854 } iostat_cbdata_t; 1855 1856 static void 1857 print_iostat_separator(iostat_cbdata_t *cb) 1858 { 1859 int i = 0; 1860 1861 for (i = 0; i < cb->cb_namewidth; i++) 1862 (void) printf("-"); 1863 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 1864 } 1865 1866 static void 1867 print_iostat_header(iostat_cbdata_t *cb) 1868 { 1869 (void) printf("%*s capacity operations bandwidth\n", 1870 cb->cb_namewidth, ""); 1871 (void) printf("%-*s used avail read write read write\n", 1872 cb->cb_namewidth, "pool"); 1873 print_iostat_separator(cb); 1874 } 1875 1876 /* 1877 * Display a single statistic. 1878 */ 1879 static void 1880 print_one_stat(uint64_t value) 1881 { 1882 char buf[64]; 1883 1884 zfs_nicenum(value, buf, sizeof (buf)); 1885 (void) printf(" %5s", buf); 1886 } 1887 1888 /* 1889 * Print out all the statistics for the given vdev. This can either be the 1890 * toplevel configuration, or called recursively. If 'name' is NULL, then this 1891 * is a verbose output, and we don't want to display the toplevel pool stats. 1892 */ 1893 void 1894 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 1895 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 1896 { 1897 nvlist_t **oldchild, **newchild; 1898 uint_t c, children; 1899 vdev_stat_t *oldvs, *newvs; 1900 vdev_stat_t zerovs = { 0 }; 1901 uint64_t tdelta; 1902 double scale; 1903 char *vname; 1904 1905 if (oldnv != NULL) { 1906 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS, 1907 (uint64_t **)&oldvs, &c) == 0); 1908 } else { 1909 oldvs = &zerovs; 1910 } 1911 1912 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS, 1913 (uint64_t **)&newvs, &c) == 0); 1914 1915 if (strlen(name) + depth > cb->cb_namewidth) 1916 (void) printf("%*s%s", depth, "", name); 1917 else 1918 (void) printf("%*s%s%*s", depth, "", name, 1919 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 1920 1921 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 1922 1923 if (tdelta == 0) 1924 scale = 1.0; 1925 else 1926 scale = (double)NANOSEC / tdelta; 1927 1928 /* only toplevel vdevs have capacity stats */ 1929 if (newvs->vs_space == 0) { 1930 (void) printf(" - -"); 1931 } else { 1932 print_one_stat(newvs->vs_alloc); 1933 print_one_stat(newvs->vs_space - newvs->vs_alloc); 1934 } 1935 1936 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 1937 oldvs->vs_ops[ZIO_TYPE_READ]))); 1938 1939 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 1940 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 1941 1942 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 1943 oldvs->vs_bytes[ZIO_TYPE_READ]))); 1944 1945 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 1946 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 1947 1948 (void) printf("\n"); 1949 1950 if (!cb->cb_verbose) 1951 return; 1952 1953 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 1954 &newchild, &children) != 0) 1955 return; 1956 1957 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 1958 &oldchild, &c) != 0) 1959 return; 1960 1961 for (c = 0; c < children; c++) { 1962 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1963 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1964 newchild[c], cb, depth + 2); 1965 free(vname); 1966 } 1967 1968 /* 1969 * Include level 2 ARC devices in iostat output 1970 */ 1971 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 1972 &newchild, &children) != 0) 1973 return; 1974 1975 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 1976 &oldchild, &c) != 0) 1977 return; 1978 1979 if (children > 0) { 1980 (void) printf("%-*s - - - - - " 1981 "-\n", cb->cb_namewidth, "cache"); 1982 for (c = 0; c < children; c++) { 1983 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1984 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1985 newchild[c], cb, depth + 2); 1986 free(vname); 1987 } 1988 } 1989 } 1990 1991 static int 1992 refresh_iostat(zpool_handle_t *zhp, void *data) 1993 { 1994 iostat_cbdata_t *cb = data; 1995 boolean_t missing; 1996 1997 /* 1998 * If the pool has disappeared, remove it from the list and continue. 1999 */ 2000 if (zpool_refresh_stats(zhp, &missing) != 0) 2001 return (-1); 2002 2003 if (missing) 2004 pool_list_remove(cb->cb_list, zhp); 2005 2006 return (0); 2007 } 2008 2009 /* 2010 * Callback to print out the iostats for the given pool. 2011 */ 2012 int 2013 print_iostat(zpool_handle_t *zhp, void *data) 2014 { 2015 iostat_cbdata_t *cb = data; 2016 nvlist_t *oldconfig, *newconfig; 2017 nvlist_t *oldnvroot, *newnvroot; 2018 2019 newconfig = zpool_get_config(zhp, &oldconfig); 2020 2021 if (cb->cb_iteration == 1) 2022 oldconfig = NULL; 2023 2024 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 2025 &newnvroot) == 0); 2026 2027 if (oldconfig == NULL) 2028 oldnvroot = NULL; 2029 else 2030 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 2031 &oldnvroot) == 0); 2032 2033 /* 2034 * Print out the statistics for the pool. 2035 */ 2036 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 2037 2038 if (cb->cb_verbose) 2039 print_iostat_separator(cb); 2040 2041 return (0); 2042 } 2043 2044 int 2045 get_namewidth(zpool_handle_t *zhp, void *data) 2046 { 2047 iostat_cbdata_t *cb = data; 2048 nvlist_t *config, *nvroot; 2049 2050 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 2051 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2052 &nvroot) == 0); 2053 if (!cb->cb_verbose) 2054 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 2055 else 2056 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); 2057 } 2058 2059 /* 2060 * The width must fall into the range [10,38]. The upper limit is the 2061 * maximum we can have and still fit in 80 columns. 2062 */ 2063 if (cb->cb_namewidth < 10) 2064 cb->cb_namewidth = 10; 2065 if (cb->cb_namewidth > 38) 2066 cb->cb_namewidth = 38; 2067 2068 return (0); 2069 } 2070 2071 /* 2072 * zpool iostat [-v] [pool] ... [interval [count]] 2073 * 2074 * -v Display statistics for individual vdevs 2075 * 2076 * This command can be tricky because we want to be able to deal with pool 2077 * creation/destruction as well as vdev configuration changes. The bulk of this 2078 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 2079 * on pool_list_update() to detect the addition of new pools. Configuration 2080 * changes are all handled within libzfs. 2081 */ 2082 int 2083 zpool_do_iostat(int argc, char **argv) 2084 { 2085 int c; 2086 int ret; 2087 int npools; 2088 unsigned long interval = 0, count = 0; 2089 zpool_list_t *list; 2090 boolean_t verbose = B_FALSE; 2091 iostat_cbdata_t cb; 2092 2093 /* check options */ 2094 while ((c = getopt(argc, argv, "v")) != -1) { 2095 switch (c) { 2096 case 'v': 2097 verbose = B_TRUE; 2098 break; 2099 case '?': 2100 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2101 optopt); 2102 usage(B_FALSE); 2103 } 2104 } 2105 2106 argc -= optind; 2107 argv += optind; 2108 2109 /* 2110 * Determine if the last argument is an integer or a pool name 2111 */ 2112 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2113 char *end; 2114 2115 errno = 0; 2116 interval = strtoul(argv[argc - 1], &end, 10); 2117 2118 if (*end == '\0' && errno == 0) { 2119 if (interval == 0) { 2120 (void) fprintf(stderr, gettext("interval " 2121 "cannot be zero\n")); 2122 usage(B_FALSE); 2123 } 2124 2125 /* 2126 * Ignore the last parameter 2127 */ 2128 argc--; 2129 } else { 2130 /* 2131 * If this is not a valid number, just plow on. The 2132 * user will get a more informative error message later 2133 * on. 2134 */ 2135 interval = 0; 2136 } 2137 } 2138 2139 /* 2140 * If the last argument is also an integer, then we have both a count 2141 * and an integer. 2142 */ 2143 if (argc > 0 && isdigit(argv[argc - 1][0])) { 2144 char *end; 2145 2146 errno = 0; 2147 count = interval; 2148 interval = strtoul(argv[argc - 1], &end, 10); 2149 2150 if (*end == '\0' && errno == 0) { 2151 if (interval == 0) { 2152 (void) fprintf(stderr, gettext("interval " 2153 "cannot be zero\n")); 2154 usage(B_FALSE); 2155 } 2156 2157 /* 2158 * Ignore the last parameter 2159 */ 2160 argc--; 2161 } else { 2162 interval = 0; 2163 } 2164 } 2165 2166 /* 2167 * Construct the list of all interesting pools. 2168 */ 2169 ret = 0; 2170 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 2171 return (1); 2172 2173 if (pool_list_count(list) == 0 && argc != 0) { 2174 pool_list_free(list); 2175 return (1); 2176 } 2177 2178 if (pool_list_count(list) == 0 && interval == 0) { 2179 pool_list_free(list); 2180 (void) fprintf(stderr, gettext("no pools available\n")); 2181 return (1); 2182 } 2183 2184 /* 2185 * Enter the main iostat loop. 2186 */ 2187 cb.cb_list = list; 2188 cb.cb_verbose = verbose; 2189 cb.cb_iteration = 0; 2190 cb.cb_namewidth = 0; 2191 2192 for (;;) { 2193 pool_list_update(list); 2194 2195 if ((npools = pool_list_count(list)) == 0) 2196 break; 2197 2198 /* 2199 * Refresh all statistics. This is done as an explicit step 2200 * before calculating the maximum name width, so that any 2201 * configuration changes are properly accounted for. 2202 */ 2203 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 2204 2205 /* 2206 * Iterate over all pools to determine the maximum width 2207 * for the pool / device name column across all pools. 2208 */ 2209 cb.cb_namewidth = 0; 2210 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2211 2212 /* 2213 * If it's the first time, or verbose mode, print the header. 2214 */ 2215 if (++cb.cb_iteration == 1 || verbose) 2216 print_iostat_header(&cb); 2217 2218 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2219 2220 /* 2221 * If there's more than one pool, and we're not in verbose mode 2222 * (which prints a separator for us), then print a separator. 2223 */ 2224 if (npools > 1 && !verbose) 2225 print_iostat_separator(&cb); 2226 2227 if (verbose) 2228 (void) printf("\n"); 2229 2230 /* 2231 * Flush the output so that redirection to a file isn't buffered 2232 * indefinitely. 2233 */ 2234 (void) fflush(stdout); 2235 2236 if (interval == 0) 2237 break; 2238 2239 if (count != 0 && --count == 0) 2240 break; 2241 2242 (void) sleep(interval); 2243 } 2244 2245 pool_list_free(list); 2246 2247 return (ret); 2248 } 2249 2250 typedef struct list_cbdata { 2251 boolean_t cb_scripted; 2252 boolean_t cb_first; 2253 zprop_list_t *cb_proplist; 2254 } list_cbdata_t; 2255 2256 /* 2257 * Given a list of columns to display, output appropriate headers for each one. 2258 */ 2259 static void 2260 print_header(zprop_list_t *pl) 2261 { 2262 const char *header; 2263 boolean_t first = B_TRUE; 2264 boolean_t right_justify; 2265 2266 for (; pl != NULL; pl = pl->pl_next) { 2267 if (pl->pl_prop == ZPROP_INVAL) 2268 continue; 2269 2270 if (!first) 2271 (void) printf(" "); 2272 else 2273 first = B_FALSE; 2274 2275 header = zpool_prop_column_name(pl->pl_prop); 2276 right_justify = zpool_prop_align_right(pl->pl_prop); 2277 2278 if (pl->pl_next == NULL && !right_justify) 2279 (void) printf("%s", header); 2280 else if (right_justify) 2281 (void) printf("%*s", pl->pl_width, header); 2282 else 2283 (void) printf("%-*s", pl->pl_width, header); 2284 } 2285 2286 (void) printf("\n"); 2287 } 2288 2289 /* 2290 * Given a pool and a list of properties, print out all the properties according 2291 * to the described layout. 2292 */ 2293 static void 2294 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted) 2295 { 2296 boolean_t first = B_TRUE; 2297 char property[ZPOOL_MAXPROPLEN]; 2298 char *propstr; 2299 boolean_t right_justify; 2300 int width; 2301 2302 for (; pl != NULL; pl = pl->pl_next) { 2303 if (!first) { 2304 if (scripted) 2305 (void) printf("\t"); 2306 else 2307 (void) printf(" "); 2308 } else { 2309 first = B_FALSE; 2310 } 2311 2312 right_justify = B_FALSE; 2313 if (pl->pl_prop != ZPROP_INVAL) { 2314 if (zpool_get_prop(zhp, pl->pl_prop, property, 2315 sizeof (property), NULL) != 0) 2316 propstr = "-"; 2317 else 2318 propstr = property; 2319 2320 right_justify = zpool_prop_align_right(pl->pl_prop); 2321 } else { 2322 propstr = "-"; 2323 } 2324 2325 width = pl->pl_width; 2326 2327 /* 2328 * If this is being called in scripted mode, or if this is the 2329 * last column and it is left-justified, don't include a width 2330 * format specifier. 2331 */ 2332 if (scripted || (pl->pl_next == NULL && !right_justify)) 2333 (void) printf("%s", propstr); 2334 else if (right_justify) 2335 (void) printf("%*s", width, propstr); 2336 else 2337 (void) printf("%-*s", width, propstr); 2338 } 2339 2340 (void) printf("\n"); 2341 } 2342 2343 /* 2344 * Generic callback function to list a pool. 2345 */ 2346 int 2347 list_callback(zpool_handle_t *zhp, void *data) 2348 { 2349 list_cbdata_t *cbp = data; 2350 2351 if (cbp->cb_first) { 2352 if (!cbp->cb_scripted) 2353 print_header(cbp->cb_proplist); 2354 cbp->cb_first = B_FALSE; 2355 } 2356 2357 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted); 2358 2359 return (0); 2360 } 2361 2362 /* 2363 * zpool list [-H] [-o prop[,prop]*] [pool] ... 2364 * 2365 * -H Scripted mode. Don't display headers, and separate properties 2366 * by a single tab. 2367 * -o List of properties to display. Defaults to 2368 * "name,size,used,available,capacity,health,altroot" 2369 * 2370 * List all pools in the system, whether or not they're healthy. Output space 2371 * statistics for each one, as well as health status summary. 2372 */ 2373 int 2374 zpool_do_list(int argc, char **argv) 2375 { 2376 int c; 2377 int ret; 2378 list_cbdata_t cb = { 0 }; 2379 static char default_props[] = 2380 "name,size,used,available,capacity,health,altroot"; 2381 char *props = default_props; 2382 2383 /* check options */ 2384 while ((c = getopt(argc, argv, ":Ho:")) != -1) { 2385 switch (c) { 2386 case 'H': 2387 cb.cb_scripted = B_TRUE; 2388 break; 2389 case 'o': 2390 props = optarg; 2391 break; 2392 case ':': 2393 (void) fprintf(stderr, gettext("missing argument for " 2394 "'%c' option\n"), optopt); 2395 usage(B_FALSE); 2396 break; 2397 case '?': 2398 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2399 optopt); 2400 usage(B_FALSE); 2401 } 2402 } 2403 2404 argc -= optind; 2405 argv += optind; 2406 2407 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 2408 usage(B_FALSE); 2409 2410 cb.cb_first = B_TRUE; 2411 2412 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 2413 list_callback, &cb); 2414 2415 zprop_free_list(cb.cb_proplist); 2416 2417 if (argc == 0 && cb.cb_first && !cb.cb_scripted) { 2418 (void) printf(gettext("no pools available\n")); 2419 return (0); 2420 } 2421 2422 return (ret); 2423 } 2424 2425 static nvlist_t * 2426 zpool_get_vdev_by_name(nvlist_t *nv, char *name) 2427 { 2428 nvlist_t **child; 2429 uint_t c, children; 2430 nvlist_t *match; 2431 char *path; 2432 2433 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2434 &child, &children) != 0) { 2435 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2436 if (strncmp(name, "/dev/dsk/", 9) == 0) 2437 name += 9; 2438 if (strncmp(path, "/dev/dsk/", 9) == 0) 2439 path += 9; 2440 if (strcmp(name, path) == 0) 2441 return (nv); 2442 return (NULL); 2443 } 2444 2445 for (c = 0; c < children; c++) 2446 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 2447 return (match); 2448 2449 return (NULL); 2450 } 2451 2452 static int 2453 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 2454 { 2455 boolean_t force = B_FALSE; 2456 int c; 2457 nvlist_t *nvroot; 2458 char *poolname, *old_disk, *new_disk; 2459 zpool_handle_t *zhp; 2460 int ret; 2461 2462 /* check options */ 2463 while ((c = getopt(argc, argv, "f")) != -1) { 2464 switch (c) { 2465 case 'f': 2466 force = B_TRUE; 2467 break; 2468 case '?': 2469 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2470 optopt); 2471 usage(B_FALSE); 2472 } 2473 } 2474 2475 argc -= optind; 2476 argv += optind; 2477 2478 /* get pool name and check number of arguments */ 2479 if (argc < 1) { 2480 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2481 usage(B_FALSE); 2482 } 2483 2484 poolname = argv[0]; 2485 2486 if (argc < 2) { 2487 (void) fprintf(stderr, 2488 gettext("missing <device> specification\n")); 2489 usage(B_FALSE); 2490 } 2491 2492 old_disk = argv[1]; 2493 2494 if (argc < 3) { 2495 if (!replacing) { 2496 (void) fprintf(stderr, 2497 gettext("missing <new_device> specification\n")); 2498 usage(B_FALSE); 2499 } 2500 new_disk = old_disk; 2501 argc -= 1; 2502 argv += 1; 2503 } else { 2504 new_disk = argv[2]; 2505 argc -= 2; 2506 argv += 2; 2507 } 2508 2509 if (argc > 1) { 2510 (void) fprintf(stderr, gettext("too many arguments\n")); 2511 usage(B_FALSE); 2512 } 2513 2514 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2515 return (1); 2516 2517 if (zpool_get_config(zhp, NULL) == NULL) { 2518 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2519 poolname); 2520 zpool_close(zhp); 2521 return (1); 2522 } 2523 2524 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 2525 argc, argv); 2526 if (nvroot == NULL) { 2527 zpool_close(zhp); 2528 return (1); 2529 } 2530 2531 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2532 2533 nvlist_free(nvroot); 2534 zpool_close(zhp); 2535 2536 return (ret); 2537 } 2538 2539 /* 2540 * zpool replace [-f] <pool> <device> <new_device> 2541 * 2542 * -f Force attach, even if <new_device> appears to be in use. 2543 * 2544 * Replace <device> with <new_device>. 2545 */ 2546 /* ARGSUSED */ 2547 int 2548 zpool_do_replace(int argc, char **argv) 2549 { 2550 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2551 } 2552 2553 /* 2554 * zpool attach [-f] <pool> <device> <new_device> 2555 * 2556 * -f Force attach, even if <new_device> appears to be in use. 2557 * 2558 * Attach <new_device> to the mirror containing <device>. If <device> is not 2559 * part of a mirror, then <device> will be transformed into a mirror of 2560 * <device> and <new_device>. In either case, <new_device> will begin life 2561 * with a DTL of [0, now], and will immediately begin to resilver itself. 2562 */ 2563 int 2564 zpool_do_attach(int argc, char **argv) 2565 { 2566 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2567 } 2568 2569 /* 2570 * zpool detach [-f] <pool> <device> 2571 * 2572 * -f Force detach of <device>, even if DTLs argue against it 2573 * (not supported yet) 2574 * 2575 * Detach a device from a mirror. The operation will be refused if <device> 2576 * is the last device in the mirror, or if the DTLs indicate that this device 2577 * has the only valid copy of some data. 2578 */ 2579 /* ARGSUSED */ 2580 int 2581 zpool_do_detach(int argc, char **argv) 2582 { 2583 int c; 2584 char *poolname, *path; 2585 zpool_handle_t *zhp; 2586 int ret; 2587 2588 /* check options */ 2589 while ((c = getopt(argc, argv, "f")) != -1) { 2590 switch (c) { 2591 case 'f': 2592 case '?': 2593 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2594 optopt); 2595 usage(B_FALSE); 2596 } 2597 } 2598 2599 argc -= optind; 2600 argv += optind; 2601 2602 /* get pool name and check number of arguments */ 2603 if (argc < 1) { 2604 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2605 usage(B_FALSE); 2606 } 2607 2608 if (argc < 2) { 2609 (void) fprintf(stderr, 2610 gettext("missing <device> specification\n")); 2611 usage(B_FALSE); 2612 } 2613 2614 poolname = argv[0]; 2615 path = argv[1]; 2616 2617 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2618 return (1); 2619 2620 ret = zpool_vdev_detach(zhp, path); 2621 2622 zpool_close(zhp); 2623 2624 return (ret); 2625 } 2626 2627 /* 2628 * zpool online <pool> <device> ... 2629 */ 2630 int 2631 zpool_do_online(int argc, char **argv) 2632 { 2633 int c, i; 2634 char *poolname; 2635 zpool_handle_t *zhp; 2636 int ret = 0; 2637 vdev_state_t newstate; 2638 int flags = 0; 2639 2640 /* check options */ 2641 while ((c = getopt(argc, argv, "et")) != -1) { 2642 switch (c) { 2643 case 'e': 2644 flags |= ZFS_ONLINE_EXPAND; 2645 break; 2646 case 't': 2647 case '?': 2648 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2649 optopt); 2650 usage(B_FALSE); 2651 } 2652 } 2653 2654 argc -= optind; 2655 argv += optind; 2656 2657 /* get pool name and check number of arguments */ 2658 if (argc < 1) { 2659 (void) fprintf(stderr, gettext("missing pool name\n")); 2660 usage(B_FALSE); 2661 } 2662 if (argc < 2) { 2663 (void) fprintf(stderr, gettext("missing device name\n")); 2664 usage(B_FALSE); 2665 } 2666 2667 poolname = argv[0]; 2668 2669 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2670 return (1); 2671 2672 for (i = 1; i < argc; i++) { 2673 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 2674 if (newstate != VDEV_STATE_HEALTHY) { 2675 (void) printf(gettext("warning: device '%s' " 2676 "onlined, but remains in faulted state\n"), 2677 argv[i]); 2678 if (newstate == VDEV_STATE_FAULTED) 2679 (void) printf(gettext("use 'zpool " 2680 "clear' to restore a faulted " 2681 "device\n")); 2682 else 2683 (void) printf(gettext("use 'zpool " 2684 "replace' to replace devices " 2685 "that are no longer present\n")); 2686 } 2687 } else { 2688 ret = 1; 2689 } 2690 } 2691 2692 zpool_close(zhp); 2693 2694 return (ret); 2695 } 2696 2697 /* 2698 * zpool offline [-ft] <pool> <device> ... 2699 * 2700 * -f Force the device into the offline state, even if doing 2701 * so would appear to compromise pool availability. 2702 * (not supported yet) 2703 * 2704 * -t Only take the device off-line temporarily. The offline 2705 * state will not be persistent across reboots. 2706 */ 2707 /* ARGSUSED */ 2708 int 2709 zpool_do_offline(int argc, char **argv) 2710 { 2711 int c, i; 2712 char *poolname; 2713 zpool_handle_t *zhp; 2714 int ret = 0; 2715 boolean_t istmp = B_FALSE; 2716 2717 /* check options */ 2718 while ((c = getopt(argc, argv, "ft")) != -1) { 2719 switch (c) { 2720 case 't': 2721 istmp = B_TRUE; 2722 break; 2723 case 'f': 2724 case '?': 2725 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2726 optopt); 2727 usage(B_FALSE); 2728 } 2729 } 2730 2731 argc -= optind; 2732 argv += optind; 2733 2734 /* get pool name and check number of arguments */ 2735 if (argc < 1) { 2736 (void) fprintf(stderr, gettext("missing pool name\n")); 2737 usage(B_FALSE); 2738 } 2739 if (argc < 2) { 2740 (void) fprintf(stderr, gettext("missing device name\n")); 2741 usage(B_FALSE); 2742 } 2743 2744 poolname = argv[0]; 2745 2746 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2747 return (1); 2748 2749 for (i = 1; i < argc; i++) { 2750 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 2751 ret = 1; 2752 } 2753 2754 zpool_close(zhp); 2755 2756 return (ret); 2757 } 2758 2759 /* 2760 * zpool clear <pool> [device] 2761 * 2762 * Clear all errors associated with a pool or a particular device. 2763 */ 2764 int 2765 zpool_do_clear(int argc, char **argv) 2766 { 2767 int ret = 0; 2768 zpool_handle_t *zhp; 2769 char *pool, *device; 2770 2771 if (argc < 2) { 2772 (void) fprintf(stderr, gettext("missing pool name\n")); 2773 usage(B_FALSE); 2774 } 2775 2776 if (argc > 3) { 2777 (void) fprintf(stderr, gettext("too many arguments\n")); 2778 usage(B_FALSE); 2779 } 2780 2781 pool = argv[1]; 2782 device = argc == 3 ? argv[2] : NULL; 2783 2784 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 2785 return (1); 2786 2787 if (zpool_clear(zhp, device) != 0) 2788 ret = 1; 2789 2790 zpool_close(zhp); 2791 2792 return (ret); 2793 } 2794 2795 typedef struct scrub_cbdata { 2796 int cb_type; 2797 int cb_argc; 2798 char **cb_argv; 2799 } scrub_cbdata_t; 2800 2801 int 2802 scrub_callback(zpool_handle_t *zhp, void *data) 2803 { 2804 scrub_cbdata_t *cb = data; 2805 int err; 2806 2807 /* 2808 * Ignore faulted pools. 2809 */ 2810 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2811 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2812 "currently unavailable\n"), zpool_get_name(zhp)); 2813 return (1); 2814 } 2815 2816 err = zpool_scrub(zhp, cb->cb_type); 2817 2818 return (err != 0); 2819 } 2820 2821 /* 2822 * zpool scrub [-s] <pool> ... 2823 * 2824 * -s Stop. Stops any in-progress scrub. 2825 */ 2826 int 2827 zpool_do_scrub(int argc, char **argv) 2828 { 2829 int c; 2830 scrub_cbdata_t cb; 2831 2832 cb.cb_type = POOL_SCRUB_EVERYTHING; 2833 2834 /* check options */ 2835 while ((c = getopt(argc, argv, "s")) != -1) { 2836 switch (c) { 2837 case 's': 2838 cb.cb_type = POOL_SCRUB_NONE; 2839 break; 2840 case '?': 2841 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2842 optopt); 2843 usage(B_FALSE); 2844 } 2845 } 2846 2847 cb.cb_argc = argc; 2848 cb.cb_argv = argv; 2849 argc -= optind; 2850 argv += optind; 2851 2852 if (argc < 1) { 2853 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2854 usage(B_FALSE); 2855 } 2856 2857 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 2858 } 2859 2860 typedef struct status_cbdata { 2861 int cb_count; 2862 boolean_t cb_allpools; 2863 boolean_t cb_verbose; 2864 boolean_t cb_explain; 2865 boolean_t cb_first; 2866 } status_cbdata_t; 2867 2868 /* 2869 * Print out detailed scrub status. 2870 */ 2871 void 2872 print_scrub_status(nvlist_t *nvroot) 2873 { 2874 vdev_stat_t *vs; 2875 uint_t vsc; 2876 time_t start, end, now; 2877 double fraction_done; 2878 uint64_t examined, total, minutes_left, minutes_taken; 2879 char *scrub_type; 2880 2881 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2882 (uint64_t **)&vs, &vsc) == 0); 2883 2884 /* 2885 * If there's never been a scrub, there's not much to say. 2886 */ 2887 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2888 (void) printf(gettext("none requested\n")); 2889 return; 2890 } 2891 2892 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2893 "resilver" : "scrub"; 2894 2895 start = vs->vs_scrub_start; 2896 end = vs->vs_scrub_end; 2897 now = time(NULL); 2898 examined = vs->vs_scrub_examined; 2899 total = vs->vs_alloc; 2900 2901 if (end != 0) { 2902 minutes_taken = (uint64_t)((end - start) / 60); 2903 2904 (void) printf(gettext("%s %s after %lluh%um with %llu errors " 2905 "on %s"), 2906 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2907 (u_longlong_t)(minutes_taken / 60), 2908 (uint_t)(minutes_taken % 60), 2909 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2910 return; 2911 } 2912 2913 if (examined == 0) 2914 examined = 1; 2915 if (examined > total) 2916 total = examined; 2917 2918 fraction_done = (double)examined / total; 2919 minutes_left = (uint64_t)((now - start) * 2920 (1 - fraction_done) / fraction_done / 60); 2921 minutes_taken = (uint64_t)((now - start) / 60); 2922 2923 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, " 2924 "%lluh%um to go\n"), 2925 scrub_type, (u_longlong_t)(minutes_taken / 60), 2926 (uint_t)(minutes_taken % 60), 100 * fraction_done, 2927 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2928 } 2929 2930 static void 2931 print_error_log(zpool_handle_t *zhp) 2932 { 2933 nvlist_t *nverrlist = NULL; 2934 nvpair_t *elem; 2935 char *pathname; 2936 size_t len = MAXPATHLEN * 2; 2937 2938 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2939 (void) printf("errors: List of errors unavailable " 2940 "(insufficient privileges)\n"); 2941 return; 2942 } 2943 2944 (void) printf("errors: Permanent errors have been " 2945 "detected in the following files:\n\n"); 2946 2947 pathname = safe_malloc(len); 2948 elem = NULL; 2949 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2950 nvlist_t *nv; 2951 uint64_t dsobj, obj; 2952 2953 verify(nvpair_value_nvlist(elem, &nv) == 0); 2954 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2955 &dsobj) == 0); 2956 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2957 &obj) == 0); 2958 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2959 (void) printf("%7s %s\n", "", pathname); 2960 } 2961 free(pathname); 2962 nvlist_free(nverrlist); 2963 } 2964 2965 static void 2966 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2967 int namewidth) 2968 { 2969 uint_t i; 2970 char *name; 2971 2972 if (nspares == 0) 2973 return; 2974 2975 (void) printf(gettext("\tspares\n")); 2976 2977 for (i = 0; i < nspares; i++) { 2978 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2979 print_status_config(zhp, name, spares[i], 2980 namewidth, 2, B_TRUE); 2981 free(name); 2982 } 2983 } 2984 2985 static void 2986 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 2987 int namewidth) 2988 { 2989 uint_t i; 2990 char *name; 2991 2992 if (nl2cache == 0) 2993 return; 2994 2995 (void) printf(gettext("\tcache\n")); 2996 2997 for (i = 0; i < nl2cache; i++) { 2998 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]); 2999 print_status_config(zhp, name, l2cache[i], 3000 namewidth, 2, B_FALSE); 3001 free(name); 3002 } 3003 } 3004 3005 /* 3006 * Display a summary of pool status. Displays a summary such as: 3007 * 3008 * pool: tank 3009 * status: DEGRADED 3010 * reason: One or more devices ... 3011 * see: http://www.sun.com/msg/ZFS-xxxx-01 3012 * config: 3013 * mirror DEGRADED 3014 * c1t0d0 OK 3015 * c2t0d0 UNAVAIL 3016 * 3017 * When given the '-v' option, we print out the complete config. If the '-e' 3018 * option is specified, then we print out error rate information as well. 3019 */ 3020 int 3021 status_callback(zpool_handle_t *zhp, void *data) 3022 { 3023 status_cbdata_t *cbp = data; 3024 nvlist_t *config, *nvroot; 3025 char *msgid; 3026 int reason; 3027 const char *health; 3028 uint_t c; 3029 vdev_stat_t *vs; 3030 3031 config = zpool_get_config(zhp, NULL); 3032 reason = zpool_get_status(zhp, &msgid); 3033 3034 cbp->cb_count++; 3035 3036 /* 3037 * If we were given 'zpool status -x', only report those pools with 3038 * problems. 3039 */ 3040 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 3041 if (!cbp->cb_allpools) { 3042 (void) printf(gettext("pool '%s' is healthy\n"), 3043 zpool_get_name(zhp)); 3044 if (cbp->cb_first) 3045 cbp->cb_first = B_FALSE; 3046 } 3047 return (0); 3048 } 3049 3050 if (cbp->cb_first) 3051 cbp->cb_first = B_FALSE; 3052 else 3053 (void) printf("\n"); 3054 3055 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3056 &nvroot) == 0); 3057 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 3058 (uint64_t **)&vs, &c) == 0); 3059 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 3060 3061 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 3062 (void) printf(gettext(" state: %s\n"), health); 3063 3064 switch (reason) { 3065 case ZPOOL_STATUS_MISSING_DEV_R: 3066 (void) printf(gettext("status: One or more devices could not " 3067 "be opened. Sufficient replicas exist for\n\tthe pool to " 3068 "continue functioning in a degraded state.\n")); 3069 (void) printf(gettext("action: Attach the missing device and " 3070 "online it using 'zpool online'.\n")); 3071 break; 3072 3073 case ZPOOL_STATUS_MISSING_DEV_NR: 3074 (void) printf(gettext("status: One or more devices could not " 3075 "be opened. There are insufficient\n\treplicas for the " 3076 "pool to continue functioning.\n")); 3077 (void) printf(gettext("action: Attach the missing device and " 3078 "online it using 'zpool online'.\n")); 3079 break; 3080 3081 case ZPOOL_STATUS_CORRUPT_LABEL_R: 3082 (void) printf(gettext("status: One or more devices could not " 3083 "be used because the label is missing or\n\tinvalid. " 3084 "Sufficient replicas exist for the pool to continue\n\t" 3085 "functioning in a degraded state.\n")); 3086 (void) printf(gettext("action: Replace the device using " 3087 "'zpool replace'.\n")); 3088 break; 3089 3090 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 3091 (void) printf(gettext("status: One or more devices could not " 3092 "be used because the label is missing \n\tor invalid. " 3093 "There are insufficient replicas for the pool to " 3094 "continue\n\tfunctioning.\n")); 3095 (void) printf(gettext("action: Destroy and re-create the pool " 3096 "from a backup source.\n")); 3097 break; 3098 3099 case ZPOOL_STATUS_FAILING_DEV: 3100 (void) printf(gettext("status: One or more devices has " 3101 "experienced an unrecoverable error. An\n\tattempt was " 3102 "made to correct the error. Applications are " 3103 "unaffected.\n")); 3104 (void) printf(gettext("action: Determine if the device needs " 3105 "to be replaced, and clear the errors\n\tusing " 3106 "'zpool clear' or replace the device with 'zpool " 3107 "replace'.\n")); 3108 break; 3109 3110 case ZPOOL_STATUS_OFFLINE_DEV: 3111 (void) printf(gettext("status: One or more devices has " 3112 "been taken offline by the administrator.\n\tSufficient " 3113 "replicas exist for the pool to continue functioning in " 3114 "a\n\tdegraded state.\n")); 3115 (void) printf(gettext("action: Online the device using " 3116 "'zpool online' or replace the device with\n\t'zpool " 3117 "replace'.\n")); 3118 break; 3119 3120 case ZPOOL_STATUS_RESILVERING: 3121 (void) printf(gettext("status: One or more devices is " 3122 "currently being resilvered. The pool will\n\tcontinue " 3123 "to function, possibly in a degraded state.\n")); 3124 (void) printf(gettext("action: Wait for the resilver to " 3125 "complete.\n")); 3126 break; 3127 3128 case ZPOOL_STATUS_CORRUPT_DATA: 3129 (void) printf(gettext("status: One or more devices has " 3130 "experienced an error resulting in data\n\tcorruption. " 3131 "Applications may be affected.\n")); 3132 (void) printf(gettext("action: Restore the file in question " 3133 "if possible. Otherwise restore the\n\tentire pool from " 3134 "backup.\n")); 3135 break; 3136 3137 case ZPOOL_STATUS_CORRUPT_POOL: 3138 (void) printf(gettext("status: The pool metadata is corrupted " 3139 "and the pool cannot be opened.\n")); 3140 (void) printf(gettext("action: Destroy and re-create the pool " 3141 "from a backup source.\n")); 3142 break; 3143 3144 case ZPOOL_STATUS_VERSION_OLDER: 3145 (void) printf(gettext("status: The pool is formatted using an " 3146 "older on-disk format. The pool can\n\tstill be used, but " 3147 "some features are unavailable.\n")); 3148 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3149 "upgrade'. Once this is done, the\n\tpool will no longer " 3150 "be accessible on older software versions.\n")); 3151 break; 3152 3153 case ZPOOL_STATUS_VERSION_NEWER: 3154 (void) printf(gettext("status: The pool has been upgraded to a " 3155 "newer, incompatible on-disk version.\n\tThe pool cannot " 3156 "be accessed on this system.\n")); 3157 (void) printf(gettext("action: Access the pool from a system " 3158 "running more recent software, or\n\trestore the pool from " 3159 "backup.\n")); 3160 break; 3161 3162 case ZPOOL_STATUS_FAULTED_DEV_R: 3163 (void) printf(gettext("status: One or more devices are " 3164 "faulted in response to persistent errors.\n\tSufficient " 3165 "replicas exist for the pool to continue functioning " 3166 "in a\n\tdegraded state.\n")); 3167 (void) printf(gettext("action: Replace the faulted device, " 3168 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3169 break; 3170 3171 case ZPOOL_STATUS_FAULTED_DEV_NR: 3172 (void) printf(gettext("status: One or more devices are " 3173 "faulted in response to persistent errors. There are " 3174 "insufficient replicas for the pool to\n\tcontinue " 3175 "functioning.\n")); 3176 (void) printf(gettext("action: Destroy and re-create the pool " 3177 "from a backup source. Manually marking the device\n" 3178 "\trepaired using 'zpool clear' may allow some data " 3179 "to be recovered.\n")); 3180 break; 3181 3182 case ZPOOL_STATUS_IO_FAILURE_WAIT: 3183 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 3184 (void) printf(gettext("status: One or more devices are " 3185 "faulted in response to IO failures.\n")); 3186 (void) printf(gettext("action: Make sure the affected devices " 3187 "are connected, then run 'zpool clear'.\n")); 3188 break; 3189 3190 case ZPOOL_STATUS_BAD_LOG: 3191 (void) printf(gettext("status: An intent log record " 3192 "could not be read.\n" 3193 "\tWaiting for adminstrator intervention to fix the " 3194 "faulted pool.\n")); 3195 (void) printf(gettext("action: Either restore the affected " 3196 "device(s) and run 'zpool online',\n" 3197 "\tor ignore the intent log records by running " 3198 "'zpool clear'.\n")); 3199 break; 3200 3201 default: 3202 /* 3203 * The remaining errors can't actually be generated, yet. 3204 */ 3205 assert(reason == ZPOOL_STATUS_OK); 3206 } 3207 3208 if (msgid != NULL) 3209 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3210 msgid); 3211 3212 if (config != NULL) { 3213 int namewidth; 3214 uint64_t nerr; 3215 nvlist_t **spares, **l2cache; 3216 uint_t nspares, nl2cache; 3217 3218 3219 (void) printf(gettext(" scrub: ")); 3220 print_scrub_status(nvroot); 3221 3222 namewidth = max_width(zhp, nvroot, 0, 0); 3223 if (namewidth < 10) 3224 namewidth = 10; 3225 3226 (void) printf(gettext("config:\n\n")); 3227 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3228 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3229 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3230 namewidth, 0, B_FALSE); 3231 3232 if (num_logs(nvroot) > 0) 3233 print_logs(zhp, nvroot, namewidth, B_TRUE); 3234 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3235 &l2cache, &nl2cache) == 0) 3236 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3237 3238 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3239 &spares, &nspares) == 0) 3240 print_spares(zhp, spares, nspares, namewidth); 3241 3242 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3243 &nerr) == 0) { 3244 nvlist_t *nverrlist = NULL; 3245 3246 /* 3247 * If the approximate error count is small, get a 3248 * precise count by fetching the entire log and 3249 * uniquifying the results. 3250 */ 3251 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3252 zpool_get_errlog(zhp, &nverrlist) == 0) { 3253 nvpair_t *elem; 3254 3255 elem = NULL; 3256 nerr = 0; 3257 while ((elem = nvlist_next_nvpair(nverrlist, 3258 elem)) != NULL) { 3259 nerr++; 3260 } 3261 } 3262 nvlist_free(nverrlist); 3263 3264 (void) printf("\n"); 3265 3266 if (nerr == 0) 3267 (void) printf(gettext("errors: No known data " 3268 "errors\n")); 3269 else if (!cbp->cb_verbose) 3270 (void) printf(gettext("errors: %llu data " 3271 "errors, use '-v' for a list\n"), 3272 (u_longlong_t)nerr); 3273 else 3274 print_error_log(zhp); 3275 } 3276 } else { 3277 (void) printf(gettext("config: The configuration cannot be " 3278 "determined.\n")); 3279 } 3280 3281 return (0); 3282 } 3283 3284 /* 3285 * zpool status [-vx] [pool] ... 3286 * 3287 * -v Display complete error logs 3288 * -x Display only pools with potential problems 3289 * 3290 * Describes the health status of all pools or some subset. 3291 */ 3292 int 3293 zpool_do_status(int argc, char **argv) 3294 { 3295 int c; 3296 int ret; 3297 status_cbdata_t cb = { 0 }; 3298 3299 /* check options */ 3300 while ((c = getopt(argc, argv, "vx")) != -1) { 3301 switch (c) { 3302 case 'v': 3303 cb.cb_verbose = B_TRUE; 3304 break; 3305 case 'x': 3306 cb.cb_explain = B_TRUE; 3307 break; 3308 case '?': 3309 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3310 optopt); 3311 usage(B_FALSE); 3312 } 3313 } 3314 3315 argc -= optind; 3316 argv += optind; 3317 3318 cb.cb_first = B_TRUE; 3319 3320 if (argc == 0) 3321 cb.cb_allpools = B_TRUE; 3322 3323 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3324 3325 if (argc == 0 && cb.cb_count == 0) 3326 (void) printf(gettext("no pools available\n")); 3327 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3328 (void) printf(gettext("all pools are healthy\n")); 3329 3330 return (ret); 3331 } 3332 3333 typedef struct upgrade_cbdata { 3334 int cb_all; 3335 int cb_first; 3336 int cb_newer; 3337 int cb_argc; 3338 uint64_t cb_version; 3339 char **cb_argv; 3340 } upgrade_cbdata_t; 3341 3342 static int 3343 upgrade_cb(zpool_handle_t *zhp, void *arg) 3344 { 3345 upgrade_cbdata_t *cbp = arg; 3346 nvlist_t *config; 3347 uint64_t version; 3348 int ret = 0; 3349 3350 config = zpool_get_config(zhp, NULL); 3351 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3352 &version) == 0); 3353 3354 if (!cbp->cb_newer && version < SPA_VERSION) { 3355 if (!cbp->cb_all) { 3356 if (cbp->cb_first) { 3357 (void) printf(gettext("The following pools are " 3358 "out of date, and can be upgraded. After " 3359 "being\nupgraded, these pools will no " 3360 "longer be accessible by older software " 3361 "versions.\n\n")); 3362 (void) printf(gettext("VER POOL\n")); 3363 (void) printf(gettext("--- ------------\n")); 3364 cbp->cb_first = B_FALSE; 3365 } 3366 3367 (void) printf("%2llu %s\n", (u_longlong_t)version, 3368 zpool_get_name(zhp)); 3369 } else { 3370 cbp->cb_first = B_FALSE; 3371 ret = zpool_upgrade(zhp, cbp->cb_version); 3372 if (!ret) { 3373 (void) printf(gettext("Successfully upgraded " 3374 "'%s'\n\n"), zpool_get_name(zhp)); 3375 } 3376 } 3377 } else if (cbp->cb_newer && version > SPA_VERSION) { 3378 assert(!cbp->cb_all); 3379 3380 if (cbp->cb_first) { 3381 (void) printf(gettext("The following pools are " 3382 "formatted using a newer software version and\n" 3383 "cannot be accessed on the current system.\n\n")); 3384 (void) printf(gettext("VER POOL\n")); 3385 (void) printf(gettext("--- ------------\n")); 3386 cbp->cb_first = B_FALSE; 3387 } 3388 3389 (void) printf("%2llu %s\n", (u_longlong_t)version, 3390 zpool_get_name(zhp)); 3391 } 3392 3393 zpool_close(zhp); 3394 return (ret); 3395 } 3396 3397 /* ARGSUSED */ 3398 static int 3399 upgrade_one(zpool_handle_t *zhp, void *data) 3400 { 3401 upgrade_cbdata_t *cbp = data; 3402 uint64_t cur_version; 3403 int ret; 3404 3405 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3406 (void) printf(gettext("'log' is now a reserved word\n" 3407 "Pool 'log' must be renamed using export and import" 3408 " to upgrade.\n")); 3409 return (1); 3410 } 3411 3412 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3413 if (cur_version > cbp->cb_version) { 3414 (void) printf(gettext("Pool '%s' is already formatted " 3415 "using more current version '%llu'.\n"), 3416 zpool_get_name(zhp), cur_version); 3417 return (0); 3418 } 3419 if (cur_version == cbp->cb_version) { 3420 (void) printf(gettext("Pool '%s' is already formatted " 3421 "using the current version.\n"), zpool_get_name(zhp)); 3422 return (0); 3423 } 3424 3425 ret = zpool_upgrade(zhp, cbp->cb_version); 3426 3427 if (!ret) { 3428 (void) printf(gettext("Successfully upgraded '%s' " 3429 "from version %llu to version %llu\n\n"), 3430 zpool_get_name(zhp), (u_longlong_t)cur_version, 3431 (u_longlong_t)cbp->cb_version); 3432 } 3433 3434 return (ret != 0); 3435 } 3436 3437 /* 3438 * zpool upgrade 3439 * zpool upgrade -v 3440 * zpool upgrade [-V version] <-a | pool ...> 3441 * 3442 * With no arguments, display downrev'd ZFS pool available for upgrade. 3443 * Individual pools can be upgraded by specifying the pool, and '-a' will 3444 * upgrade all pools. 3445 */ 3446 int 3447 zpool_do_upgrade(int argc, char **argv) 3448 { 3449 int c; 3450 upgrade_cbdata_t cb = { 0 }; 3451 int ret = 0; 3452 boolean_t showversions = B_FALSE; 3453 char *end; 3454 3455 3456 /* check options */ 3457 while ((c = getopt(argc, argv, ":avV:")) != -1) { 3458 switch (c) { 3459 case 'a': 3460 cb.cb_all = B_TRUE; 3461 break; 3462 case 'v': 3463 showversions = B_TRUE; 3464 break; 3465 case 'V': 3466 cb.cb_version = strtoll(optarg, &end, 10); 3467 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3468 cb.cb_version < SPA_VERSION_1) { 3469 (void) fprintf(stderr, 3470 gettext("invalid version '%s'\n"), optarg); 3471 usage(B_FALSE); 3472 } 3473 break; 3474 case ':': 3475 (void) fprintf(stderr, gettext("missing argument for " 3476 "'%c' option\n"), optopt); 3477 usage(B_FALSE); 3478 break; 3479 case '?': 3480 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3481 optopt); 3482 usage(B_FALSE); 3483 } 3484 } 3485 3486 cb.cb_argc = argc; 3487 cb.cb_argv = argv; 3488 argc -= optind; 3489 argv += optind; 3490 3491 if (cb.cb_version == 0) { 3492 cb.cb_version = SPA_VERSION; 3493 } else if (!cb.cb_all && argc == 0) { 3494 (void) fprintf(stderr, gettext("-V option is " 3495 "incompatible with other arguments\n")); 3496 usage(B_FALSE); 3497 } 3498 3499 if (showversions) { 3500 if (cb.cb_all || argc != 0) { 3501 (void) fprintf(stderr, gettext("-v option is " 3502 "incompatible with other arguments\n")); 3503 usage(B_FALSE); 3504 } 3505 } else if (cb.cb_all) { 3506 if (argc != 0) { 3507 (void) fprintf(stderr, gettext("-a option should not " 3508 "be used along with a pool name\n")); 3509 usage(B_FALSE); 3510 } 3511 } 3512 3513 (void) printf(gettext("This system is currently running " 3514 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3515 cb.cb_first = B_TRUE; 3516 if (showversions) { 3517 (void) printf(gettext("The following versions are " 3518 "supported:\n\n")); 3519 (void) printf(gettext("VER DESCRIPTION\n")); 3520 (void) printf("--- -----------------------------------------" 3521 "---------------\n"); 3522 (void) printf(gettext(" 1 Initial ZFS version\n")); 3523 (void) printf(gettext(" 2 Ditto blocks " 3524 "(replicated metadata)\n")); 3525 (void) printf(gettext(" 3 Hot spares and double parity " 3526 "RAID-Z\n")); 3527 (void) printf(gettext(" 4 zpool history\n")); 3528 (void) printf(gettext(" 5 Compression using the gzip " 3529 "algorithm\n")); 3530 (void) printf(gettext(" 6 bootfs pool property\n")); 3531 (void) printf(gettext(" 7 Separate intent log devices\n")); 3532 (void) printf(gettext(" 8 Delegated administration\n")); 3533 (void) printf(gettext(" 9 refquota and refreservation " 3534 "properties\n")); 3535 (void) printf(gettext(" 10 Cache devices\n")); 3536 (void) printf(gettext(" 11 Improved scrub performance\n")); 3537 (void) printf(gettext(" 12 Snapshot properties\n")); 3538 (void) printf(gettext(" 13 snapused property\n")); 3539 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 3540 (void) printf(gettext(" 15 user/group space accounting\n")); 3541 (void) printf(gettext(" 16 stmf property support\n")); 3542 (void) printf(gettext("For more information on a particular " 3543 "version, including supported releases, see:\n\n")); 3544 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3545 "version/N\n\n"); 3546 (void) printf(gettext("Where 'N' is the version number.\n")); 3547 } else if (argc == 0) { 3548 int notfound; 3549 3550 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3551 notfound = cb.cb_first; 3552 3553 if (!cb.cb_all && ret == 0) { 3554 if (!cb.cb_first) 3555 (void) printf("\n"); 3556 cb.cb_first = B_TRUE; 3557 cb.cb_newer = B_TRUE; 3558 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3559 if (!cb.cb_first) { 3560 notfound = B_FALSE; 3561 (void) printf("\n"); 3562 } 3563 } 3564 3565 if (ret == 0) { 3566 if (notfound) 3567 (void) printf(gettext("All pools are formatted " 3568 "using this version.\n")); 3569 else if (!cb.cb_all) 3570 (void) printf(gettext("Use 'zpool upgrade -v' " 3571 "for a list of available versions and " 3572 "their associated\nfeatures.\n")); 3573 } 3574 } else { 3575 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3576 upgrade_one, &cb); 3577 } 3578 3579 return (ret); 3580 } 3581 3582 typedef struct hist_cbdata { 3583 boolean_t first; 3584 int longfmt; 3585 int internal; 3586 } hist_cbdata_t; 3587 3588 char *hist_event_table[LOG_END] = { 3589 "invalid event", 3590 "pool create", 3591 "vdev add", 3592 "pool remove", 3593 "pool destroy", 3594 "pool export", 3595 "pool import", 3596 "vdev attach", 3597 "vdev replace", 3598 "vdev detach", 3599 "vdev online", 3600 "vdev offline", 3601 "vdev upgrade", 3602 "pool clear", 3603 "pool scrub", 3604 "pool property set", 3605 "create", 3606 "clone", 3607 "destroy", 3608 "destroy_begin_sync", 3609 "inherit", 3610 "property set", 3611 "quota set", 3612 "permission update", 3613 "permission remove", 3614 "permission who remove", 3615 "promote", 3616 "receive", 3617 "rename", 3618 "reservation set", 3619 "replay_inc_sync", 3620 "replay_full_sync", 3621 "rollback", 3622 "snapshot", 3623 "filesystem version upgrade", 3624 "refquota set", 3625 "refreservation set", 3626 "pool scrub done", 3627 }; 3628 3629 /* 3630 * Print out the command history for a specific pool. 3631 */ 3632 static int 3633 get_history_one(zpool_handle_t *zhp, void *data) 3634 { 3635 nvlist_t *nvhis; 3636 nvlist_t **records; 3637 uint_t numrecords; 3638 char *cmdstr; 3639 char *pathstr; 3640 uint64_t dst_time; 3641 time_t tsec; 3642 struct tm t; 3643 char tbuf[30]; 3644 int ret, i; 3645 uint64_t who; 3646 struct passwd *pwd; 3647 char *hostname; 3648 char *zonename; 3649 char internalstr[MAXPATHLEN]; 3650 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3651 uint64_t txg; 3652 uint64_t ievent; 3653 3654 cb->first = B_FALSE; 3655 3656 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3657 3658 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3659 return (ret); 3660 3661 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3662 &records, &numrecords) == 0); 3663 for (i = 0; i < numrecords; i++) { 3664 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3665 &dst_time) != 0) 3666 continue; 3667 3668 /* is it an internal event or a standard event? */ 3669 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3670 &cmdstr) != 0) { 3671 if (cb->internal == 0) 3672 continue; 3673 3674 if (nvlist_lookup_uint64(records[i], 3675 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3676 continue; 3677 verify(nvlist_lookup_uint64(records[i], 3678 ZPOOL_HIST_TXG, &txg) == 0); 3679 verify(nvlist_lookup_string(records[i], 3680 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3681 if (ievent >= LOG_END) 3682 continue; 3683 (void) snprintf(internalstr, 3684 sizeof (internalstr), 3685 "[internal %s txg:%lld] %s", 3686 hist_event_table[ievent], txg, 3687 pathstr); 3688 cmdstr = internalstr; 3689 } 3690 tsec = dst_time; 3691 (void) localtime_r(&tsec, &t); 3692 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3693 (void) printf("%s %s", tbuf, cmdstr); 3694 3695 if (!cb->longfmt) { 3696 (void) printf("\n"); 3697 continue; 3698 } 3699 (void) printf(" ["); 3700 if (nvlist_lookup_uint64(records[i], 3701 ZPOOL_HIST_WHO, &who) == 0) { 3702 pwd = getpwuid((uid_t)who); 3703 if (pwd) 3704 (void) printf("user %s on", 3705 pwd->pw_name); 3706 else 3707 (void) printf("user %d on", 3708 (int)who); 3709 } else { 3710 (void) printf(gettext("no info]\n")); 3711 continue; 3712 } 3713 if (nvlist_lookup_string(records[i], 3714 ZPOOL_HIST_HOST, &hostname) == 0) { 3715 (void) printf(" %s", hostname); 3716 } 3717 if (nvlist_lookup_string(records[i], 3718 ZPOOL_HIST_ZONE, &zonename) == 0) { 3719 (void) printf(":%s", zonename); 3720 } 3721 3722 (void) printf("]"); 3723 (void) printf("\n"); 3724 } 3725 (void) printf("\n"); 3726 nvlist_free(nvhis); 3727 3728 return (ret); 3729 } 3730 3731 /* 3732 * zpool history <pool> 3733 * 3734 * Displays the history of commands that modified pools. 3735 */ 3736 3737 3738 int 3739 zpool_do_history(int argc, char **argv) 3740 { 3741 hist_cbdata_t cbdata = { 0 }; 3742 int ret; 3743 int c; 3744 3745 cbdata.first = B_TRUE; 3746 /* check options */ 3747 while ((c = getopt(argc, argv, "li")) != -1) { 3748 switch (c) { 3749 case 'l': 3750 cbdata.longfmt = 1; 3751 break; 3752 case 'i': 3753 cbdata.internal = 1; 3754 break; 3755 case '?': 3756 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3757 optopt); 3758 usage(B_FALSE); 3759 } 3760 } 3761 argc -= optind; 3762 argv += optind; 3763 3764 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3765 &cbdata); 3766 3767 if (argc == 0 && cbdata.first == B_TRUE) { 3768 (void) printf(gettext("no pools available\n")); 3769 return (0); 3770 } 3771 3772 return (ret); 3773 } 3774 3775 static int 3776 get_callback(zpool_handle_t *zhp, void *data) 3777 { 3778 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3779 char value[MAXNAMELEN]; 3780 zprop_source_t srctype; 3781 zprop_list_t *pl; 3782 3783 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3784 3785 /* 3786 * Skip the special fake placeholder. This will also skip 3787 * over the name property when 'all' is specified. 3788 */ 3789 if (pl->pl_prop == ZPOOL_PROP_NAME && 3790 pl == cbp->cb_proplist) 3791 continue; 3792 3793 if (zpool_get_prop(zhp, pl->pl_prop, 3794 value, sizeof (value), &srctype) != 0) 3795 continue; 3796 3797 zprop_print_one_property(zpool_get_name(zhp), cbp, 3798 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3799 } 3800 return (0); 3801 } 3802 3803 int 3804 zpool_do_get(int argc, char **argv) 3805 { 3806 zprop_get_cbdata_t cb = { 0 }; 3807 zprop_list_t fake_name = { 0 }; 3808 int ret; 3809 3810 if (argc < 3) 3811 usage(B_FALSE); 3812 3813 cb.cb_first = B_TRUE; 3814 cb.cb_sources = ZPROP_SRC_ALL; 3815 cb.cb_columns[0] = GET_COL_NAME; 3816 cb.cb_columns[1] = GET_COL_PROPERTY; 3817 cb.cb_columns[2] = GET_COL_VALUE; 3818 cb.cb_columns[3] = GET_COL_SOURCE; 3819 cb.cb_type = ZFS_TYPE_POOL; 3820 3821 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3822 ZFS_TYPE_POOL) != 0) 3823 usage(B_FALSE); 3824 3825 if (cb.cb_proplist != NULL) { 3826 fake_name.pl_prop = ZPOOL_PROP_NAME; 3827 fake_name.pl_width = strlen(gettext("NAME")); 3828 fake_name.pl_next = cb.cb_proplist; 3829 cb.cb_proplist = &fake_name; 3830 } 3831 3832 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3833 get_callback, &cb); 3834 3835 if (cb.cb_proplist == &fake_name) 3836 zprop_free_list(fake_name.pl_next); 3837 else 3838 zprop_free_list(cb.cb_proplist); 3839 3840 return (ret); 3841 } 3842 3843 typedef struct set_cbdata { 3844 char *cb_propname; 3845 char *cb_value; 3846 boolean_t cb_any_successful; 3847 } set_cbdata_t; 3848 3849 int 3850 set_callback(zpool_handle_t *zhp, void *data) 3851 { 3852 int error; 3853 set_cbdata_t *cb = (set_cbdata_t *)data; 3854 3855 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3856 3857 if (!error) 3858 cb->cb_any_successful = B_TRUE; 3859 3860 return (error); 3861 } 3862 3863 int 3864 zpool_do_set(int argc, char **argv) 3865 { 3866 set_cbdata_t cb = { 0 }; 3867 int error; 3868 3869 if (argc > 1 && argv[1][0] == '-') { 3870 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3871 argv[1][1]); 3872 usage(B_FALSE); 3873 } 3874 3875 if (argc < 2) { 3876 (void) fprintf(stderr, gettext("missing property=value " 3877 "argument\n")); 3878 usage(B_FALSE); 3879 } 3880 3881 if (argc < 3) { 3882 (void) fprintf(stderr, gettext("missing pool name\n")); 3883 usage(B_FALSE); 3884 } 3885 3886 if (argc > 3) { 3887 (void) fprintf(stderr, gettext("too many pool names\n")); 3888 usage(B_FALSE); 3889 } 3890 3891 cb.cb_propname = argv[1]; 3892 cb.cb_value = strchr(cb.cb_propname, '='); 3893 if (cb.cb_value == NULL) { 3894 (void) fprintf(stderr, gettext("missing value in " 3895 "property=value argument\n")); 3896 usage(B_FALSE); 3897 } 3898 3899 *(cb.cb_value) = '\0'; 3900 cb.cb_value++; 3901 3902 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3903 set_callback, &cb); 3904 3905 return (error); 3906 } 3907 3908 static int 3909 find_command_idx(char *command, int *idx) 3910 { 3911 int i; 3912 3913 for (i = 0; i < NCOMMAND; i++) { 3914 if (command_table[i].name == NULL) 3915 continue; 3916 3917 if (strcmp(command, command_table[i].name) == 0) { 3918 *idx = i; 3919 return (0); 3920 } 3921 } 3922 return (1); 3923 } 3924 3925 int 3926 main(int argc, char **argv) 3927 { 3928 int ret; 3929 int i; 3930 char *cmdname; 3931 3932 (void) setlocale(LC_ALL, ""); 3933 (void) textdomain(TEXT_DOMAIN); 3934 3935 if ((g_zfs = libzfs_init()) == NULL) { 3936 (void) fprintf(stderr, gettext("internal error: failed to " 3937 "initialize ZFS library\n")); 3938 return (1); 3939 } 3940 3941 libzfs_print_on_error(g_zfs, B_TRUE); 3942 3943 opterr = 0; 3944 3945 /* 3946 * Make sure the user has specified some command. 3947 */ 3948 if (argc < 2) { 3949 (void) fprintf(stderr, gettext("missing command\n")); 3950 usage(B_FALSE); 3951 } 3952 3953 cmdname = argv[1]; 3954 3955 /* 3956 * Special case '-?' 3957 */ 3958 if (strcmp(cmdname, "-?") == 0) 3959 usage(B_TRUE); 3960 3961 zpool_set_history_str("zpool", argc, argv, history_str); 3962 verify(zpool_stage_history(g_zfs, history_str) == 0); 3963 3964 /* 3965 * Run the appropriate command. 3966 */ 3967 if (find_command_idx(cmdname, &i) == 0) { 3968 current_command = &command_table[i]; 3969 ret = command_table[i].func(argc - 1, argv + 1); 3970 } else if (strchr(cmdname, '=')) { 3971 verify(find_command_idx("set", &i) == 0); 3972 current_command = &command_table[i]; 3973 ret = command_table[i].func(argc, argv); 3974 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3975 /* 3976 * 'freeze' is a vile debugging abomination, so we treat 3977 * it as such. 3978 */ 3979 char buf[16384]; 3980 int fd = open(ZFS_DEV, O_RDWR); 3981 (void) strcpy((void *)buf, argv[2]); 3982 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3983 } else { 3984 (void) fprintf(stderr, gettext("unrecognized " 3985 "command '%s'\n"), cmdname); 3986 usage(B_FALSE); 3987 } 3988 3989 libzfs_fini(g_zfs); 3990 3991 /* 3992 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3993 * for the purposes of running ::findleaks. 3994 */ 3995 if (getenv("ZFS_ABORT") != NULL) { 3996 (void) printf("dumping core by request\n"); 3997 abort(); 3998 } 3999 4000 return (ret); 4001 } 4002