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 nvlist_free(props); 3271 usage(B_FALSE); 3272 } 3273 break; 3274 case 'n': 3275 flags.dryrun = B_TRUE; 3276 break; 3277 case 'o': 3278 if ((propval = strchr(optarg, '=')) != NULL) { 3279 *propval = '\0'; 3280 propval++; 3281 if (add_prop_list(optarg, propval, 3282 &props, B_TRUE) != 0) { 3283 nvlist_free(props); 3284 usage(B_FALSE); 3285 } 3286 } else { 3287 mntopts = optarg; 3288 } 3289 break; 3290 case ':': 3291 (void) fprintf(stderr, gettext("missing argument for " 3292 "'%c' option\n"), optopt); 3293 usage(B_FALSE); 3294 break; 3295 case '?': 3296 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3297 optopt); 3298 usage(B_FALSE); 3299 break; 3300 } 3301 } 3302 3303 if (!flags.import && mntopts != NULL) { 3304 (void) fprintf(stderr, gettext("setting mntopts is only " 3305 "valid when importing the pool\n")); 3306 usage(B_FALSE); 3307 } 3308 3309 argc -= optind; 3310 argv += optind; 3311 3312 if (argc < 1) { 3313 (void) fprintf(stderr, gettext("Missing pool name\n")); 3314 usage(B_FALSE); 3315 } 3316 if (argc < 2) { 3317 (void) fprintf(stderr, gettext("Missing new pool name\n")); 3318 usage(B_FALSE); 3319 } 3320 3321 srcpool = argv[0]; 3322 newpool = argv[1]; 3323 3324 argc -= 2; 3325 argv += 2; 3326 3327 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 3328 return (1); 3329 3330 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 3331 if (config == NULL) { 3332 ret = 1; 3333 } else { 3334 if (flags.dryrun) { 3335 (void) printf(gettext("would create '%s' with the " 3336 "following layout:\n\n"), newpool); 3337 print_vdev_tree(NULL, newpool, config, 0, B_FALSE); 3338 } 3339 nvlist_free(config); 3340 } 3341 3342 zpool_close(zhp); 3343 3344 if (ret != 0 || flags.dryrun || !flags.import) 3345 return (ret); 3346 3347 /* 3348 * The split was successful. Now we need to open the new 3349 * pool and import it. 3350 */ 3351 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 3352 return (1); 3353 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 3354 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 3355 ret = 1; 3356 (void) fprintf(stderr, gettext("Split was successful, but " 3357 "the datasets could not all be mounted\n")); 3358 (void) fprintf(stderr, gettext("Try doing '%s' with a " 3359 "different altroot\n"), "zpool import"); 3360 } 3361 zpool_close(zhp); 3362 3363 return (ret); 3364 } 3365 3366 3367 3368 /* 3369 * zpool online <pool> <device> ... 3370 */ 3371 int 3372 zpool_do_online(int argc, char **argv) 3373 { 3374 int c, i; 3375 char *poolname; 3376 zpool_handle_t *zhp; 3377 int ret = 0; 3378 vdev_state_t newstate; 3379 int flags = 0; 3380 3381 /* check options */ 3382 while ((c = getopt(argc, argv, "et")) != -1) { 3383 switch (c) { 3384 case 'e': 3385 flags |= ZFS_ONLINE_EXPAND; 3386 break; 3387 case 't': 3388 case '?': 3389 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3390 optopt); 3391 usage(B_FALSE); 3392 } 3393 } 3394 3395 argc -= optind; 3396 argv += optind; 3397 3398 /* get pool name and check number of arguments */ 3399 if (argc < 1) { 3400 (void) fprintf(stderr, gettext("missing pool name\n")); 3401 usage(B_FALSE); 3402 } 3403 if (argc < 2) { 3404 (void) fprintf(stderr, gettext("missing device name\n")); 3405 usage(B_FALSE); 3406 } 3407 3408 poolname = argv[0]; 3409 3410 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3411 return (1); 3412 3413 for (i = 1; i < argc; i++) { 3414 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 3415 if (newstate != VDEV_STATE_HEALTHY) { 3416 (void) printf(gettext("warning: device '%s' " 3417 "onlined, but remains in faulted state\n"), 3418 argv[i]); 3419 if (newstate == VDEV_STATE_FAULTED) 3420 (void) printf(gettext("use 'zpool " 3421 "clear' to restore a faulted " 3422 "device\n")); 3423 else 3424 (void) printf(gettext("use 'zpool " 3425 "replace' to replace devices " 3426 "that are no longer present\n")); 3427 } 3428 } else { 3429 ret = 1; 3430 } 3431 } 3432 3433 zpool_close(zhp); 3434 3435 return (ret); 3436 } 3437 3438 /* 3439 * zpool offline [-ft] <pool> <device> ... 3440 * 3441 * -f Force the device into the offline state, even if doing 3442 * so would appear to compromise pool availability. 3443 * (not supported yet) 3444 * 3445 * -t Only take the device off-line temporarily. The offline 3446 * state will not be persistent across reboots. 3447 */ 3448 /* ARGSUSED */ 3449 int 3450 zpool_do_offline(int argc, char **argv) 3451 { 3452 int c, i; 3453 char *poolname; 3454 zpool_handle_t *zhp; 3455 int ret = 0; 3456 boolean_t istmp = B_FALSE; 3457 3458 /* check options */ 3459 while ((c = getopt(argc, argv, "ft")) != -1) { 3460 switch (c) { 3461 case 't': 3462 istmp = B_TRUE; 3463 break; 3464 case 'f': 3465 case '?': 3466 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3467 optopt); 3468 usage(B_FALSE); 3469 } 3470 } 3471 3472 argc -= optind; 3473 argv += optind; 3474 3475 /* get pool name and check number of arguments */ 3476 if (argc < 1) { 3477 (void) fprintf(stderr, gettext("missing pool name\n")); 3478 usage(B_FALSE); 3479 } 3480 if (argc < 2) { 3481 (void) fprintf(stderr, gettext("missing device name\n")); 3482 usage(B_FALSE); 3483 } 3484 3485 poolname = argv[0]; 3486 3487 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3488 return (1); 3489 3490 for (i = 1; i < argc; i++) { 3491 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 3492 ret = 1; 3493 } 3494 3495 zpool_close(zhp); 3496 3497 return (ret); 3498 } 3499 3500 /* 3501 * zpool clear <pool> [device] 3502 * 3503 * Clear all errors associated with a pool or a particular device. 3504 */ 3505 int 3506 zpool_do_clear(int argc, char **argv) 3507 { 3508 int c; 3509 int ret = 0; 3510 boolean_t dryrun = B_FALSE; 3511 boolean_t do_rewind = B_FALSE; 3512 boolean_t xtreme_rewind = B_FALSE; 3513 uint32_t rewind_policy = ZPOOL_NO_REWIND; 3514 nvlist_t *policy = NULL; 3515 zpool_handle_t *zhp; 3516 char *pool, *device; 3517 3518 /* check options */ 3519 while ((c = getopt(argc, argv, "FnX")) != -1) { 3520 switch (c) { 3521 case 'F': 3522 do_rewind = B_TRUE; 3523 break; 3524 case 'n': 3525 dryrun = B_TRUE; 3526 break; 3527 case 'X': 3528 xtreme_rewind = B_TRUE; 3529 break; 3530 case '?': 3531 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3532 optopt); 3533 usage(B_FALSE); 3534 } 3535 } 3536 3537 argc -= optind; 3538 argv += optind; 3539 3540 if (argc < 1) { 3541 (void) fprintf(stderr, gettext("missing pool name\n")); 3542 usage(B_FALSE); 3543 } 3544 3545 if (argc > 2) { 3546 (void) fprintf(stderr, gettext("too many arguments\n")); 3547 usage(B_FALSE); 3548 } 3549 3550 if ((dryrun || xtreme_rewind) && !do_rewind) { 3551 (void) fprintf(stderr, 3552 gettext("-n or -X only meaningful with -F\n")); 3553 usage(B_FALSE); 3554 } 3555 if (dryrun) 3556 rewind_policy = ZPOOL_TRY_REWIND; 3557 else if (do_rewind) 3558 rewind_policy = ZPOOL_DO_REWIND; 3559 if (xtreme_rewind) 3560 rewind_policy |= ZPOOL_EXTREME_REWIND; 3561 3562 /* In future, further rewind policy choices can be passed along here */ 3563 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 3564 nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) 3565 return (1); 3566 3567 pool = argv[0]; 3568 device = argc == 2 ? argv[1] : NULL; 3569 3570 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 3571 nvlist_free(policy); 3572 return (1); 3573 } 3574 3575 if (zpool_clear(zhp, device, policy) != 0) 3576 ret = 1; 3577 3578 zpool_close(zhp); 3579 3580 nvlist_free(policy); 3581 3582 return (ret); 3583 } 3584 3585 /* 3586 * zpool reguid <pool> 3587 */ 3588 int 3589 zpool_do_reguid(int argc, char **argv) 3590 { 3591 int c; 3592 char *poolname; 3593 zpool_handle_t *zhp; 3594 int ret = 0; 3595 3596 /* check options */ 3597 while ((c = getopt(argc, argv, "")) != -1) { 3598 switch (c) { 3599 case '?': 3600 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3601 optopt); 3602 usage(B_FALSE); 3603 } 3604 } 3605 3606 argc -= optind; 3607 argv += optind; 3608 3609 /* get pool name and check number of arguments */ 3610 if (argc < 1) { 3611 (void) fprintf(stderr, gettext("missing pool name\n")); 3612 usage(B_FALSE); 3613 } 3614 3615 if (argc > 1) { 3616 (void) fprintf(stderr, gettext("too many arguments\n")); 3617 usage(B_FALSE); 3618 } 3619 3620 poolname = argv[0]; 3621 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 3622 return (1); 3623 3624 ret = zpool_reguid(zhp); 3625 3626 zpool_close(zhp); 3627 return (ret); 3628 } 3629 3630 3631 /* 3632 * zpool reopen <pool> 3633 * 3634 * Reopen the pool so that the kernel can update the sizes of all vdevs. 3635 */ 3636 int 3637 zpool_do_reopen(int argc, char **argv) 3638 { 3639 int c; 3640 int ret = 0; 3641 zpool_handle_t *zhp; 3642 char *pool; 3643 3644 /* check options */ 3645 while ((c = getopt(argc, argv, "")) != -1) { 3646 switch (c) { 3647 case '?': 3648 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3649 optopt); 3650 usage(B_FALSE); 3651 } 3652 } 3653 3654 argc--; 3655 argv++; 3656 3657 if (argc < 1) { 3658 (void) fprintf(stderr, gettext("missing pool name\n")); 3659 usage(B_FALSE); 3660 } 3661 3662 if (argc > 1) { 3663 (void) fprintf(stderr, gettext("too many arguments\n")); 3664 usage(B_FALSE); 3665 } 3666 3667 pool = argv[0]; 3668 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 3669 return (1); 3670 3671 ret = zpool_reopen(zhp); 3672 zpool_close(zhp); 3673 return (ret); 3674 } 3675 3676 typedef struct scrub_cbdata { 3677 int cb_type; 3678 int cb_argc; 3679 char **cb_argv; 3680 } scrub_cbdata_t; 3681 3682 int 3683 scrub_callback(zpool_handle_t *zhp, void *data) 3684 { 3685 scrub_cbdata_t *cb = data; 3686 int err; 3687 3688 /* 3689 * Ignore faulted pools. 3690 */ 3691 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 3692 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 3693 "currently unavailable\n"), zpool_get_name(zhp)); 3694 return (1); 3695 } 3696 3697 err = zpool_scan(zhp, cb->cb_type); 3698 3699 return (err != 0); 3700 } 3701 3702 /* 3703 * zpool scrub [-s] <pool> ... 3704 * 3705 * -s Stop. Stops any in-progress scrub. 3706 */ 3707 int 3708 zpool_do_scrub(int argc, char **argv) 3709 { 3710 int c; 3711 scrub_cbdata_t cb; 3712 3713 cb.cb_type = POOL_SCAN_SCRUB; 3714 3715 /* check options */ 3716 while ((c = getopt(argc, argv, "s")) != -1) { 3717 switch (c) { 3718 case 's': 3719 cb.cb_type = POOL_SCAN_NONE; 3720 break; 3721 case '?': 3722 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3723 optopt); 3724 usage(B_FALSE); 3725 } 3726 } 3727 3728 cb.cb_argc = argc; 3729 cb.cb_argv = argv; 3730 argc -= optind; 3731 argv += optind; 3732 3733 if (argc < 1) { 3734 (void) fprintf(stderr, gettext("missing pool name argument\n")); 3735 usage(B_FALSE); 3736 } 3737 3738 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 3739 } 3740 3741 typedef struct status_cbdata { 3742 int cb_count; 3743 boolean_t cb_allpools; 3744 boolean_t cb_verbose; 3745 boolean_t cb_explain; 3746 boolean_t cb_first; 3747 boolean_t cb_dedup_stats; 3748 } status_cbdata_t; 3749 3750 /* 3751 * Print out detailed scrub status. 3752 */ 3753 void 3754 print_scan_status(pool_scan_stat_t *ps) 3755 { 3756 time_t start, end; 3757 uint64_t elapsed, mins_left, hours_left; 3758 uint64_t pass_exam, examined, total; 3759 uint_t rate; 3760 double fraction_done; 3761 char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 3762 3763 (void) printf(gettext(" scan: ")); 3764 3765 /* If there's never been a scan, there's not much to say. */ 3766 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 3767 ps->pss_func >= POOL_SCAN_FUNCS) { 3768 (void) printf(gettext("none requested\n")); 3769 return; 3770 } 3771 3772 start = ps->pss_start_time; 3773 end = ps->pss_end_time; 3774 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 3775 3776 assert(ps->pss_func == POOL_SCAN_SCRUB || 3777 ps->pss_func == POOL_SCAN_RESILVER); 3778 /* 3779 * Scan is finished or canceled. 3780 */ 3781 if (ps->pss_state == DSS_FINISHED) { 3782 uint64_t minutes_taken = (end - start) / 60; 3783 char *fmt; 3784 3785 if (ps->pss_func == POOL_SCAN_SCRUB) { 3786 fmt = gettext("scrub repaired %s in %lluh%um with " 3787 "%llu errors on %s"); 3788 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3789 fmt = gettext("resilvered %s in %lluh%um with " 3790 "%llu errors on %s"); 3791 } 3792 /* LINTED */ 3793 (void) printf(fmt, processed_buf, 3794 (u_longlong_t)(minutes_taken / 60), 3795 (uint_t)(minutes_taken % 60), 3796 (u_longlong_t)ps->pss_errors, 3797 ctime((time_t *)&end)); 3798 return; 3799 } else if (ps->pss_state == DSS_CANCELED) { 3800 if (ps->pss_func == POOL_SCAN_SCRUB) { 3801 (void) printf(gettext("scrub canceled on %s"), 3802 ctime(&end)); 3803 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3804 (void) printf(gettext("resilver canceled on %s"), 3805 ctime(&end)); 3806 } 3807 return; 3808 } 3809 3810 assert(ps->pss_state == DSS_SCANNING); 3811 3812 /* 3813 * Scan is in progress. 3814 */ 3815 if (ps->pss_func == POOL_SCAN_SCRUB) { 3816 (void) printf(gettext("scrub in progress since %s"), 3817 ctime(&start)); 3818 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 3819 (void) printf(gettext("resilver in progress since %s"), 3820 ctime(&start)); 3821 } 3822 3823 examined = ps->pss_examined ? ps->pss_examined : 1; 3824 total = ps->pss_to_examine; 3825 fraction_done = (double)examined / total; 3826 3827 /* elapsed time for this pass */ 3828 elapsed = time(NULL) - ps->pss_pass_start; 3829 elapsed = elapsed ? elapsed : 1; 3830 pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1; 3831 rate = pass_exam / elapsed; 3832 rate = rate ? rate : 1; 3833 mins_left = ((total - examined) / rate) / 60; 3834 hours_left = mins_left / 60; 3835 3836 zfs_nicenum(examined, examined_buf, sizeof (examined_buf)); 3837 zfs_nicenum(total, total_buf, sizeof (total_buf)); 3838 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 3839 3840 /* 3841 * do not print estimated time if hours_left is more than 30 days 3842 */ 3843 (void) printf(gettext(" %s scanned out of %s at %s/s"), 3844 examined_buf, total_buf, rate_buf); 3845 if (hours_left < (30 * 24)) { 3846 (void) printf(gettext(", %lluh%um to go\n"), 3847 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 3848 } else { 3849 (void) printf(gettext( 3850 ", (scan is slow, no estimated time)\n")); 3851 } 3852 3853 if (ps->pss_func == POOL_SCAN_RESILVER) { 3854 (void) printf(gettext(" %s resilvered, %.2f%% done\n"), 3855 processed_buf, 100 * fraction_done); 3856 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 3857 (void) printf(gettext(" %s repaired, %.2f%% done\n"), 3858 processed_buf, 100 * fraction_done); 3859 } 3860 } 3861 3862 static void 3863 print_error_log(zpool_handle_t *zhp) 3864 { 3865 nvlist_t *nverrlist = NULL; 3866 nvpair_t *elem; 3867 char *pathname; 3868 size_t len = MAXPATHLEN * 2; 3869 3870 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 3871 (void) printf("errors: List of errors unavailable " 3872 "(insufficient privileges)\n"); 3873 return; 3874 } 3875 3876 (void) printf("errors: Permanent errors have been " 3877 "detected in the following files:\n\n"); 3878 3879 pathname = safe_malloc(len); 3880 elem = NULL; 3881 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 3882 nvlist_t *nv; 3883 uint64_t dsobj, obj; 3884 3885 verify(nvpair_value_nvlist(elem, &nv) == 0); 3886 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 3887 &dsobj) == 0); 3888 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 3889 &obj) == 0); 3890 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 3891 (void) printf("%7s %s\n", "", pathname); 3892 } 3893 free(pathname); 3894 nvlist_free(nverrlist); 3895 } 3896 3897 static void 3898 print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 3899 int namewidth) 3900 { 3901 uint_t i; 3902 char *name; 3903 3904 if (nspares == 0) 3905 return; 3906 3907 (void) printf(gettext("\tspares\n")); 3908 3909 for (i = 0; i < nspares; i++) { 3910 name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE); 3911 print_status_config(zhp, name, spares[i], 3912 namewidth, 2, B_TRUE); 3913 free(name); 3914 } 3915 } 3916 3917 static void 3918 print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 3919 int namewidth) 3920 { 3921 uint_t i; 3922 char *name; 3923 3924 if (nl2cache == 0) 3925 return; 3926 3927 (void) printf(gettext("\tcache\n")); 3928 3929 for (i = 0; i < nl2cache; i++) { 3930 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE); 3931 print_status_config(zhp, name, l2cache[i], 3932 namewidth, 2, B_FALSE); 3933 free(name); 3934 } 3935 } 3936 3937 static void 3938 print_dedup_stats(nvlist_t *config) 3939 { 3940 ddt_histogram_t *ddh; 3941 ddt_stat_t *dds; 3942 ddt_object_t *ddo; 3943 uint_t c; 3944 3945 /* 3946 * If the pool was faulted then we may not have been able to 3947 * obtain the config. Otherwise, if we have anything in the dedup 3948 * table continue processing the stats. 3949 */ 3950 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 3951 (uint64_t **)&ddo, &c) != 0) 3952 return; 3953 3954 (void) printf("\n"); 3955 (void) printf(gettext(" dedup: ")); 3956 if (ddo->ddo_count == 0) { 3957 (void) printf(gettext("no DDT entries\n")); 3958 return; 3959 } 3960 3961 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 3962 (u_longlong_t)ddo->ddo_count, 3963 (u_longlong_t)ddo->ddo_dspace, 3964 (u_longlong_t)ddo->ddo_mspace); 3965 3966 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 3967 (uint64_t **)&dds, &c) == 0); 3968 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 3969 (uint64_t **)&ddh, &c) == 0); 3970 zpool_dump_ddt(dds, ddh); 3971 } 3972 3973 /* 3974 * Display a summary of pool status. Displays a summary such as: 3975 * 3976 * pool: tank 3977 * status: DEGRADED 3978 * reason: One or more devices ... 3979 * see: http://illumos.org/msg/ZFS-xxxx-01 3980 * config: 3981 * mirror DEGRADED 3982 * c1t0d0 OK 3983 * c2t0d0 UNAVAIL 3984 * 3985 * When given the '-v' option, we print out the complete config. If the '-e' 3986 * option is specified, then we print out error rate information as well. 3987 */ 3988 int 3989 status_callback(zpool_handle_t *zhp, void *data) 3990 { 3991 status_cbdata_t *cbp = data; 3992 nvlist_t *config, *nvroot; 3993 char *msgid; 3994 int reason; 3995 const char *health; 3996 uint_t c; 3997 vdev_stat_t *vs; 3998 3999 config = zpool_get_config(zhp, NULL); 4000 reason = zpool_get_status(zhp, &msgid); 4001 4002 cbp->cb_count++; 4003 4004 /* 4005 * If we were given 'zpool status -x', only report those pools with 4006 * problems. 4007 */ 4008 if (cbp->cb_explain && 4009 (reason == ZPOOL_STATUS_OK || 4010 reason == ZPOOL_STATUS_VERSION_OLDER || 4011 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 4012 if (!cbp->cb_allpools) { 4013 (void) printf(gettext("pool '%s' is healthy\n"), 4014 zpool_get_name(zhp)); 4015 if (cbp->cb_first) 4016 cbp->cb_first = B_FALSE; 4017 } 4018 return (0); 4019 } 4020 4021 if (cbp->cb_first) 4022 cbp->cb_first = B_FALSE; 4023 else 4024 (void) printf("\n"); 4025 4026 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 4027 &nvroot) == 0); 4028 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 4029 (uint64_t **)&vs, &c) == 0); 4030 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 4031 4032 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 4033 (void) printf(gettext(" state: %s\n"), health); 4034 4035 switch (reason) { 4036 case ZPOOL_STATUS_MISSING_DEV_R: 4037 (void) printf(gettext("status: One or more devices could not " 4038 "be opened. Sufficient replicas exist for\n\tthe pool to " 4039 "continue functioning in a degraded state.\n")); 4040 (void) printf(gettext("action: Attach the missing device and " 4041 "online it using 'zpool online'.\n")); 4042 break; 4043 4044 case ZPOOL_STATUS_MISSING_DEV_NR: 4045 (void) printf(gettext("status: One or more devices could not " 4046 "be opened. There are insufficient\n\treplicas for the " 4047 "pool to continue functioning.\n")); 4048 (void) printf(gettext("action: Attach the missing device and " 4049 "online it using 'zpool online'.\n")); 4050 break; 4051 4052 case ZPOOL_STATUS_CORRUPT_LABEL_R: 4053 (void) printf(gettext("status: One or more devices could not " 4054 "be used because the label is missing or\n\tinvalid. " 4055 "Sufficient replicas exist for the pool to continue\n\t" 4056 "functioning in a degraded state.\n")); 4057 (void) printf(gettext("action: Replace the device using " 4058 "'zpool replace'.\n")); 4059 break; 4060 4061 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 4062 (void) printf(gettext("status: One or more devices could not " 4063 "be used because the label is missing \n\tor invalid. " 4064 "There are insufficient replicas for the pool to " 4065 "continue\n\tfunctioning.\n")); 4066 zpool_explain_recover(zpool_get_handle(zhp), 4067 zpool_get_name(zhp), reason, config); 4068 break; 4069 4070 case ZPOOL_STATUS_FAILING_DEV: 4071 (void) printf(gettext("status: One or more devices has " 4072 "experienced an unrecoverable error. An\n\tattempt was " 4073 "made to correct the error. Applications are " 4074 "unaffected.\n")); 4075 (void) printf(gettext("action: Determine if the device needs " 4076 "to be replaced, and clear the errors\n\tusing " 4077 "'zpool clear' or replace the device with 'zpool " 4078 "replace'.\n")); 4079 break; 4080 4081 case ZPOOL_STATUS_OFFLINE_DEV: 4082 (void) printf(gettext("status: One or more devices has " 4083 "been taken offline by the administrator.\n\tSufficient " 4084 "replicas exist for the pool to continue functioning in " 4085 "a\n\tdegraded state.\n")); 4086 (void) printf(gettext("action: Online the device using " 4087 "'zpool online' or replace the device with\n\t'zpool " 4088 "replace'.\n")); 4089 break; 4090 4091 case ZPOOL_STATUS_REMOVED_DEV: 4092 (void) printf(gettext("status: One or more devices has " 4093 "been removed by the administrator.\n\tSufficient " 4094 "replicas exist for the pool to continue functioning in " 4095 "a\n\tdegraded state.\n")); 4096 (void) printf(gettext("action: Online the device using " 4097 "'zpool online' or replace the device with\n\t'zpool " 4098 "replace'.\n")); 4099 break; 4100 4101 case ZPOOL_STATUS_RESILVERING: 4102 (void) printf(gettext("status: One or more devices is " 4103 "currently being resilvered. The pool will\n\tcontinue " 4104 "to function, possibly in a degraded state.\n")); 4105 (void) printf(gettext("action: Wait for the resilver to " 4106 "complete.\n")); 4107 break; 4108 4109 case ZPOOL_STATUS_CORRUPT_DATA: 4110 (void) printf(gettext("status: One or more devices has " 4111 "experienced an error resulting in data\n\tcorruption. " 4112 "Applications may be affected.\n")); 4113 (void) printf(gettext("action: Restore the file in question " 4114 "if possible. Otherwise restore the\n\tentire pool from " 4115 "backup.\n")); 4116 break; 4117 4118 case ZPOOL_STATUS_CORRUPT_POOL: 4119 (void) printf(gettext("status: The pool metadata is corrupted " 4120 "and the pool cannot be opened.\n")); 4121 zpool_explain_recover(zpool_get_handle(zhp), 4122 zpool_get_name(zhp), reason, config); 4123 break; 4124 4125 case ZPOOL_STATUS_VERSION_OLDER: 4126 (void) printf(gettext("status: The pool is formatted using a " 4127 "legacy on-disk format. The pool can\n\tstill be used, " 4128 "but some features are unavailable.\n")); 4129 (void) printf(gettext("action: Upgrade the pool using 'zpool " 4130 "upgrade'. Once this is done, the\n\tpool will no longer " 4131 "be accessible on software that does not support feature\n" 4132 "\tflags.\n")); 4133 break; 4134 4135 case ZPOOL_STATUS_VERSION_NEWER: 4136 (void) printf(gettext("status: The pool has been upgraded to a " 4137 "newer, incompatible on-disk version.\n\tThe pool cannot " 4138 "be accessed on this system.\n")); 4139 (void) printf(gettext("action: Access the pool from a system " 4140 "running more recent software, or\n\trestore the pool from " 4141 "backup.\n")); 4142 break; 4143 4144 case ZPOOL_STATUS_FEAT_DISABLED: 4145 (void) printf(gettext("status: Some supported features are not " 4146 "enabled on the pool. The pool can\n\tstill be used, but " 4147 "some features are unavailable.\n")); 4148 (void) printf(gettext("action: Enable all features using " 4149 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 4150 "longer be accessible by software that does not support\n\t" 4151 "the features. See zpool-features(5) for details.\n")); 4152 break; 4153 4154 case ZPOOL_STATUS_UNSUP_FEAT_READ: 4155 (void) printf(gettext("status: The pool cannot be accessed on " 4156 "this system because it uses the\n\tfollowing feature(s) " 4157 "not supported on this system:\n")); 4158 zpool_print_unsup_feat(config); 4159 (void) printf("\n"); 4160 (void) printf(gettext("action: Access the pool from a system " 4161 "that supports the required feature(s),\n\tor restore the " 4162 "pool from backup.\n")); 4163 break; 4164 4165 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 4166 (void) printf(gettext("status: The pool can only be accessed " 4167 "in read-only mode on this system. It\n\tcannot be " 4168 "accessed in read-write mode because it uses the " 4169 "following\n\tfeature(s) not supported on this system:\n")); 4170 zpool_print_unsup_feat(config); 4171 (void) printf("\n"); 4172 (void) printf(gettext("action: The pool cannot be accessed in " 4173 "read-write mode. Import the pool with\n" 4174 "\t\"-o readonly=on\", access the pool from a system that " 4175 "supports the\n\trequired feature(s), or restore the " 4176 "pool from backup.\n")); 4177 break; 4178 4179 case ZPOOL_STATUS_FAULTED_DEV_R: 4180 (void) printf(gettext("status: One or more devices are " 4181 "faulted in response to persistent errors.\n\tSufficient " 4182 "replicas exist for the pool to continue functioning " 4183 "in a\n\tdegraded state.\n")); 4184 (void) printf(gettext("action: Replace the faulted device, " 4185 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 4186 break; 4187 4188 case ZPOOL_STATUS_FAULTED_DEV_NR: 4189 (void) printf(gettext("status: One or more devices are " 4190 "faulted in response to persistent errors. There are " 4191 "insufficient replicas for the pool to\n\tcontinue " 4192 "functioning.\n")); 4193 (void) printf(gettext("action: Destroy and re-create the pool " 4194 "from a backup source. Manually marking the device\n" 4195 "\trepaired using 'zpool clear' may allow some data " 4196 "to be recovered.\n")); 4197 break; 4198 4199 case ZPOOL_STATUS_IO_FAILURE_WAIT: 4200 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 4201 (void) printf(gettext("status: One or more devices are " 4202 "faulted in response to IO failures.\n")); 4203 (void) printf(gettext("action: Make sure the affected devices " 4204 "are connected, then run 'zpool clear'.\n")); 4205 break; 4206 4207 case ZPOOL_STATUS_BAD_LOG: 4208 (void) printf(gettext("status: An intent log record " 4209 "could not be read.\n" 4210 "\tWaiting for adminstrator intervention to fix the " 4211 "faulted pool.\n")); 4212 (void) printf(gettext("action: Either restore the affected " 4213 "device(s) and run 'zpool online',\n" 4214 "\tor ignore the intent log records by running " 4215 "'zpool clear'.\n")); 4216 break; 4217 4218 default: 4219 /* 4220 * The remaining errors can't actually be generated, yet. 4221 */ 4222 assert(reason == ZPOOL_STATUS_OK); 4223 } 4224 4225 if (msgid != NULL) 4226 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 4227 msgid); 4228 4229 if (config != NULL) { 4230 int namewidth; 4231 uint64_t nerr; 4232 nvlist_t **spares, **l2cache; 4233 uint_t nspares, nl2cache; 4234 pool_scan_stat_t *ps = NULL; 4235 4236 (void) nvlist_lookup_uint64_array(nvroot, 4237 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 4238 print_scan_status(ps); 4239 4240 namewidth = max_width(zhp, nvroot, 0, 0); 4241 if (namewidth < 10) 4242 namewidth = 10; 4243 4244 (void) printf(gettext("config:\n\n")); 4245 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 4246 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 4247 print_status_config(zhp, zpool_get_name(zhp), nvroot, 4248 namewidth, 0, B_FALSE); 4249 4250 if (num_logs(nvroot) > 0) 4251 print_logs(zhp, nvroot, namewidth, B_TRUE); 4252 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 4253 &l2cache, &nl2cache) == 0) 4254 print_l2cache(zhp, l2cache, nl2cache, namewidth); 4255 4256 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 4257 &spares, &nspares) == 0) 4258 print_spares(zhp, spares, nspares, namewidth); 4259 4260 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 4261 &nerr) == 0) { 4262 nvlist_t *nverrlist = NULL; 4263 4264 /* 4265 * If the approximate error count is small, get a 4266 * precise count by fetching the entire log and 4267 * uniquifying the results. 4268 */ 4269 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 4270 zpool_get_errlog(zhp, &nverrlist) == 0) { 4271 nvpair_t *elem; 4272 4273 elem = NULL; 4274 nerr = 0; 4275 while ((elem = nvlist_next_nvpair(nverrlist, 4276 elem)) != NULL) { 4277 nerr++; 4278 } 4279 } 4280 nvlist_free(nverrlist); 4281 4282 (void) printf("\n"); 4283 4284 if (nerr == 0) 4285 (void) printf(gettext("errors: No known data " 4286 "errors\n")); 4287 else if (!cbp->cb_verbose) 4288 (void) printf(gettext("errors: %llu data " 4289 "errors, use '-v' for a list\n"), 4290 (u_longlong_t)nerr); 4291 else 4292 print_error_log(zhp); 4293 } 4294 4295 if (cbp->cb_dedup_stats) 4296 print_dedup_stats(config); 4297 } else { 4298 (void) printf(gettext("config: The configuration cannot be " 4299 "determined.\n")); 4300 } 4301 4302 return (0); 4303 } 4304 4305 /* 4306 * zpool status [-vx] [-T d|u] [pool] ... [interval [count]] 4307 * 4308 * -v Display complete error logs 4309 * -x Display only pools with potential problems 4310 * -D Display dedup status (undocumented) 4311 * -T Display a timestamp in date(1) or Unix format 4312 * 4313 * Describes the health status of all pools or some subset. 4314 */ 4315 int 4316 zpool_do_status(int argc, char **argv) 4317 { 4318 int c; 4319 int ret; 4320 unsigned long interval = 0, count = 0; 4321 status_cbdata_t cb = { 0 }; 4322 4323 /* check options */ 4324 while ((c = getopt(argc, argv, "vxDT:")) != -1) { 4325 switch (c) { 4326 case 'v': 4327 cb.cb_verbose = B_TRUE; 4328 break; 4329 case 'x': 4330 cb.cb_explain = B_TRUE; 4331 break; 4332 case 'D': 4333 cb.cb_dedup_stats = B_TRUE; 4334 break; 4335 case 'T': 4336 get_timestamp_arg(*optarg); 4337 break; 4338 case '?': 4339 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4340 optopt); 4341 usage(B_FALSE); 4342 } 4343 } 4344 4345 argc -= optind; 4346 argv += optind; 4347 4348 get_interval_count(&argc, argv, &interval, &count); 4349 4350 if (argc == 0) 4351 cb.cb_allpools = B_TRUE; 4352 4353 cb.cb_first = B_TRUE; 4354 4355 for (;;) { 4356 if (timestamp_fmt != NODATE) 4357 print_timestamp(timestamp_fmt); 4358 4359 ret = for_each_pool(argc, argv, B_TRUE, NULL, 4360 status_callback, &cb); 4361 4362 if (argc == 0 && cb.cb_count == 0) 4363 (void) printf(gettext("no pools available\n")); 4364 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 4365 (void) printf(gettext("all pools are healthy\n")); 4366 4367 if (ret != 0) 4368 return (ret); 4369 4370 if (interval == 0) 4371 break; 4372 4373 if (count != 0 && --count == 0) 4374 break; 4375 4376 (void) sleep(interval); 4377 } 4378 4379 return (0); 4380 } 4381 4382 typedef struct upgrade_cbdata { 4383 int cb_first; 4384 int cb_argc; 4385 uint64_t cb_version; 4386 char **cb_argv; 4387 } upgrade_cbdata_t; 4388 4389 static int 4390 upgrade_version(zpool_handle_t *zhp, uint64_t version) 4391 { 4392 int ret; 4393 nvlist_t *config; 4394 uint64_t oldversion; 4395 4396 config = zpool_get_config(zhp, NULL); 4397 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4398 &oldversion) == 0); 4399 4400 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 4401 assert(oldversion < version); 4402 4403 ret = zpool_upgrade(zhp, version); 4404 if (ret != 0) 4405 return (ret); 4406 4407 if (version >= SPA_VERSION_FEATURES) { 4408 (void) printf(gettext("Successfully upgraded " 4409 "'%s' from version %llu to feature flags.\n"), 4410 zpool_get_name(zhp), oldversion); 4411 } else { 4412 (void) printf(gettext("Successfully upgraded " 4413 "'%s' from version %llu to version %llu.\n"), 4414 zpool_get_name(zhp), oldversion, version); 4415 } 4416 4417 return (0); 4418 } 4419 4420 static int 4421 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 4422 { 4423 int i, ret, count; 4424 boolean_t firstff = B_TRUE; 4425 nvlist_t *enabled = zpool_get_features(zhp); 4426 4427 count = 0; 4428 for (i = 0; i < SPA_FEATURES; i++) { 4429 const char *fname = spa_feature_table[i].fi_uname; 4430 const char *fguid = spa_feature_table[i].fi_guid; 4431 if (!nvlist_exists(enabled, fguid)) { 4432 char *propname; 4433 verify(-1 != asprintf(&propname, "feature@%s", fname)); 4434 ret = zpool_set_prop(zhp, propname, 4435 ZFS_FEATURE_ENABLED); 4436 if (ret != 0) { 4437 free(propname); 4438 return (ret); 4439 } 4440 count++; 4441 4442 if (firstff) { 4443 (void) printf(gettext("Enabled the " 4444 "following features on '%s':\n"), 4445 zpool_get_name(zhp)); 4446 firstff = B_FALSE; 4447 } 4448 (void) printf(gettext(" %s\n"), fname); 4449 free(propname); 4450 } 4451 } 4452 4453 if (countp != NULL) 4454 *countp = count; 4455 return (0); 4456 } 4457 4458 static int 4459 upgrade_cb(zpool_handle_t *zhp, void *arg) 4460 { 4461 upgrade_cbdata_t *cbp = arg; 4462 nvlist_t *config; 4463 uint64_t version; 4464 boolean_t printnl = B_FALSE; 4465 int ret; 4466 4467 config = zpool_get_config(zhp, NULL); 4468 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4469 &version) == 0); 4470 4471 assert(SPA_VERSION_IS_SUPPORTED(version)); 4472 4473 if (version < cbp->cb_version) { 4474 cbp->cb_first = B_FALSE; 4475 ret = upgrade_version(zhp, cbp->cb_version); 4476 if (ret != 0) 4477 return (ret); 4478 printnl = B_TRUE; 4479 4480 /* 4481 * If they did "zpool upgrade -a", then we could 4482 * be doing ioctls to different pools. We need 4483 * to log this history once to each pool, and bypass 4484 * the normal history logging that happens in main(). 4485 */ 4486 (void) zpool_log_history(g_zfs, history_str); 4487 log_history = B_FALSE; 4488 } 4489 4490 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 4491 int count; 4492 ret = upgrade_enable_all(zhp, &count); 4493 if (ret != 0) 4494 return (ret); 4495 4496 if (count > 0) { 4497 cbp->cb_first = B_FALSE; 4498 printnl = B_TRUE; 4499 } 4500 } 4501 4502 if (printnl) { 4503 (void) printf(gettext("\n")); 4504 } 4505 4506 return (0); 4507 } 4508 4509 static int 4510 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 4511 { 4512 upgrade_cbdata_t *cbp = arg; 4513 nvlist_t *config; 4514 uint64_t version; 4515 4516 config = zpool_get_config(zhp, NULL); 4517 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4518 &version) == 0); 4519 4520 assert(SPA_VERSION_IS_SUPPORTED(version)); 4521 4522 if (version < SPA_VERSION_FEATURES) { 4523 if (cbp->cb_first) { 4524 (void) printf(gettext("The following pools are " 4525 "formatted with legacy version numbers and can\n" 4526 "be upgraded to use feature flags. After " 4527 "being upgraded, these pools\nwill no " 4528 "longer be accessible by software that does not " 4529 "support feature\nflags.\n\n")); 4530 (void) printf(gettext("VER POOL\n")); 4531 (void) printf(gettext("--- ------------\n")); 4532 cbp->cb_first = B_FALSE; 4533 } 4534 4535 (void) printf("%2llu %s\n", (u_longlong_t)version, 4536 zpool_get_name(zhp)); 4537 } 4538 4539 return (0); 4540 } 4541 4542 static int 4543 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 4544 { 4545 upgrade_cbdata_t *cbp = arg; 4546 nvlist_t *config; 4547 uint64_t version; 4548 4549 config = zpool_get_config(zhp, NULL); 4550 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 4551 &version) == 0); 4552 4553 if (version >= SPA_VERSION_FEATURES) { 4554 int i; 4555 boolean_t poolfirst = B_TRUE; 4556 nvlist_t *enabled = zpool_get_features(zhp); 4557 4558 for (i = 0; i < SPA_FEATURES; i++) { 4559 const char *fguid = spa_feature_table[i].fi_guid; 4560 const char *fname = spa_feature_table[i].fi_uname; 4561 if (!nvlist_exists(enabled, fguid)) { 4562 if (cbp->cb_first) { 4563 (void) printf(gettext("\nSome " 4564 "supported features are not " 4565 "enabled on the following pools. " 4566 "Once a\nfeature is enabled the " 4567 "pool may become incompatible with " 4568 "software\nthat does not support " 4569 "the feature. See " 4570 "zpool-features(5) for " 4571 "details.\n\n")); 4572 (void) printf(gettext("POOL " 4573 "FEATURE\n")); 4574 (void) printf(gettext("------" 4575 "---------\n")); 4576 cbp->cb_first = B_FALSE; 4577 } 4578 4579 if (poolfirst) { 4580 (void) printf(gettext("%s\n"), 4581 zpool_get_name(zhp)); 4582 poolfirst = B_FALSE; 4583 } 4584 4585 (void) printf(gettext(" %s\n"), fname); 4586 } 4587 } 4588 } 4589 4590 return (0); 4591 } 4592 4593 /* ARGSUSED */ 4594 static int 4595 upgrade_one(zpool_handle_t *zhp, void *data) 4596 { 4597 boolean_t printnl = B_FALSE; 4598 upgrade_cbdata_t *cbp = data; 4599 uint64_t cur_version; 4600 int ret; 4601 4602 if (strcmp("log", zpool_get_name(zhp)) == 0) { 4603 (void) printf(gettext("'log' is now a reserved word\n" 4604 "Pool 'log' must be renamed using export and import" 4605 " to upgrade.\n")); 4606 return (1); 4607 } 4608 4609 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 4610 if (cur_version > cbp->cb_version) { 4611 (void) printf(gettext("Pool '%s' is already formatted " 4612 "using more current version '%llu'.\n\n"), 4613 zpool_get_name(zhp), cur_version); 4614 return (0); 4615 } 4616 4617 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 4618 (void) printf(gettext("Pool '%s' is already formatted " 4619 "using version %llu.\n\n"), zpool_get_name(zhp), 4620 cbp->cb_version); 4621 return (0); 4622 } 4623 4624 if (cur_version != cbp->cb_version) { 4625 printnl = B_TRUE; 4626 ret = upgrade_version(zhp, cbp->cb_version); 4627 if (ret != 0) 4628 return (ret); 4629 } 4630 4631 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 4632 int count = 0; 4633 ret = upgrade_enable_all(zhp, &count); 4634 if (ret != 0) 4635 return (ret); 4636 4637 if (count != 0) { 4638 printnl = B_TRUE; 4639 } else if (cur_version == SPA_VERSION) { 4640 (void) printf(gettext("Pool '%s' already has all " 4641 "supported features enabled.\n"), 4642 zpool_get_name(zhp)); 4643 } 4644 } 4645 4646 if (printnl) { 4647 (void) printf(gettext("\n")); 4648 } 4649 4650 return (0); 4651 } 4652 4653 /* 4654 * zpool upgrade 4655 * zpool upgrade -v 4656 * zpool upgrade [-V version] <-a | pool ...> 4657 * 4658 * With no arguments, display downrev'd ZFS pool available for upgrade. 4659 * Individual pools can be upgraded by specifying the pool, and '-a' will 4660 * upgrade all pools. 4661 */ 4662 int 4663 zpool_do_upgrade(int argc, char **argv) 4664 { 4665 int c; 4666 upgrade_cbdata_t cb = { 0 }; 4667 int ret = 0; 4668 boolean_t showversions = B_FALSE; 4669 boolean_t upgradeall = B_FALSE; 4670 char *end; 4671 4672 4673 /* check options */ 4674 while ((c = getopt(argc, argv, ":avV:")) != -1) { 4675 switch (c) { 4676 case 'a': 4677 upgradeall = B_TRUE; 4678 break; 4679 case 'v': 4680 showversions = B_TRUE; 4681 break; 4682 case 'V': 4683 cb.cb_version = strtoll(optarg, &end, 10); 4684 if (*end != '\0' || 4685 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 4686 (void) fprintf(stderr, 4687 gettext("invalid version '%s'\n"), optarg); 4688 usage(B_FALSE); 4689 } 4690 break; 4691 case ':': 4692 (void) fprintf(stderr, gettext("missing argument for " 4693 "'%c' option\n"), optopt); 4694 usage(B_FALSE); 4695 break; 4696 case '?': 4697 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4698 optopt); 4699 usage(B_FALSE); 4700 } 4701 } 4702 4703 cb.cb_argc = argc; 4704 cb.cb_argv = argv; 4705 argc -= optind; 4706 argv += optind; 4707 4708 if (cb.cb_version == 0) { 4709 cb.cb_version = SPA_VERSION; 4710 } else if (!upgradeall && argc == 0) { 4711 (void) fprintf(stderr, gettext("-V option is " 4712 "incompatible with other arguments\n")); 4713 usage(B_FALSE); 4714 } 4715 4716 if (showversions) { 4717 if (upgradeall || argc != 0) { 4718 (void) fprintf(stderr, gettext("-v option is " 4719 "incompatible with other arguments\n")); 4720 usage(B_FALSE); 4721 } 4722 } else if (upgradeall) { 4723 if (argc != 0) { 4724 (void) fprintf(stderr, gettext("-a option should not " 4725 "be used along with a pool name\n")); 4726 usage(B_FALSE); 4727 } 4728 } 4729 4730 (void) printf(gettext("This system supports ZFS pool feature " 4731 "flags.\n\n")); 4732 if (showversions) { 4733 int i; 4734 4735 (void) printf(gettext("The following features are " 4736 "supported:\n\n")); 4737 (void) printf(gettext("FEAT DESCRIPTION\n")); 4738 (void) printf("----------------------------------------------" 4739 "---------------\n"); 4740 for (i = 0; i < SPA_FEATURES; i++) { 4741 zfeature_info_t *fi = &spa_feature_table[i]; 4742 const char *ro = 4743 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 4744 " (read-only compatible)" : ""; 4745 4746 (void) printf("%-37s%s\n", fi->fi_uname, ro); 4747 (void) printf(" %s\n", fi->fi_desc); 4748 } 4749 (void) printf("\n"); 4750 4751 (void) printf(gettext("The following legacy versions are also " 4752 "supported:\n\n")); 4753 (void) printf(gettext("VER DESCRIPTION\n")); 4754 (void) printf("--- -----------------------------------------" 4755 "---------------\n"); 4756 (void) printf(gettext(" 1 Initial ZFS version\n")); 4757 (void) printf(gettext(" 2 Ditto blocks " 4758 "(replicated metadata)\n")); 4759 (void) printf(gettext(" 3 Hot spares and double parity " 4760 "RAID-Z\n")); 4761 (void) printf(gettext(" 4 zpool history\n")); 4762 (void) printf(gettext(" 5 Compression using the gzip " 4763 "algorithm\n")); 4764 (void) printf(gettext(" 6 bootfs pool property\n")); 4765 (void) printf(gettext(" 7 Separate intent log devices\n")); 4766 (void) printf(gettext(" 8 Delegated administration\n")); 4767 (void) printf(gettext(" 9 refquota and refreservation " 4768 "properties\n")); 4769 (void) printf(gettext(" 10 Cache devices\n")); 4770 (void) printf(gettext(" 11 Improved scrub performance\n")); 4771 (void) printf(gettext(" 12 Snapshot properties\n")); 4772 (void) printf(gettext(" 13 snapused property\n")); 4773 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 4774 (void) printf(gettext(" 15 user/group space accounting\n")); 4775 (void) printf(gettext(" 16 stmf property support\n")); 4776 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 4777 (void) printf(gettext(" 18 Snapshot user holds\n")); 4778 (void) printf(gettext(" 19 Log device removal\n")); 4779 (void) printf(gettext(" 20 Compression using zle " 4780 "(zero-length encoding)\n")); 4781 (void) printf(gettext(" 21 Deduplication\n")); 4782 (void) printf(gettext(" 22 Received properties\n")); 4783 (void) printf(gettext(" 23 Slim ZIL\n")); 4784 (void) printf(gettext(" 24 System attributes\n")); 4785 (void) printf(gettext(" 25 Improved scrub stats\n")); 4786 (void) printf(gettext(" 26 Improved snapshot deletion " 4787 "performance\n")); 4788 (void) printf(gettext(" 27 Improved snapshot creation " 4789 "performance\n")); 4790 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 4791 (void) printf(gettext("\nFor more information on a particular " 4792 "version, including supported releases,\n")); 4793 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 4794 } else if (argc == 0 && upgradeall) { 4795 cb.cb_first = B_TRUE; 4796 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 4797 if (ret == 0 && cb.cb_first) { 4798 if (cb.cb_version == SPA_VERSION) { 4799 (void) printf(gettext("All pools are already " 4800 "formatted using feature flags.\n\n")); 4801 (void) printf(gettext("Every feature flags " 4802 "pool already has all supported features " 4803 "enabled.\n")); 4804 } else { 4805 (void) printf(gettext("All pools are already " 4806 "formatted with version %llu or higher.\n"), 4807 cb.cb_version); 4808 } 4809 } 4810 } else if (argc == 0) { 4811 cb.cb_first = B_TRUE; 4812 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 4813 assert(ret == 0); 4814 4815 if (cb.cb_first) { 4816 (void) printf(gettext("All pools are formatted " 4817 "using feature flags.\n\n")); 4818 } else { 4819 (void) printf(gettext("\nUse 'zpool upgrade -v' " 4820 "for a list of available legacy versions.\n")); 4821 } 4822 4823 cb.cb_first = B_TRUE; 4824 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 4825 assert(ret == 0); 4826 4827 if (cb.cb_first) { 4828 (void) printf(gettext("Every feature flags pool has " 4829 "all supported features enabled.\n")); 4830 } else { 4831 (void) printf(gettext("\n")); 4832 } 4833 } else { 4834 ret = for_each_pool(argc, argv, B_FALSE, NULL, 4835 upgrade_one, &cb); 4836 } 4837 4838 return (ret); 4839 } 4840 4841 typedef struct hist_cbdata { 4842 boolean_t first; 4843 boolean_t longfmt; 4844 boolean_t internal; 4845 } hist_cbdata_t; 4846 4847 /* 4848 * Print out the command history for a specific pool. 4849 */ 4850 static int 4851 get_history_one(zpool_handle_t *zhp, void *data) 4852 { 4853 nvlist_t *nvhis; 4854 nvlist_t **records; 4855 uint_t numrecords; 4856 int ret, i; 4857 hist_cbdata_t *cb = (hist_cbdata_t *)data; 4858 4859 cb->first = B_FALSE; 4860 4861 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 4862 4863 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 4864 return (ret); 4865 4866 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 4867 &records, &numrecords) == 0); 4868 for (i = 0; i < numrecords; i++) { 4869 nvlist_t *rec = records[i]; 4870 char tbuf[30] = ""; 4871 4872 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 4873 time_t tsec; 4874 struct tm t; 4875 4876 tsec = fnvlist_lookup_uint64(records[i], 4877 ZPOOL_HIST_TIME); 4878 (void) localtime_r(&tsec, &t); 4879 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 4880 } 4881 4882 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 4883 (void) printf("%s %s", tbuf, 4884 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 4885 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 4886 int ievent = 4887 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 4888 if (!cb->internal) 4889 continue; 4890 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 4891 (void) printf("%s unrecognized record:\n", 4892 tbuf); 4893 dump_nvlist(rec, 4); 4894 continue; 4895 } 4896 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 4897 zfs_history_event_names[ievent], 4898 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 4899 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 4900 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 4901 if (!cb->internal) 4902 continue; 4903 (void) printf("%s [txg:%lld] %s", tbuf, 4904 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 4905 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 4906 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 4907 (void) printf(" %s (%llu)", 4908 fnvlist_lookup_string(rec, 4909 ZPOOL_HIST_DSNAME), 4910 fnvlist_lookup_uint64(rec, 4911 ZPOOL_HIST_DSID)); 4912 } 4913 (void) printf(" %s", fnvlist_lookup_string(rec, 4914 ZPOOL_HIST_INT_STR)); 4915 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 4916 if (!cb->internal) 4917 continue; 4918 (void) printf("%s ioctl %s\n", tbuf, 4919 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 4920 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 4921 (void) printf(" input:\n"); 4922 dump_nvlist(fnvlist_lookup_nvlist(rec, 4923 ZPOOL_HIST_INPUT_NVL), 8); 4924 } 4925 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 4926 (void) printf(" output:\n"); 4927 dump_nvlist(fnvlist_lookup_nvlist(rec, 4928 ZPOOL_HIST_OUTPUT_NVL), 8); 4929 } 4930 } else { 4931 if (!cb->internal) 4932 continue; 4933 (void) printf("%s unrecognized record:\n", tbuf); 4934 dump_nvlist(rec, 4); 4935 } 4936 4937 if (!cb->longfmt) { 4938 (void) printf("\n"); 4939 continue; 4940 } 4941 (void) printf(" ["); 4942 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 4943 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 4944 struct passwd *pwd = getpwuid(who); 4945 (void) printf("user %d ", (int)who); 4946 if (pwd != NULL) 4947 (void) printf("(%s) ", pwd->pw_name); 4948 } 4949 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 4950 (void) printf("on %s", 4951 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 4952 } 4953 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 4954 (void) printf(":%s", 4955 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 4956 } 4957 (void) printf("]"); 4958 (void) printf("\n"); 4959 } 4960 (void) printf("\n"); 4961 nvlist_free(nvhis); 4962 4963 return (ret); 4964 } 4965 4966 /* 4967 * zpool history <pool> 4968 * 4969 * Displays the history of commands that modified pools. 4970 */ 4971 int 4972 zpool_do_history(int argc, char **argv) 4973 { 4974 hist_cbdata_t cbdata = { 0 }; 4975 int ret; 4976 int c; 4977 4978 cbdata.first = B_TRUE; 4979 /* check options */ 4980 while ((c = getopt(argc, argv, "li")) != -1) { 4981 switch (c) { 4982 case 'l': 4983 cbdata.longfmt = B_TRUE; 4984 break; 4985 case 'i': 4986 cbdata.internal = B_TRUE; 4987 break; 4988 case '?': 4989 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4990 optopt); 4991 usage(B_FALSE); 4992 } 4993 } 4994 argc -= optind; 4995 argv += optind; 4996 4997 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 4998 &cbdata); 4999 5000 if (argc == 0 && cbdata.first == B_TRUE) { 5001 (void) printf(gettext("no pools available\n")); 5002 return (0); 5003 } 5004 5005 return (ret); 5006 } 5007 5008 static int 5009 get_callback(zpool_handle_t *zhp, void *data) 5010 { 5011 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 5012 char value[MAXNAMELEN]; 5013 zprop_source_t srctype; 5014 zprop_list_t *pl; 5015 5016 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 5017 5018 /* 5019 * Skip the special fake placeholder. This will also skip 5020 * over the name property when 'all' is specified. 5021 */ 5022 if (pl->pl_prop == ZPOOL_PROP_NAME && 5023 pl == cbp->cb_proplist) 5024 continue; 5025 5026 if (pl->pl_prop == ZPROP_INVAL && 5027 (zpool_prop_feature(pl->pl_user_prop) || 5028 zpool_prop_unsupported(pl->pl_user_prop))) { 5029 srctype = ZPROP_SRC_LOCAL; 5030 5031 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 5032 value, sizeof (value)) == 0) { 5033 zprop_print_one_property(zpool_get_name(zhp), 5034 cbp, pl->pl_user_prop, value, srctype, 5035 NULL, NULL); 5036 } 5037 } else { 5038 if (zpool_get_prop(zhp, pl->pl_prop, value, 5039 sizeof (value), &srctype, cbp->cb_literal) != 0) 5040 continue; 5041 5042 zprop_print_one_property(zpool_get_name(zhp), cbp, 5043 zpool_prop_to_name(pl->pl_prop), value, srctype, 5044 NULL, NULL); 5045 } 5046 } 5047 return (0); 5048 } 5049 5050 /* 5051 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 5052 * 5053 * -H Scripted mode. Don't display headers, and separate properties 5054 * by a single tab. 5055 * -o List of columns to display. Defaults to 5056 * "name,property,value,source". 5057 * -p Diplay values in parsable (exact) format. 5058 * 5059 * Get properties of pools in the system. Output space statistics 5060 * for each one as well as other attributes. 5061 */ 5062 int 5063 zpool_do_get(int argc, char **argv) 5064 { 5065 zprop_get_cbdata_t cb = { 0 }; 5066 zprop_list_t fake_name = { 0 }; 5067 int ret; 5068 int c, i; 5069 char *value; 5070 5071 cb.cb_first = B_TRUE; 5072 5073 /* 5074 * Set up default columns and sources. 5075 */ 5076 cb.cb_sources = ZPROP_SRC_ALL; 5077 cb.cb_columns[0] = GET_COL_NAME; 5078 cb.cb_columns[1] = GET_COL_PROPERTY; 5079 cb.cb_columns[2] = GET_COL_VALUE; 5080 cb.cb_columns[3] = GET_COL_SOURCE; 5081 cb.cb_type = ZFS_TYPE_POOL; 5082 5083 /* check options */ 5084 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 5085 switch (c) { 5086 case 'p': 5087 cb.cb_literal = B_TRUE; 5088 break; 5089 case 'H': 5090 cb.cb_scripted = B_TRUE; 5091 break; 5092 case 'o': 5093 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 5094 i = 0; 5095 while (*optarg != '\0') { 5096 static char *col_subopts[] = 5097 { "name", "property", "value", "source", 5098 "all", NULL }; 5099 5100 if (i == ZFS_GET_NCOLS) { 5101 (void) fprintf(stderr, gettext("too " 5102 "many fields given to -o " 5103 "option\n")); 5104 usage(B_FALSE); 5105 } 5106 5107 switch (getsubopt(&optarg, col_subopts, 5108 &value)) { 5109 case 0: 5110 cb.cb_columns[i++] = GET_COL_NAME; 5111 break; 5112 case 1: 5113 cb.cb_columns[i++] = GET_COL_PROPERTY; 5114 break; 5115 case 2: 5116 cb.cb_columns[i++] = GET_COL_VALUE; 5117 break; 5118 case 3: 5119 cb.cb_columns[i++] = GET_COL_SOURCE; 5120 break; 5121 case 4: 5122 if (i > 0) { 5123 (void) fprintf(stderr, 5124 gettext("\"all\" conflicts " 5125 "with specific fields " 5126 "given to -o option\n")); 5127 usage(B_FALSE); 5128 } 5129 cb.cb_columns[0] = GET_COL_NAME; 5130 cb.cb_columns[1] = GET_COL_PROPERTY; 5131 cb.cb_columns[2] = GET_COL_VALUE; 5132 cb.cb_columns[3] = GET_COL_SOURCE; 5133 i = ZFS_GET_NCOLS; 5134 break; 5135 default: 5136 (void) fprintf(stderr, 5137 gettext("invalid column name " 5138 "'%s'\n"), value); 5139 usage(B_FALSE); 5140 } 5141 } 5142 break; 5143 case '?': 5144 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5145 optopt); 5146 usage(B_FALSE); 5147 } 5148 } 5149 5150 argc -= optind; 5151 argv += optind; 5152 5153 if (argc < 1) { 5154 (void) fprintf(stderr, gettext("missing property " 5155 "argument\n")); 5156 usage(B_FALSE); 5157 } 5158 5159 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 5160 ZFS_TYPE_POOL) != 0) 5161 usage(B_FALSE); 5162 5163 argc--; 5164 argv++; 5165 5166 if (cb.cb_proplist != NULL) { 5167 fake_name.pl_prop = ZPOOL_PROP_NAME; 5168 fake_name.pl_width = strlen(gettext("NAME")); 5169 fake_name.pl_next = cb.cb_proplist; 5170 cb.cb_proplist = &fake_name; 5171 } 5172 5173 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 5174 get_callback, &cb); 5175 5176 if (cb.cb_proplist == &fake_name) 5177 zprop_free_list(fake_name.pl_next); 5178 else 5179 zprop_free_list(cb.cb_proplist); 5180 5181 return (ret); 5182 } 5183 5184 typedef struct set_cbdata { 5185 char *cb_propname; 5186 char *cb_value; 5187 boolean_t cb_any_successful; 5188 } set_cbdata_t; 5189 5190 int 5191 set_callback(zpool_handle_t *zhp, void *data) 5192 { 5193 int error; 5194 set_cbdata_t *cb = (set_cbdata_t *)data; 5195 5196 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 5197 5198 if (!error) 5199 cb->cb_any_successful = B_TRUE; 5200 5201 return (error); 5202 } 5203 5204 int 5205 zpool_do_set(int argc, char **argv) 5206 { 5207 set_cbdata_t cb = { 0 }; 5208 int error; 5209 5210 if (argc > 1 && argv[1][0] == '-') { 5211 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5212 argv[1][1]); 5213 usage(B_FALSE); 5214 } 5215 5216 if (argc < 2) { 5217 (void) fprintf(stderr, gettext("missing property=value " 5218 "argument\n")); 5219 usage(B_FALSE); 5220 } 5221 5222 if (argc < 3) { 5223 (void) fprintf(stderr, gettext("missing pool name\n")); 5224 usage(B_FALSE); 5225 } 5226 5227 if (argc > 3) { 5228 (void) fprintf(stderr, gettext("too many pool names\n")); 5229 usage(B_FALSE); 5230 } 5231 5232 cb.cb_propname = argv[1]; 5233 cb.cb_value = strchr(cb.cb_propname, '='); 5234 if (cb.cb_value == NULL) { 5235 (void) fprintf(stderr, gettext("missing value in " 5236 "property=value argument\n")); 5237 usage(B_FALSE); 5238 } 5239 5240 *(cb.cb_value) = '\0'; 5241 cb.cb_value++; 5242 5243 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 5244 set_callback, &cb); 5245 5246 return (error); 5247 } 5248 5249 static int 5250 find_command_idx(char *command, int *idx) 5251 { 5252 int i; 5253 5254 for (i = 0; i < NCOMMAND; i++) { 5255 if (command_table[i].name == NULL) 5256 continue; 5257 5258 if (strcmp(command, command_table[i].name) == 0) { 5259 *idx = i; 5260 return (0); 5261 } 5262 } 5263 return (1); 5264 } 5265 5266 int 5267 main(int argc, char **argv) 5268 { 5269 int ret; 5270 int i; 5271 char *cmdname; 5272 5273 (void) setlocale(LC_ALL, ""); 5274 (void) textdomain(TEXT_DOMAIN); 5275 5276 if ((g_zfs = libzfs_init()) == NULL) { 5277 (void) fprintf(stderr, gettext("internal error: failed to " 5278 "initialize ZFS library\n")); 5279 return (1); 5280 } 5281 5282 libzfs_print_on_error(g_zfs, B_TRUE); 5283 5284 opterr = 0; 5285 5286 /* 5287 * Make sure the user has specified some command. 5288 */ 5289 if (argc < 2) { 5290 (void) fprintf(stderr, gettext("missing command\n")); 5291 usage(B_FALSE); 5292 } 5293 5294 cmdname = argv[1]; 5295 5296 /* Log zpool commands to syslog. */ 5297 if (argc > 1) { 5298 char *fullcmd, *tmp; 5299 int full_arg_len = 1; 5300 int arg_len; 5301 5302 openlog("zpool", LOG_PID, LOG_DAEMON); 5303 for (i = 0; i < argc; i++) { 5304 full_arg_len += strlen(argv[i]) + 1; 5305 } 5306 fullcmd = malloc(full_arg_len); 5307 assert(fullcmd != NULL); 5308 5309 tmp = fullcmd; 5310 for (i = 0; i < argc; i++) { 5311 arg_len = strlen(argv[i]); 5312 strncpy(tmp, argv[i], arg_len); 5313 tmp += arg_len; 5314 strcpy(tmp, " "); 5315 ++tmp; 5316 } 5317 syslog(LOG_INFO, "%s", fullcmd); 5318 closelog(); 5319 free(fullcmd); 5320 } 5321 5322 /* 5323 * Special case '-?' 5324 */ 5325 if (strcmp(cmdname, "-?") == 0) 5326 usage(B_TRUE); 5327 5328 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 5329 5330 /* 5331 * Run the appropriate command. 5332 */ 5333 if (find_command_idx(cmdname, &i) == 0) { 5334 current_command = &command_table[i]; 5335 ret = command_table[i].func(argc - 1, argv + 1); 5336 } else if (strchr(cmdname, '=')) { 5337 verify(find_command_idx("set", &i) == 0); 5338 current_command = &command_table[i]; 5339 ret = command_table[i].func(argc, argv); 5340 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 5341 /* 5342 * 'freeze' is a vile debugging abomination, so we treat 5343 * it as such. 5344 */ 5345 char buf[16384]; 5346 int fd = open(ZFS_DEV, O_RDWR); 5347 (void) strcpy((void *)buf, argv[2]); 5348 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 5349 } else { 5350 (void) fprintf(stderr, gettext("unrecognized " 5351 "command '%s'\n"), cmdname); 5352 usage(B_FALSE); 5353 } 5354 5355 if (ret == 0 && log_history) 5356 (void) zpool_log_history(g_zfs, history_str); 5357 5358 libzfs_fini(g_zfs); 5359 5360 /* 5361 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 5362 * for the purposes of running ::findleaks. 5363 */ 5364 if (getenv("ZFS_ABORT") != NULL) { 5365 (void) printf("dumping core by request\n"); 5366 abort(); 5367 } 5368 5369 return (ret); 5370 } 5371