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