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