1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <assert.h> 28 #include <ctype.h> 29 #include <dirent.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <libgen.h> 33 #include <libintl.h> 34 #include <libuutil.h> 35 #include <locale.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <strings.h> 40 #include <unistd.h> 41 #include <priv.h> 42 #include <pwd.h> 43 #include <zone.h> 44 #include <sys/fs/zfs.h> 45 46 #include <sys/stat.h> 47 48 #include <libzfs.h> 49 50 #include "zpool_util.h" 51 #include "zfs_comutil.h" 52 53 static int zpool_do_create(int, char **); 54 static int zpool_do_destroy(int, char **); 55 56 static int zpool_do_add(int, char **); 57 static int zpool_do_remove(int, char **); 58 59 static int zpool_do_list(int, char **); 60 static int zpool_do_iostat(int, char **); 61 static int zpool_do_status(int, char **); 62 63 static int zpool_do_online(int, char **); 64 static int zpool_do_offline(int, char **); 65 static int zpool_do_clear(int, char **); 66 67 static int zpool_do_attach(int, char **); 68 static int zpool_do_detach(int, char **); 69 static int zpool_do_replace(int, char **); 70 71 static int zpool_do_scrub(int, char **); 72 73 static int zpool_do_import(int, char **); 74 static int zpool_do_export(int, char **); 75 76 static int zpool_do_upgrade(int, char **); 77 78 static int zpool_do_history(int, char **); 79 80 static int zpool_do_get(int, char **); 81 static int zpool_do_set(int, char **); 82 83 /* 84 * These libumem hooks provide a reasonable set of defaults for the allocator's 85 * debugging facilities. 86 */ 87 88 #ifdef DEBUG 89 const char * 90 _umem_debug_init(void) 91 { 92 return ("default,verbose"); /* $UMEM_DEBUG setting */ 93 } 94 95 const char * 96 _umem_logging_init(void) 97 { 98 return ("fail,contents"); /* $UMEM_LOGGING setting */ 99 } 100 #endif 101 102 typedef enum { 103 HELP_ADD, 104 HELP_ATTACH, 105 HELP_CLEAR, 106 HELP_CREATE, 107 HELP_DESTROY, 108 HELP_DETACH, 109 HELP_EXPORT, 110 HELP_HISTORY, 111 HELP_IMPORT, 112 HELP_IOSTAT, 113 HELP_LIST, 114 HELP_OFFLINE, 115 HELP_ONLINE, 116 HELP_REPLACE, 117 HELP_REMOVE, 118 HELP_SCRUB, 119 HELP_STATUS, 120 HELP_UPGRADE, 121 HELP_GET, 122 HELP_SET 123 } zpool_help_t; 124 125 126 typedef struct zpool_command { 127 const char *name; 128 int (*func)(int, char **); 129 zpool_help_t usage; 130 } zpool_command_t; 131 132 /* 133 * Master command table. Each ZFS command has a name, associated function, and 134 * usage message. The usage messages need to be internationalized, so we have 135 * to have a function to return the usage message based on a command index. 136 * 137 * These commands are organized according to how they are displayed in the usage 138 * message. An empty command (one with a NULL name) indicates an empty line in 139 * the generic usage message. 140 */ 141 static zpool_command_t command_table[] = { 142 { "create", zpool_do_create, HELP_CREATE }, 143 { "destroy", zpool_do_destroy, HELP_DESTROY }, 144 { NULL }, 145 { "add", zpool_do_add, HELP_ADD }, 146 { "remove", zpool_do_remove, HELP_REMOVE }, 147 { NULL }, 148 { "list", zpool_do_list, HELP_LIST }, 149 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 150 { "status", zpool_do_status, HELP_STATUS }, 151 { NULL }, 152 { "online", zpool_do_online, HELP_ONLINE }, 153 { "offline", zpool_do_offline, HELP_OFFLINE }, 154 { "clear", zpool_do_clear, HELP_CLEAR }, 155 { NULL }, 156 { "attach", zpool_do_attach, HELP_ATTACH }, 157 { "detach", zpool_do_detach, HELP_DETACH }, 158 { "replace", zpool_do_replace, HELP_REPLACE }, 159 { NULL }, 160 { "scrub", zpool_do_scrub, HELP_SCRUB }, 161 { NULL }, 162 { "import", zpool_do_import, HELP_IMPORT }, 163 { "export", zpool_do_export, HELP_EXPORT }, 164 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 165 { NULL }, 166 { "history", zpool_do_history, HELP_HISTORY }, 167 { "get", zpool_do_get, HELP_GET }, 168 { "set", zpool_do_set, HELP_SET }, 169 }; 170 171 #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 172 173 zpool_command_t *current_command; 174 static char history_str[HIS_MAX_RECORD_LEN]; 175 176 static const char * 177 get_usage(zpool_help_t idx) { 178 switch (idx) { 179 case HELP_ADD: 180 return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 181 case HELP_ATTACH: 182 return (gettext("\tattach [-f] <pool> <device> " 183 "<new-device>\n")); 184 case HELP_CLEAR: 185 return (gettext("\tclear <pool> [device]\n")); 186 case HELP_CREATE: 187 return (gettext("\tcreate [-fn] [-o property=value] ... \n" 188 "\t [-O file-system-property=value] ... \n" 189 "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 190 case HELP_DESTROY: 191 return (gettext("\tdestroy [-f] <pool>\n")); 192 case HELP_DETACH: 193 return (gettext("\tdetach <pool> <device>\n")); 194 case HELP_EXPORT: 195 return (gettext("\texport [-f] <pool> ...\n")); 196 case HELP_HISTORY: 197 return (gettext("\thistory [-il] [<pool>] ...\n")); 198 case HELP_IMPORT: 199 return (gettext("\timport [-d dir] [-D]\n" 200 "\timport [-o mntopts] [-o property=value] ... \n" 201 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n" 202 "\timport [-o mntopts] [-o property=value] ... \n" 203 "\t [-d dir | -c cachefile] [-D] [-f] [-R root] " 204 "<pool | id> [newpool]\n")); 205 case HELP_IOSTAT: 206 return (gettext("\tiostat [-v] [pool] ... [interval " 207 "[count]]\n")); 208 case HELP_LIST: 209 return (gettext("\tlist [-H] [-o property[,...]] " 210 "[pool] ...\n")); 211 case HELP_OFFLINE: 212 return (gettext("\toffline [-t] <pool> <device> ...\n")); 213 case HELP_ONLINE: 214 return (gettext("\tonline <pool> <device> ...\n")); 215 case HELP_REPLACE: 216 return (gettext("\treplace [-f] <pool> <device> " 217 "[new-device]\n")); 218 case HELP_REMOVE: 219 return (gettext("\tremove <pool> <device> ...\n")); 220 case HELP_SCRUB: 221 return (gettext("\tscrub [-s] <pool> ...\n")); 222 case HELP_STATUS: 223 return (gettext("\tstatus [-vx] [pool] ...\n")); 224 case HELP_UPGRADE: 225 return (gettext("\tupgrade\n" 226 "\tupgrade -v\n" 227 "\tupgrade [-V version] <-a | pool ...>\n")); 228 case HELP_GET: 229 return (gettext("\tget <\"all\" | property[,...]> " 230 "<pool> ...\n")); 231 case HELP_SET: 232 return (gettext("\tset <property=value> <pool> \n")); 233 } 234 235 abort(); 236 /* NOTREACHED */ 237 } 238 239 240 /* 241 * Callback routine that will print out a pool property value. 242 */ 243 static int 244 print_prop_cb(int prop, void *cb) 245 { 246 FILE *fp = cb; 247 248 (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop)); 249 250 if (zpool_prop_readonly(prop)) 251 (void) fprintf(fp, " NO "); 252 else 253 (void) fprintf(fp, " YES "); 254 255 if (zpool_prop_values(prop) == NULL) 256 (void) fprintf(fp, "-\n"); 257 else 258 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 259 260 return (ZPROP_CONT); 261 } 262 263 /* 264 * Display usage message. If we're inside a command, display only the usage for 265 * that command. Otherwise, iterate over the entire command table and display 266 * a complete usage message. 267 */ 268 void 269 usage(boolean_t requested) 270 { 271 FILE *fp = requested ? stdout : stderr; 272 273 if (current_command == NULL) { 274 int i; 275 276 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 277 (void) fprintf(fp, 278 gettext("where 'command' is one of the following:\n\n")); 279 280 for (i = 0; i < NCOMMAND; i++) { 281 if (command_table[i].name == NULL) 282 (void) fprintf(fp, "\n"); 283 else 284 (void) fprintf(fp, "%s", 285 get_usage(command_table[i].usage)); 286 } 287 } else { 288 (void) fprintf(fp, gettext("usage:\n")); 289 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 290 } 291 292 if (current_command != NULL && 293 ((strcmp(current_command->name, "set") == 0) || 294 (strcmp(current_command->name, "get") == 0) || 295 (strcmp(current_command->name, "list") == 0))) { 296 297 (void) fprintf(fp, 298 gettext("\nthe following properties are supported:\n")); 299 300 (void) fprintf(fp, "\n\t%-13s %s %s\n\n", 301 "PROPERTY", "EDIT", "VALUES"); 302 303 /* Iterate over all properties */ 304 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 305 ZFS_TYPE_POOL); 306 } 307 308 /* 309 * See comments at end of main(). 310 */ 311 if (getenv("ZFS_ABORT") != NULL) { 312 (void) printf("dumping core by request\n"); 313 abort(); 314 } 315 316 exit(requested ? 0 : 2); 317 } 318 319 void 320 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 321 boolean_t print_logs) 322 { 323 nvlist_t **child; 324 uint_t c, children; 325 char *vname; 326 327 if (name != NULL) 328 (void) printf("\t%*s%s\n", indent, "", name); 329 330 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 331 &child, &children) != 0) 332 return; 333 334 for (c = 0; c < children; c++) { 335 uint64_t is_log = B_FALSE; 336 337 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 338 &is_log); 339 if ((is_log && !print_logs) || (!is_log && print_logs)) 340 continue; 341 342 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 343 print_vdev_tree(zhp, vname, child[c], indent + 2, 344 B_FALSE); 345 free(vname); 346 } 347 } 348 349 /* 350 * Add a property pair (name, string-value) into a property nvlist. 351 */ 352 static int 353 add_prop_list(const char *propname, char *propval, nvlist_t **props, 354 boolean_t poolprop) 355 { 356 zpool_prop_t prop = ZPROP_INVAL; 357 zfs_prop_t fprop; 358 nvlist_t *proplist; 359 const char *normnm; 360 char *strval; 361 362 if (*props == NULL && 363 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 364 (void) fprintf(stderr, 365 gettext("internal error: out of memory\n")); 366 return (1); 367 } 368 369 proplist = *props; 370 371 if (poolprop) { 372 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { 373 (void) fprintf(stderr, gettext("property '%s' is " 374 "not a valid pool property\n"), propname); 375 return (2); 376 } 377 normnm = zpool_prop_to_name(prop); 378 } else { 379 if ((fprop = zfs_name_to_prop(propname)) == ZPROP_INVAL) { 380 (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_get_state(zhp) != POOL_STATE_UNAVAIL && 1327 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 1328 zpool_close(zhp); 1329 return (1); 1330 } 1331 1332 zpool_close(zhp); 1333 return (error); 1334 } 1335 1336 /* 1337 * zpool import [-d dir] [-D] 1338 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1339 * [-d dir | -c cachefile] [-f] -a 1340 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1341 * [-d dir | -c cachefile] [-f] <pool | id> [newpool] 1342 * 1343 * -c Read pool information from a cachefile instead of searching 1344 * devices. 1345 * 1346 * -d Scan in a specific directory, other than /dev/dsk. More than 1347 * one directory can be specified using multiple '-d' options. 1348 * 1349 * -D Scan for previously destroyed pools or import all or only 1350 * specified destroyed pools. 1351 * 1352 * -R Temporarily import the pool, with all mountpoints relative to 1353 * the given root. The pool will remain exported when the machine 1354 * is rebooted. 1355 * 1356 * -f Force import, even if it appears that the pool is active. 1357 * 1358 * -F Import even in the presence of faulted vdevs. This is an 1359 * intentionally undocumented option for testing purposes, and 1360 * treats the pool configuration as complete, leaving any bad 1361 * vdevs in the FAULTED state. 1362 * 1363 * -a Import all pools found. 1364 * 1365 * -o Set property=value and/or temporary mount options (without '='). 1366 * 1367 * The import command scans for pools to import, and import pools based on pool 1368 * name and GUID. The pool can also be renamed as part of the import process. 1369 */ 1370 int 1371 zpool_do_import(int argc, char **argv) 1372 { 1373 char **searchdirs = NULL; 1374 int nsearch = 0; 1375 int c; 1376 int err; 1377 nvlist_t *pools = NULL; 1378 boolean_t do_all = B_FALSE; 1379 boolean_t do_destroyed = B_FALSE; 1380 char *mntopts = NULL; 1381 boolean_t do_force = B_FALSE; 1382 nvpair_t *elem; 1383 nvlist_t *config; 1384 uint64_t searchguid = 0; 1385 char *searchname = NULL; 1386 char *propval; 1387 nvlist_t *found_config; 1388 nvlist_t *props = NULL; 1389 boolean_t first; 1390 boolean_t allow_faulted = B_FALSE; 1391 uint64_t pool_state; 1392 char *cachefile = NULL; 1393 1394 /* check options */ 1395 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) { 1396 switch (c) { 1397 case 'a': 1398 do_all = B_TRUE; 1399 break; 1400 case 'c': 1401 cachefile = optarg; 1402 break; 1403 case 'd': 1404 if (searchdirs == NULL) { 1405 searchdirs = safe_malloc(sizeof (char *)); 1406 } else { 1407 char **tmp = safe_malloc((nsearch + 1) * 1408 sizeof (char *)); 1409 bcopy(searchdirs, tmp, nsearch * 1410 sizeof (char *)); 1411 free(searchdirs); 1412 searchdirs = tmp; 1413 } 1414 searchdirs[nsearch++] = optarg; 1415 break; 1416 case 'D': 1417 do_destroyed = B_TRUE; 1418 break; 1419 case 'f': 1420 do_force = B_TRUE; 1421 break; 1422 case 'F': 1423 allow_faulted = B_TRUE; 1424 break; 1425 case 'o': 1426 if ((propval = strchr(optarg, '=')) != NULL) { 1427 *propval = '\0'; 1428 propval++; 1429 if (add_prop_list(optarg, propval, 1430 &props, B_TRUE)) 1431 goto error; 1432 } else { 1433 mntopts = optarg; 1434 } 1435 break; 1436 case 'R': 1437 if (add_prop_list(zpool_prop_to_name( 1438 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1439 goto error; 1440 if (nvlist_lookup_string(props, 1441 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 1442 &propval) == 0) 1443 break; 1444 if (add_prop_list(zpool_prop_to_name( 1445 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1446 goto error; 1447 break; 1448 case ':': 1449 (void) fprintf(stderr, gettext("missing argument for " 1450 "'%c' option\n"), optopt); 1451 usage(B_FALSE); 1452 break; 1453 case '?': 1454 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1455 optopt); 1456 usage(B_FALSE); 1457 } 1458 } 1459 1460 argc -= optind; 1461 argv += optind; 1462 1463 if (cachefile && nsearch != 0) { 1464 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 1465 usage(B_FALSE); 1466 } 1467 1468 if (searchdirs == NULL) { 1469 searchdirs = safe_malloc(sizeof (char *)); 1470 searchdirs[0] = "/dev/dsk"; 1471 nsearch = 1; 1472 } 1473 1474 /* check argument count */ 1475 if (do_all) { 1476 if (argc != 0) { 1477 (void) fprintf(stderr, gettext("too many arguments\n")); 1478 usage(B_FALSE); 1479 } 1480 } else { 1481 if (argc > 2) { 1482 (void) fprintf(stderr, gettext("too many arguments\n")); 1483 usage(B_FALSE); 1484 } 1485 1486 /* 1487 * Check for the SYS_CONFIG privilege. We do this explicitly 1488 * here because otherwise any attempt to discover pools will 1489 * silently fail. 1490 */ 1491 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 1492 (void) fprintf(stderr, gettext("cannot " 1493 "discover pools: permission denied\n")); 1494 free(searchdirs); 1495 return (1); 1496 } 1497 } 1498 1499 /* 1500 * Depending on the arguments given, we do one of the following: 1501 * 1502 * <none> Iterate through all pools and display information about 1503 * each one. 1504 * 1505 * -a Iterate through all pools and try to import each one. 1506 * 1507 * <id> Find the pool that corresponds to the given GUID/pool 1508 * name and import that one. 1509 * 1510 * -D Above options applies only to destroyed pools. 1511 */ 1512 if (argc != 0) { 1513 char *endptr; 1514 1515 errno = 0; 1516 searchguid = strtoull(argv[0], &endptr, 10); 1517 if (errno != 0 || *endptr != '\0') 1518 searchname = argv[0]; 1519 found_config = NULL; 1520 } 1521 1522 if (cachefile) { 1523 pools = zpool_find_import_cached(g_zfs, cachefile, searchname, 1524 searchguid); 1525 } else if (searchname != NULL) { 1526 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs, 1527 searchname); 1528 } else { 1529 /* 1530 * It's OK to search by guid even if searchguid is 0. 1531 */ 1532 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs, 1533 searchguid); 1534 } 1535 1536 if (pools == NULL) { 1537 if (argc != 0) { 1538 (void) fprintf(stderr, gettext("cannot import '%s': " 1539 "no such pool available\n"), argv[0]); 1540 } 1541 free(searchdirs); 1542 return (1); 1543 } 1544 1545 /* 1546 * At this point we have a list of import candidate configs. Even if 1547 * we were searching by pool name or guid, we still need to 1548 * post-process the list to deal with pool state and possible 1549 * duplicate names. 1550 */ 1551 err = 0; 1552 elem = NULL; 1553 first = B_TRUE; 1554 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 1555 1556 verify(nvpair_value_nvlist(elem, &config) == 0); 1557 1558 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1559 &pool_state) == 0); 1560 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 1561 continue; 1562 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 1563 continue; 1564 1565 if (argc == 0) { 1566 if (first) 1567 first = B_FALSE; 1568 else if (!do_all) 1569 (void) printf("\n"); 1570 1571 if (do_all) 1572 err |= do_import(config, NULL, mntopts, 1573 do_force, props, allow_faulted); 1574 else 1575 show_import(config); 1576 } else if (searchname != NULL) { 1577 char *name; 1578 1579 /* 1580 * We are searching for a pool based on name. 1581 */ 1582 verify(nvlist_lookup_string(config, 1583 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 1584 1585 if (strcmp(name, searchname) == 0) { 1586 if (found_config != NULL) { 1587 (void) fprintf(stderr, gettext( 1588 "cannot import '%s': more than " 1589 "one matching pool\n"), searchname); 1590 (void) fprintf(stderr, gettext( 1591 "import by numeric ID instead\n")); 1592 err = B_TRUE; 1593 } 1594 found_config = config; 1595 } 1596 } else { 1597 uint64_t guid; 1598 1599 /* 1600 * Search for a pool by guid. 1601 */ 1602 verify(nvlist_lookup_uint64(config, 1603 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 1604 1605 if (guid == searchguid) 1606 found_config = config; 1607 } 1608 } 1609 1610 /* 1611 * If we were searching for a specific pool, verify that we found a 1612 * pool, and then do the import. 1613 */ 1614 if (argc != 0 && err == 0) { 1615 if (found_config == NULL) { 1616 (void) fprintf(stderr, gettext("cannot import '%s': " 1617 "no such pool available\n"), argv[0]); 1618 err = B_TRUE; 1619 } else { 1620 err |= do_import(found_config, argc == 1 ? NULL : 1621 argv[1], mntopts, do_force, props, allow_faulted); 1622 } 1623 } 1624 1625 /* 1626 * If we were just looking for pools, report an error if none were 1627 * found. 1628 */ 1629 if (argc == 0 && first) 1630 (void) fprintf(stderr, 1631 gettext("no pools available to import\n")); 1632 1633 error: 1634 nvlist_free(props); 1635 nvlist_free(pools); 1636 free(searchdirs); 1637 1638 return (err ? 1 : 0); 1639 } 1640 1641 typedef struct iostat_cbdata { 1642 zpool_list_t *cb_list; 1643 int cb_verbose; 1644 int cb_iteration; 1645 int cb_namewidth; 1646 } iostat_cbdata_t; 1647 1648 static void 1649 print_iostat_separator(iostat_cbdata_t *cb) 1650 { 1651 int i = 0; 1652 1653 for (i = 0; i < cb->cb_namewidth; i++) 1654 (void) printf("-"); 1655 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 1656 } 1657 1658 static void 1659 print_iostat_header(iostat_cbdata_t *cb) 1660 { 1661 (void) printf("%*s capacity operations bandwidth\n", 1662 cb->cb_namewidth, ""); 1663 (void) printf("%-*s used avail read write read write\n", 1664 cb->cb_namewidth, "pool"); 1665 print_iostat_separator(cb); 1666 } 1667 1668 /* 1669 * Display a single statistic. 1670 */ 1671 static void 1672 print_one_stat(uint64_t value) 1673 { 1674 char buf[64]; 1675 1676 zfs_nicenum(value, buf, sizeof (buf)); 1677 (void) printf(" %5s", buf); 1678 } 1679 1680 /* 1681 * Print out all the statistics for the given vdev. This can either be the 1682 * toplevel configuration, or called recursively. If 'name' is NULL, then this 1683 * is a verbose output, and we don't want to display the toplevel pool stats. 1684 */ 1685 void 1686 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 1687 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 1688 { 1689 nvlist_t **oldchild, **newchild; 1690 uint_t c, children; 1691 vdev_stat_t *oldvs, *newvs; 1692 vdev_stat_t zerovs = { 0 }; 1693 uint64_t tdelta; 1694 double scale; 1695 char *vname; 1696 1697 if (oldnv != NULL) { 1698 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS, 1699 (uint64_t **)&oldvs, &c) == 0); 1700 } else { 1701 oldvs = &zerovs; 1702 } 1703 1704 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS, 1705 (uint64_t **)&newvs, &c) == 0); 1706 1707 if (strlen(name) + depth > cb->cb_namewidth) 1708 (void) printf("%*s%s", depth, "", name); 1709 else 1710 (void) printf("%*s%s%*s", depth, "", name, 1711 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 1712 1713 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 1714 1715 if (tdelta == 0) 1716 scale = 1.0; 1717 else 1718 scale = (double)NANOSEC / tdelta; 1719 1720 /* only toplevel vdevs have capacity stats */ 1721 if (newvs->vs_space == 0) { 1722 (void) printf(" - -"); 1723 } else { 1724 print_one_stat(newvs->vs_alloc); 1725 print_one_stat(newvs->vs_space - newvs->vs_alloc); 1726 } 1727 1728 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 1729 oldvs->vs_ops[ZIO_TYPE_READ]))); 1730 1731 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 1732 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 1733 1734 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 1735 oldvs->vs_bytes[ZIO_TYPE_READ]))); 1736 1737 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 1738 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 1739 1740 (void) printf("\n"); 1741 1742 if (!cb->cb_verbose) 1743 return; 1744 1745 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 1746 &newchild, &children) != 0) 1747 return; 1748 1749 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 1750 &oldchild, &c) != 0) 1751 return; 1752 1753 for (c = 0; c < children; c++) { 1754 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1755 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1756 newchild[c], cb, depth + 2); 1757 free(vname); 1758 } 1759 1760 /* 1761 * Include level 2 ARC devices in iostat output 1762 */ 1763 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 1764 &newchild, &children) != 0) 1765 return; 1766 1767 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 1768 &oldchild, &c) != 0) 1769 return; 1770 1771 if (children > 0) { 1772 (void) printf("%-*s - - - - - " 1773 "-\n", cb->cb_namewidth, "cache"); 1774 for (c = 0; c < children; c++) { 1775 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1776 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1777 newchild[c], cb, depth + 2); 1778 free(vname); 1779 } 1780 } 1781 } 1782 1783 static int 1784 refresh_iostat(zpool_handle_t *zhp, void *data) 1785 { 1786 iostat_cbdata_t *cb = data; 1787 boolean_t missing; 1788 1789 /* 1790 * If the pool has disappeared, remove it from the list and continue. 1791 */ 1792 if (zpool_refresh_stats(zhp, &missing) != 0) 1793 return (-1); 1794 1795 if (missing) 1796 pool_list_remove(cb->cb_list, zhp); 1797 1798 return (0); 1799 } 1800 1801 /* 1802 * Callback to print out the iostats for the given pool. 1803 */ 1804 int 1805 print_iostat(zpool_handle_t *zhp, void *data) 1806 { 1807 iostat_cbdata_t *cb = data; 1808 nvlist_t *oldconfig, *newconfig; 1809 nvlist_t *oldnvroot, *newnvroot; 1810 1811 newconfig = zpool_get_config(zhp, &oldconfig); 1812 1813 if (cb->cb_iteration == 1) 1814 oldconfig = NULL; 1815 1816 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 1817 &newnvroot) == 0); 1818 1819 if (oldconfig == NULL) 1820 oldnvroot = NULL; 1821 else 1822 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 1823 &oldnvroot) == 0); 1824 1825 /* 1826 * Print out the statistics for the pool. 1827 */ 1828 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 1829 1830 if (cb->cb_verbose) 1831 print_iostat_separator(cb); 1832 1833 return (0); 1834 } 1835 1836 int 1837 get_namewidth(zpool_handle_t *zhp, void *data) 1838 { 1839 iostat_cbdata_t *cb = data; 1840 nvlist_t *config, *nvroot; 1841 1842 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 1843 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1844 &nvroot) == 0); 1845 if (!cb->cb_verbose) 1846 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 1847 else 1848 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); 1849 } 1850 1851 /* 1852 * The width must fall into the range [10,38]. The upper limit is the 1853 * maximum we can have and still fit in 80 columns. 1854 */ 1855 if (cb->cb_namewidth < 10) 1856 cb->cb_namewidth = 10; 1857 if (cb->cb_namewidth > 38) 1858 cb->cb_namewidth = 38; 1859 1860 return (0); 1861 } 1862 1863 /* 1864 * zpool iostat [-v] [pool] ... [interval [count]] 1865 * 1866 * -v Display statistics for individual vdevs 1867 * 1868 * This command can be tricky because we want to be able to deal with pool 1869 * creation/destruction as well as vdev configuration changes. The bulk of this 1870 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 1871 * on pool_list_update() to detect the addition of new pools. Configuration 1872 * changes are all handled within libzfs. 1873 */ 1874 int 1875 zpool_do_iostat(int argc, char **argv) 1876 { 1877 int c; 1878 int ret; 1879 int npools; 1880 unsigned long interval = 0, count = 0; 1881 zpool_list_t *list; 1882 boolean_t verbose = B_FALSE; 1883 iostat_cbdata_t cb; 1884 1885 /* check options */ 1886 while ((c = getopt(argc, argv, "v")) != -1) { 1887 switch (c) { 1888 case 'v': 1889 verbose = B_TRUE; 1890 break; 1891 case '?': 1892 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1893 optopt); 1894 usage(B_FALSE); 1895 } 1896 } 1897 1898 argc -= optind; 1899 argv += optind; 1900 1901 /* 1902 * Determine if the last argument is an integer or a pool name 1903 */ 1904 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1905 char *end; 1906 1907 errno = 0; 1908 interval = strtoul(argv[argc - 1], &end, 10); 1909 1910 if (*end == '\0' && errno == 0) { 1911 if (interval == 0) { 1912 (void) fprintf(stderr, gettext("interval " 1913 "cannot be zero\n")); 1914 usage(B_FALSE); 1915 } 1916 1917 /* 1918 * Ignore the last parameter 1919 */ 1920 argc--; 1921 } else { 1922 /* 1923 * If this is not a valid number, just plow on. The 1924 * user will get a more informative error message later 1925 * on. 1926 */ 1927 interval = 0; 1928 } 1929 } 1930 1931 /* 1932 * If the last argument is also an integer, then we have both a count 1933 * and an integer. 1934 */ 1935 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1936 char *end; 1937 1938 errno = 0; 1939 count = interval; 1940 interval = strtoul(argv[argc - 1], &end, 10); 1941 1942 if (*end == '\0' && errno == 0) { 1943 if (interval == 0) { 1944 (void) fprintf(stderr, gettext("interval " 1945 "cannot be zero\n")); 1946 usage(B_FALSE); 1947 } 1948 1949 /* 1950 * Ignore the last parameter 1951 */ 1952 argc--; 1953 } else { 1954 interval = 0; 1955 } 1956 } 1957 1958 /* 1959 * Construct the list of all interesting pools. 1960 */ 1961 ret = 0; 1962 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 1963 return (1); 1964 1965 if (pool_list_count(list) == 0 && argc != 0) { 1966 pool_list_free(list); 1967 return (1); 1968 } 1969 1970 if (pool_list_count(list) == 0 && interval == 0) { 1971 pool_list_free(list); 1972 (void) fprintf(stderr, gettext("no pools available\n")); 1973 return (1); 1974 } 1975 1976 /* 1977 * Enter the main iostat loop. 1978 */ 1979 cb.cb_list = list; 1980 cb.cb_verbose = verbose; 1981 cb.cb_iteration = 0; 1982 cb.cb_namewidth = 0; 1983 1984 for (;;) { 1985 pool_list_update(list); 1986 1987 if ((npools = pool_list_count(list)) == 0) 1988 break; 1989 1990 /* 1991 * Refresh all statistics. This is done as an explicit step 1992 * before calculating the maximum name width, so that any 1993 * configuration changes are properly accounted for. 1994 */ 1995 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 1996 1997 /* 1998 * Iterate over all pools to determine the maximum width 1999 * for the pool / device name column across all pools. 2000 */ 2001 cb.cb_namewidth = 0; 2002 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2003 2004 /* 2005 * If it's the first time, or verbose mode, print the header. 2006 */ 2007 if (++cb.cb_iteration == 1 || verbose) 2008 print_iostat_header(&cb); 2009 2010 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2011 2012 /* 2013 * If there's more than one pool, and we're not in verbose mode 2014 * (which prints a separator for us), then print a separator. 2015 */ 2016 if (npools > 1 && !verbose) 2017 print_iostat_separator(&cb); 2018 2019 if (verbose) 2020 (void) printf("\n"); 2021 2022 /* 2023 * Flush the output so that redirection to a file isn't buffered 2024 * indefinitely. 2025 */ 2026 (void) fflush(stdout); 2027 2028 if (interval == 0) 2029 break; 2030 2031 if (count != 0 && --count == 0) 2032 break; 2033 2034 (void) sleep(interval); 2035 } 2036 2037 pool_list_free(list); 2038 2039 return (ret); 2040 } 2041 2042 typedef struct list_cbdata { 2043 boolean_t cb_scripted; 2044 boolean_t cb_first; 2045 zprop_list_t *cb_proplist; 2046 } list_cbdata_t; 2047 2048 /* 2049 * Given a list of columns to display, output appropriate headers for each one. 2050 */ 2051 static void 2052 print_header(zprop_list_t *pl) 2053 { 2054 const char *header; 2055 boolean_t first = B_TRUE; 2056 boolean_t right_justify; 2057 2058 for (; pl != NULL; pl = pl->pl_next) { 2059 if (pl->pl_prop == ZPROP_INVAL) 2060 continue; 2061 2062 if (!first) 2063 (void) printf(" "); 2064 else 2065 first = B_FALSE; 2066 2067 header = zpool_prop_column_name(pl->pl_prop); 2068 right_justify = zpool_prop_align_right(pl->pl_prop); 2069 2070 if (pl->pl_next == NULL && !right_justify) 2071 (void) printf("%s", header); 2072 else if (right_justify) 2073 (void) printf("%*s", pl->pl_width, header); 2074 else 2075 (void) printf("%-*s", pl->pl_width, header); 2076 } 2077 2078 (void) printf("\n"); 2079 } 2080 2081 /* 2082 * Given a pool and a list of properties, print out all the properties according 2083 * to the described layout. 2084 */ 2085 static void 2086 print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted) 2087 { 2088 boolean_t first = B_TRUE; 2089 char property[ZPOOL_MAXPROPLEN]; 2090 char *propstr; 2091 boolean_t right_justify; 2092 int width; 2093 2094 for (; pl != NULL; pl = pl->pl_next) { 2095 if (!first) { 2096 if (scripted) 2097 (void) printf("\t"); 2098 else 2099 (void) printf(" "); 2100 } else { 2101 first = B_FALSE; 2102 } 2103 2104 right_justify = B_FALSE; 2105 if (pl->pl_prop != ZPROP_INVAL) { 2106 if (zpool_get_prop(zhp, pl->pl_prop, property, 2107 sizeof (property), NULL) != 0) 2108 propstr = "-"; 2109 else 2110 propstr = property; 2111 2112 right_justify = zpool_prop_align_right(pl->pl_prop); 2113 } else { 2114 propstr = "-"; 2115 } 2116 2117 width = pl->pl_width; 2118 2119 /* 2120 * If this is being called in scripted mode, or if this is the 2121 * last column and it is left-justified, don't include a width 2122 * format specifier. 2123 */ 2124 if (scripted || (pl->pl_next == NULL && !right_justify)) 2125 (void) printf("%s", propstr); 2126 else if (right_justify) 2127 (void) printf("%*s", width, propstr); 2128 else 2129 (void) printf("%-*s", width, propstr); 2130 } 2131 2132 (void) printf("\n"); 2133 } 2134 2135 /* 2136 * Generic callback function to list a pool. 2137 */ 2138 int 2139 list_callback(zpool_handle_t *zhp, void *data) 2140 { 2141 list_cbdata_t *cbp = data; 2142 2143 if (cbp->cb_first) { 2144 if (!cbp->cb_scripted) 2145 print_header(cbp->cb_proplist); 2146 cbp->cb_first = B_FALSE; 2147 } 2148 2149 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted); 2150 2151 return (0); 2152 } 2153 2154 /* 2155 * zpool list [-H] [-o prop[,prop]*] [pool] ... 2156 * 2157 * -H Scripted mode. Don't display headers, and separate properties 2158 * by a single tab. 2159 * -o List of properties to display. Defaults to 2160 * "name,size,used,available,capacity,health,altroot" 2161 * 2162 * List all pools in the system, whether or not they're healthy. Output space 2163 * statistics for each one, as well as health status summary. 2164 */ 2165 int 2166 zpool_do_list(int argc, char **argv) 2167 { 2168 int c; 2169 int ret; 2170 list_cbdata_t cb = { 0 }; 2171 static char default_props[] = 2172 "name,size,used,available,capacity,health,altroot"; 2173 char *props = default_props; 2174 2175 /* check options */ 2176 while ((c = getopt(argc, argv, ":Ho:")) != -1) { 2177 switch (c) { 2178 case 'H': 2179 cb.cb_scripted = B_TRUE; 2180 break; 2181 case 'o': 2182 props = optarg; 2183 break; 2184 case ':': 2185 (void) fprintf(stderr, gettext("missing argument for " 2186 "'%c' option\n"), optopt); 2187 usage(B_FALSE); 2188 break; 2189 case '?': 2190 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2191 optopt); 2192 usage(B_FALSE); 2193 } 2194 } 2195 2196 argc -= optind; 2197 argv += optind; 2198 2199 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 2200 usage(B_FALSE); 2201 2202 cb.cb_first = B_TRUE; 2203 2204 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 2205 list_callback, &cb); 2206 2207 zprop_free_list(cb.cb_proplist); 2208 2209 if (argc == 0 && cb.cb_first && !cb.cb_scripted) { 2210 (void) printf(gettext("no pools available\n")); 2211 return (0); 2212 } 2213 2214 return (ret); 2215 } 2216 2217 static nvlist_t * 2218 zpool_get_vdev_by_name(nvlist_t *nv, char *name) 2219 { 2220 nvlist_t **child; 2221 uint_t c, children; 2222 nvlist_t *match; 2223 char *path; 2224 2225 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2226 &child, &children) != 0) { 2227 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2228 if (strncmp(name, "/dev/dsk/", 9) == 0) 2229 name += 9; 2230 if (strncmp(path, "/dev/dsk/", 9) == 0) 2231 path += 9; 2232 if (strcmp(name, path) == 0) 2233 return (nv); 2234 return (NULL); 2235 } 2236 2237 for (c = 0; c < children; c++) 2238 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 2239 return (match); 2240 2241 return (NULL); 2242 } 2243 2244 static int 2245 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 2246 { 2247 boolean_t force = B_FALSE; 2248 int c; 2249 nvlist_t *nvroot; 2250 char *poolname, *old_disk, *new_disk; 2251 zpool_handle_t *zhp; 2252 int ret; 2253 2254 /* check options */ 2255 while ((c = getopt(argc, argv, "f")) != -1) { 2256 switch (c) { 2257 case 'f': 2258 force = B_TRUE; 2259 break; 2260 case '?': 2261 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2262 optopt); 2263 usage(B_FALSE); 2264 } 2265 } 2266 2267 argc -= optind; 2268 argv += optind; 2269 2270 /* get pool name and check number of arguments */ 2271 if (argc < 1) { 2272 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2273 usage(B_FALSE); 2274 } 2275 2276 poolname = argv[0]; 2277 2278 if (argc < 2) { 2279 (void) fprintf(stderr, 2280 gettext("missing <device> specification\n")); 2281 usage(B_FALSE); 2282 } 2283 2284 old_disk = argv[1]; 2285 2286 if (argc < 3) { 2287 if (!replacing) { 2288 (void) fprintf(stderr, 2289 gettext("missing <new_device> specification\n")); 2290 usage(B_FALSE); 2291 } 2292 new_disk = old_disk; 2293 argc -= 1; 2294 argv += 1; 2295 } else { 2296 new_disk = argv[2]; 2297 argc -= 2; 2298 argv += 2; 2299 } 2300 2301 if (argc > 1) { 2302 (void) fprintf(stderr, gettext("too many arguments\n")); 2303 usage(B_FALSE); 2304 } 2305 2306 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2307 return (1); 2308 2309 if (zpool_get_config(zhp, NULL) == NULL) { 2310 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2311 poolname); 2312 zpool_close(zhp); 2313 return (1); 2314 } 2315 2316 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 2317 argc, argv); 2318 if (nvroot == NULL) { 2319 zpool_close(zhp); 2320 return (1); 2321 } 2322 2323 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2324 2325 nvlist_free(nvroot); 2326 zpool_close(zhp); 2327 2328 return (ret); 2329 } 2330 2331 /* 2332 * zpool replace [-f] <pool> <device> <new_device> 2333 * 2334 * -f Force attach, even if <new_device> appears to be in use. 2335 * 2336 * Replace <device> with <new_device>. 2337 */ 2338 /* ARGSUSED */ 2339 int 2340 zpool_do_replace(int argc, char **argv) 2341 { 2342 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2343 } 2344 2345 /* 2346 * zpool attach [-f] <pool> <device> <new_device> 2347 * 2348 * -f Force attach, even if <new_device> appears to be in use. 2349 * 2350 * Attach <new_device> to the mirror containing <device>. If <device> is not 2351 * part of a mirror, then <device> will be transformed into a mirror of 2352 * <device> and <new_device>. In either case, <new_device> will begin life 2353 * with a DTL of [0, now], and will immediately begin to resilver itself. 2354 */ 2355 int 2356 zpool_do_attach(int argc, char **argv) 2357 { 2358 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2359 } 2360 2361 /* 2362 * zpool detach [-f] <pool> <device> 2363 * 2364 * -f Force detach of <device>, even if DTLs argue against it 2365 * (not supported yet) 2366 * 2367 * Detach a device from a mirror. The operation will be refused if <device> 2368 * is the last device in the mirror, or if the DTLs indicate that this device 2369 * has the only valid copy of some data. 2370 */ 2371 /* ARGSUSED */ 2372 int 2373 zpool_do_detach(int argc, char **argv) 2374 { 2375 int c; 2376 char *poolname, *path; 2377 zpool_handle_t *zhp; 2378 int ret; 2379 2380 /* check options */ 2381 while ((c = getopt(argc, argv, "f")) != -1) { 2382 switch (c) { 2383 case 'f': 2384 case '?': 2385 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2386 optopt); 2387 usage(B_FALSE); 2388 } 2389 } 2390 2391 argc -= optind; 2392 argv += optind; 2393 2394 /* get pool name and check number of arguments */ 2395 if (argc < 1) { 2396 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2397 usage(B_FALSE); 2398 } 2399 2400 if (argc < 2) { 2401 (void) fprintf(stderr, 2402 gettext("missing <device> specification\n")); 2403 usage(B_FALSE); 2404 } 2405 2406 poolname = argv[0]; 2407 path = argv[1]; 2408 2409 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2410 return (1); 2411 2412 ret = zpool_vdev_detach(zhp, path); 2413 2414 zpool_close(zhp); 2415 2416 return (ret); 2417 } 2418 2419 /* 2420 * zpool online <pool> <device> ... 2421 */ 2422 int 2423 zpool_do_online(int argc, char **argv) 2424 { 2425 int c, i; 2426 char *poolname; 2427 zpool_handle_t *zhp; 2428 int ret = 0; 2429 vdev_state_t newstate; 2430 2431 /* check options */ 2432 while ((c = getopt(argc, argv, "t")) != -1) { 2433 switch (c) { 2434 case 't': 2435 case '?': 2436 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2437 optopt); 2438 usage(B_FALSE); 2439 } 2440 } 2441 2442 argc -= optind; 2443 argv += optind; 2444 2445 /* get pool name and check number of arguments */ 2446 if (argc < 1) { 2447 (void) fprintf(stderr, gettext("missing pool name\n")); 2448 usage(B_FALSE); 2449 } 2450 if (argc < 2) { 2451 (void) fprintf(stderr, gettext("missing device name\n")); 2452 usage(B_FALSE); 2453 } 2454 2455 poolname = argv[0]; 2456 2457 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2458 return (1); 2459 2460 for (i = 1; i < argc; i++) { 2461 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) { 2462 if (newstate != VDEV_STATE_HEALTHY) { 2463 (void) printf(gettext("warning: device '%s' " 2464 "onlined, but remains in faulted state\n"), 2465 argv[i]); 2466 if (newstate == VDEV_STATE_FAULTED) 2467 (void) printf(gettext("use 'zpool " 2468 "clear' to restore a faulted " 2469 "device\n")); 2470 else 2471 (void) printf(gettext("use 'zpool " 2472 "replace' to replace devices " 2473 "that are no longer present\n")); 2474 } 2475 } else { 2476 ret = 1; 2477 } 2478 } 2479 2480 zpool_close(zhp); 2481 2482 return (ret); 2483 } 2484 2485 /* 2486 * zpool offline [-ft] <pool> <device> ... 2487 * 2488 * -f Force the device into the offline state, even if doing 2489 * so would appear to compromise pool availability. 2490 * (not supported yet) 2491 * 2492 * -t Only take the device off-line temporarily. The offline 2493 * state will not be persistent across reboots. 2494 */ 2495 /* ARGSUSED */ 2496 int 2497 zpool_do_offline(int argc, char **argv) 2498 { 2499 int c, i; 2500 char *poolname; 2501 zpool_handle_t *zhp; 2502 int ret = 0; 2503 boolean_t istmp = B_FALSE; 2504 2505 /* check options */ 2506 while ((c = getopt(argc, argv, "ft")) != -1) { 2507 switch (c) { 2508 case 't': 2509 istmp = B_TRUE; 2510 break; 2511 case 'f': 2512 case '?': 2513 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2514 optopt); 2515 usage(B_FALSE); 2516 } 2517 } 2518 2519 argc -= optind; 2520 argv += optind; 2521 2522 /* get pool name and check number of arguments */ 2523 if (argc < 1) { 2524 (void) fprintf(stderr, gettext("missing pool name\n")); 2525 usage(B_FALSE); 2526 } 2527 if (argc < 2) { 2528 (void) fprintf(stderr, gettext("missing device name\n")); 2529 usage(B_FALSE); 2530 } 2531 2532 poolname = argv[0]; 2533 2534 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2535 return (1); 2536 2537 for (i = 1; i < argc; i++) { 2538 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 2539 ret = 1; 2540 } 2541 2542 zpool_close(zhp); 2543 2544 return (ret); 2545 } 2546 2547 /* 2548 * zpool clear <pool> [device] 2549 * 2550 * Clear all errors associated with a pool or a particular device. 2551 */ 2552 int 2553 zpool_do_clear(int argc, char **argv) 2554 { 2555 int ret = 0; 2556 zpool_handle_t *zhp; 2557 char *pool, *device; 2558 2559 if (argc < 2) { 2560 (void) fprintf(stderr, gettext("missing pool name\n")); 2561 usage(B_FALSE); 2562 } 2563 2564 if (argc > 3) { 2565 (void) fprintf(stderr, gettext("too many arguments\n")); 2566 usage(B_FALSE); 2567 } 2568 2569 pool = argv[1]; 2570 device = argc == 3 ? argv[2] : NULL; 2571 2572 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 2573 return (1); 2574 2575 if (zpool_clear(zhp, device) != 0) 2576 ret = 1; 2577 2578 zpool_close(zhp); 2579 2580 return (ret); 2581 } 2582 2583 typedef struct scrub_cbdata { 2584 int cb_type; 2585 int cb_argc; 2586 char **cb_argv; 2587 } scrub_cbdata_t; 2588 2589 int 2590 scrub_callback(zpool_handle_t *zhp, void *data) 2591 { 2592 scrub_cbdata_t *cb = data; 2593 int err; 2594 2595 /* 2596 * Ignore faulted pools. 2597 */ 2598 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2599 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2600 "currently unavailable\n"), zpool_get_name(zhp)); 2601 return (1); 2602 } 2603 2604 err = zpool_scrub(zhp, cb->cb_type); 2605 2606 return (err != 0); 2607 } 2608 2609 /* 2610 * zpool scrub [-s] <pool> ... 2611 * 2612 * -s Stop. Stops any in-progress scrub. 2613 */ 2614 int 2615 zpool_do_scrub(int argc, char **argv) 2616 { 2617 int c; 2618 scrub_cbdata_t cb; 2619 2620 cb.cb_type = POOL_SCRUB_EVERYTHING; 2621 2622 /* check options */ 2623 while ((c = getopt(argc, argv, "s")) != -1) { 2624 switch (c) { 2625 case 's': 2626 cb.cb_type = POOL_SCRUB_NONE; 2627 break; 2628 case '?': 2629 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2630 optopt); 2631 usage(B_FALSE); 2632 } 2633 } 2634 2635 cb.cb_argc = argc; 2636 cb.cb_argv = argv; 2637 argc -= optind; 2638 argv += optind; 2639 2640 if (argc < 1) { 2641 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2642 usage(B_FALSE); 2643 } 2644 2645 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 2646 } 2647 2648 typedef struct status_cbdata { 2649 int cb_count; 2650 boolean_t cb_allpools; 2651 boolean_t cb_verbose; 2652 boolean_t cb_explain; 2653 boolean_t cb_first; 2654 } status_cbdata_t; 2655 2656 /* 2657 * Print out detailed scrub status. 2658 */ 2659 void 2660 print_scrub_status(nvlist_t *nvroot) 2661 { 2662 vdev_stat_t *vs; 2663 uint_t vsc; 2664 time_t start, end, now; 2665 double fraction_done; 2666 uint64_t examined, total, minutes_left, minutes_taken; 2667 char *scrub_type; 2668 2669 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2670 (uint64_t **)&vs, &vsc) == 0); 2671 2672 /* 2673 * If there's never been a scrub, there's not much to say. 2674 */ 2675 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2676 (void) printf(gettext("none requested\n")); 2677 return; 2678 } 2679 2680 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2681 "resilver" : "scrub"; 2682 2683 start = vs->vs_scrub_start; 2684 end = vs->vs_scrub_end; 2685 now = time(NULL); 2686 examined = vs->vs_scrub_examined; 2687 total = vs->vs_alloc; 2688 2689 if (end != 0) { 2690 minutes_taken = (uint64_t)((end - start) / 60); 2691 2692 (void) printf(gettext("%s %s after %lluh%um with %llu errors " 2693 "on %s"), 2694 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2695 (u_longlong_t)(minutes_taken / 60), 2696 (uint_t)(minutes_taken % 60), 2697 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2698 return; 2699 } 2700 2701 if (examined == 0) 2702 examined = 1; 2703 if (examined > total) 2704 total = examined; 2705 2706 fraction_done = (double)examined / total; 2707 minutes_left = (uint64_t)((now - start) * 2708 (1 - fraction_done) / fraction_done / 60); 2709 minutes_taken = (uint64_t)((now - start) / 60); 2710 2711 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, " 2712 "%lluh%um to go\n"), 2713 scrub_type, (u_longlong_t)(minutes_taken / 60), 2714 (uint_t)(minutes_taken % 60), 100 * fraction_done, 2715 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2716 } 2717 2718 typedef struct spare_cbdata { 2719 uint64_t cb_guid; 2720 zpool_handle_t *cb_zhp; 2721 } spare_cbdata_t; 2722 2723 static boolean_t 2724 find_vdev(nvlist_t *nv, uint64_t search) 2725 { 2726 uint64_t guid; 2727 nvlist_t **child; 2728 uint_t c, children; 2729 2730 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2731 search == guid) 2732 return (B_TRUE); 2733 2734 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2735 &child, &children) == 0) { 2736 for (c = 0; c < children; c++) 2737 if (find_vdev(child[c], search)) 2738 return (B_TRUE); 2739 } 2740 2741 return (B_FALSE); 2742 } 2743 2744 static int 2745 find_spare(zpool_handle_t *zhp, void *data) 2746 { 2747 spare_cbdata_t *cbp = data; 2748 nvlist_t *config, *nvroot; 2749 2750 config = zpool_get_config(zhp, NULL); 2751 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2752 &nvroot) == 0); 2753 2754 if (find_vdev(nvroot, cbp->cb_guid)) { 2755 cbp->cb_zhp = zhp; 2756 return (1); 2757 } 2758 2759 zpool_close(zhp); 2760 return (0); 2761 } 2762 2763 /* 2764 * Print out configuration state as requested by status_callback. 2765 */ 2766 void 2767 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2768 int namewidth, int depth, boolean_t isspare, boolean_t print_logs) 2769 { 2770 nvlist_t **child; 2771 uint_t c, children; 2772 vdev_stat_t *vs; 2773 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2774 char *vname; 2775 uint64_t notpresent; 2776 spare_cbdata_t cb; 2777 char *state; 2778 2779 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2780 (uint64_t **)&vs, &c) == 0); 2781 2782 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2783 &child, &children) != 0) 2784 children = 0; 2785 2786 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2787 if (isspare) { 2788 /* 2789 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2790 * online drives. 2791 */ 2792 if (vs->vs_aux == VDEV_AUX_SPARED) 2793 state = "INUSE"; 2794 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2795 state = "AVAIL"; 2796 } 2797 2798 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2799 name, state); 2800 2801 if (!isspare) { 2802 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2803 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2804 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2805 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2806 } 2807 2808 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2809 ¬present) == 0) { 2810 char *path; 2811 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2812 (void) printf(" was %s", path); 2813 } else if (vs->vs_aux != 0) { 2814 (void) printf(" "); 2815 2816 switch (vs->vs_aux) { 2817 case VDEV_AUX_OPEN_FAILED: 2818 (void) printf(gettext("cannot open")); 2819 break; 2820 2821 case VDEV_AUX_BAD_GUID_SUM: 2822 (void) printf(gettext("missing device")); 2823 break; 2824 2825 case VDEV_AUX_NO_REPLICAS: 2826 (void) printf(gettext("insufficient replicas")); 2827 break; 2828 2829 case VDEV_AUX_VERSION_NEWER: 2830 (void) printf(gettext("newer version")); 2831 break; 2832 2833 case VDEV_AUX_SPARED: 2834 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2835 &cb.cb_guid) == 0); 2836 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2837 if (strcmp(zpool_get_name(cb.cb_zhp), 2838 zpool_get_name(zhp)) == 0) 2839 (void) printf(gettext("currently in " 2840 "use")); 2841 else 2842 (void) printf(gettext("in use by " 2843 "pool '%s'"), 2844 zpool_get_name(cb.cb_zhp)); 2845 zpool_close(cb.cb_zhp); 2846 } else { 2847 (void) printf(gettext("currently in use")); 2848 } 2849 break; 2850 2851 case VDEV_AUX_ERR_EXCEEDED: 2852 (void) printf(gettext("too many errors")); 2853 break; 2854 2855 case VDEV_AUX_IO_FAILURE: 2856 (void) printf(gettext("experienced I/O failures")); 2857 break; 2858 2859 case VDEV_AUX_BAD_LOG: 2860 (void) printf(gettext("bad intent log")); 2861 break; 2862 2863 default: 2864 (void) printf(gettext("corrupted data")); 2865 break; 2866 } 2867 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2868 /* 2869 * Report bytes resilvered/repaired on leaf devices. 2870 */ 2871 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2872 (void) printf(gettext(" %s %s"), repaired, 2873 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2874 "resilvered" : "repaired"); 2875 } 2876 2877 (void) printf("\n"); 2878 2879 for (c = 0; c < children; c++) { 2880 uint64_t is_log = B_FALSE; 2881 2882 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2883 &is_log); 2884 if ((is_log && !print_logs) || (!is_log && print_logs)) 2885 continue; 2886 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2887 print_status_config(zhp, vname, child[c], 2888 namewidth, depth + 2, isspare, B_FALSE); 2889 free(vname); 2890 } 2891 } 2892 2893 static void 2894 print_error_log(zpool_handle_t *zhp) 2895 { 2896 nvlist_t *nverrlist = NULL; 2897 nvpair_t *elem; 2898 char *pathname; 2899 size_t len = MAXPATHLEN * 2; 2900 2901 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2902 (void) printf("errors: List of errors unavailable " 2903 "(insufficient privileges)\n"); 2904 return; 2905 } 2906 2907 (void) printf("errors: Permanent errors have been " 2908 "detected in the following files:\n\n"); 2909 2910 pathname = safe_malloc(len); 2911 elem = NULL; 2912 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2913 nvlist_t *nv; 2914 uint64_t dsobj, obj; 2915 2916 verify(nvpair_value_nvlist(elem, &nv) == 0); 2917 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2918 &dsobj) == 0); 2919 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2920 &obj) == 0); 2921 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2922 (void) printf("%7s %s\n", "", pathname); 2923 } 2924 free(pathname); 2925 nvlist_free(nverrlist); 2926 } 2927 2928 static void 2929 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2930 int namewidth) 2931 { 2932 uint_t i; 2933 char *name; 2934 2935 if (nspares == 0) 2936 return; 2937 2938 (void) printf(gettext("\tspares\n")); 2939 2940 for (i = 0; i < nspares; i++) { 2941 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2942 print_status_config(zhp, name, spares[i], 2943 namewidth, 2, B_TRUE, B_FALSE); 2944 free(name); 2945 } 2946 } 2947 2948 static void 2949 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 2950 int namewidth) 2951 { 2952 uint_t i; 2953 char *name; 2954 2955 if (nl2cache == 0) 2956 return; 2957 2958 (void) printf(gettext("\tcache\n")); 2959 2960 for (i = 0; i < nl2cache; i++) { 2961 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]); 2962 print_status_config(zhp, name, l2cache[i], 2963 namewidth, 2, B_FALSE, B_FALSE); 2964 free(name); 2965 } 2966 } 2967 2968 /* 2969 * Display a summary of pool status. Displays a summary such as: 2970 * 2971 * pool: tank 2972 * status: DEGRADED 2973 * reason: One or more devices ... 2974 * see: http://www.sun.com/msg/ZFS-xxxx-01 2975 * config: 2976 * mirror DEGRADED 2977 * c1t0d0 OK 2978 * c2t0d0 UNAVAIL 2979 * 2980 * When given the '-v' option, we print out the complete config. If the '-e' 2981 * option is specified, then we print out error rate information as well. 2982 */ 2983 int 2984 status_callback(zpool_handle_t *zhp, void *data) 2985 { 2986 status_cbdata_t *cbp = data; 2987 nvlist_t *config, *nvroot; 2988 char *msgid; 2989 int reason; 2990 const char *health; 2991 uint_t c; 2992 vdev_stat_t *vs; 2993 2994 config = zpool_get_config(zhp, NULL); 2995 reason = zpool_get_status(zhp, &msgid); 2996 2997 cbp->cb_count++; 2998 2999 /* 3000 * If we were given 'zpool status -x', only report those pools with 3001 * problems. 3002 */ 3003 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 3004 if (!cbp->cb_allpools) { 3005 (void) printf(gettext("pool '%s' is healthy\n"), 3006 zpool_get_name(zhp)); 3007 if (cbp->cb_first) 3008 cbp->cb_first = B_FALSE; 3009 } 3010 return (0); 3011 } 3012 3013 if (cbp->cb_first) 3014 cbp->cb_first = B_FALSE; 3015 else 3016 (void) printf("\n"); 3017 3018 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3019 &nvroot) == 0); 3020 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 3021 (uint64_t **)&vs, &c) == 0); 3022 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 3023 3024 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 3025 (void) printf(gettext(" state: %s\n"), health); 3026 3027 switch (reason) { 3028 case ZPOOL_STATUS_MISSING_DEV_R: 3029 (void) printf(gettext("status: One or more devices could not " 3030 "be opened. Sufficient replicas exist for\n\tthe pool to " 3031 "continue functioning in a degraded state.\n")); 3032 (void) printf(gettext("action: Attach the missing device and " 3033 "online it using 'zpool online'.\n")); 3034 break; 3035 3036 case ZPOOL_STATUS_MISSING_DEV_NR: 3037 (void) printf(gettext("status: One or more devices could not " 3038 "be opened. There are insufficient\n\treplicas for the " 3039 "pool to continue functioning.\n")); 3040 (void) printf(gettext("action: Attach the missing device and " 3041 "online it using 'zpool online'.\n")); 3042 break; 3043 3044 case ZPOOL_STATUS_CORRUPT_LABEL_R: 3045 (void) printf(gettext("status: One or more devices could not " 3046 "be used because the label is missing or\n\tinvalid. " 3047 "Sufficient replicas exist for the pool to continue\n\t" 3048 "functioning in a degraded state.\n")); 3049 (void) printf(gettext("action: Replace the device using " 3050 "'zpool replace'.\n")); 3051 break; 3052 3053 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 3054 (void) printf(gettext("status: One or more devices could not " 3055 "be used because the label is missing \n\tor invalid. " 3056 "There are insufficient replicas for the pool to " 3057 "continue\n\tfunctioning.\n")); 3058 (void) printf(gettext("action: Destroy and re-create the pool " 3059 "from a backup source.\n")); 3060 break; 3061 3062 case ZPOOL_STATUS_FAILING_DEV: 3063 (void) printf(gettext("status: One or more devices has " 3064 "experienced an unrecoverable error. An\n\tattempt was " 3065 "made to correct the error. Applications are " 3066 "unaffected.\n")); 3067 (void) printf(gettext("action: Determine if the device needs " 3068 "to be replaced, and clear the errors\n\tusing " 3069 "'zpool clear' or replace the device with 'zpool " 3070 "replace'.\n")); 3071 break; 3072 3073 case ZPOOL_STATUS_OFFLINE_DEV: 3074 (void) printf(gettext("status: One or more devices has " 3075 "been taken offline by the administrator.\n\tSufficient " 3076 "replicas exist for the pool to continue functioning in " 3077 "a\n\tdegraded state.\n")); 3078 (void) printf(gettext("action: Online the device using " 3079 "'zpool online' or replace the device with\n\t'zpool " 3080 "replace'.\n")); 3081 break; 3082 3083 case ZPOOL_STATUS_RESILVERING: 3084 (void) printf(gettext("status: One or more devices is " 3085 "currently being resilvered. The pool will\n\tcontinue " 3086 "to function, possibly in a degraded state.\n")); 3087 (void) printf(gettext("action: Wait for the resilver to " 3088 "complete.\n")); 3089 break; 3090 3091 case ZPOOL_STATUS_CORRUPT_DATA: 3092 (void) printf(gettext("status: One or more devices has " 3093 "experienced an error resulting in data\n\tcorruption. " 3094 "Applications may be affected.\n")); 3095 (void) printf(gettext("action: Restore the file in question " 3096 "if possible. Otherwise restore the\n\tentire pool from " 3097 "backup.\n")); 3098 break; 3099 3100 case ZPOOL_STATUS_CORRUPT_POOL: 3101 (void) printf(gettext("status: The pool metadata is corrupted " 3102 "and the pool cannot be opened.\n")); 3103 (void) printf(gettext("action: Destroy and re-create the pool " 3104 "from a backup source.\n")); 3105 break; 3106 3107 case ZPOOL_STATUS_VERSION_OLDER: 3108 (void) printf(gettext("status: The pool is formatted using an " 3109 "older on-disk format. The pool can\n\tstill be used, but " 3110 "some features are unavailable.\n")); 3111 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3112 "upgrade'. Once this is done, the\n\tpool will no longer " 3113 "be accessible on older software versions.\n")); 3114 break; 3115 3116 case ZPOOL_STATUS_VERSION_NEWER: 3117 (void) printf(gettext("status: The pool has been upgraded to a " 3118 "newer, incompatible on-disk version.\n\tThe pool cannot " 3119 "be accessed on this system.\n")); 3120 (void) printf(gettext("action: Access the pool from a system " 3121 "running more recent software, or\n\trestore the pool from " 3122 "backup.\n")); 3123 break; 3124 3125 case ZPOOL_STATUS_FAULTED_DEV_R: 3126 (void) printf(gettext("status: One or more devices are " 3127 "faulted in response to persistent errors.\n\tSufficient " 3128 "replicas exist for the pool to continue functioning " 3129 "in a\n\tdegraded state.\n")); 3130 (void) printf(gettext("action: Replace the faulted device, " 3131 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3132 break; 3133 3134 case ZPOOL_STATUS_FAULTED_DEV_NR: 3135 (void) printf(gettext("status: One or more devices are " 3136 "faulted in response to persistent errors. There are " 3137 "insufficient replicas for the pool to\n\tcontinue " 3138 "functioning.\n")); 3139 (void) printf(gettext("action: Destroy and re-create the pool " 3140 "from a backup source. Manually marking the device\n" 3141 "\trepaired using 'zpool clear' may allow some data " 3142 "to be recovered.\n")); 3143 break; 3144 3145 case ZPOOL_STATUS_IO_FAILURE_WAIT: 3146 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 3147 (void) printf(gettext("status: One or more devices are " 3148 "faulted in response to IO failures.\n")); 3149 (void) printf(gettext("action: Make sure the affected devices " 3150 "are connected, then run 'zpool clear'.\n")); 3151 break; 3152 3153 case ZPOOL_STATUS_BAD_LOG: 3154 (void) printf(gettext("status: An intent log record " 3155 "could not be read.\n" 3156 "\tWaiting for adminstrator intervention to fix the " 3157 "faulted pool.\n")); 3158 (void) printf(gettext("action: Either restore the affected " 3159 "device(s) and run 'zpool online',\n" 3160 "\tor ignore the intent log records by running " 3161 "'zpool clear'.\n")); 3162 break; 3163 3164 default: 3165 /* 3166 * The remaining errors can't actually be generated, yet. 3167 */ 3168 assert(reason == ZPOOL_STATUS_OK); 3169 } 3170 3171 if (msgid != NULL) 3172 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3173 msgid); 3174 3175 if (config != NULL) { 3176 int namewidth; 3177 uint64_t nerr; 3178 nvlist_t **spares, **l2cache; 3179 uint_t nspares, nl2cache; 3180 3181 3182 (void) printf(gettext(" scrub: ")); 3183 print_scrub_status(nvroot); 3184 3185 namewidth = max_width(zhp, nvroot, 0, 0); 3186 if (namewidth < 10) 3187 namewidth = 10; 3188 3189 (void) printf(gettext("config:\n\n")); 3190 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3191 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3192 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3193 namewidth, 0, B_FALSE, B_FALSE); 3194 if (num_logs(nvroot) > 0) 3195 print_status_config(zhp, "logs", nvroot, namewidth, 0, 3196 B_FALSE, B_TRUE); 3197 3198 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3199 &l2cache, &nl2cache) == 0) 3200 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3201 3202 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3203 &spares, &nspares) == 0) 3204 print_spares(zhp, spares, nspares, namewidth); 3205 3206 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3207 &nerr) == 0) { 3208 nvlist_t *nverrlist = NULL; 3209 3210 /* 3211 * If the approximate error count is small, get a 3212 * precise count by fetching the entire log and 3213 * uniquifying the results. 3214 */ 3215 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3216 zpool_get_errlog(zhp, &nverrlist) == 0) { 3217 nvpair_t *elem; 3218 3219 elem = NULL; 3220 nerr = 0; 3221 while ((elem = nvlist_next_nvpair(nverrlist, 3222 elem)) != NULL) { 3223 nerr++; 3224 } 3225 } 3226 nvlist_free(nverrlist); 3227 3228 (void) printf("\n"); 3229 3230 if (nerr == 0) 3231 (void) printf(gettext("errors: No known data " 3232 "errors\n")); 3233 else if (!cbp->cb_verbose) 3234 (void) printf(gettext("errors: %llu data " 3235 "errors, use '-v' for a list\n"), 3236 (u_longlong_t)nerr); 3237 else 3238 print_error_log(zhp); 3239 } 3240 } else { 3241 (void) printf(gettext("config: The configuration cannot be " 3242 "determined.\n")); 3243 } 3244 3245 return (0); 3246 } 3247 3248 /* 3249 * zpool status [-vx] [pool] ... 3250 * 3251 * -v Display complete error logs 3252 * -x Display only pools with potential problems 3253 * 3254 * Describes the health status of all pools or some subset. 3255 */ 3256 int 3257 zpool_do_status(int argc, char **argv) 3258 { 3259 int c; 3260 int ret; 3261 status_cbdata_t cb = { 0 }; 3262 3263 /* check options */ 3264 while ((c = getopt(argc, argv, "vx")) != -1) { 3265 switch (c) { 3266 case 'v': 3267 cb.cb_verbose = B_TRUE; 3268 break; 3269 case 'x': 3270 cb.cb_explain = B_TRUE; 3271 break; 3272 case '?': 3273 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3274 optopt); 3275 usage(B_FALSE); 3276 } 3277 } 3278 3279 argc -= optind; 3280 argv += optind; 3281 3282 cb.cb_first = B_TRUE; 3283 3284 if (argc == 0) 3285 cb.cb_allpools = B_TRUE; 3286 3287 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3288 3289 if (argc == 0 && cb.cb_count == 0) 3290 (void) printf(gettext("no pools available\n")); 3291 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3292 (void) printf(gettext("all pools are healthy\n")); 3293 3294 return (ret); 3295 } 3296 3297 typedef struct upgrade_cbdata { 3298 int cb_all; 3299 int cb_first; 3300 int cb_newer; 3301 int cb_argc; 3302 uint64_t cb_version; 3303 char **cb_argv; 3304 } upgrade_cbdata_t; 3305 3306 static int 3307 upgrade_cb(zpool_handle_t *zhp, void *arg) 3308 { 3309 upgrade_cbdata_t *cbp = arg; 3310 nvlist_t *config; 3311 uint64_t version; 3312 int ret = 0; 3313 3314 config = zpool_get_config(zhp, NULL); 3315 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3316 &version) == 0); 3317 3318 if (!cbp->cb_newer && version < SPA_VERSION) { 3319 if (!cbp->cb_all) { 3320 if (cbp->cb_first) { 3321 (void) printf(gettext("The following pools are " 3322 "out of date, and can be upgraded. After " 3323 "being\nupgraded, these pools will no " 3324 "longer be accessible by older software " 3325 "versions.\n\n")); 3326 (void) printf(gettext("VER POOL\n")); 3327 (void) printf(gettext("--- ------------\n")); 3328 cbp->cb_first = B_FALSE; 3329 } 3330 3331 (void) printf("%2llu %s\n", (u_longlong_t)version, 3332 zpool_get_name(zhp)); 3333 } else { 3334 cbp->cb_first = B_FALSE; 3335 ret = zpool_upgrade(zhp, cbp->cb_version); 3336 if (!ret) { 3337 (void) printf(gettext("Successfully upgraded " 3338 "'%s'\n\n"), zpool_get_name(zhp)); 3339 } 3340 } 3341 } else if (cbp->cb_newer && version > SPA_VERSION) { 3342 assert(!cbp->cb_all); 3343 3344 if (cbp->cb_first) { 3345 (void) printf(gettext("The following pools are " 3346 "formatted using a newer software version and\n" 3347 "cannot be accessed on the current system.\n\n")); 3348 (void) printf(gettext("VER POOL\n")); 3349 (void) printf(gettext("--- ------------\n")); 3350 cbp->cb_first = B_FALSE; 3351 } 3352 3353 (void) printf("%2llu %s\n", (u_longlong_t)version, 3354 zpool_get_name(zhp)); 3355 } 3356 3357 zpool_close(zhp); 3358 return (ret); 3359 } 3360 3361 /* ARGSUSED */ 3362 static int 3363 upgrade_one(zpool_handle_t *zhp, void *data) 3364 { 3365 upgrade_cbdata_t *cbp = data; 3366 uint64_t cur_version; 3367 int ret; 3368 3369 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3370 (void) printf(gettext("'log' is now a reserved word\n" 3371 "Pool 'log' must be renamed using export and import" 3372 " to upgrade.\n")); 3373 return (1); 3374 } 3375 3376 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3377 if (cur_version > cbp->cb_version) { 3378 (void) printf(gettext("Pool '%s' is already formatted " 3379 "using more current version '%llu'.\n"), 3380 zpool_get_name(zhp), cur_version); 3381 return (0); 3382 } 3383 if (cur_version == cbp->cb_version) { 3384 (void) printf(gettext("Pool '%s' is already formatted " 3385 "using the current version.\n"), zpool_get_name(zhp)); 3386 return (0); 3387 } 3388 3389 ret = zpool_upgrade(zhp, cbp->cb_version); 3390 3391 if (!ret) { 3392 (void) printf(gettext("Successfully upgraded '%s' " 3393 "from version %llu to version %llu\n\n"), 3394 zpool_get_name(zhp), (u_longlong_t)cur_version, 3395 (u_longlong_t)cbp->cb_version); 3396 } 3397 3398 return (ret != 0); 3399 } 3400 3401 /* 3402 * zpool upgrade 3403 * zpool upgrade -v 3404 * zpool upgrade [-V version] <-a | pool ...> 3405 * 3406 * With no arguments, display downrev'd ZFS pool available for upgrade. 3407 * Individual pools can be upgraded by specifying the pool, and '-a' will 3408 * upgrade all pools. 3409 */ 3410 int 3411 zpool_do_upgrade(int argc, char **argv) 3412 { 3413 int c; 3414 upgrade_cbdata_t cb = { 0 }; 3415 int ret = 0; 3416 boolean_t showversions = B_FALSE; 3417 char *end; 3418 3419 3420 /* check options */ 3421 while ((c = getopt(argc, argv, "avV:")) != -1) { 3422 switch (c) { 3423 case 'a': 3424 cb.cb_all = B_TRUE; 3425 break; 3426 case 'v': 3427 showversions = B_TRUE; 3428 break; 3429 case 'V': 3430 cb.cb_version = strtoll(optarg, &end, 10); 3431 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3432 cb.cb_version < SPA_VERSION_1) { 3433 (void) fprintf(stderr, 3434 gettext("invalid version '%s'\n"), optarg); 3435 usage(B_FALSE); 3436 } 3437 break; 3438 case '?': 3439 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3440 optopt); 3441 usage(B_FALSE); 3442 } 3443 } 3444 3445 cb.cb_argc = argc; 3446 cb.cb_argv = argv; 3447 argc -= optind; 3448 argv += optind; 3449 3450 if (cb.cb_version == 0) { 3451 cb.cb_version = SPA_VERSION; 3452 } else if (!cb.cb_all && argc == 0) { 3453 (void) fprintf(stderr, gettext("-V option is " 3454 "incompatible with other arguments\n")); 3455 usage(B_FALSE); 3456 } 3457 3458 if (showversions) { 3459 if (cb.cb_all || argc != 0) { 3460 (void) fprintf(stderr, gettext("-v option is " 3461 "incompatible with other arguments\n")); 3462 usage(B_FALSE); 3463 } 3464 } else if (cb.cb_all) { 3465 if (argc != 0) { 3466 (void) fprintf(stderr, gettext("-a option should not " 3467 "be used along with a pool name\n")); 3468 usage(B_FALSE); 3469 } 3470 } 3471 3472 (void) printf(gettext("This system is currently running " 3473 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3474 cb.cb_first = B_TRUE; 3475 if (showversions) { 3476 (void) printf(gettext("The following versions are " 3477 "supported:\n\n")); 3478 (void) printf(gettext("VER DESCRIPTION\n")); 3479 (void) printf("--- -----------------------------------------" 3480 "---------------\n"); 3481 (void) printf(gettext(" 1 Initial ZFS version\n")); 3482 (void) printf(gettext(" 2 Ditto blocks " 3483 "(replicated metadata)\n")); 3484 (void) printf(gettext(" 3 Hot spares and double parity " 3485 "RAID-Z\n")); 3486 (void) printf(gettext(" 4 zpool history\n")); 3487 (void) printf(gettext(" 5 Compression using the gzip " 3488 "algorithm\n")); 3489 (void) printf(gettext(" 6 bootfs pool property\n")); 3490 (void) printf(gettext(" 7 Separate intent log devices\n")); 3491 (void) printf(gettext(" 8 Delegated administration\n")); 3492 (void) printf(gettext(" 9 refquota and refreservation " 3493 "properties\n")); 3494 (void) printf(gettext(" 10 Cache devices\n")); 3495 (void) printf(gettext(" 11 Improved scrub performance\n")); 3496 (void) printf(gettext(" 12 Snapshot properties\n")); 3497 (void) printf(gettext(" 13 snapused property\n")); 3498 (void) printf(gettext(" 14 passthrough-x aclinherit " 3499 "support\n")); 3500 (void) printf(gettext("For more information on a particular " 3501 "version, including supported releases, see:\n\n")); 3502 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3503 "version/N\n\n"); 3504 (void) printf(gettext("Where 'N' is the version number.\n")); 3505 } else if (argc == 0) { 3506 int notfound; 3507 3508 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3509 notfound = cb.cb_first; 3510 3511 if (!cb.cb_all && ret == 0) { 3512 if (!cb.cb_first) 3513 (void) printf("\n"); 3514 cb.cb_first = B_TRUE; 3515 cb.cb_newer = B_TRUE; 3516 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3517 if (!cb.cb_first) { 3518 notfound = B_FALSE; 3519 (void) printf("\n"); 3520 } 3521 } 3522 3523 if (ret == 0) { 3524 if (notfound) 3525 (void) printf(gettext("All pools are formatted " 3526 "using this version.\n")); 3527 else if (!cb.cb_all) 3528 (void) printf(gettext("Use 'zpool upgrade -v' " 3529 "for a list of available versions and " 3530 "their associated\nfeatures.\n")); 3531 } 3532 } else { 3533 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3534 upgrade_one, &cb); 3535 } 3536 3537 return (ret); 3538 } 3539 3540 typedef struct hist_cbdata { 3541 boolean_t first; 3542 int longfmt; 3543 int internal; 3544 } hist_cbdata_t; 3545 3546 char *hist_event_table[LOG_END] = { 3547 "invalid event", 3548 "pool create", 3549 "vdev add", 3550 "pool remove", 3551 "pool destroy", 3552 "pool export", 3553 "pool import", 3554 "vdev attach", 3555 "vdev replace", 3556 "vdev detach", 3557 "vdev online", 3558 "vdev offline", 3559 "vdev upgrade", 3560 "pool clear", 3561 "pool scrub", 3562 "pool property set", 3563 "create", 3564 "clone", 3565 "destroy", 3566 "destroy_begin_sync", 3567 "inherit", 3568 "property set", 3569 "quota set", 3570 "permission update", 3571 "permission remove", 3572 "permission who remove", 3573 "promote", 3574 "receive", 3575 "rename", 3576 "reservation set", 3577 "replay_inc_sync", 3578 "replay_full_sync", 3579 "rollback", 3580 "snapshot", 3581 "filesystem version upgrade", 3582 "refquota set", 3583 "refreservation set", 3584 "pool scrub done", 3585 }; 3586 3587 /* 3588 * Print out the command history for a specific pool. 3589 */ 3590 static int 3591 get_history_one(zpool_handle_t *zhp, void *data) 3592 { 3593 nvlist_t *nvhis; 3594 nvlist_t **records; 3595 uint_t numrecords; 3596 char *cmdstr; 3597 char *pathstr; 3598 uint64_t dst_time; 3599 time_t tsec; 3600 struct tm t; 3601 char tbuf[30]; 3602 int ret, i; 3603 uint64_t who; 3604 struct passwd *pwd; 3605 char *hostname; 3606 char *zonename; 3607 char internalstr[MAXPATHLEN]; 3608 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3609 uint64_t txg; 3610 uint64_t ievent; 3611 3612 cb->first = B_FALSE; 3613 3614 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3615 3616 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3617 return (ret); 3618 3619 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3620 &records, &numrecords) == 0); 3621 for (i = 0; i < numrecords; i++) { 3622 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3623 &dst_time) != 0) 3624 continue; 3625 3626 /* is it an internal event or a standard event? */ 3627 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3628 &cmdstr) != 0) { 3629 if (cb->internal == 0) 3630 continue; 3631 3632 if (nvlist_lookup_uint64(records[i], 3633 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3634 continue; 3635 verify(nvlist_lookup_uint64(records[i], 3636 ZPOOL_HIST_TXG, &txg) == 0); 3637 verify(nvlist_lookup_string(records[i], 3638 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3639 if (ievent >= LOG_END) 3640 continue; 3641 (void) snprintf(internalstr, 3642 sizeof (internalstr), 3643 "[internal %s txg:%lld] %s", 3644 hist_event_table[ievent], txg, 3645 pathstr); 3646 cmdstr = internalstr; 3647 } 3648 tsec = dst_time; 3649 (void) localtime_r(&tsec, &t); 3650 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3651 (void) printf("%s %s", tbuf, cmdstr); 3652 3653 if (!cb->longfmt) { 3654 (void) printf("\n"); 3655 continue; 3656 } 3657 (void) printf(" ["); 3658 if (nvlist_lookup_uint64(records[i], 3659 ZPOOL_HIST_WHO, &who) == 0) { 3660 pwd = getpwuid((uid_t)who); 3661 if (pwd) 3662 (void) printf("user %s on", 3663 pwd->pw_name); 3664 else 3665 (void) printf("user %d on", 3666 (int)who); 3667 } else { 3668 (void) printf(gettext("no info]\n")); 3669 continue; 3670 } 3671 if (nvlist_lookup_string(records[i], 3672 ZPOOL_HIST_HOST, &hostname) == 0) { 3673 (void) printf(" %s", hostname); 3674 } 3675 if (nvlist_lookup_string(records[i], 3676 ZPOOL_HIST_ZONE, &zonename) == 0) { 3677 (void) printf(":%s", zonename); 3678 } 3679 3680 (void) printf("]"); 3681 (void) printf("\n"); 3682 } 3683 (void) printf("\n"); 3684 nvlist_free(nvhis); 3685 3686 return (ret); 3687 } 3688 3689 /* 3690 * zpool history <pool> 3691 * 3692 * Displays the history of commands that modified pools. 3693 */ 3694 3695 3696 int 3697 zpool_do_history(int argc, char **argv) 3698 { 3699 hist_cbdata_t cbdata = { 0 }; 3700 int ret; 3701 int c; 3702 3703 cbdata.first = B_TRUE; 3704 /* check options */ 3705 while ((c = getopt(argc, argv, "li")) != -1) { 3706 switch (c) { 3707 case 'l': 3708 cbdata.longfmt = 1; 3709 break; 3710 case 'i': 3711 cbdata.internal = 1; 3712 break; 3713 case '?': 3714 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3715 optopt); 3716 usage(B_FALSE); 3717 } 3718 } 3719 argc -= optind; 3720 argv += optind; 3721 3722 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3723 &cbdata); 3724 3725 if (argc == 0 && cbdata.first == B_TRUE) { 3726 (void) printf(gettext("no pools available\n")); 3727 return (0); 3728 } 3729 3730 return (ret); 3731 } 3732 3733 static int 3734 get_callback(zpool_handle_t *zhp, void *data) 3735 { 3736 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3737 char value[MAXNAMELEN]; 3738 zprop_source_t srctype; 3739 zprop_list_t *pl; 3740 3741 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3742 3743 /* 3744 * Skip the special fake placeholder. This will also skip 3745 * over the name property when 'all' is specified. 3746 */ 3747 if (pl->pl_prop == ZPOOL_PROP_NAME && 3748 pl == cbp->cb_proplist) 3749 continue; 3750 3751 if (zpool_get_prop(zhp, pl->pl_prop, 3752 value, sizeof (value), &srctype) != 0) 3753 continue; 3754 3755 zprop_print_one_property(zpool_get_name(zhp), cbp, 3756 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3757 } 3758 return (0); 3759 } 3760 3761 int 3762 zpool_do_get(int argc, char **argv) 3763 { 3764 zprop_get_cbdata_t cb = { 0 }; 3765 zprop_list_t fake_name = { 0 }; 3766 int ret; 3767 3768 if (argc < 3) 3769 usage(B_FALSE); 3770 3771 cb.cb_first = B_TRUE; 3772 cb.cb_sources = ZPROP_SRC_ALL; 3773 cb.cb_columns[0] = GET_COL_NAME; 3774 cb.cb_columns[1] = GET_COL_PROPERTY; 3775 cb.cb_columns[2] = GET_COL_VALUE; 3776 cb.cb_columns[3] = GET_COL_SOURCE; 3777 cb.cb_type = ZFS_TYPE_POOL; 3778 3779 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3780 ZFS_TYPE_POOL) != 0) 3781 usage(B_FALSE); 3782 3783 if (cb.cb_proplist != NULL) { 3784 fake_name.pl_prop = ZPOOL_PROP_NAME; 3785 fake_name.pl_width = strlen(gettext("NAME")); 3786 fake_name.pl_next = cb.cb_proplist; 3787 cb.cb_proplist = &fake_name; 3788 } 3789 3790 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3791 get_callback, &cb); 3792 3793 if (cb.cb_proplist == &fake_name) 3794 zprop_free_list(fake_name.pl_next); 3795 else 3796 zprop_free_list(cb.cb_proplist); 3797 3798 return (ret); 3799 } 3800 3801 typedef struct set_cbdata { 3802 char *cb_propname; 3803 char *cb_value; 3804 boolean_t cb_any_successful; 3805 } set_cbdata_t; 3806 3807 int 3808 set_callback(zpool_handle_t *zhp, void *data) 3809 { 3810 int error; 3811 set_cbdata_t *cb = (set_cbdata_t *)data; 3812 3813 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3814 3815 if (!error) 3816 cb->cb_any_successful = B_TRUE; 3817 3818 return (error); 3819 } 3820 3821 int 3822 zpool_do_set(int argc, char **argv) 3823 { 3824 set_cbdata_t cb = { 0 }; 3825 int error; 3826 3827 if (argc > 1 && argv[1][0] == '-') { 3828 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3829 argv[1][1]); 3830 usage(B_FALSE); 3831 } 3832 3833 if (argc < 2) { 3834 (void) fprintf(stderr, gettext("missing property=value " 3835 "argument\n")); 3836 usage(B_FALSE); 3837 } 3838 3839 if (argc < 3) { 3840 (void) fprintf(stderr, gettext("missing pool name\n")); 3841 usage(B_FALSE); 3842 } 3843 3844 if (argc > 3) { 3845 (void) fprintf(stderr, gettext("too many pool names\n")); 3846 usage(B_FALSE); 3847 } 3848 3849 cb.cb_propname = argv[1]; 3850 cb.cb_value = strchr(cb.cb_propname, '='); 3851 if (cb.cb_value == NULL) { 3852 (void) fprintf(stderr, gettext("missing value in " 3853 "property=value argument\n")); 3854 usage(B_FALSE); 3855 } 3856 3857 *(cb.cb_value) = '\0'; 3858 cb.cb_value++; 3859 3860 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3861 set_callback, &cb); 3862 3863 return (error); 3864 } 3865 3866 static int 3867 find_command_idx(char *command, int *idx) 3868 { 3869 int i; 3870 3871 for (i = 0; i < NCOMMAND; i++) { 3872 if (command_table[i].name == NULL) 3873 continue; 3874 3875 if (strcmp(command, command_table[i].name) == 0) { 3876 *idx = i; 3877 return (0); 3878 } 3879 } 3880 return (1); 3881 } 3882 3883 int 3884 main(int argc, char **argv) 3885 { 3886 int ret; 3887 int i; 3888 char *cmdname; 3889 3890 (void) setlocale(LC_ALL, ""); 3891 (void) textdomain(TEXT_DOMAIN); 3892 3893 if ((g_zfs = libzfs_init()) == NULL) { 3894 (void) fprintf(stderr, gettext("internal error: failed to " 3895 "initialize ZFS library\n")); 3896 return (1); 3897 } 3898 3899 libzfs_print_on_error(g_zfs, B_TRUE); 3900 3901 opterr = 0; 3902 3903 /* 3904 * Make sure the user has specified some command. 3905 */ 3906 if (argc < 2) { 3907 (void) fprintf(stderr, gettext("missing command\n")); 3908 usage(B_FALSE); 3909 } 3910 3911 cmdname = argv[1]; 3912 3913 /* 3914 * Special case '-?' 3915 */ 3916 if (strcmp(cmdname, "-?") == 0) 3917 usage(B_TRUE); 3918 3919 zpool_set_history_str("zpool", argc, argv, history_str); 3920 verify(zpool_stage_history(g_zfs, history_str) == 0); 3921 3922 /* 3923 * Run the appropriate command. 3924 */ 3925 if (find_command_idx(cmdname, &i) == 0) { 3926 current_command = &command_table[i]; 3927 ret = command_table[i].func(argc - 1, argv + 1); 3928 } else if (strchr(cmdname, '=')) { 3929 verify(find_command_idx("set", &i) == 0); 3930 current_command = &command_table[i]; 3931 ret = command_table[i].func(argc, argv); 3932 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3933 /* 3934 * 'freeze' is a vile debugging abomination, so we treat 3935 * it as such. 3936 */ 3937 char buf[16384]; 3938 int fd = open(ZFS_DEV, O_RDWR); 3939 (void) strcpy((void *)buf, argv[2]); 3940 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3941 } else { 3942 (void) fprintf(stderr, gettext("unrecognized " 3943 "command '%s'\n"), cmdname); 3944 usage(B_FALSE); 3945 } 3946 3947 libzfs_fini(g_zfs); 3948 3949 /* 3950 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3951 * for the purposes of running ::findleaks. 3952 */ 3953 if (getenv("ZFS_ABORT") != NULL) { 3954 (void) printf("dumping core by request\n"); 3955 abort(); 3956 } 3957 3958 return (ret); 3959 } 3960