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