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