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