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