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