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