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 2639 /* check options */ 2640 while ((c = getopt(argc, argv, "t")) != -1) { 2641 switch (c) { 2642 case 't': 2643 case '?': 2644 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2645 optopt); 2646 usage(B_FALSE); 2647 } 2648 } 2649 2650 argc -= optind; 2651 argv += optind; 2652 2653 /* get pool name and check number of arguments */ 2654 if (argc < 1) { 2655 (void) fprintf(stderr, gettext("missing pool name\n")); 2656 usage(B_FALSE); 2657 } 2658 if (argc < 2) { 2659 (void) fprintf(stderr, gettext("missing device name\n")); 2660 usage(B_FALSE); 2661 } 2662 2663 poolname = argv[0]; 2664 2665 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2666 return (1); 2667 2668 for (i = 1; i < argc; i++) { 2669 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) { 2670 if (newstate != VDEV_STATE_HEALTHY) { 2671 (void) printf(gettext("warning: device '%s' " 2672 "onlined, but remains in faulted state\n"), 2673 argv[i]); 2674 if (newstate == VDEV_STATE_FAULTED) 2675 (void) printf(gettext("use 'zpool " 2676 "clear' to restore a faulted " 2677 "device\n")); 2678 else 2679 (void) printf(gettext("use 'zpool " 2680 "replace' to replace devices " 2681 "that are no longer present\n")); 2682 } 2683 } else { 2684 ret = 1; 2685 } 2686 } 2687 2688 zpool_close(zhp); 2689 2690 return (ret); 2691 } 2692 2693 /* 2694 * zpool offline [-ft] <pool> <device> ... 2695 * 2696 * -f Force the device into the offline state, even if doing 2697 * so would appear to compromise pool availability. 2698 * (not supported yet) 2699 * 2700 * -t Only take the device off-line temporarily. The offline 2701 * state will not be persistent across reboots. 2702 */ 2703 /* ARGSUSED */ 2704 int 2705 zpool_do_offline(int argc, char **argv) 2706 { 2707 int c, i; 2708 char *poolname; 2709 zpool_handle_t *zhp; 2710 int ret = 0; 2711 boolean_t istmp = B_FALSE; 2712 2713 /* check options */ 2714 while ((c = getopt(argc, argv, "ft")) != -1) { 2715 switch (c) { 2716 case 't': 2717 istmp = B_TRUE; 2718 break; 2719 case 'f': 2720 case '?': 2721 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2722 optopt); 2723 usage(B_FALSE); 2724 } 2725 } 2726 2727 argc -= optind; 2728 argv += optind; 2729 2730 /* get pool name and check number of arguments */ 2731 if (argc < 1) { 2732 (void) fprintf(stderr, gettext("missing pool name\n")); 2733 usage(B_FALSE); 2734 } 2735 if (argc < 2) { 2736 (void) fprintf(stderr, gettext("missing device name\n")); 2737 usage(B_FALSE); 2738 } 2739 2740 poolname = argv[0]; 2741 2742 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2743 return (1); 2744 2745 for (i = 1; i < argc; i++) { 2746 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 2747 ret = 1; 2748 } 2749 2750 zpool_close(zhp); 2751 2752 return (ret); 2753 } 2754 2755 /* 2756 * zpool clear <pool> [device] 2757 * 2758 * Clear all errors associated with a pool or a particular device. 2759 */ 2760 int 2761 zpool_do_clear(int argc, char **argv) 2762 { 2763 int ret = 0; 2764 zpool_handle_t *zhp; 2765 char *pool, *device; 2766 2767 if (argc < 2) { 2768 (void) fprintf(stderr, gettext("missing pool name\n")); 2769 usage(B_FALSE); 2770 } 2771 2772 if (argc > 3) { 2773 (void) fprintf(stderr, gettext("too many arguments\n")); 2774 usage(B_FALSE); 2775 } 2776 2777 pool = argv[1]; 2778 device = argc == 3 ? argv[2] : NULL; 2779 2780 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 2781 return (1); 2782 2783 if (zpool_clear(zhp, device) != 0) 2784 ret = 1; 2785 2786 zpool_close(zhp); 2787 2788 return (ret); 2789 } 2790 2791 typedef struct scrub_cbdata { 2792 int cb_type; 2793 int cb_argc; 2794 char **cb_argv; 2795 } scrub_cbdata_t; 2796 2797 int 2798 scrub_callback(zpool_handle_t *zhp, void *data) 2799 { 2800 scrub_cbdata_t *cb = data; 2801 int err; 2802 2803 /* 2804 * Ignore faulted pools. 2805 */ 2806 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2807 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2808 "currently unavailable\n"), zpool_get_name(zhp)); 2809 return (1); 2810 } 2811 2812 err = zpool_scrub(zhp, cb->cb_type); 2813 2814 return (err != 0); 2815 } 2816 2817 /* 2818 * zpool scrub [-s] <pool> ... 2819 * 2820 * -s Stop. Stops any in-progress scrub. 2821 */ 2822 int 2823 zpool_do_scrub(int argc, char **argv) 2824 { 2825 int c; 2826 scrub_cbdata_t cb; 2827 2828 cb.cb_type = POOL_SCRUB_EVERYTHING; 2829 2830 /* check options */ 2831 while ((c = getopt(argc, argv, "s")) != -1) { 2832 switch (c) { 2833 case 's': 2834 cb.cb_type = POOL_SCRUB_NONE; 2835 break; 2836 case '?': 2837 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2838 optopt); 2839 usage(B_FALSE); 2840 } 2841 } 2842 2843 cb.cb_argc = argc; 2844 cb.cb_argv = argv; 2845 argc -= optind; 2846 argv += optind; 2847 2848 if (argc < 1) { 2849 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2850 usage(B_FALSE); 2851 } 2852 2853 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 2854 } 2855 2856 typedef struct status_cbdata { 2857 int cb_count; 2858 boolean_t cb_allpools; 2859 boolean_t cb_verbose; 2860 boolean_t cb_explain; 2861 boolean_t cb_first; 2862 } status_cbdata_t; 2863 2864 /* 2865 * Print out detailed scrub status. 2866 */ 2867 void 2868 print_scrub_status(nvlist_t *nvroot) 2869 { 2870 vdev_stat_t *vs; 2871 uint_t vsc; 2872 time_t start, end, now; 2873 double fraction_done; 2874 uint64_t examined, total, minutes_left, minutes_taken; 2875 char *scrub_type; 2876 2877 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2878 (uint64_t **)&vs, &vsc) == 0); 2879 2880 /* 2881 * If there's never been a scrub, there's not much to say. 2882 */ 2883 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2884 (void) printf(gettext("none requested\n")); 2885 return; 2886 } 2887 2888 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2889 "resilver" : "scrub"; 2890 2891 start = vs->vs_scrub_start; 2892 end = vs->vs_scrub_end; 2893 now = time(NULL); 2894 examined = vs->vs_scrub_examined; 2895 total = vs->vs_alloc; 2896 2897 if (end != 0) { 2898 minutes_taken = (uint64_t)((end - start) / 60); 2899 2900 (void) printf(gettext("%s %s after %lluh%um with %llu errors " 2901 "on %s"), 2902 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2903 (u_longlong_t)(minutes_taken / 60), 2904 (uint_t)(minutes_taken % 60), 2905 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2906 return; 2907 } 2908 2909 if (examined == 0) 2910 examined = 1; 2911 if (examined > total) 2912 total = examined; 2913 2914 fraction_done = (double)examined / total; 2915 minutes_left = (uint64_t)((now - start) * 2916 (1 - fraction_done) / fraction_done / 60); 2917 minutes_taken = (uint64_t)((now - start) / 60); 2918 2919 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, " 2920 "%lluh%um to go\n"), 2921 scrub_type, (u_longlong_t)(minutes_taken / 60), 2922 (uint_t)(minutes_taken % 60), 100 * fraction_done, 2923 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2924 } 2925 2926 static void 2927 print_error_log(zpool_handle_t *zhp) 2928 { 2929 nvlist_t *nverrlist = NULL; 2930 nvpair_t *elem; 2931 char *pathname; 2932 size_t len = MAXPATHLEN * 2; 2933 2934 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2935 (void) printf("errors: List of errors unavailable " 2936 "(insufficient privileges)\n"); 2937 return; 2938 } 2939 2940 (void) printf("errors: Permanent errors have been " 2941 "detected in the following files:\n\n"); 2942 2943 pathname = safe_malloc(len); 2944 elem = NULL; 2945 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2946 nvlist_t *nv; 2947 uint64_t dsobj, obj; 2948 2949 verify(nvpair_value_nvlist(elem, &nv) == 0); 2950 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2951 &dsobj) == 0); 2952 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2953 &obj) == 0); 2954 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2955 (void) printf("%7s %s\n", "", pathname); 2956 } 2957 free(pathname); 2958 nvlist_free(nverrlist); 2959 } 2960 2961 static void 2962 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2963 int namewidth) 2964 { 2965 uint_t i; 2966 char *name; 2967 2968 if (nspares == 0) 2969 return; 2970 2971 (void) printf(gettext("\tspares\n")); 2972 2973 for (i = 0; i < nspares; i++) { 2974 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2975 print_status_config(zhp, name, spares[i], 2976 namewidth, 2, B_TRUE); 2977 free(name); 2978 } 2979 } 2980 2981 static void 2982 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 2983 int namewidth) 2984 { 2985 uint_t i; 2986 char *name; 2987 2988 if (nl2cache == 0) 2989 return; 2990 2991 (void) printf(gettext("\tcache\n")); 2992 2993 for (i = 0; i < nl2cache; i++) { 2994 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]); 2995 print_status_config(zhp, name, l2cache[i], 2996 namewidth, 2, B_FALSE); 2997 free(name); 2998 } 2999 } 3000 3001 /* 3002 * Display a summary of pool status. Displays a summary such as: 3003 * 3004 * pool: tank 3005 * status: DEGRADED 3006 * reason: One or more devices ... 3007 * see: http://www.sun.com/msg/ZFS-xxxx-01 3008 * config: 3009 * mirror DEGRADED 3010 * c1t0d0 OK 3011 * c2t0d0 UNAVAIL 3012 * 3013 * When given the '-v' option, we print out the complete config. If the '-e' 3014 * option is specified, then we print out error rate information as well. 3015 */ 3016 int 3017 status_callback(zpool_handle_t *zhp, void *data) 3018 { 3019 status_cbdata_t *cbp = data; 3020 nvlist_t *config, *nvroot; 3021 char *msgid; 3022 int reason; 3023 const char *health; 3024 uint_t c; 3025 vdev_stat_t *vs; 3026 3027 config = zpool_get_config(zhp, NULL); 3028 reason = zpool_get_status(zhp, &msgid); 3029 3030 cbp->cb_count++; 3031 3032 /* 3033 * If we were given 'zpool status -x', only report those pools with 3034 * problems. 3035 */ 3036 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 3037 if (!cbp->cb_allpools) { 3038 (void) printf(gettext("pool '%s' is healthy\n"), 3039 zpool_get_name(zhp)); 3040 if (cbp->cb_first) 3041 cbp->cb_first = B_FALSE; 3042 } 3043 return (0); 3044 } 3045 3046 if (cbp->cb_first) 3047 cbp->cb_first = B_FALSE; 3048 else 3049 (void) printf("\n"); 3050 3051 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3052 &nvroot) == 0); 3053 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 3054 (uint64_t **)&vs, &c) == 0); 3055 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 3056 3057 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 3058 (void) printf(gettext(" state: %s\n"), health); 3059 3060 switch (reason) { 3061 case ZPOOL_STATUS_MISSING_DEV_R: 3062 (void) printf(gettext("status: One or more devices could not " 3063 "be opened. Sufficient replicas exist for\n\tthe pool to " 3064 "continue functioning in a degraded state.\n")); 3065 (void) printf(gettext("action: Attach the missing device and " 3066 "online it using 'zpool online'.\n")); 3067 break; 3068 3069 case ZPOOL_STATUS_MISSING_DEV_NR: 3070 (void) printf(gettext("status: One or more devices could not " 3071 "be opened. There are insufficient\n\treplicas for the " 3072 "pool to continue functioning.\n")); 3073 (void) printf(gettext("action: Attach the missing device and " 3074 "online it using 'zpool online'.\n")); 3075 break; 3076 3077 case ZPOOL_STATUS_CORRUPT_LABEL_R: 3078 (void) printf(gettext("status: One or more devices could not " 3079 "be used because the label is missing or\n\tinvalid. " 3080 "Sufficient replicas exist for the pool to continue\n\t" 3081 "functioning in a degraded state.\n")); 3082 (void) printf(gettext("action: Replace the device using " 3083 "'zpool replace'.\n")); 3084 break; 3085 3086 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 3087 (void) printf(gettext("status: One or more devices could not " 3088 "be used because the label is missing \n\tor invalid. " 3089 "There are insufficient replicas for the pool to " 3090 "continue\n\tfunctioning.\n")); 3091 (void) printf(gettext("action: Destroy and re-create the pool " 3092 "from a backup source.\n")); 3093 break; 3094 3095 case ZPOOL_STATUS_FAILING_DEV: 3096 (void) printf(gettext("status: One or more devices has " 3097 "experienced an unrecoverable error. An\n\tattempt was " 3098 "made to correct the error. Applications are " 3099 "unaffected.\n")); 3100 (void) printf(gettext("action: Determine if the device needs " 3101 "to be replaced, and clear the errors\n\tusing " 3102 "'zpool clear' or replace the device with 'zpool " 3103 "replace'.\n")); 3104 break; 3105 3106 case ZPOOL_STATUS_OFFLINE_DEV: 3107 (void) printf(gettext("status: One or more devices has " 3108 "been taken offline by the administrator.\n\tSufficient " 3109 "replicas exist for the pool to continue functioning in " 3110 "a\n\tdegraded state.\n")); 3111 (void) printf(gettext("action: Online the device using " 3112 "'zpool online' or replace the device with\n\t'zpool " 3113 "replace'.\n")); 3114 break; 3115 3116 case ZPOOL_STATUS_RESILVERING: 3117 (void) printf(gettext("status: One or more devices is " 3118 "currently being resilvered. The pool will\n\tcontinue " 3119 "to function, possibly in a degraded state.\n")); 3120 (void) printf(gettext("action: Wait for the resilver to " 3121 "complete.\n")); 3122 break; 3123 3124 case ZPOOL_STATUS_CORRUPT_DATA: 3125 (void) printf(gettext("status: One or more devices has " 3126 "experienced an error resulting in data\n\tcorruption. " 3127 "Applications may be affected.\n")); 3128 (void) printf(gettext("action: Restore the file in question " 3129 "if possible. Otherwise restore the\n\tentire pool from " 3130 "backup.\n")); 3131 break; 3132 3133 case ZPOOL_STATUS_CORRUPT_POOL: 3134 (void) printf(gettext("status: The pool metadata is corrupted " 3135 "and the pool cannot be opened.\n")); 3136 (void) printf(gettext("action: Destroy and re-create the pool " 3137 "from a backup source.\n")); 3138 break; 3139 3140 case ZPOOL_STATUS_VERSION_OLDER: 3141 (void) printf(gettext("status: The pool is formatted using an " 3142 "older on-disk format. The pool can\n\tstill be used, but " 3143 "some features are unavailable.\n")); 3144 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3145 "upgrade'. Once this is done, the\n\tpool will no longer " 3146 "be accessible on older software versions.\n")); 3147 break; 3148 3149 case ZPOOL_STATUS_VERSION_NEWER: 3150 (void) printf(gettext("status: The pool has been upgraded to a " 3151 "newer, incompatible on-disk version.\n\tThe pool cannot " 3152 "be accessed on this system.\n")); 3153 (void) printf(gettext("action: Access the pool from a system " 3154 "running more recent software, or\n\trestore the pool from " 3155 "backup.\n")); 3156 break; 3157 3158 case ZPOOL_STATUS_FAULTED_DEV_R: 3159 (void) printf(gettext("status: One or more devices are " 3160 "faulted in response to persistent errors.\n\tSufficient " 3161 "replicas exist for the pool to continue functioning " 3162 "in a\n\tdegraded state.\n")); 3163 (void) printf(gettext("action: Replace the faulted device, " 3164 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3165 break; 3166 3167 case ZPOOL_STATUS_FAULTED_DEV_NR: 3168 (void) printf(gettext("status: One or more devices are " 3169 "faulted in response to persistent errors. There are " 3170 "insufficient replicas for the pool to\n\tcontinue " 3171 "functioning.\n")); 3172 (void) printf(gettext("action: Destroy and re-create the pool " 3173 "from a backup source. Manually marking the device\n" 3174 "\trepaired using 'zpool clear' may allow some data " 3175 "to be recovered.\n")); 3176 break; 3177 3178 case ZPOOL_STATUS_IO_FAILURE_WAIT: 3179 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 3180 (void) printf(gettext("status: One or more devices are " 3181 "faulted in response to IO failures.\n")); 3182 (void) printf(gettext("action: Make sure the affected devices " 3183 "are connected, then run 'zpool clear'.\n")); 3184 break; 3185 3186 case ZPOOL_STATUS_BAD_LOG: 3187 (void) printf(gettext("status: An intent log record " 3188 "could not be read.\n" 3189 "\tWaiting for adminstrator intervention to fix the " 3190 "faulted pool.\n")); 3191 (void) printf(gettext("action: Either restore the affected " 3192 "device(s) and run 'zpool online',\n" 3193 "\tor ignore the intent log records by running " 3194 "'zpool clear'.\n")); 3195 break; 3196 3197 default: 3198 /* 3199 * The remaining errors can't actually be generated, yet. 3200 */ 3201 assert(reason == ZPOOL_STATUS_OK); 3202 } 3203 3204 if (msgid != NULL) 3205 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3206 msgid); 3207 3208 if (config != NULL) { 3209 int namewidth; 3210 uint64_t nerr; 3211 nvlist_t **spares, **l2cache; 3212 uint_t nspares, nl2cache; 3213 3214 3215 (void) printf(gettext(" scrub: ")); 3216 print_scrub_status(nvroot); 3217 3218 namewidth = max_width(zhp, nvroot, 0, 0); 3219 if (namewidth < 10) 3220 namewidth = 10; 3221 3222 (void) printf(gettext("config:\n\n")); 3223 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3224 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3225 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3226 namewidth, 0, B_FALSE); 3227 3228 if (num_logs(nvroot) > 0) 3229 print_logs(zhp, nvroot, namewidth, B_TRUE); 3230 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3231 &l2cache, &nl2cache) == 0) 3232 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3233 3234 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3235 &spares, &nspares) == 0) 3236 print_spares(zhp, spares, nspares, namewidth); 3237 3238 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3239 &nerr) == 0) { 3240 nvlist_t *nverrlist = NULL; 3241 3242 /* 3243 * If the approximate error count is small, get a 3244 * precise count by fetching the entire log and 3245 * uniquifying the results. 3246 */ 3247 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3248 zpool_get_errlog(zhp, &nverrlist) == 0) { 3249 nvpair_t *elem; 3250 3251 elem = NULL; 3252 nerr = 0; 3253 while ((elem = nvlist_next_nvpair(nverrlist, 3254 elem)) != NULL) { 3255 nerr++; 3256 } 3257 } 3258 nvlist_free(nverrlist); 3259 3260 (void) printf("\n"); 3261 3262 if (nerr == 0) 3263 (void) printf(gettext("errors: No known data " 3264 "errors\n")); 3265 else if (!cbp->cb_verbose) 3266 (void) printf(gettext("errors: %llu data " 3267 "errors, use '-v' for a list\n"), 3268 (u_longlong_t)nerr); 3269 else 3270 print_error_log(zhp); 3271 } 3272 } else { 3273 (void) printf(gettext("config: The configuration cannot be " 3274 "determined.\n")); 3275 } 3276 3277 return (0); 3278 } 3279 3280 /* 3281 * zpool status [-vx] [pool] ... 3282 * 3283 * -v Display complete error logs 3284 * -x Display only pools with potential problems 3285 * 3286 * Describes the health status of all pools or some subset. 3287 */ 3288 int 3289 zpool_do_status(int argc, char **argv) 3290 { 3291 int c; 3292 int ret; 3293 status_cbdata_t cb = { 0 }; 3294 3295 /* check options */ 3296 while ((c = getopt(argc, argv, "vx")) != -1) { 3297 switch (c) { 3298 case 'v': 3299 cb.cb_verbose = B_TRUE; 3300 break; 3301 case 'x': 3302 cb.cb_explain = B_TRUE; 3303 break; 3304 case '?': 3305 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3306 optopt); 3307 usage(B_FALSE); 3308 } 3309 } 3310 3311 argc -= optind; 3312 argv += optind; 3313 3314 cb.cb_first = B_TRUE; 3315 3316 if (argc == 0) 3317 cb.cb_allpools = B_TRUE; 3318 3319 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3320 3321 if (argc == 0 && cb.cb_count == 0) 3322 (void) printf(gettext("no pools available\n")); 3323 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3324 (void) printf(gettext("all pools are healthy\n")); 3325 3326 return (ret); 3327 } 3328 3329 typedef struct upgrade_cbdata { 3330 int cb_all; 3331 int cb_first; 3332 int cb_newer; 3333 int cb_argc; 3334 uint64_t cb_version; 3335 char **cb_argv; 3336 } upgrade_cbdata_t; 3337 3338 static int 3339 upgrade_cb(zpool_handle_t *zhp, void *arg) 3340 { 3341 upgrade_cbdata_t *cbp = arg; 3342 nvlist_t *config; 3343 uint64_t version; 3344 int ret = 0; 3345 3346 config = zpool_get_config(zhp, NULL); 3347 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3348 &version) == 0); 3349 3350 if (!cbp->cb_newer && version < SPA_VERSION) { 3351 if (!cbp->cb_all) { 3352 if (cbp->cb_first) { 3353 (void) printf(gettext("The following pools are " 3354 "out of date, and can be upgraded. After " 3355 "being\nupgraded, these pools will no " 3356 "longer be accessible by older software " 3357 "versions.\n\n")); 3358 (void) printf(gettext("VER POOL\n")); 3359 (void) printf(gettext("--- ------------\n")); 3360 cbp->cb_first = B_FALSE; 3361 } 3362 3363 (void) printf("%2llu %s\n", (u_longlong_t)version, 3364 zpool_get_name(zhp)); 3365 } else { 3366 cbp->cb_first = B_FALSE; 3367 ret = zpool_upgrade(zhp, cbp->cb_version); 3368 if (!ret) { 3369 (void) printf(gettext("Successfully upgraded " 3370 "'%s'\n\n"), zpool_get_name(zhp)); 3371 } 3372 } 3373 } else if (cbp->cb_newer && version > SPA_VERSION) { 3374 assert(!cbp->cb_all); 3375 3376 if (cbp->cb_first) { 3377 (void) printf(gettext("The following pools are " 3378 "formatted using a newer software version and\n" 3379 "cannot be accessed on the current system.\n\n")); 3380 (void) printf(gettext("VER POOL\n")); 3381 (void) printf(gettext("--- ------------\n")); 3382 cbp->cb_first = B_FALSE; 3383 } 3384 3385 (void) printf("%2llu %s\n", (u_longlong_t)version, 3386 zpool_get_name(zhp)); 3387 } 3388 3389 zpool_close(zhp); 3390 return (ret); 3391 } 3392 3393 /* ARGSUSED */ 3394 static int 3395 upgrade_one(zpool_handle_t *zhp, void *data) 3396 { 3397 upgrade_cbdata_t *cbp = data; 3398 uint64_t cur_version; 3399 int ret; 3400 3401 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3402 (void) printf(gettext("'log' is now a reserved word\n" 3403 "Pool 'log' must be renamed using export and import" 3404 " to upgrade.\n")); 3405 return (1); 3406 } 3407 3408 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3409 if (cur_version > cbp->cb_version) { 3410 (void) printf(gettext("Pool '%s' is already formatted " 3411 "using more current version '%llu'.\n"), 3412 zpool_get_name(zhp), cur_version); 3413 return (0); 3414 } 3415 if (cur_version == cbp->cb_version) { 3416 (void) printf(gettext("Pool '%s' is already formatted " 3417 "using the current version.\n"), zpool_get_name(zhp)); 3418 return (0); 3419 } 3420 3421 ret = zpool_upgrade(zhp, cbp->cb_version); 3422 3423 if (!ret) { 3424 (void) printf(gettext("Successfully upgraded '%s' " 3425 "from version %llu to version %llu\n\n"), 3426 zpool_get_name(zhp), (u_longlong_t)cur_version, 3427 (u_longlong_t)cbp->cb_version); 3428 } 3429 3430 return (ret != 0); 3431 } 3432 3433 /* 3434 * zpool upgrade 3435 * zpool upgrade -v 3436 * zpool upgrade [-V version] <-a | pool ...> 3437 * 3438 * With no arguments, display downrev'd ZFS pool available for upgrade. 3439 * Individual pools can be upgraded by specifying the pool, and '-a' will 3440 * upgrade all pools. 3441 */ 3442 int 3443 zpool_do_upgrade(int argc, char **argv) 3444 { 3445 int c; 3446 upgrade_cbdata_t cb = { 0 }; 3447 int ret = 0; 3448 boolean_t showversions = B_FALSE; 3449 char *end; 3450 3451 3452 /* check options */ 3453 while ((c = getopt(argc, argv, ":avV:")) != -1) { 3454 switch (c) { 3455 case 'a': 3456 cb.cb_all = B_TRUE; 3457 break; 3458 case 'v': 3459 showversions = B_TRUE; 3460 break; 3461 case 'V': 3462 cb.cb_version = strtoll(optarg, &end, 10); 3463 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3464 cb.cb_version < SPA_VERSION_1) { 3465 (void) fprintf(stderr, 3466 gettext("invalid version '%s'\n"), optarg); 3467 usage(B_FALSE); 3468 } 3469 break; 3470 case ':': 3471 (void) fprintf(stderr, gettext("missing argument for " 3472 "'%c' option\n"), optopt); 3473 usage(B_FALSE); 3474 break; 3475 case '?': 3476 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3477 optopt); 3478 usage(B_FALSE); 3479 } 3480 } 3481 3482 cb.cb_argc = argc; 3483 cb.cb_argv = argv; 3484 argc -= optind; 3485 argv += optind; 3486 3487 if (cb.cb_version == 0) { 3488 cb.cb_version = SPA_VERSION; 3489 } else if (!cb.cb_all && argc == 0) { 3490 (void) fprintf(stderr, gettext("-V option is " 3491 "incompatible with other arguments\n")); 3492 usage(B_FALSE); 3493 } 3494 3495 if (showversions) { 3496 if (cb.cb_all || argc != 0) { 3497 (void) fprintf(stderr, gettext("-v option is " 3498 "incompatible with other arguments\n")); 3499 usage(B_FALSE); 3500 } 3501 } else if (cb.cb_all) { 3502 if (argc != 0) { 3503 (void) fprintf(stderr, gettext("-a option should not " 3504 "be used along with a pool name\n")); 3505 usage(B_FALSE); 3506 } 3507 } 3508 3509 (void) printf(gettext("This system is currently running " 3510 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3511 cb.cb_first = B_TRUE; 3512 if (showversions) { 3513 (void) printf(gettext("The following versions are " 3514 "supported:\n\n")); 3515 (void) printf(gettext("VER DESCRIPTION\n")); 3516 (void) printf("--- -----------------------------------------" 3517 "---------------\n"); 3518 (void) printf(gettext(" 1 Initial ZFS version\n")); 3519 (void) printf(gettext(" 2 Ditto blocks " 3520 "(replicated metadata)\n")); 3521 (void) printf(gettext(" 3 Hot spares and double parity " 3522 "RAID-Z\n")); 3523 (void) printf(gettext(" 4 zpool history\n")); 3524 (void) printf(gettext(" 5 Compression using the gzip " 3525 "algorithm\n")); 3526 (void) printf(gettext(" 6 bootfs pool property\n")); 3527 (void) printf(gettext(" 7 Separate intent log devices\n")); 3528 (void) printf(gettext(" 8 Delegated administration\n")); 3529 (void) printf(gettext(" 9 refquota and refreservation " 3530 "properties\n")); 3531 (void) printf(gettext(" 10 Cache devices\n")); 3532 (void) printf(gettext(" 11 Improved scrub performance\n")); 3533 (void) printf(gettext(" 12 Snapshot properties\n")); 3534 (void) printf(gettext(" 13 snapused property\n")); 3535 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 3536 (void) printf(gettext(" 15 user/group space accounting\n")); 3537 (void) printf(gettext(" 16 stmf property support\n")); 3538 (void) printf(gettext("For more information on a particular " 3539 "version, including supported releases, see:\n\n")); 3540 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3541 "version/N\n\n"); 3542 (void) printf(gettext("Where 'N' is the version number.\n")); 3543 } else if (argc == 0) { 3544 int notfound; 3545 3546 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3547 notfound = cb.cb_first; 3548 3549 if (!cb.cb_all && ret == 0) { 3550 if (!cb.cb_first) 3551 (void) printf("\n"); 3552 cb.cb_first = B_TRUE; 3553 cb.cb_newer = B_TRUE; 3554 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3555 if (!cb.cb_first) { 3556 notfound = B_FALSE; 3557 (void) printf("\n"); 3558 } 3559 } 3560 3561 if (ret == 0) { 3562 if (notfound) 3563 (void) printf(gettext("All pools are formatted " 3564 "using this version.\n")); 3565 else if (!cb.cb_all) 3566 (void) printf(gettext("Use 'zpool upgrade -v' " 3567 "for a list of available versions and " 3568 "their associated\nfeatures.\n")); 3569 } 3570 } else { 3571 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3572 upgrade_one, &cb); 3573 } 3574 3575 return (ret); 3576 } 3577 3578 typedef struct hist_cbdata { 3579 boolean_t first; 3580 int longfmt; 3581 int internal; 3582 } hist_cbdata_t; 3583 3584 char *hist_event_table[LOG_END] = { 3585 "invalid event", 3586 "pool create", 3587 "vdev add", 3588 "pool remove", 3589 "pool destroy", 3590 "pool export", 3591 "pool import", 3592 "vdev attach", 3593 "vdev replace", 3594 "vdev detach", 3595 "vdev online", 3596 "vdev offline", 3597 "vdev upgrade", 3598 "pool clear", 3599 "pool scrub", 3600 "pool property set", 3601 "create", 3602 "clone", 3603 "destroy", 3604 "destroy_begin_sync", 3605 "inherit", 3606 "property set", 3607 "quota set", 3608 "permission update", 3609 "permission remove", 3610 "permission who remove", 3611 "promote", 3612 "receive", 3613 "rename", 3614 "reservation set", 3615 "replay_inc_sync", 3616 "replay_full_sync", 3617 "rollback", 3618 "snapshot", 3619 "filesystem version upgrade", 3620 "refquota set", 3621 "refreservation set", 3622 "pool scrub done", 3623 }; 3624 3625 /* 3626 * Print out the command history for a specific pool. 3627 */ 3628 static int 3629 get_history_one(zpool_handle_t *zhp, void *data) 3630 { 3631 nvlist_t *nvhis; 3632 nvlist_t **records; 3633 uint_t numrecords; 3634 char *cmdstr; 3635 char *pathstr; 3636 uint64_t dst_time; 3637 time_t tsec; 3638 struct tm t; 3639 char tbuf[30]; 3640 int ret, i; 3641 uint64_t who; 3642 struct passwd *pwd; 3643 char *hostname; 3644 char *zonename; 3645 char internalstr[MAXPATHLEN]; 3646 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3647 uint64_t txg; 3648 uint64_t ievent; 3649 3650 cb->first = B_FALSE; 3651 3652 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3653 3654 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3655 return (ret); 3656 3657 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3658 &records, &numrecords) == 0); 3659 for (i = 0; i < numrecords; i++) { 3660 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3661 &dst_time) != 0) 3662 continue; 3663 3664 /* is it an internal event or a standard event? */ 3665 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3666 &cmdstr) != 0) { 3667 if (cb->internal == 0) 3668 continue; 3669 3670 if (nvlist_lookup_uint64(records[i], 3671 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3672 continue; 3673 verify(nvlist_lookup_uint64(records[i], 3674 ZPOOL_HIST_TXG, &txg) == 0); 3675 verify(nvlist_lookup_string(records[i], 3676 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3677 if (ievent >= LOG_END) 3678 continue; 3679 (void) snprintf(internalstr, 3680 sizeof (internalstr), 3681 "[internal %s txg:%lld] %s", 3682 hist_event_table[ievent], txg, 3683 pathstr); 3684 cmdstr = internalstr; 3685 } 3686 tsec = dst_time; 3687 (void) localtime_r(&tsec, &t); 3688 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3689 (void) printf("%s %s", tbuf, cmdstr); 3690 3691 if (!cb->longfmt) { 3692 (void) printf("\n"); 3693 continue; 3694 } 3695 (void) printf(" ["); 3696 if (nvlist_lookup_uint64(records[i], 3697 ZPOOL_HIST_WHO, &who) == 0) { 3698 pwd = getpwuid((uid_t)who); 3699 if (pwd) 3700 (void) printf("user %s on", 3701 pwd->pw_name); 3702 else 3703 (void) printf("user %d on", 3704 (int)who); 3705 } else { 3706 (void) printf(gettext("no info]\n")); 3707 continue; 3708 } 3709 if (nvlist_lookup_string(records[i], 3710 ZPOOL_HIST_HOST, &hostname) == 0) { 3711 (void) printf(" %s", hostname); 3712 } 3713 if (nvlist_lookup_string(records[i], 3714 ZPOOL_HIST_ZONE, &zonename) == 0) { 3715 (void) printf(":%s", zonename); 3716 } 3717 3718 (void) printf("]"); 3719 (void) printf("\n"); 3720 } 3721 (void) printf("\n"); 3722 nvlist_free(nvhis); 3723 3724 return (ret); 3725 } 3726 3727 /* 3728 * zpool history <pool> 3729 * 3730 * Displays the history of commands that modified pools. 3731 */ 3732 3733 3734 int 3735 zpool_do_history(int argc, char **argv) 3736 { 3737 hist_cbdata_t cbdata = { 0 }; 3738 int ret; 3739 int c; 3740 3741 cbdata.first = B_TRUE; 3742 /* check options */ 3743 while ((c = getopt(argc, argv, "li")) != -1) { 3744 switch (c) { 3745 case 'l': 3746 cbdata.longfmt = 1; 3747 break; 3748 case 'i': 3749 cbdata.internal = 1; 3750 break; 3751 case '?': 3752 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3753 optopt); 3754 usage(B_FALSE); 3755 } 3756 } 3757 argc -= optind; 3758 argv += optind; 3759 3760 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3761 &cbdata); 3762 3763 if (argc == 0 && cbdata.first == B_TRUE) { 3764 (void) printf(gettext("no pools available\n")); 3765 return (0); 3766 } 3767 3768 return (ret); 3769 } 3770 3771 static int 3772 get_callback(zpool_handle_t *zhp, void *data) 3773 { 3774 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3775 char value[MAXNAMELEN]; 3776 zprop_source_t srctype; 3777 zprop_list_t *pl; 3778 3779 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3780 3781 /* 3782 * Skip the special fake placeholder. This will also skip 3783 * over the name property when 'all' is specified. 3784 */ 3785 if (pl->pl_prop == ZPOOL_PROP_NAME && 3786 pl == cbp->cb_proplist) 3787 continue; 3788 3789 if (zpool_get_prop(zhp, pl->pl_prop, 3790 value, sizeof (value), &srctype) != 0) 3791 continue; 3792 3793 zprop_print_one_property(zpool_get_name(zhp), cbp, 3794 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3795 } 3796 return (0); 3797 } 3798 3799 int 3800 zpool_do_get(int argc, char **argv) 3801 { 3802 zprop_get_cbdata_t cb = { 0 }; 3803 zprop_list_t fake_name = { 0 }; 3804 int ret; 3805 3806 if (argc < 3) 3807 usage(B_FALSE); 3808 3809 cb.cb_first = B_TRUE; 3810 cb.cb_sources = ZPROP_SRC_ALL; 3811 cb.cb_columns[0] = GET_COL_NAME; 3812 cb.cb_columns[1] = GET_COL_PROPERTY; 3813 cb.cb_columns[2] = GET_COL_VALUE; 3814 cb.cb_columns[3] = GET_COL_SOURCE; 3815 cb.cb_type = ZFS_TYPE_POOL; 3816 3817 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3818 ZFS_TYPE_POOL) != 0) 3819 usage(B_FALSE); 3820 3821 if (cb.cb_proplist != NULL) { 3822 fake_name.pl_prop = ZPOOL_PROP_NAME; 3823 fake_name.pl_width = strlen(gettext("NAME")); 3824 fake_name.pl_next = cb.cb_proplist; 3825 cb.cb_proplist = &fake_name; 3826 } 3827 3828 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3829 get_callback, &cb); 3830 3831 if (cb.cb_proplist == &fake_name) 3832 zprop_free_list(fake_name.pl_next); 3833 else 3834 zprop_free_list(cb.cb_proplist); 3835 3836 return (ret); 3837 } 3838 3839 typedef struct set_cbdata { 3840 char *cb_propname; 3841 char *cb_value; 3842 boolean_t cb_any_successful; 3843 } set_cbdata_t; 3844 3845 int 3846 set_callback(zpool_handle_t *zhp, void *data) 3847 { 3848 int error; 3849 set_cbdata_t *cb = (set_cbdata_t *)data; 3850 3851 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3852 3853 if (!error) 3854 cb->cb_any_successful = B_TRUE; 3855 3856 return (error); 3857 } 3858 3859 int 3860 zpool_do_set(int argc, char **argv) 3861 { 3862 set_cbdata_t cb = { 0 }; 3863 int error; 3864 3865 if (argc > 1 && argv[1][0] == '-') { 3866 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3867 argv[1][1]); 3868 usage(B_FALSE); 3869 } 3870 3871 if (argc < 2) { 3872 (void) fprintf(stderr, gettext("missing property=value " 3873 "argument\n")); 3874 usage(B_FALSE); 3875 } 3876 3877 if (argc < 3) { 3878 (void) fprintf(stderr, gettext("missing pool name\n")); 3879 usage(B_FALSE); 3880 } 3881 3882 if (argc > 3) { 3883 (void) fprintf(stderr, gettext("too many pool names\n")); 3884 usage(B_FALSE); 3885 } 3886 3887 cb.cb_propname = argv[1]; 3888 cb.cb_value = strchr(cb.cb_propname, '='); 3889 if (cb.cb_value == NULL) { 3890 (void) fprintf(stderr, gettext("missing value in " 3891 "property=value argument\n")); 3892 usage(B_FALSE); 3893 } 3894 3895 *(cb.cb_value) = '\0'; 3896 cb.cb_value++; 3897 3898 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3899 set_callback, &cb); 3900 3901 return (error); 3902 } 3903 3904 static int 3905 find_command_idx(char *command, int *idx) 3906 { 3907 int i; 3908 3909 for (i = 0; i < NCOMMAND; i++) { 3910 if (command_table[i].name == NULL) 3911 continue; 3912 3913 if (strcmp(command, command_table[i].name) == 0) { 3914 *idx = i; 3915 return (0); 3916 } 3917 } 3918 return (1); 3919 } 3920 3921 int 3922 main(int argc, char **argv) 3923 { 3924 int ret; 3925 int i; 3926 char *cmdname; 3927 3928 (void) setlocale(LC_ALL, ""); 3929 (void) textdomain(TEXT_DOMAIN); 3930 3931 if ((g_zfs = libzfs_init()) == NULL) { 3932 (void) fprintf(stderr, gettext("internal error: failed to " 3933 "initialize ZFS library\n")); 3934 return (1); 3935 } 3936 3937 libzfs_print_on_error(g_zfs, B_TRUE); 3938 3939 opterr = 0; 3940 3941 /* 3942 * Make sure the user has specified some command. 3943 */ 3944 if (argc < 2) { 3945 (void) fprintf(stderr, gettext("missing command\n")); 3946 usage(B_FALSE); 3947 } 3948 3949 cmdname = argv[1]; 3950 3951 /* 3952 * Special case '-?' 3953 */ 3954 if (strcmp(cmdname, "-?") == 0) 3955 usage(B_TRUE); 3956 3957 zpool_set_history_str("zpool", argc, argv, history_str); 3958 verify(zpool_stage_history(g_zfs, history_str) == 0); 3959 3960 /* 3961 * Run the appropriate command. 3962 */ 3963 if (find_command_idx(cmdname, &i) == 0) { 3964 current_command = &command_table[i]; 3965 ret = command_table[i].func(argc - 1, argv + 1); 3966 } else if (strchr(cmdname, '=')) { 3967 verify(find_command_idx("set", &i) == 0); 3968 current_command = &command_table[i]; 3969 ret = command_table[i].func(argc, argv); 3970 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3971 /* 3972 * 'freeze' is a vile debugging abomination, so we treat 3973 * it as such. 3974 */ 3975 char buf[16384]; 3976 int fd = open(ZFS_DEV, O_RDWR); 3977 (void) strcpy((void *)buf, argv[2]); 3978 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3979 } else { 3980 (void) fprintf(stderr, gettext("unrecognized " 3981 "command '%s'\n"), cmdname); 3982 usage(B_FALSE); 3983 } 3984 3985 libzfs_fini(g_zfs); 3986 3987 /* 3988 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3989 * for the purposes of running ::findleaks. 3990 */ 3991 if (getenv("ZFS_ABORT") != NULL) { 3992 (void) printf("dumping core by request\n"); 3993 abort(); 3994 } 3995 3996 return (ret); 3997 } 3998