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