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