1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2011, 2018 by Delphix. All rights reserved. 25 * Copyright (c) 2012 by Frederik Wessels. All rights reserved. 26 * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. 27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>. 28 * Copyright 2016 Nexenta Systems, Inc. 29 * Copyright (c) 2017 Datto Inc. 30 * Copyright (c) 2017, Intel Corporation. 31 * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com> 32 * Copyright 2020 Joyent, Inc. 33 * Copyright (c) 2012 by Cyril Plisko. All rights reserved. 34 * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. 35 */ 36 37 #include <assert.h> 38 #include <ctype.h> 39 #include <dirent.h> 40 #include <errno.h> 41 #include <fcntl.h> 42 #include <getopt.h> 43 #include <libgen.h> 44 #include <libintl.h> 45 #include <libuutil.h> 46 #include <locale.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <strings.h> 51 #include <unistd.h> 52 #include <priv.h> 53 #include <pwd.h> 54 #include <zone.h> 55 #include <zfs_prop.h> 56 #include <sys/fs/zfs.h> 57 #include <sys/stat.h> 58 #include <sys/debug.h> 59 #include <math.h> 60 #include <sys/sysmacros.h> 61 #include <sys/termios.h> 62 63 #include <libzfs.h> 64 #include <libzutil.h> 65 66 #include "zpool_util.h" 67 #include "zfs_comutil.h" 68 #include "zfeature_common.h" 69 70 #include "statcommon.h" 71 72 static int zpool_do_create(int, char **); 73 static int zpool_do_destroy(int, char **); 74 75 static int zpool_do_add(int, char **); 76 static int zpool_do_remove(int, char **); 77 static int zpool_do_labelclear(int, char **); 78 79 static int zpool_do_checkpoint(int, char **); 80 81 static int zpool_do_list(int, char **); 82 static int zpool_do_iostat(int, char **); 83 static int zpool_do_status(int, char **); 84 85 static int zpool_do_online(int, char **); 86 static int zpool_do_offline(int, char **); 87 static int zpool_do_clear(int, char **); 88 static int zpool_do_reopen(int, char **); 89 90 static int zpool_do_reguid(int, char **); 91 92 static int zpool_do_attach(int, char **); 93 static int zpool_do_detach(int, char **); 94 static int zpool_do_replace(int, char **); 95 static int zpool_do_split(int, char **); 96 97 static int zpool_do_initialize(int, char **); 98 static int zpool_do_scrub(int, char **); 99 static int zpool_do_resilver(int, char **); 100 static int zpool_do_trim(int, char **); 101 102 static int zpool_do_import(int, char **); 103 static int zpool_do_export(int, char **); 104 105 static int zpool_do_upgrade(int, char **); 106 107 static int zpool_do_history(int, char **); 108 109 static int zpool_do_get(int, char **); 110 static int zpool_do_set(int, char **); 111 112 static int zpool_do_sync(int, char **); 113 114 /* 115 * These libumem hooks provide a reasonable set of defaults for the allocator's 116 * debugging facilities. 117 */ 118 119 #ifdef DEBUG 120 const char * 121 _umem_debug_init(void) 122 { 123 return ("default,verbose"); /* $UMEM_DEBUG setting */ 124 } 125 126 const char * 127 _umem_logging_init(void) 128 { 129 return ("fail,contents"); /* $UMEM_LOGGING setting */ 130 } 131 #endif 132 133 typedef enum { 134 HELP_ADD, 135 HELP_ATTACH, 136 HELP_CLEAR, 137 HELP_CREATE, 138 HELP_CHECKPOINT, 139 HELP_DESTROY, 140 HELP_DETACH, 141 HELP_EXPORT, 142 HELP_HISTORY, 143 HELP_IMPORT, 144 HELP_IOSTAT, 145 HELP_LABELCLEAR, 146 HELP_LIST, 147 HELP_OFFLINE, 148 HELP_ONLINE, 149 HELP_REPLACE, 150 HELP_REMOVE, 151 HELP_INITIALIZE, 152 HELP_SCRUB, 153 HELP_RESILVER, 154 HELP_TRIM, 155 HELP_STATUS, 156 HELP_UPGRADE, 157 HELP_GET, 158 HELP_SET, 159 HELP_SPLIT, 160 HELP_SYNC, 161 HELP_REGUID, 162 HELP_REOPEN 163 } zpool_help_t; 164 165 166 /* 167 * Flags for stats to display with "zpool iostats" 168 */ 169 enum iostat_type { 170 IOS_DEFAULT = 0, 171 IOS_LATENCY = 1, 172 IOS_QUEUES = 2, 173 IOS_L_HISTO = 3, 174 IOS_RQ_HISTO = 4, 175 IOS_COUNT, /* always last element */ 176 }; 177 178 /* iostat_type entries as bitmasks */ 179 #define IOS_DEFAULT_M (1ULL << IOS_DEFAULT) 180 #define IOS_LATENCY_M (1ULL << IOS_LATENCY) 181 #define IOS_QUEUES_M (1ULL << IOS_QUEUES) 182 #define IOS_L_HISTO_M (1ULL << IOS_L_HISTO) 183 #define IOS_RQ_HISTO_M (1ULL << IOS_RQ_HISTO) 184 185 /* Mask of all the histo bits */ 186 #define IOS_ANYHISTO_M (IOS_L_HISTO_M | IOS_RQ_HISTO_M) 187 188 /* 189 * Lookup table for iostat flags to nvlist names. Basically a list 190 * of all the nvlists a flag requires. Also specifies the order in 191 * which data gets printed in zpool iostat. 192 */ 193 static const char *vsx_type_to_nvlist[IOS_COUNT][13] = { 194 [IOS_L_HISTO] = { 195 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 196 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 197 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 198 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 199 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO, 200 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO, 201 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO, 202 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO, 203 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO, 204 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 205 NULL}, 206 [IOS_LATENCY] = { 207 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 208 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 209 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 210 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 211 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 212 NULL}, 213 [IOS_QUEUES] = { 214 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE, 215 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE, 216 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE, 217 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE, 218 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE, 219 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE, 220 NULL}, 221 [IOS_RQ_HISTO] = { 222 ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO, 223 ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO, 224 ZPOOL_CONFIG_VDEV_SYNC_IND_W_HISTO, 225 ZPOOL_CONFIG_VDEV_SYNC_AGG_W_HISTO, 226 ZPOOL_CONFIG_VDEV_ASYNC_IND_R_HISTO, 227 ZPOOL_CONFIG_VDEV_ASYNC_AGG_R_HISTO, 228 ZPOOL_CONFIG_VDEV_ASYNC_IND_W_HISTO, 229 ZPOOL_CONFIG_VDEV_ASYNC_AGG_W_HISTO, 230 ZPOOL_CONFIG_VDEV_IND_SCRUB_HISTO, 231 ZPOOL_CONFIG_VDEV_AGG_SCRUB_HISTO, 232 ZPOOL_CONFIG_VDEV_IND_TRIM_HISTO, 233 ZPOOL_CONFIG_VDEV_AGG_TRIM_HISTO, 234 NULL}, 235 }; 236 237 238 /* 239 * Given a cb->cb_flags with a histogram bit set, return the iostat_type. 240 * Right now, only one histo bit is ever set at one time, so we can 241 * just do a highbit64(a) 242 */ 243 #define IOS_HISTO_IDX(a) (highbit64(a & IOS_ANYHISTO_M) - 1) 244 245 typedef struct zpool_command { 246 const char *name; 247 int (*func)(int, char **); 248 zpool_help_t usage; 249 } zpool_command_t; 250 251 /* 252 * Master command table. Each ZFS command has a name, associated function, and 253 * usage message. The usage messages need to be internationalized, so we have 254 * to have a function to return the usage message based on a command index. 255 * 256 * These commands are organized according to how they are displayed in the usage 257 * message. An empty command (one with a NULL name) indicates an empty line in 258 * the generic usage message. 259 */ 260 static zpool_command_t command_table[] = { 261 { "create", zpool_do_create, HELP_CREATE }, 262 { "destroy", zpool_do_destroy, HELP_DESTROY }, 263 { NULL }, 264 { "add", zpool_do_add, HELP_ADD }, 265 { "remove", zpool_do_remove, HELP_REMOVE }, 266 { NULL }, 267 { "labelclear", zpool_do_labelclear, HELP_LABELCLEAR }, 268 { NULL }, 269 { "checkpoint", zpool_do_checkpoint, HELP_CHECKPOINT }, 270 { NULL }, 271 { "list", zpool_do_list, HELP_LIST }, 272 { "iostat", zpool_do_iostat, HELP_IOSTAT }, 273 { "status", zpool_do_status, HELP_STATUS }, 274 { NULL }, 275 { "online", zpool_do_online, HELP_ONLINE }, 276 { "offline", zpool_do_offline, HELP_OFFLINE }, 277 { "clear", zpool_do_clear, HELP_CLEAR }, 278 { "reopen", zpool_do_reopen, HELP_REOPEN }, 279 { NULL }, 280 { "attach", zpool_do_attach, HELP_ATTACH }, 281 { "detach", zpool_do_detach, HELP_DETACH }, 282 { "replace", zpool_do_replace, HELP_REPLACE }, 283 { "split", zpool_do_split, HELP_SPLIT }, 284 { NULL }, 285 { "initialize", zpool_do_initialize, HELP_INITIALIZE }, 286 { "resilver", zpool_do_resilver, HELP_RESILVER }, 287 { "scrub", zpool_do_scrub, HELP_SCRUB }, 288 { "trim", zpool_do_trim, HELP_TRIM }, 289 { NULL }, 290 { "import", zpool_do_import, HELP_IMPORT }, 291 { "export", zpool_do_export, HELP_EXPORT }, 292 { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 293 { "reguid", zpool_do_reguid, HELP_REGUID }, 294 { NULL }, 295 { "history", zpool_do_history, HELP_HISTORY }, 296 { "get", zpool_do_get, HELP_GET }, 297 { "set", zpool_do_set, HELP_SET }, 298 { "sync", zpool_do_sync, HELP_SYNC }, 299 }; 300 301 #define NCOMMAND (ARRAY_SIZE(command_table)) 302 303 #define VDEV_ALLOC_CLASS_LOGS "logs" 304 305 static zpool_command_t *current_command; 306 static char history_str[HIS_MAX_RECORD_LEN]; 307 static boolean_t log_history = B_TRUE; 308 static uint_t timestamp_fmt = NODATE; 309 310 static const char * 311 get_usage(zpool_help_t idx) 312 { 313 switch (idx) { 314 case HELP_ADD: 315 return (gettext("\tadd [-fgLnP] [-o property=value] " 316 "<pool> <vdev> ...\n")); 317 case HELP_ATTACH: 318 return (gettext("\tattach [-f] [-o property=value] " 319 "<pool> <device> <new-device>\n")); 320 case HELP_CLEAR: 321 return (gettext("\tclear [-nF] <pool> [device]\n")); 322 case HELP_CREATE: 323 return (gettext("\tcreate [-fnd] [-B] " 324 "[-o property=value] ... \n" 325 "\t [-O file-system-property=value] ...\n" 326 "\t [-m mountpoint] [-R root] [-t tempname] " 327 "<pool> <vdev> ...\n")); 328 case HELP_CHECKPOINT: 329 return (gettext("\tcheckpoint [--discard] <pool> ...\n")); 330 case HELP_DESTROY: 331 return (gettext("\tdestroy [-f] <pool>\n")); 332 case HELP_DETACH: 333 return (gettext("\tdetach <pool> <device>\n")); 334 case HELP_EXPORT: 335 return (gettext("\texport [-f] <pool> ...\n")); 336 case HELP_HISTORY: 337 return (gettext("\thistory [-il] [<pool>] ...\n")); 338 case HELP_IMPORT: 339 return (gettext("\timport [-d dir] [-D]\n" 340 "\timport [-d dir | -c cachefile] [-F [-n]] [-l] " 341 "<pool | id>\n" 342 "\timport [-o mntopts] [-o property=value] ... \n" 343 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] " 344 "[-R root] [-F [-n]] -a\n" 345 "\timport [-o mntopts] [-o property=value] ... \n" 346 "\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] " 347 "[-R root] [-F [-n]] [-t]\n" 348 "\t [--rewind-to-checkpoint] <pool | id> [newpool]\n")); 349 case HELP_IOSTAT: 350 return (gettext("\tiostat " 351 "[[-lq]|[-rw]] [-T d | u] [-ghHLpPvy]\n" 352 "\t [[pool] ...]|[pool vdev ...]|[vdev ...]]" 353 " [[-n] interval [count]]\n")); 354 case HELP_LABELCLEAR: 355 return (gettext("\tlabelclear [-f] <vdev>\n")); 356 case HELP_LIST: 357 return (gettext("\tlist [-gHLpPv] [-o property[,...]] " 358 "[-T d|u] [pool] ... [interval [count]]\n")); 359 case HELP_OFFLINE: 360 return (gettext("\toffline [-t] <pool> <device> ...\n")); 361 case HELP_ONLINE: 362 return (gettext("\tonline <pool> <device> ...\n")); 363 case HELP_REPLACE: 364 return (gettext("\treplace [-f] <pool> <device> " 365 "[new-device]\n")); 366 case HELP_REMOVE: 367 return (gettext("\tremove [-nps] <pool> <device> ...\n")); 368 case HELP_REOPEN: 369 return (gettext("\treopen <pool>\n")); 370 case HELP_INITIALIZE: 371 return (gettext("\tinitialize [-c | -s] <pool> " 372 "[<device> ...]\n")); 373 case HELP_SCRUB: 374 return (gettext("\tscrub [-s | -p] <pool> ...\n")); 375 case HELP_RESILVER: 376 return (gettext("\tresilver <pool> ...\n")); 377 case HELP_TRIM: 378 return (gettext("\ttrim [-d] [-r <rate>] [-c | -s] <pool> " 379 "[<device> ...]\n")); 380 case HELP_STATUS: 381 return (gettext("\tstatus " 382 "[-igLpPsvxD] [-T d|u] [pool] ... " 383 "[interval [count]]\n")); 384 case HELP_UPGRADE: 385 return (gettext("\tupgrade\n" 386 "\tupgrade -v\n" 387 "\tupgrade [-V version] <-a | pool ...>\n")); 388 case HELP_GET: 389 return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " 390 "<\"all\" | property[,...]> <pool> ...\n")); 391 case HELP_SET: 392 return (gettext("\tset <property=value> <pool> \n")); 393 case HELP_SPLIT: 394 return (gettext("\tsplit [-gLlnP] [-R altroot] [-o mntopts]\n" 395 "\t [-o property=value] <pool> <newpool> " 396 "[<device> ...]\n")); 397 case HELP_REGUID: 398 return (gettext("\treguid <pool>\n")); 399 case HELP_SYNC: 400 return (gettext("\tsync [pool] ...\n")); 401 } 402 403 abort(); 404 /* NOTREACHED */ 405 } 406 407 static void 408 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res) 409 { 410 uint_t children = 0; 411 nvlist_t **child; 412 uint_t i; 413 414 (void) nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 415 &child, &children); 416 417 if (children == 0) { 418 char *path = zpool_vdev_name(g_zfs, zhp, nvroot, 0); 419 420 if (strcmp(path, VDEV_TYPE_INDIRECT) != 0 && 421 strcmp(path, VDEV_TYPE_HOLE) != 0) 422 fnvlist_add_boolean(res, path); 423 424 free(path); 425 return; 426 } 427 428 for (i = 0; i < children; i++) { 429 zpool_collect_leaves(zhp, child[i], res); 430 } 431 } 432 433 /* 434 * Callback routine that will print out a pool property value. 435 */ 436 static int 437 print_prop_cb(int prop, void *cb) 438 { 439 FILE *fp = cb; 440 441 (void) fprintf(fp, "\t%-19s ", zpool_prop_to_name(prop)); 442 443 if (zpool_prop_readonly(prop)) 444 (void) fprintf(fp, " NO "); 445 else 446 (void) fprintf(fp, " YES "); 447 448 if (zpool_prop_values(prop) == NULL) 449 (void) fprintf(fp, "-\n"); 450 else 451 (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 452 453 return (ZPROP_CONT); 454 } 455 456 /* 457 * Display usage message. If we're inside a command, display only the usage for 458 * that command. Otherwise, iterate over the entire command table and display 459 * a complete usage message. 460 */ 461 void 462 usage(boolean_t requested) 463 { 464 FILE *fp = requested ? stdout : stderr; 465 466 if (current_command == NULL) { 467 int i; 468 469 (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 470 (void) fprintf(fp, 471 gettext("where 'command' is one of the following:\n\n")); 472 473 for (i = 0; i < NCOMMAND; i++) { 474 if (command_table[i].name == NULL) 475 (void) fprintf(fp, "\n"); 476 else 477 (void) fprintf(fp, "%s", 478 get_usage(command_table[i].usage)); 479 } 480 } else { 481 (void) fprintf(fp, gettext("usage:\n")); 482 (void) fprintf(fp, "%s", get_usage(current_command->usage)); 483 } 484 485 if (current_command != NULL && 486 ((strcmp(current_command->name, "set") == 0) || 487 (strcmp(current_command->name, "get") == 0) || 488 (strcmp(current_command->name, "list") == 0))) { 489 490 (void) fprintf(fp, 491 gettext("\nthe following properties are supported:\n")); 492 493 (void) fprintf(fp, "\n\t%-19s %s %s\n\n", 494 "PROPERTY", "EDIT", "VALUES"); 495 496 /* Iterate over all properties */ 497 (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 498 ZFS_TYPE_POOL); 499 500 (void) fprintf(fp, "\t%-19s ", "feature@..."); 501 (void) fprintf(fp, "YES disabled | enabled | active\n"); 502 503 (void) fprintf(fp, gettext("\nThe feature@ properties must be " 504 "appended with a feature name.\nSee zpool-features(5).\n")); 505 } 506 507 /* 508 * See comments at end of main(). 509 */ 510 if (getenv("ZFS_ABORT") != NULL) { 511 (void) printf("dumping core by request\n"); 512 abort(); 513 } 514 515 exit(requested ? 0 : 2); 516 } 517 518 /* 519 * print a pool vdev config for dry runs 520 */ 521 static void 522 print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 523 const char *match, int name_flags) 524 { 525 nvlist_t **child; 526 uint_t c, children; 527 char *vname; 528 boolean_t printed = B_FALSE; 529 530 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 531 &child, &children) != 0) { 532 if (name != NULL) 533 (void) printf("\t%*s%s\n", indent, "", name); 534 return; 535 } 536 537 for (c = 0; c < children; c++) { 538 uint64_t is_log = B_FALSE; 539 char *class = ""; 540 541 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 542 &is_log); 543 if (is_log) 544 class = VDEV_ALLOC_BIAS_LOG; 545 (void) nvlist_lookup_string(child[c], 546 ZPOOL_CONFIG_ALLOCATION_BIAS, &class); 547 if (strcmp(match, class) != 0) 548 continue; 549 550 if (!printed && name != NULL) { 551 (void) printf("\t%*s%s\n", indent, "", name); 552 printed = B_TRUE; 553 } 554 vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags); 555 print_vdev_tree(zhp, vname, child[c], indent + 2, "", 556 name_flags); 557 free(vname); 558 } 559 } 560 561 static boolean_t 562 prop_list_contains_feature(nvlist_t *proplist) 563 { 564 nvpair_t *nvp; 565 for (nvp = nvlist_next_nvpair(proplist, NULL); NULL != nvp; 566 nvp = nvlist_next_nvpair(proplist, nvp)) { 567 if (zpool_prop_feature(nvpair_name(nvp))) 568 return (B_TRUE); 569 } 570 return (B_FALSE); 571 } 572 573 /* 574 * Add a property pair (name, string-value) into a property nvlist. 575 */ 576 static int 577 add_prop_list(const char *propname, char *propval, nvlist_t **props, 578 boolean_t poolprop) 579 { 580 zpool_prop_t prop = ZPOOL_PROP_INVAL; 581 zfs_prop_t fprop; 582 nvlist_t *proplist; 583 const char *normnm; 584 char *strval; 585 586 if (*props == NULL && 587 nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 588 (void) fprintf(stderr, 589 gettext("internal error: out of memory\n")); 590 return (1); 591 } 592 593 proplist = *props; 594 595 if (poolprop) { 596 const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION); 597 598 if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL && 599 !zpool_prop_feature(propname)) { 600 (void) fprintf(stderr, gettext("property '%s' is " 601 "not a valid pool property\n"), propname); 602 return (2); 603 } 604 605 /* 606 * feature@ properties and version should not be specified 607 * at the same time. 608 */ 609 if ((prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname) && 610 nvlist_exists(proplist, vname)) || 611 (prop == ZPOOL_PROP_VERSION && 612 prop_list_contains_feature(proplist))) { 613 (void) fprintf(stderr, gettext("'feature@' and " 614 "'version' properties cannot be specified " 615 "together\n")); 616 return (2); 617 } 618 619 620 if (zpool_prop_feature(propname)) 621 normnm = propname; 622 else 623 normnm = zpool_prop_to_name(prop); 624 } else { 625 if ((fprop = zfs_name_to_prop(propname)) != ZPROP_INVAL) { 626 normnm = zfs_prop_to_name(fprop); 627 } else { 628 normnm = propname; 629 } 630 } 631 632 if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 633 prop != ZPOOL_PROP_CACHEFILE) { 634 (void) fprintf(stderr, gettext("property '%s' " 635 "specified multiple times\n"), propname); 636 return (2); 637 } 638 639 if (nvlist_add_string(proplist, normnm, propval) != 0) { 640 (void) fprintf(stderr, gettext("internal " 641 "error: out of memory\n")); 642 return (1); 643 } 644 645 return (0); 646 } 647 648 /* 649 * Set a default property pair (name, string-value) in a property nvlist 650 */ 651 static int 652 add_prop_list_default(const char *propname, char *propval, nvlist_t **props, 653 boolean_t poolprop) 654 { 655 char *pval; 656 657 if (nvlist_lookup_string(*props, propname, &pval) == 0) 658 return (0); 659 660 return (add_prop_list(propname, propval, props, poolprop)); 661 } 662 663 /* 664 * zpool add [-fgLnP] [-o property=value] <pool> <vdev> ... 665 * 666 * -f Force addition of devices, even if they appear in use 667 * -g Display guid for individual vdev name. 668 * -L Follow links when resolving vdev path name. 669 * -n Do not add the devices, but display the resulting layout if 670 * they were to be added. 671 * -P Display full path for vdev name. 672 * -o Set property=value. 673 * 674 * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 675 * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 676 * libzfs. 677 */ 678 int 679 zpool_do_add(int argc, char **argv) 680 { 681 boolean_t force = B_FALSE; 682 boolean_t dryrun = B_FALSE; 683 int name_flags = 0; 684 int c; 685 nvlist_t *nvroot; 686 char *poolname; 687 zpool_boot_label_t boot_type; 688 uint64_t boot_size; 689 int ret; 690 zpool_handle_t *zhp; 691 nvlist_t *config; 692 nvlist_t *props = NULL; 693 char *propval; 694 695 /* check options */ 696 while ((c = getopt(argc, argv, "fgLnPo:")) != -1) { 697 switch (c) { 698 case 'f': 699 force = B_TRUE; 700 break; 701 case 'g': 702 name_flags |= VDEV_NAME_GUID; 703 break; 704 case 'L': 705 name_flags |= VDEV_NAME_FOLLOW_LINKS; 706 break; 707 case 'n': 708 dryrun = B_TRUE; 709 break; 710 case 'P': 711 name_flags |= VDEV_NAME_PATH; 712 break; 713 case 'o': 714 if ((propval = strchr(optarg, '=')) == NULL) { 715 (void) fprintf(stderr, gettext("missing " 716 "'=' for -o option\n")); 717 usage(B_FALSE); 718 } 719 *propval = '\0'; 720 propval++; 721 722 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 723 (add_prop_list(optarg, propval, &props, B_TRUE))) 724 usage(B_FALSE); 725 break; 726 case '?': 727 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 728 optopt); 729 usage(B_FALSE); 730 } 731 } 732 733 argc -= optind; 734 argv += optind; 735 736 /* get pool name and check number of arguments */ 737 if (argc < 1) { 738 (void) fprintf(stderr, gettext("missing pool name argument\n")); 739 usage(B_FALSE); 740 } 741 if (argc < 2) { 742 (void) fprintf(stderr, gettext("missing vdev specification\n")); 743 usage(B_FALSE); 744 } 745 746 poolname = argv[0]; 747 748 argc--; 749 argv++; 750 751 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 752 return (1); 753 754 if ((config = zpool_get_config(zhp, NULL)) == NULL) { 755 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 756 poolname); 757 zpool_close(zhp); 758 return (1); 759 } 760 761 if (zpool_is_bootable(zhp)) 762 boot_type = ZPOOL_COPY_BOOT_LABEL; 763 else 764 boot_type = ZPOOL_NO_BOOT_LABEL; 765 766 /* unless manually specified use "ashift" pool property (if set) */ 767 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 768 int intval; 769 zprop_source_t src; 770 char strval[ZPOOL_MAXPROPLEN]; 771 772 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 773 if (src != ZPROP_SRC_DEFAULT) { 774 (void) sprintf(strval, "%" PRId32, intval); 775 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 776 &props, B_TRUE) == 0); 777 } 778 } 779 780 /* pass off to get_vdev_spec for processing */ 781 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 782 nvroot = make_root_vdev(zhp, props, force, !force, B_FALSE, dryrun, 783 boot_type, boot_size, argc, argv); 784 if (nvroot == NULL) { 785 zpool_close(zhp); 786 return (1); 787 } 788 789 if (dryrun) { 790 nvlist_t *poolnvroot; 791 792 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 793 &poolnvroot) == 0); 794 795 (void) printf(gettext("would update '%s' to the following " 796 "configuration:\n"), zpool_get_name(zhp)); 797 798 /* print original main pool and new tree */ 799 print_vdev_tree(zhp, poolname, poolnvroot, 0, "", 800 name_flags | VDEV_NAME_TYPE_ID); 801 print_vdev_tree(zhp, NULL, nvroot, 0, "", name_flags); 802 803 /* print other classes: 'dedup', 'special', and 'log' */ 804 print_vdev_tree(zhp, "dedup", poolnvroot, 0, 805 VDEV_ALLOC_BIAS_DEDUP, name_flags); 806 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_DEDUP, 807 name_flags); 808 809 print_vdev_tree(zhp, "special", poolnvroot, 0, 810 VDEV_ALLOC_BIAS_SPECIAL, name_flags); 811 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_SPECIAL, 812 name_flags); 813 814 print_vdev_tree(zhp, "logs", poolnvroot, 0, VDEV_ALLOC_BIAS_LOG, 815 name_flags); 816 print_vdev_tree(zhp, NULL, nvroot, 0, VDEV_ALLOC_BIAS_LOG, 817 name_flags); 818 819 ret = 0; 820 } else { 821 ret = (zpool_add(zhp, nvroot) != 0); 822 } 823 824 nvlist_free(props); 825 nvlist_free(nvroot); 826 zpool_close(zhp); 827 828 return (ret); 829 } 830 831 /* 832 * zpool remove <pool> <vdev> ... 833 * 834 * Removes the given vdev from the pool. 835 */ 836 int 837 zpool_do_remove(int argc, char **argv) 838 { 839 char *poolname; 840 int i, ret = 0; 841 zpool_handle_t *zhp; 842 boolean_t stop = B_FALSE; 843 boolean_t noop = B_FALSE; 844 boolean_t parsable = B_FALSE; 845 char c; 846 847 /* check options */ 848 while ((c = getopt(argc, argv, "nps")) != -1) { 849 switch (c) { 850 case 'n': 851 noop = B_TRUE; 852 break; 853 case 'p': 854 parsable = B_TRUE; 855 break; 856 case 's': 857 stop = B_TRUE; 858 break; 859 case '?': 860 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 861 optopt); 862 usage(B_FALSE); 863 } 864 } 865 866 argc -= optind; 867 argv += optind; 868 869 /* get pool name and check number of arguments */ 870 if (argc < 1) { 871 (void) fprintf(stderr, gettext("missing pool name argument\n")); 872 usage(B_FALSE); 873 } 874 875 poolname = argv[0]; 876 877 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 878 return (1); 879 880 if (stop && noop) { 881 (void) fprintf(stderr, gettext("stop request ignored\n")); 882 return (0); 883 } 884 885 if (stop) { 886 if (argc > 1) { 887 (void) fprintf(stderr, gettext("too many arguments\n")); 888 usage(B_FALSE); 889 } 890 if (zpool_vdev_remove_cancel(zhp) != 0) 891 ret = 1; 892 } else { 893 if (argc < 2) { 894 (void) fprintf(stderr, gettext("missing device\n")); 895 usage(B_FALSE); 896 } 897 898 for (i = 1; i < argc; i++) { 899 if (noop) { 900 uint64_t size; 901 902 if (zpool_vdev_indirect_size(zhp, argv[i], 903 &size) != 0) { 904 ret = 1; 905 break; 906 } 907 if (parsable) { 908 (void) printf("%s %llu\n", 909 argv[i], size); 910 } else { 911 char valstr[32]; 912 zfs_nicenum(size, valstr, 913 sizeof (valstr)); 914 (void) printf("Memory that will be " 915 "used after removing %s: %s\n", 916 argv[i], valstr); 917 } 918 } else { 919 if (zpool_vdev_remove(zhp, argv[i]) != 0) 920 ret = 1; 921 } 922 } 923 } 924 925 return (ret); 926 } 927 928 /* 929 * zpool labelclear [-f] <vdev> 930 * 931 * -f Force clearing the label for the vdevs which are members of 932 * the exported or foreign pools. 933 * 934 * Verifies that the vdev is not active and zeros out the label information 935 * on the device. 936 */ 937 int 938 zpool_do_labelclear(int argc, char **argv) 939 { 940 char vdev[MAXPATHLEN]; 941 char *name = NULL; 942 struct stat st; 943 int c, fd, ret = 0; 944 nvlist_t *config; 945 pool_state_t state; 946 boolean_t inuse = B_FALSE; 947 boolean_t force = B_FALSE; 948 949 /* check options */ 950 while ((c = getopt(argc, argv, "f")) != -1) { 951 switch (c) { 952 case 'f': 953 force = B_TRUE; 954 break; 955 default: 956 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 957 optopt); 958 usage(B_FALSE); 959 } 960 } 961 962 argc -= optind; 963 argv += optind; 964 965 /* get vdev name */ 966 if (argc < 1) { 967 (void) fprintf(stderr, gettext("missing vdev name\n")); 968 usage(B_FALSE); 969 } 970 if (argc > 1) { 971 (void) fprintf(stderr, gettext("too many arguments\n")); 972 usage(B_FALSE); 973 } 974 975 /* 976 * Check if we were given absolute path and use it as is. 977 * Otherwise if the provided vdev name doesn't point to a file, 978 * try prepending dsk path and appending s0. 979 */ 980 (void) strlcpy(vdev, argv[0], sizeof (vdev)); 981 if (vdev[0] != '/' && stat(vdev, &st) != 0) { 982 char *s; 983 984 (void) snprintf(vdev, sizeof (vdev), "%s/%s", 985 ZFS_DISK_ROOT, argv[0]); 986 if ((s = strrchr(argv[0], 's')) == NULL || 987 !isdigit(*(s + 1))) 988 (void) strlcat(vdev, "s0", sizeof (vdev)); 989 if (stat(vdev, &st) != 0) { 990 (void) fprintf(stderr, gettext( 991 "failed to find device %s, try specifying absolute " 992 "path instead\n"), argv[0]); 993 return (1); 994 } 995 } 996 997 if ((fd = open(vdev, O_RDWR)) < 0) { 998 (void) fprintf(stderr, gettext("failed to open %s: %s\n"), 999 vdev, strerror(errno)); 1000 return (1); 1001 } 1002 1003 if (zpool_read_label(fd, &config, NULL) != 0) { 1004 (void) fprintf(stderr, 1005 gettext("failed to read label from %s\n"), vdev); 1006 return (1); 1007 } 1008 nvlist_free(config); 1009 1010 ret = zpool_in_use(g_zfs, fd, &state, &name, &inuse); 1011 if (ret != 0) { 1012 (void) fprintf(stderr, 1013 gettext("failed to check state for %s\n"), vdev); 1014 return (1); 1015 } 1016 1017 if (!inuse) 1018 goto wipe_label; 1019 1020 switch (state) { 1021 default: 1022 case POOL_STATE_ACTIVE: 1023 case POOL_STATE_SPARE: 1024 case POOL_STATE_L2CACHE: 1025 (void) fprintf(stderr, gettext( 1026 "%s is a member (%s) of pool \"%s\"\n"), 1027 vdev, zpool_pool_state_to_name(state), name); 1028 ret = 1; 1029 goto errout; 1030 1031 case POOL_STATE_EXPORTED: 1032 if (force) 1033 break; 1034 (void) fprintf(stderr, gettext( 1035 "use '-f' to override the following error:\n" 1036 "%s is a member of exported pool \"%s\"\n"), 1037 vdev, name); 1038 ret = 1; 1039 goto errout; 1040 1041 case POOL_STATE_POTENTIALLY_ACTIVE: 1042 if (force) 1043 break; 1044 (void) fprintf(stderr, gettext( 1045 "use '-f' to override the following error:\n" 1046 "%s is a member of potentially active pool \"%s\"\n"), 1047 vdev, name); 1048 ret = 1; 1049 goto errout; 1050 1051 case POOL_STATE_DESTROYED: 1052 /* inuse should never be set for a destroyed pool */ 1053 assert(0); 1054 break; 1055 } 1056 1057 wipe_label: 1058 ret = zpool_clear_label(fd); 1059 if (ret != 0) { 1060 (void) fprintf(stderr, 1061 gettext("failed to clear label for %s\n"), vdev); 1062 } 1063 1064 errout: 1065 free(name); 1066 (void) close(fd); 1067 1068 return (ret); 1069 } 1070 1071 /* 1072 * zpool create [-fnd] [-B] [-o property=value] ... 1073 * [-O file-system-property=value] ... 1074 * [-R root] [-m mountpoint] [-t tempname] <pool> <dev> ... 1075 * 1076 * -B Create boot partition. 1077 * -f Force creation, even if devices appear in use 1078 * -n Do not create the pool, but display the resulting layout if it 1079 * were to be created. 1080 * -R Create a pool under an alternate root 1081 * -m Set default mountpoint for the root dataset. By default it's 1082 * '/<pool>' 1083 * -t Use the temporary name until the pool is exported. 1084 * -o Set property=value. 1085 * -o Set feature@feature=enabled|disabled. 1086 * -d Don't automatically enable all supported pool features 1087 * (individual features can be enabled with -o). 1088 * -O Set fsproperty=value in the pool's root file system 1089 * 1090 * Creates the named pool according to the given vdev specification. The 1091 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 1092 * we get the nvlist back from get_vdev_spec(), we either print out the contents 1093 * (if '-n' was specified), or pass it to libzfs to do the creation. 1094 */ 1095 1096 #define SYSTEM256 (256 * 1024 * 1024) 1097 int 1098 zpool_do_create(int argc, char **argv) 1099 { 1100 boolean_t force = B_FALSE; 1101 boolean_t dryrun = B_FALSE; 1102 boolean_t enable_all_pool_feat = B_TRUE; 1103 zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL; 1104 uint64_t boot_size = 0; 1105 int c; 1106 nvlist_t *nvroot = NULL; 1107 char *poolname; 1108 char *tname = NULL; 1109 int ret = 1; 1110 char *altroot = NULL; 1111 char *mountpoint = NULL; 1112 nvlist_t *fsprops = NULL; 1113 nvlist_t *props = NULL; 1114 char *propval; 1115 1116 /* check options */ 1117 while ((c = getopt(argc, argv, ":fndBR:m:o:O:t:")) != -1) { 1118 switch (c) { 1119 case 'f': 1120 force = B_TRUE; 1121 break; 1122 case 'n': 1123 dryrun = B_TRUE; 1124 break; 1125 case 'd': 1126 enable_all_pool_feat = B_FALSE; 1127 break; 1128 case 'B': 1129 /* 1130 * We should create the system partition. 1131 * Also make sure the size is set. 1132 */ 1133 boot_type = ZPOOL_CREATE_BOOT_LABEL; 1134 if (boot_size == 0) 1135 boot_size = SYSTEM256; 1136 break; 1137 case 'R': 1138 altroot = optarg; 1139 if (add_prop_list(zpool_prop_to_name( 1140 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1141 goto errout; 1142 if (add_prop_list_default(zpool_prop_to_name( 1143 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1144 goto errout; 1145 break; 1146 case 'm': 1147 /* Equivalent to -O mountpoint=optarg */ 1148 mountpoint = optarg; 1149 break; 1150 case 'o': 1151 if ((propval = strchr(optarg, '=')) == NULL) { 1152 (void) fprintf(stderr, gettext("missing " 1153 "'=' for -o option\n")); 1154 goto errout; 1155 } 1156 *propval = '\0'; 1157 propval++; 1158 1159 if (add_prop_list(optarg, propval, &props, B_TRUE)) 1160 goto errout; 1161 1162 /* 1163 * Get bootsize value for make_root_vdev(). 1164 */ 1165 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_BOOTSIZE) { 1166 if (zfs_nicestrtonum(g_zfs, propval, 1167 &boot_size) < 0 || boot_size == 0) { 1168 (void) fprintf(stderr, 1169 gettext("bad boot partition size " 1170 "'%s': %s\n"), propval, 1171 libzfs_error_description(g_zfs)); 1172 goto errout; 1173 } 1174 } 1175 1176 /* 1177 * If the user is creating a pool that doesn't support 1178 * feature flags, don't enable any features. 1179 */ 1180 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) { 1181 char *end; 1182 u_longlong_t ver; 1183 1184 ver = strtoull(propval, &end, 10); 1185 if (*end == '\0' && 1186 ver < SPA_VERSION_FEATURES) { 1187 enable_all_pool_feat = B_FALSE; 1188 } 1189 } 1190 if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT) 1191 altroot = propval; 1192 break; 1193 case 'O': 1194 if ((propval = strchr(optarg, '=')) == NULL) { 1195 (void) fprintf(stderr, gettext("missing " 1196 "'=' for -O option\n")); 1197 goto errout; 1198 } 1199 *propval = '\0'; 1200 propval++; 1201 1202 /* 1203 * Mountpoints are checked and then added later. 1204 * Uniquely among properties, they can be specified 1205 * more than once, to avoid conflict with -m. 1206 */ 1207 if (0 == strcmp(optarg, 1208 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT))) { 1209 mountpoint = propval; 1210 } else if (add_prop_list(optarg, propval, &fsprops, 1211 B_FALSE)) { 1212 goto errout; 1213 } 1214 break; 1215 case 't': 1216 /* 1217 * Sanity check temporary pool name. 1218 */ 1219 if (strchr(optarg, '/') != NULL) { 1220 (void) fprintf(stderr, gettext("cannot create " 1221 "'%s': invalid character '/' in temporary " 1222 "name\n"), optarg); 1223 (void) fprintf(stderr, gettext("use 'zfs " 1224 "create' to create a dataset\n")); 1225 goto errout; 1226 } 1227 1228 if (add_prop_list(zpool_prop_to_name( 1229 ZPOOL_PROP_TNAME), optarg, &props, B_TRUE)) 1230 goto errout; 1231 if (add_prop_list_default(zpool_prop_to_name( 1232 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1233 goto errout; 1234 tname = optarg; 1235 break; 1236 case ':': 1237 (void) fprintf(stderr, gettext("missing argument for " 1238 "'%c' option\n"), optopt); 1239 goto badusage; 1240 case '?': 1241 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1242 optopt); 1243 goto badusage; 1244 } 1245 } 1246 1247 argc -= optind; 1248 argv += optind; 1249 1250 /* get pool name and check number of arguments */ 1251 if (argc < 1) { 1252 (void) fprintf(stderr, gettext("missing pool name argument\n")); 1253 goto badusage; 1254 } 1255 if (argc < 2) { 1256 (void) fprintf(stderr, gettext("missing vdev specification\n")); 1257 goto badusage; 1258 } 1259 1260 poolname = argv[0]; 1261 1262 /* 1263 * As a special case, check for use of '/' in the name, and direct the 1264 * user to use 'zfs create' instead. 1265 */ 1266 if (strchr(poolname, '/') != NULL) { 1267 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 1268 "character '/' in pool name\n"), poolname); 1269 (void) fprintf(stderr, gettext("use 'zfs create' to " 1270 "create a dataset\n")); 1271 goto errout; 1272 } 1273 1274 /* 1275 * Make sure the bootsize is set when ZPOOL_CREATE_BOOT_LABEL is used, 1276 * and not set otherwise. 1277 */ 1278 if (boot_type == ZPOOL_CREATE_BOOT_LABEL) { 1279 const char *propname; 1280 char *strptr, *buf = NULL; 1281 int rv; 1282 1283 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1284 if (nvlist_lookup_string(props, propname, &strptr) != 0) { 1285 (void) asprintf(&buf, "%" PRIu64, boot_size); 1286 if (buf == NULL) { 1287 (void) fprintf(stderr, 1288 gettext("internal error: out of memory\n")); 1289 goto errout; 1290 } 1291 rv = add_prop_list(propname, buf, &props, B_TRUE); 1292 free(buf); 1293 if (rv != 0) 1294 goto errout; 1295 } 1296 } else { 1297 const char *propname; 1298 char *strptr; 1299 1300 propname = zpool_prop_to_name(ZPOOL_PROP_BOOTSIZE); 1301 if (nvlist_lookup_string(props, propname, &strptr) == 0) { 1302 (void) fprintf(stderr, gettext("error: setting boot " 1303 "partition size requires option '-B'\n")); 1304 goto errout; 1305 } 1306 } 1307 1308 /* pass off to get_vdev_spec for bulk processing */ 1309 nvroot = make_root_vdev(NULL, props, force, !force, B_FALSE, dryrun, 1310 boot_type, boot_size, argc - 1, argv + 1); 1311 if (nvroot == NULL) 1312 goto errout; 1313 1314 /* make_root_vdev() allows 0 toplevel children if there are spares */ 1315 if (!zfs_allocatable_devs(nvroot)) { 1316 (void) fprintf(stderr, gettext("invalid vdev " 1317 "specification: at least one toplevel vdev must be " 1318 "specified\n")); 1319 goto errout; 1320 } 1321 1322 if (altroot != NULL && altroot[0] != '/') { 1323 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 1324 "must be an absolute path\n"), altroot); 1325 goto errout; 1326 } 1327 1328 /* 1329 * Check the validity of the mountpoint and direct the user to use the 1330 * '-m' mountpoint option if it looks like its in use. 1331 */ 1332 if (mountpoint == NULL || 1333 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 1334 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 1335 char buf[MAXPATHLEN]; 1336 DIR *dirp; 1337 1338 if (mountpoint && mountpoint[0] != '/') { 1339 (void) fprintf(stderr, gettext("invalid mountpoint " 1340 "'%s': must be an absolute path, 'legacy', or " 1341 "'none'\n"), mountpoint); 1342 goto errout; 1343 } 1344 1345 if (mountpoint == NULL) { 1346 if (altroot != NULL) 1347 (void) snprintf(buf, sizeof (buf), "%s/%s", 1348 altroot, poolname); 1349 else 1350 (void) snprintf(buf, sizeof (buf), "/%s", 1351 poolname); 1352 } else { 1353 if (altroot != NULL) 1354 (void) snprintf(buf, sizeof (buf), "%s%s", 1355 altroot, mountpoint); 1356 else 1357 (void) snprintf(buf, sizeof (buf), "%s", 1358 mountpoint); 1359 } 1360 1361 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 1362 (void) fprintf(stderr, gettext("mountpoint '%s' : " 1363 "%s\n"), buf, strerror(errno)); 1364 (void) fprintf(stderr, gettext("use '-m' " 1365 "option to provide a different default\n")); 1366 goto errout; 1367 } else if (dirp) { 1368 int count = 0; 1369 1370 while (count < 3 && readdir(dirp) != NULL) 1371 count++; 1372 (void) closedir(dirp); 1373 1374 if (count > 2) { 1375 (void) fprintf(stderr, gettext("mountpoint " 1376 "'%s' exists and is not empty\n"), buf); 1377 (void) fprintf(stderr, gettext("use '-m' " 1378 "option to provide a " 1379 "different default\n")); 1380 goto errout; 1381 } 1382 } 1383 } 1384 1385 /* 1386 * Now that the mountpoint's validity has been checked, ensure that 1387 * the property is set appropriately prior to creating the pool. 1388 */ 1389 if (mountpoint != NULL) { 1390 ret = add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1391 mountpoint, &fsprops, B_FALSE); 1392 if (ret != 0) 1393 goto errout; 1394 } 1395 1396 ret = 1; 1397 if (dryrun) { 1398 /* 1399 * For a dry run invocation, print out a basic message and run 1400 * through all the vdevs in the list and print out in an 1401 * appropriate hierarchy. 1402 */ 1403 (void) printf(gettext("would create '%s' with the " 1404 "following layout:\n\n"), poolname); 1405 1406 print_vdev_tree(NULL, poolname, nvroot, 0, "", 0); 1407 print_vdev_tree(NULL, "dedup", nvroot, 0, 1408 VDEV_ALLOC_BIAS_DEDUP, 0); 1409 print_vdev_tree(NULL, "special", nvroot, 0, 1410 VDEV_ALLOC_BIAS_SPECIAL, 0); 1411 print_vdev_tree(NULL, "logs", nvroot, 0, 1412 VDEV_ALLOC_BIAS_LOG, 0); 1413 1414 ret = 0; 1415 } else { 1416 /* 1417 * Hand off to libzfs. 1418 */ 1419 1420 spa_feature_t i; 1421 for (i = 0; i < SPA_FEATURES; i++) { 1422 char propname[MAXPATHLEN]; 1423 char *propval; 1424 zfeature_info_t *feat = &spa_feature_table[i]; 1425 (void) snprintf(propname, sizeof (propname), 1426 "feature@%s", feat->fi_uname); 1427 1428 /* 1429 * Only features contained in props will be enabled: 1430 * remove from the nvlist every ZFS_FEATURE_DISABLED 1431 * value and add every missing ZFS_FEATURE_ENABLED if 1432 * enable_all_pool_feat is set. 1433 */ 1434 if (!nvlist_lookup_string(props, propname, &propval)) { 1435 if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0) 1436 (void) nvlist_remove_all(props, 1437 propname); 1438 } else if (enable_all_pool_feat) { 1439 ret = add_prop_list(propname, 1440 ZFS_FEATURE_ENABLED, &props, B_TRUE); 1441 if (ret != 0) 1442 goto errout; 1443 } 1444 } 1445 1446 ret = 1; 1447 if (zpool_create(g_zfs, poolname, 1448 nvroot, props, fsprops) == 0) { 1449 zfs_handle_t *pool = zfs_open(g_zfs, 1450 tname ? tname : poolname, ZFS_TYPE_FILESYSTEM); 1451 if (pool != NULL) { 1452 if (zfs_mount(pool, NULL, 0) == 0) 1453 ret = zfs_shareall(pool); 1454 zfs_close(pool); 1455 } 1456 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 1457 (void) fprintf(stderr, gettext("pool name may have " 1458 "been omitted\n")); 1459 } 1460 } 1461 1462 errout: 1463 nvlist_free(nvroot); 1464 nvlist_free(fsprops); 1465 nvlist_free(props); 1466 return (ret); 1467 badusage: 1468 nvlist_free(fsprops); 1469 nvlist_free(props); 1470 usage(B_FALSE); 1471 return (2); 1472 } 1473 1474 /* 1475 * zpool destroy <pool> 1476 * 1477 * -f Forcefully unmount any datasets 1478 * 1479 * Destroy the given pool. Automatically unmounts any datasets in the pool. 1480 */ 1481 int 1482 zpool_do_destroy(int argc, char **argv) 1483 { 1484 boolean_t force = B_FALSE; 1485 int c; 1486 char *pool; 1487 zpool_handle_t *zhp; 1488 int ret; 1489 1490 /* check options */ 1491 while ((c = getopt(argc, argv, "f")) != -1) { 1492 switch (c) { 1493 case 'f': 1494 force = B_TRUE; 1495 break; 1496 case '?': 1497 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1498 optopt); 1499 usage(B_FALSE); 1500 } 1501 } 1502 1503 argc -= optind; 1504 argv += optind; 1505 1506 /* check arguments */ 1507 if (argc < 1) { 1508 (void) fprintf(stderr, gettext("missing pool argument\n")); 1509 usage(B_FALSE); 1510 } 1511 if (argc > 1) { 1512 (void) fprintf(stderr, gettext("too many arguments\n")); 1513 usage(B_FALSE); 1514 } 1515 1516 pool = argv[0]; 1517 1518 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 1519 /* 1520 * As a special case, check for use of '/' in the name, and 1521 * direct the user to use 'zfs destroy' instead. 1522 */ 1523 if (strchr(pool, '/') != NULL) 1524 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 1525 "destroy a dataset\n")); 1526 return (1); 1527 } 1528 1529 if (zpool_disable_datasets(zhp, force) != 0) { 1530 (void) fprintf(stderr, gettext("could not destroy '%s': " 1531 "could not unmount datasets\n"), zpool_get_name(zhp)); 1532 return (1); 1533 } 1534 1535 /* The history must be logged as part of the export */ 1536 log_history = B_FALSE; 1537 1538 ret = (zpool_destroy(zhp, history_str) != 0); 1539 1540 zpool_close(zhp); 1541 1542 return (ret); 1543 } 1544 1545 /* 1546 * zpool export [-f] <pool> ... 1547 * 1548 * -f Forcefully unmount datasets 1549 * 1550 * Export the given pools. By default, the command will attempt to cleanly 1551 * unmount any active datasets within the pool. If the '-f' flag is specified, 1552 * then the datasets will be forcefully unmounted. 1553 */ 1554 int 1555 zpool_do_export(int argc, char **argv) 1556 { 1557 boolean_t force = B_FALSE; 1558 boolean_t hardforce = B_FALSE; 1559 int c; 1560 zpool_handle_t *zhp; 1561 int ret; 1562 int i; 1563 1564 /* check options */ 1565 while ((c = getopt(argc, argv, "fF")) != -1) { 1566 switch (c) { 1567 case 'f': 1568 force = B_TRUE; 1569 break; 1570 case 'F': 1571 hardforce = B_TRUE; 1572 break; 1573 case '?': 1574 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1575 optopt); 1576 usage(B_FALSE); 1577 } 1578 } 1579 1580 argc -= optind; 1581 argv += optind; 1582 1583 /* check arguments */ 1584 if (argc < 1) { 1585 (void) fprintf(stderr, gettext("missing pool argument\n")); 1586 usage(B_FALSE); 1587 } 1588 1589 ret = 0; 1590 for (i = 0; i < argc; i++) { 1591 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 1592 ret = 1; 1593 continue; 1594 } 1595 1596 if (zpool_disable_datasets(zhp, force) != 0) { 1597 ret = 1; 1598 zpool_close(zhp); 1599 continue; 1600 } 1601 1602 /* The history must be logged as part of the export */ 1603 log_history = B_FALSE; 1604 1605 if (hardforce) { 1606 if (zpool_export_force(zhp, history_str) != 0) 1607 ret = 1; 1608 } else if (zpool_export(zhp, force, history_str) != 0) { 1609 ret = 1; 1610 } 1611 1612 zpool_close(zhp); 1613 } 1614 1615 return (ret); 1616 } 1617 1618 /* 1619 * Given a vdev configuration, determine the maximum width needed for the device 1620 * name column. 1621 */ 1622 static int 1623 max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max, 1624 int name_flags) 1625 { 1626 char *name; 1627 nvlist_t **child; 1628 uint_t c, children; 1629 int ret; 1630 1631 name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID); 1632 if (strlen(name) + depth > max) 1633 max = strlen(name) + depth; 1634 1635 free(name); 1636 1637 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1638 &child, &children) == 0) { 1639 for (c = 0; c < children; c++) 1640 if ((ret = max_width(zhp, child[c], depth + 2, 1641 max, name_flags)) > max) 1642 max = ret; 1643 } 1644 1645 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1646 &child, &children) == 0) { 1647 for (c = 0; c < children; c++) 1648 if ((ret = max_width(zhp, child[c], depth + 2, 1649 max, name_flags)) > max) 1650 max = ret; 1651 } 1652 1653 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1654 &child, &children) == 0) { 1655 for (c = 0; c < children; c++) 1656 if ((ret = max_width(zhp, child[c], depth + 2, 1657 max, name_flags)) > max) 1658 max = ret; 1659 } 1660 1661 return (max); 1662 } 1663 1664 typedef struct spare_cbdata { 1665 uint64_t cb_guid; 1666 zpool_handle_t *cb_zhp; 1667 } spare_cbdata_t; 1668 1669 static boolean_t 1670 find_vdev(nvlist_t *nv, uint64_t search) 1671 { 1672 uint64_t guid; 1673 nvlist_t **child; 1674 uint_t c, children; 1675 1676 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 1677 search == guid) 1678 return (B_TRUE); 1679 1680 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1681 &child, &children) == 0) { 1682 for (c = 0; c < children; c++) 1683 if (find_vdev(child[c], search)) 1684 return (B_TRUE); 1685 } 1686 1687 return (B_FALSE); 1688 } 1689 1690 static int 1691 find_spare(zpool_handle_t *zhp, void *data) 1692 { 1693 spare_cbdata_t *cbp = data; 1694 nvlist_t *config, *nvroot; 1695 1696 config = zpool_get_config(zhp, NULL); 1697 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1698 &nvroot) == 0); 1699 1700 if (find_vdev(nvroot, cbp->cb_guid)) { 1701 cbp->cb_zhp = zhp; 1702 return (1); 1703 } 1704 1705 zpool_close(zhp); 1706 return (0); 1707 } 1708 1709 typedef struct status_cbdata { 1710 int cb_count; 1711 int cb_name_flags; 1712 int cb_namewidth; 1713 boolean_t cb_allpools; 1714 boolean_t cb_verbose; 1715 boolean_t cb_literal; 1716 boolean_t cb_explain; 1717 boolean_t cb_first; 1718 boolean_t cb_dedup_stats; 1719 boolean_t cb_print_status; 1720 boolean_t cb_print_slow_ios; 1721 boolean_t cb_print_vdev_init; 1722 boolean_t cb_print_vdev_trim; 1723 } status_cbdata_t; 1724 1725 /* 1726 * Print vdev initialization status for leaves 1727 */ 1728 static void 1729 print_status_initialize(vdev_stat_t *vs, boolean_t verbose) 1730 { 1731 if (verbose) { 1732 if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE || 1733 vs->vs_initialize_state == VDEV_INITIALIZE_SUSPENDED || 1734 vs->vs_initialize_state == VDEV_INITIALIZE_COMPLETE) && 1735 !vs->vs_scan_removing) { 1736 char zbuf[1024]; 1737 char tbuf[256]; 1738 struct tm zaction_ts; 1739 1740 time_t t = vs->vs_initialize_action_time; 1741 int initialize_pct = 100; 1742 if (vs->vs_initialize_state != 1743 VDEV_INITIALIZE_COMPLETE) { 1744 initialize_pct = (vs->vs_initialize_bytes_done * 1745 100 / (vs->vs_initialize_bytes_est + 1)); 1746 } 1747 1748 (void) localtime_r(&t, &zaction_ts); 1749 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts); 1750 1751 switch (vs->vs_initialize_state) { 1752 case VDEV_INITIALIZE_SUSPENDED: 1753 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1754 gettext("suspended, started at"), tbuf); 1755 break; 1756 case VDEV_INITIALIZE_ACTIVE: 1757 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1758 gettext("started at"), tbuf); 1759 break; 1760 case VDEV_INITIALIZE_COMPLETE: 1761 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1762 gettext("completed at"), tbuf); 1763 break; 1764 } 1765 1766 (void) printf(gettext(" (%d%% initialized%s)"), 1767 initialize_pct, zbuf); 1768 } else { 1769 (void) printf(gettext(" (uninitialized)")); 1770 } 1771 } else if (vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE) { 1772 (void) printf(gettext(" (initializing)")); 1773 } 1774 } 1775 1776 /* 1777 * Print vdev TRIM status for leaves 1778 */ 1779 static void 1780 print_status_trim(vdev_stat_t *vs, boolean_t verbose) 1781 { 1782 if (verbose) { 1783 if ((vs->vs_trim_state == VDEV_TRIM_ACTIVE || 1784 vs->vs_trim_state == VDEV_TRIM_SUSPENDED || 1785 vs->vs_trim_state == VDEV_TRIM_COMPLETE) && 1786 !vs->vs_scan_removing) { 1787 char zbuf[1024]; 1788 char tbuf[256]; 1789 struct tm zaction_ts; 1790 1791 time_t t = vs->vs_trim_action_time; 1792 int trim_pct = 100; 1793 if (vs->vs_trim_state != VDEV_TRIM_COMPLETE) { 1794 trim_pct = (vs->vs_trim_bytes_done * 1795 100 / (vs->vs_trim_bytes_est + 1)); 1796 } 1797 1798 (void) localtime_r(&t, &zaction_ts); 1799 (void) strftime(tbuf, sizeof (tbuf), "%c", &zaction_ts); 1800 1801 switch (vs->vs_trim_state) { 1802 case VDEV_TRIM_SUSPENDED: 1803 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1804 gettext("suspended, started at"), tbuf); 1805 break; 1806 case VDEV_TRIM_ACTIVE: 1807 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1808 gettext("started at"), tbuf); 1809 break; 1810 case VDEV_TRIM_COMPLETE: 1811 (void) snprintf(zbuf, sizeof (zbuf), ", %s %s", 1812 gettext("completed at"), tbuf); 1813 break; 1814 } 1815 1816 (void) printf(gettext(" (%d%% trimmed%s)"), 1817 trim_pct, zbuf); 1818 } else if (vs->vs_trim_notsup) { 1819 (void) printf(gettext(" (trim unsupported)")); 1820 } else { 1821 (void) printf(gettext(" (untrimmed)")); 1822 } 1823 } else if (vs->vs_trim_state == VDEV_TRIM_ACTIVE) { 1824 (void) printf(gettext(" (trimming)")); 1825 } 1826 } 1827 1828 /* 1829 * Print out configuration state as requested by status_callback. 1830 */ 1831 static void 1832 print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name, 1833 nvlist_t *nv, int depth, boolean_t isspare) 1834 { 1835 nvlist_t **child, *root; 1836 uint_t c, children; 1837 pool_scan_stat_t *ps = NULL; 1838 vdev_stat_t *vs; 1839 char rbuf[6], wbuf[6], cbuf[6]; 1840 char *vname; 1841 uint64_t notpresent; 1842 spare_cbdata_t spare_cb; 1843 const char *state; 1844 char *type; 1845 1846 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1847 &child, &children) != 0) 1848 children = 0; 1849 1850 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 1851 (uint64_t **)&vs, &c) == 0); 1852 1853 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 1854 1855 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) 1856 return; 1857 1858 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1859 if (isspare) { 1860 /* 1861 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 1862 * online drives. 1863 */ 1864 if (vs->vs_aux == VDEV_AUX_SPARED) 1865 state = "INUSE"; 1866 else if (vs->vs_state == VDEV_STATE_HEALTHY) 1867 state = "AVAIL"; 1868 } 1869 1870 (void) printf("\t%*s%-*s %-8s", depth, "", cb->cb_namewidth - depth, 1871 name, state); 1872 1873 if (!isspare) { 1874 if (cb->cb_literal) { 1875 printf(" %5llu %5llu %5llu", 1876 (u_longlong_t)vs->vs_read_errors, 1877 (u_longlong_t)vs->vs_write_errors, 1878 (u_longlong_t)vs->vs_checksum_errors); 1879 } else { 1880 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 1881 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 1882 zfs_nicenum(vs->vs_checksum_errors, cbuf, 1883 sizeof (cbuf)); 1884 printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 1885 } 1886 1887 if (cb->cb_print_slow_ios) { 1888 if (children == 0) { 1889 /* Only leafs vdevs have slow IOs */ 1890 zfs_nicenum(vs->vs_slow_ios, rbuf, 1891 sizeof (rbuf)); 1892 } else { 1893 (void) snprintf(rbuf, sizeof (rbuf), "-"); 1894 } 1895 1896 if (cb->cb_literal) 1897 printf(" %5llu", (u_longlong_t)vs->vs_slow_ios); 1898 else 1899 printf(" %5s", rbuf); 1900 } 1901 1902 } 1903 1904 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 1905 ¬present) == 0) { 1906 char *path; 1907 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 1908 (void) printf(" was %s", path); 1909 } else if (vs->vs_aux != 0) { 1910 (void) printf(" "); 1911 1912 switch (vs->vs_aux) { 1913 case VDEV_AUX_OPEN_FAILED: 1914 (void) printf(gettext("cannot open")); 1915 break; 1916 1917 case VDEV_AUX_BAD_GUID_SUM: 1918 (void) printf(gettext("missing device")); 1919 break; 1920 1921 case VDEV_AUX_NO_REPLICAS: 1922 (void) printf(gettext("insufficient replicas")); 1923 break; 1924 1925 case VDEV_AUX_VERSION_NEWER: 1926 (void) printf(gettext("newer version")); 1927 break; 1928 1929 case VDEV_AUX_UNSUP_FEAT: 1930 (void) printf(gettext("unsupported feature(s)")); 1931 break; 1932 1933 case VDEV_AUX_SPARED: 1934 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 1935 &spare_cb.cb_guid) == 0); 1936 if (zpool_iter(g_zfs, find_spare, &spare_cb) == 1) { 1937 if (strcmp(zpool_get_name(spare_cb.cb_zhp), 1938 zpool_get_name(zhp)) == 0) 1939 (void) printf(gettext("currently in " 1940 "use")); 1941 else 1942 (void) printf(gettext("in use by " 1943 "pool '%s'"), 1944 zpool_get_name(spare_cb.cb_zhp)); 1945 zpool_close(spare_cb.cb_zhp); 1946 } else { 1947 (void) printf(gettext("currently in use")); 1948 } 1949 break; 1950 1951 case VDEV_AUX_ERR_EXCEEDED: 1952 (void) printf(gettext("too many errors")); 1953 break; 1954 1955 case VDEV_AUX_IO_FAILURE: 1956 (void) printf(gettext("experienced I/O failures")); 1957 break; 1958 1959 case VDEV_AUX_BAD_LOG: 1960 (void) printf(gettext("bad intent log")); 1961 break; 1962 1963 case VDEV_AUX_EXTERNAL: 1964 (void) printf(gettext("external device fault")); 1965 break; 1966 1967 case VDEV_AUX_SPLIT_POOL: 1968 (void) printf(gettext("split into new pool")); 1969 break; 1970 1971 case VDEV_AUX_ACTIVE: 1972 (void) printf(gettext("currently in use")); 1973 break; 1974 1975 case VDEV_AUX_CHILDREN_OFFLINE: 1976 (void) printf(gettext("all children offline")); 1977 break; 1978 1979 default: 1980 (void) printf(gettext("corrupted data")); 1981 break; 1982 } 1983 } 1984 1985 /* The root vdev has the scrub/resilver stats */ 1986 root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL), 1987 ZPOOL_CONFIG_VDEV_TREE); 1988 (void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS, 1989 (uint64_t **)&ps, &c); 1990 1991 if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) { 1992 if (vs->vs_scan_processed != 0) { 1993 (void) printf(gettext(" (%s)"), 1994 (ps->pss_func == POOL_SCAN_RESILVER) ? 1995 "resilvering" : "repairing"); 1996 } else if (vs->vs_resilver_deferred) { 1997 (void) printf(gettext(" (awaiting resilver)")); 1998 } 1999 } 2000 2001 /* Display vdev initialization and trim status for leaves */ 2002 if (children == 0) { 2003 print_status_initialize(vs, cb->cb_print_vdev_init); 2004 print_status_trim(vs, cb->cb_print_vdev_trim); 2005 } 2006 2007 (void) printf("\n"); 2008 2009 for (c = 0; c < children; c++) { 2010 uint64_t islog = B_FALSE, ishole = B_FALSE; 2011 2012 /* Don't print logs or holes here */ 2013 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2014 &islog); 2015 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE, 2016 &ishole); 2017 if (islog || ishole) 2018 continue; 2019 /* Only print normal classes here */ 2020 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 2021 continue; 2022 2023 vname = zpool_vdev_name(g_zfs, zhp, child[c], 2024 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2025 2026 print_status_config(zhp, cb, vname, child[c], depth + 2, 2027 isspare); 2028 free(vname); 2029 } 2030 } 2031 2032 /* 2033 * Print the configuration of an exported pool. Iterate over all vdevs in the 2034 * pool, printing out the name and status for each one. 2035 */ 2036 static void 2037 print_import_config(status_cbdata_t *cb, const char *name, nvlist_t *nv, 2038 int depth) 2039 { 2040 nvlist_t **child; 2041 uint_t c, children; 2042 vdev_stat_t *vs; 2043 char *type, *vname; 2044 2045 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 2046 if (strcmp(type, VDEV_TYPE_MISSING) == 0 || 2047 strcmp(type, VDEV_TYPE_HOLE) == 0) 2048 return; 2049 2050 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 2051 (uint64_t **)&vs, &c) == 0); 2052 2053 (void) printf("\t%*s%-*s", depth, "", cb->cb_namewidth - depth, name); 2054 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 2055 2056 if (vs->vs_aux != 0) { 2057 (void) printf(" "); 2058 2059 switch (vs->vs_aux) { 2060 case VDEV_AUX_OPEN_FAILED: 2061 (void) printf(gettext("cannot open")); 2062 break; 2063 2064 case VDEV_AUX_BAD_GUID_SUM: 2065 (void) printf(gettext("missing device")); 2066 break; 2067 2068 case VDEV_AUX_NO_REPLICAS: 2069 (void) printf(gettext("insufficient replicas")); 2070 break; 2071 2072 case VDEV_AUX_VERSION_NEWER: 2073 (void) printf(gettext("newer version")); 2074 break; 2075 2076 case VDEV_AUX_UNSUP_FEAT: 2077 (void) printf(gettext("unsupported feature(s)")); 2078 break; 2079 2080 case VDEV_AUX_ERR_EXCEEDED: 2081 (void) printf(gettext("too many errors")); 2082 break; 2083 2084 case VDEV_AUX_ACTIVE: 2085 (void) printf(gettext("currently in use")); 2086 break; 2087 2088 case VDEV_AUX_CHILDREN_OFFLINE: 2089 (void) printf(gettext("all children offline")); 2090 break; 2091 2092 default: 2093 (void) printf(gettext("corrupted data")); 2094 break; 2095 } 2096 } 2097 (void) printf("\n"); 2098 2099 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2100 &child, &children) != 0) 2101 return; 2102 2103 for (c = 0; c < children; c++) { 2104 uint64_t is_log = B_FALSE; 2105 2106 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2107 &is_log); 2108 if (is_log) 2109 continue; 2110 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 2111 continue; 2112 2113 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2114 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2115 print_import_config(cb, vname, child[c], depth + 2); 2116 free(vname); 2117 } 2118 2119 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 2120 &child, &children) == 0) { 2121 (void) printf(gettext("\tcache\n")); 2122 for (c = 0; c < children; c++) { 2123 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2124 cb->cb_name_flags); 2125 (void) printf("\t %s\n", vname); 2126 free(vname); 2127 } 2128 } 2129 2130 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 2131 &child, &children) == 0) { 2132 (void) printf(gettext("\tspares\n")); 2133 for (c = 0; c < children; c++) { 2134 vname = zpool_vdev_name(g_zfs, NULL, child[c], 2135 cb->cb_name_flags); 2136 (void) printf("\t %s\n", vname); 2137 free(vname); 2138 } 2139 } 2140 } 2141 2142 /* 2143 * Print specialized class vdevs. 2144 * 2145 * These are recorded as top level vdevs in the main pool child array 2146 * but with "is_log" set to 1 or an "alloc_bias" string. We use either 2147 * print_status_config() or print_import_config() to print the top level 2148 * class vdevs then any of their children (eg mirrored slogs) are printed 2149 * recursively - which works because only the top level vdev is marked. 2150 */ 2151 static void 2152 print_class_vdevs(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t *nv, 2153 const char *class) 2154 { 2155 uint_t c, children; 2156 nvlist_t **child; 2157 boolean_t printed = B_FALSE; 2158 2159 assert(zhp != NULL || !cb->cb_verbose); 2160 2161 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, 2162 &children) != 0) 2163 return; 2164 2165 for (c = 0; c < children; c++) { 2166 uint64_t is_log = B_FALSE; 2167 char *bias = NULL; 2168 char *type = NULL; 2169 2170 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2171 &is_log); 2172 2173 if (is_log) { 2174 bias = VDEV_ALLOC_CLASS_LOGS; 2175 } else { 2176 (void) nvlist_lookup_string(child[c], 2177 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 2178 (void) nvlist_lookup_string(child[c], 2179 ZPOOL_CONFIG_TYPE, &type); 2180 } 2181 2182 if (bias == NULL || strcmp(bias, class) != 0) 2183 continue; 2184 if (!is_log && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 2185 continue; 2186 2187 if (!printed) { 2188 (void) printf("\t%s\t\n", gettext(class)); 2189 printed = B_TRUE; 2190 } 2191 2192 char *name = zpool_vdev_name(g_zfs, zhp, child[c], 2193 cb->cb_name_flags | VDEV_NAME_TYPE_ID); 2194 if (cb->cb_print_status) 2195 print_status_config(zhp, cb, name, child[c], 2, 2196 B_FALSE); 2197 else 2198 print_import_config(cb, name, child[c], 2); 2199 free(name); 2200 } 2201 } 2202 2203 /* 2204 * Display the status for the given pool. 2205 */ 2206 static void 2207 show_import(nvlist_t *config) 2208 { 2209 uint64_t pool_state; 2210 vdev_stat_t *vs; 2211 char *name; 2212 uint64_t guid; 2213 uint64_t hostid = 0; 2214 char *msgid; 2215 char *hostname = "unknown"; 2216 nvlist_t *nvroot, *nvinfo; 2217 int reason; 2218 zpool_errata_t errata; 2219 const char *health; 2220 uint_t vsc; 2221 char *comment; 2222 status_cbdata_t cb = { 0 }; 2223 2224 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 2225 &name) == 0); 2226 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 2227 &guid) == 0); 2228 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 2229 &pool_state) == 0); 2230 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2231 &nvroot) == 0); 2232 2233 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 2234 (uint64_t **)&vs, &vsc) == 0); 2235 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2236 2237 reason = zpool_import_status(config, &msgid, &errata); 2238 2239 (void) printf(gettext(" pool: %s\n"), name); 2240 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 2241 (void) printf(gettext(" state: %s"), health); 2242 if (pool_state == POOL_STATE_DESTROYED) 2243 (void) printf(gettext(" (DESTROYED)")); 2244 (void) printf("\n"); 2245 2246 switch (reason) { 2247 case ZPOOL_STATUS_MISSING_DEV_R: 2248 case ZPOOL_STATUS_MISSING_DEV_NR: 2249 case ZPOOL_STATUS_BAD_GUID_SUM: 2250 (void) printf(gettext(" status: One or more devices are " 2251 "missing from the system.\n")); 2252 break; 2253 2254 case ZPOOL_STATUS_CORRUPT_LABEL_R: 2255 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 2256 (void) printf(gettext(" status: One or more devices contains " 2257 "corrupted data.\n")); 2258 break; 2259 2260 case ZPOOL_STATUS_CORRUPT_DATA: 2261 (void) printf( 2262 gettext(" status: The pool data is corrupted.\n")); 2263 break; 2264 2265 case ZPOOL_STATUS_OFFLINE_DEV: 2266 (void) printf(gettext(" status: One or more devices " 2267 "are offlined.\n")); 2268 break; 2269 2270 case ZPOOL_STATUS_CORRUPT_POOL: 2271 (void) printf(gettext(" status: The pool metadata is " 2272 "corrupted.\n")); 2273 break; 2274 2275 case ZPOOL_STATUS_VERSION_OLDER: 2276 (void) printf(gettext(" status: The pool is formatted using a " 2277 "legacy on-disk version.\n")); 2278 break; 2279 2280 case ZPOOL_STATUS_VERSION_NEWER: 2281 (void) printf(gettext(" status: The pool is formatted using an " 2282 "incompatible version.\n")); 2283 break; 2284 2285 case ZPOOL_STATUS_FEAT_DISABLED: 2286 (void) printf(gettext(" status: Some supported features are " 2287 "not enabled on the pool.\n")); 2288 break; 2289 2290 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2291 (void) printf(gettext("status: The pool uses the following " 2292 "feature(s) not supported on this system:\n")); 2293 zpool_print_unsup_feat(config); 2294 break; 2295 2296 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2297 (void) printf(gettext("status: The pool can only be accessed " 2298 "in read-only mode on this system. It\n\tcannot be " 2299 "accessed in read-write mode because it uses the " 2300 "following\n\tfeature(s) not supported on this system:\n")); 2301 zpool_print_unsup_feat(config); 2302 break; 2303 2304 case ZPOOL_STATUS_HOSTID_ACTIVE: 2305 (void) printf(gettext(" status: The pool is currently " 2306 "imported by another system.\n")); 2307 break; 2308 2309 case ZPOOL_STATUS_HOSTID_REQUIRED: 2310 (void) printf(gettext(" status: The pool has the " 2311 "multihost property on. It cannot\n\tbe safely imported " 2312 "when the system hostid is not set.\n")); 2313 break; 2314 2315 case ZPOOL_STATUS_HOSTID_MISMATCH: 2316 (void) printf(gettext(" status: The pool was last accessed by " 2317 "another system.\n")); 2318 break; 2319 2320 case ZPOOL_STATUS_FAULTED_DEV_R: 2321 case ZPOOL_STATUS_FAULTED_DEV_NR: 2322 (void) printf(gettext(" status: One or more devices are " 2323 "faulted.\n")); 2324 break; 2325 2326 case ZPOOL_STATUS_BAD_LOG: 2327 (void) printf(gettext(" status: An intent log record cannot be " 2328 "read.\n")); 2329 break; 2330 2331 case ZPOOL_STATUS_RESILVERING: 2332 (void) printf(gettext(" status: One or more devices were being " 2333 "resilvered.\n")); 2334 break; 2335 2336 case ZPOOL_STATUS_ERRATA: 2337 (void) printf(gettext(" status: Errata #%d detected.\n"), 2338 errata); 2339 break; 2340 2341 default: 2342 /* 2343 * No other status can be seen when importing pools. 2344 */ 2345 assert(reason == ZPOOL_STATUS_OK); 2346 } 2347 2348 /* 2349 * Print out an action according to the overall state of the pool. 2350 */ 2351 if (vs->vs_state == VDEV_STATE_HEALTHY) { 2352 if (reason == ZPOOL_STATUS_VERSION_OLDER || 2353 reason == ZPOOL_STATUS_FEAT_DISABLED) { 2354 (void) printf(gettext(" action: The pool can be " 2355 "imported using its name or numeric identifier, " 2356 "though\n\tsome features will not be available " 2357 "without an explicit 'zpool upgrade'.\n")); 2358 } else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) { 2359 (void) printf(gettext(" action: The pool can be " 2360 "imported using its name or numeric " 2361 "identifier and\n\tthe '-f' flag.\n")); 2362 } else if (reason == ZPOOL_STATUS_ERRATA) { 2363 switch (errata) { 2364 case ZPOOL_ERRATA_NONE: 2365 break; 2366 2367 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 2368 (void) printf(gettext(" action: The pool can " 2369 "be imported using its name or numeric " 2370 "identifier,\n\thowever there is a compat" 2371 "ibility issue which should be corrected" 2372 "\n\tby running 'zpool scrub'\n")); 2373 break; 2374 2375 case ZPOOL_ERRATA_ZOL_2094_ASYNC_DESTROY: 2376 (void) printf(gettext(" action: The pool can" 2377 "not be imported with this version of ZFS " 2378 "due to\n\tan active asynchronous destroy. " 2379 "Revert to an earlier version\n\tand " 2380 "allow the destroy to complete before " 2381 "updating.\n")); 2382 break; 2383 2384 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 2385 (void) printf(gettext(" action: Existing " 2386 "encrypted datasets contain an on-disk " 2387 "incompatibility, which\n\tneeds to be " 2388 "corrected. Backup these datasets to new " 2389 "encrypted datasets\n\tand destroy the " 2390 "old ones.\n")); 2391 break; 2392 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 2393 (void) printf(gettext(" action: Any existing " 2394 "encrypted datasets contain an on-disk " 2395 "incompatibility which\n\tmay cause " 2396 "on-disk corruption with 'zfs recv' and " 2397 "which needs to be\n\tcorrected. Enable " 2398 "the bookmark_v2 feature and backup " 2399 "these datasets to new encrypted " 2400 "datasets and\n\tdestroy the old ones. " 2401 "If this pool does not contain any " 2402 "encrypted datasets, simply enable\n\t" 2403 "the bookmark_v2 feature.\n")); 2404 break; 2405 default: 2406 /* 2407 * All errata must contain an action message. 2408 */ 2409 assert(0); 2410 } 2411 } else { 2412 (void) printf(gettext(" action: The pool can be " 2413 "imported using its name or numeric " 2414 "identifier.\n")); 2415 } 2416 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 2417 (void) printf(gettext(" action: The pool can be imported " 2418 "despite missing or damaged devices. The\n\tfault " 2419 "tolerance of the pool may be compromised if imported.\n")); 2420 } else { 2421 switch (reason) { 2422 case ZPOOL_STATUS_VERSION_NEWER: 2423 (void) printf(gettext(" action: The pool cannot be " 2424 "imported. Access the pool on a system running " 2425 "newer\n\tsoftware, or recreate the pool from " 2426 "backup.\n")); 2427 break; 2428 case ZPOOL_STATUS_UNSUP_FEAT_READ: 2429 (void) printf(gettext("action: The pool cannot be " 2430 "imported. Access the pool on a system that " 2431 "supports\n\tthe required feature(s), or recreate " 2432 "the pool from backup.\n")); 2433 break; 2434 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 2435 (void) printf(gettext("action: The pool cannot be " 2436 "imported in read-write mode. Import the pool " 2437 "with\n" 2438 "\t\"-o readonly=on\", access the pool on a system " 2439 "that supports the\n\trequired feature(s), or " 2440 "recreate the pool from backup.\n")); 2441 break; 2442 case ZPOOL_STATUS_MISSING_DEV_R: 2443 case ZPOOL_STATUS_MISSING_DEV_NR: 2444 case ZPOOL_STATUS_BAD_GUID_SUM: 2445 (void) printf(gettext(" action: The pool cannot be " 2446 "imported. Attach the missing\n\tdevices and try " 2447 "again.\n")); 2448 break; 2449 case ZPOOL_STATUS_HOSTID_ACTIVE: 2450 VERIFY0(nvlist_lookup_nvlist(config, 2451 ZPOOL_CONFIG_LOAD_INFO, &nvinfo)); 2452 2453 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 2454 hostname = fnvlist_lookup_string(nvinfo, 2455 ZPOOL_CONFIG_MMP_HOSTNAME); 2456 2457 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 2458 hostid = fnvlist_lookup_uint64(nvinfo, 2459 ZPOOL_CONFIG_MMP_HOSTID); 2460 2461 (void) printf(gettext(" action: The pool must be " 2462 "exported from %s (hostid=%lx)\n\tbefore it " 2463 "can be safely imported.\n"), hostname, 2464 (unsigned long) hostid); 2465 break; 2466 case ZPOOL_STATUS_HOSTID_REQUIRED: 2467 (void) printf(gettext(" action: Check the SMF " 2468 "svc:/system/hostid service.\n")); 2469 break; 2470 default: 2471 (void) printf(gettext(" action: The pool cannot be " 2472 "imported due to damaged devices or data.\n")); 2473 } 2474 } 2475 2476 /* Print the comment attached to the pool. */ 2477 if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) 2478 (void) printf(gettext("comment: %s\n"), comment); 2479 2480 /* 2481 * If the state is "closed" or "can't open", and the aux state 2482 * is "corrupt data": 2483 */ 2484 if (((vs->vs_state == VDEV_STATE_CLOSED) || 2485 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 2486 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 2487 if (pool_state == POOL_STATE_DESTROYED) 2488 (void) printf(gettext("\tThe pool was destroyed, " 2489 "but can be imported using the '-Df' flags.\n")); 2490 else if (pool_state != POOL_STATE_EXPORTED) 2491 (void) printf(gettext("\tThe pool may be active on " 2492 "another system, but can be imported using\n\t" 2493 "the '-f' flag.\n")); 2494 } 2495 2496 if (msgid != NULL) 2497 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 2498 msgid); 2499 2500 (void) printf(gettext(" config:\n\n")); 2501 2502 cb.cb_namewidth = max_width(NULL, nvroot, 0, strlen(name), 2503 VDEV_NAME_TYPE_ID); 2504 if (cb.cb_namewidth < 10) 2505 cb.cb_namewidth = 10; 2506 2507 print_import_config(&cb, name, nvroot, 0); 2508 2509 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_DEDUP); 2510 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 2511 print_class_vdevs(NULL, &cb, nvroot, VDEV_ALLOC_CLASS_LOGS); 2512 2513 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 2514 (void) printf(gettext("\n\tAdditional devices are known to " 2515 "be part of this pool, though their\n\texact " 2516 "configuration cannot be determined.\n")); 2517 } 2518 } 2519 2520 static boolean_t 2521 zfs_force_import_required(nvlist_t *config) 2522 { 2523 uint64_t state; 2524 uint64_t hostid = 0; 2525 nvlist_t *nvinfo; 2526 2527 state = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE); 2528 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid); 2529 2530 if (state != POOL_STATE_EXPORTED && hostid != get_system_hostid()) 2531 return (B_TRUE); 2532 2533 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 2534 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) { 2535 mmp_state_t mmp_state = fnvlist_lookup_uint64(nvinfo, 2536 ZPOOL_CONFIG_MMP_STATE); 2537 2538 if (mmp_state != MMP_STATE_INACTIVE) 2539 return (B_TRUE); 2540 } 2541 2542 return (B_FALSE); 2543 } 2544 2545 /* 2546 * Perform the import for the given configuration. This passes the heavy 2547 * lifting off to zpool_import_props(), and then mounts the datasets contained 2548 * within the pool. 2549 */ 2550 static int 2551 do_import(nvlist_t *config, const char *newname, const char *mntopts, 2552 nvlist_t *props, int flags) 2553 { 2554 int ret = 0; 2555 zpool_handle_t *zhp; 2556 char *name; 2557 uint64_t version; 2558 2559 name = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); 2560 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION); 2561 2562 if (!SPA_VERSION_IS_SUPPORTED(version)) { 2563 (void) fprintf(stderr, gettext("cannot import '%s': pool " 2564 "is formatted using an unsupported ZFS version\n"), name); 2565 return (1); 2566 } else if (zfs_force_import_required(config) && 2567 !(flags & ZFS_IMPORT_ANY_HOST)) { 2568 mmp_state_t mmp_state = MMP_STATE_INACTIVE; 2569 nvlist_t *nvinfo; 2570 2571 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); 2572 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_STATE)) 2573 mmp_state = fnvlist_lookup_uint64(nvinfo, 2574 ZPOOL_CONFIG_MMP_STATE); 2575 2576 if (mmp_state == MMP_STATE_ACTIVE) { 2577 char *hostname = "<unknown>"; 2578 uint64_t hostid = 0; 2579 2580 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTNAME)) 2581 hostname = fnvlist_lookup_string(nvinfo, 2582 ZPOOL_CONFIG_MMP_HOSTNAME); 2583 2584 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_MMP_HOSTID)) 2585 hostid = fnvlist_lookup_uint64(nvinfo, 2586 ZPOOL_CONFIG_MMP_HOSTID); 2587 2588 (void) fprintf(stderr, gettext("cannot import '%s': " 2589 "pool is imported on %s (hostid: " 2590 "0x%lx)\nExport the pool on the other system, " 2591 "then run 'zpool import'.\n"), 2592 name, hostname, (unsigned long) hostid); 2593 } else if (mmp_state == MMP_STATE_NO_HOSTID) { 2594 (void) fprintf(stderr, gettext("Cannot import '%s': " 2595 "pool has the multihost property on and the\n" 2596 "system's hostid is not set.\n"), name); 2597 } else { 2598 char *hostname = "<unknown>"; 2599 uint64_t timestamp = 0; 2600 uint64_t hostid = 0; 2601 2602 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTNAME)) 2603 hostname = fnvlist_lookup_string(config, 2604 ZPOOL_CONFIG_HOSTNAME); 2605 2606 if (nvlist_exists(config, ZPOOL_CONFIG_TIMESTAMP)) 2607 timestamp = fnvlist_lookup_uint64(config, 2608 ZPOOL_CONFIG_TIMESTAMP); 2609 2610 if (nvlist_exists(config, ZPOOL_CONFIG_HOSTID)) 2611 hostid = fnvlist_lookup_uint64(config, 2612 ZPOOL_CONFIG_HOSTID); 2613 2614 (void) fprintf(stderr, gettext("cannot import '%s': " 2615 "pool was previously in use from another system.\n" 2616 "Last accessed by %s (hostid=%lx) at %s" 2617 "The pool can be imported, use 'zpool import -f' " 2618 "to import the pool.\n"), name, hostname, 2619 (unsigned long)hostid, ctime((time_t *)×tamp)); 2620 2621 } 2622 2623 return (1); 2624 } 2625 2626 if (zpool_import_props(g_zfs, config, newname, props, flags) != 0) 2627 return (1); 2628 2629 if (newname != NULL) 2630 name = (char *)newname; 2631 2632 if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL) 2633 return (1); 2634 2635 /* 2636 * Loading keys is best effort. We don't want to return immediately 2637 * if it fails but we do want to give the error to the caller. 2638 */ 2639 if (flags & ZFS_IMPORT_LOAD_KEYS) { 2640 ret = zfs_crypto_attempt_load_keys(g_zfs, name); 2641 if (ret != 0) 2642 ret = 1; 2643 } 2644 2645 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 2646 !(flags & ZFS_IMPORT_ONLY) && 2647 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 2648 zpool_close(zhp); 2649 return (1); 2650 } 2651 2652 zpool_close(zhp); 2653 return (ret); 2654 } 2655 2656 typedef struct target_exists_args { 2657 const char *poolname; 2658 uint64_t poolguid; 2659 } target_exists_args_t; 2660 2661 static int 2662 name_or_guid_exists(zpool_handle_t *zhp, void *data) 2663 { 2664 target_exists_args_t *args = data; 2665 nvlist_t *config = zpool_get_config(zhp, NULL); 2666 int found = 0; 2667 2668 if (config == NULL) 2669 return (0); 2670 2671 if (args->poolname != NULL) { 2672 char *pool_name; 2673 2674 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 2675 &pool_name) == 0); 2676 if (strcmp(pool_name, args->poolname) == 0) 2677 found = 1; 2678 } else { 2679 uint64_t pool_guid; 2680 2681 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 2682 &pool_guid) == 0); 2683 if (pool_guid == args->poolguid) 2684 found = 1; 2685 } 2686 zpool_close(zhp); 2687 2688 return (found); 2689 } 2690 /* 2691 * zpool checkpoint <pool> 2692 * checkpoint --discard <pool> 2693 * 2694 * -d Discard the checkpoint from a checkpointed 2695 * --discard pool. 2696 * 2697 * Checkpoints the specified pool, by taking a "snapshot" of its 2698 * current state. A pool can only have one checkpoint at a time. 2699 */ 2700 int 2701 zpool_do_checkpoint(int argc, char **argv) 2702 { 2703 boolean_t discard; 2704 char *pool; 2705 zpool_handle_t *zhp; 2706 int c, err; 2707 2708 struct option long_options[] = { 2709 {"discard", no_argument, NULL, 'd'}, 2710 {0, 0, 0, 0} 2711 }; 2712 2713 discard = B_FALSE; 2714 while ((c = getopt_long(argc, argv, ":d", long_options, NULL)) != -1) { 2715 switch (c) { 2716 case 'd': 2717 discard = B_TRUE; 2718 break; 2719 case '?': 2720 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2721 optopt); 2722 usage(B_FALSE); 2723 } 2724 } 2725 2726 argc -= optind; 2727 argv += optind; 2728 2729 if (argc < 1) { 2730 (void) fprintf(stderr, gettext("missing pool argument\n")); 2731 usage(B_FALSE); 2732 } 2733 2734 if (argc > 1) { 2735 (void) fprintf(stderr, gettext("too many arguments\n")); 2736 usage(B_FALSE); 2737 } 2738 2739 pool = argv[0]; 2740 2741 if ((zhp = zpool_open(g_zfs, pool)) == NULL) { 2742 /* As a special case, check for use of '/' in the name */ 2743 if (strchr(pool, '/') != NULL) 2744 (void) fprintf(stderr, gettext("'zpool checkpoint' " 2745 "doesn't work on datasets. To save the state " 2746 "of a dataset from a specific point in time " 2747 "please use 'zfs snapshot'\n")); 2748 return (1); 2749 } 2750 2751 if (discard) 2752 err = (zpool_discard_checkpoint(zhp) != 0); 2753 else 2754 err = (zpool_checkpoint(zhp) != 0); 2755 2756 zpool_close(zhp); 2757 2758 return (err); 2759 } 2760 2761 #define CHECKPOINT_OPT 1024 2762 2763 /* 2764 * zpool import [-d dir] [-D] 2765 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l] 2766 * [-d dir | -c cachefile] [-f] -a 2767 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] [-l] 2768 * [-d dir | -c cachefile] [-f] [-n] [-F] [-t] 2769 * <pool | id> [newpool] 2770 * 2771 * -c Read pool information from a cachefile instead of searching 2772 * devices. 2773 * 2774 * -d Scan in a specific directory, other than /dev/dsk. More than 2775 * one directory can be specified using multiple '-d' options. 2776 * 2777 * -D Scan for previously destroyed pools or import all or only 2778 * specified destroyed pools. 2779 * 2780 * -R Temporarily import the pool, with all mountpoints relative to 2781 * the given root. The pool will remain exported when the machine 2782 * is rebooted. 2783 * 2784 * -V Import even in the presence of faulted vdevs. This is an 2785 * intentionally undocumented option for testing purposes, and 2786 * treats the pool configuration as complete, leaving any bad 2787 * vdevs in the FAULTED state. In other words, it does verbatim 2788 * import. 2789 * 2790 * -f Force import, even if it appears that the pool is active. 2791 * 2792 * -F Attempt rewind if necessary. 2793 * 2794 * -n See if rewind would work, but don't actually rewind. 2795 * 2796 * -N Import the pool but don't mount datasets. 2797 * 2798 * -t Use newpool as a temporary pool name instead of renaming 2799 * the pool. 2800 * 2801 * -T Specify a starting txg to use for import. This option is 2802 * intentionally undocumented option for testing purposes. 2803 * 2804 * -a Import all pools found. 2805 * 2806 * -o Set property=value and/or temporary mount options (without '='). 2807 * -l Load encryption keys while importing. 2808 * 2809 * --rewind-to-checkpoint 2810 * Import the pool and revert back to the checkpoint. 2811 * 2812 * The import command scans for pools to import, and import pools based on pool 2813 * name and GUID. The pool can also be renamed as part of the import process. 2814 */ 2815 int 2816 zpool_do_import(int argc, char **argv) 2817 { 2818 char **searchdirs = NULL; 2819 int nsearch = 0; 2820 int c; 2821 int err = 0; 2822 nvlist_t *pools = NULL; 2823 boolean_t do_all = B_FALSE; 2824 boolean_t do_destroyed = B_FALSE; 2825 char *mntopts = NULL; 2826 nvpair_t *elem; 2827 nvlist_t *config; 2828 uint64_t searchguid = 0; 2829 char *searchname = NULL; 2830 char *propval; 2831 nvlist_t *found_config; 2832 nvlist_t *policy = NULL; 2833 nvlist_t *props = NULL; 2834 boolean_t first; 2835 int flags = ZFS_IMPORT_NORMAL; 2836 uint32_t rewind_policy = ZPOOL_NO_REWIND; 2837 boolean_t dryrun = B_FALSE; 2838 boolean_t do_rewind = B_FALSE; 2839 boolean_t xtreme_rewind = B_FALSE; 2840 boolean_t pool_exists = B_FALSE; 2841 uint64_t pool_state, txg = -1ULL; 2842 char *cachefile = NULL; 2843 importargs_t idata = { 0 }; 2844 char *endptr; 2845 2846 2847 struct option long_options[] = { 2848 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT}, 2849 {0, 0, 0, 0} 2850 }; 2851 2852 /* check options */ 2853 while ((c = getopt_long(argc, argv, ":aCc:d:DEfFlmnNo:rR:tT:VX", 2854 long_options, NULL)) != -1) { 2855 switch (c) { 2856 case 'a': 2857 do_all = B_TRUE; 2858 break; 2859 case 'c': 2860 cachefile = optarg; 2861 break; 2862 case 'd': 2863 if (searchdirs == NULL) { 2864 searchdirs = safe_malloc(sizeof (char *)); 2865 } else { 2866 char **tmp = safe_malloc((nsearch + 1) * 2867 sizeof (char *)); 2868 bcopy(searchdirs, tmp, nsearch * 2869 sizeof (char *)); 2870 free(searchdirs); 2871 searchdirs = tmp; 2872 } 2873 searchdirs[nsearch++] = optarg; 2874 break; 2875 case 'D': 2876 do_destroyed = B_TRUE; 2877 break; 2878 case 'f': 2879 flags |= ZFS_IMPORT_ANY_HOST; 2880 break; 2881 case 'F': 2882 do_rewind = B_TRUE; 2883 break; 2884 case 'l': 2885 flags |= ZFS_IMPORT_LOAD_KEYS; 2886 break; 2887 case 'm': 2888 flags |= ZFS_IMPORT_MISSING_LOG; 2889 break; 2890 case 'n': 2891 dryrun = B_TRUE; 2892 break; 2893 case 'N': 2894 flags |= ZFS_IMPORT_ONLY; 2895 break; 2896 case 'o': 2897 if ((propval = strchr(optarg, '=')) != NULL) { 2898 *propval = '\0'; 2899 propval++; 2900 if (add_prop_list(optarg, propval, 2901 &props, B_TRUE)) 2902 goto error; 2903 } else { 2904 mntopts = optarg; 2905 } 2906 break; 2907 case 'R': 2908 if (add_prop_list(zpool_prop_to_name( 2909 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 2910 goto error; 2911 if (add_prop_list_default(zpool_prop_to_name( 2912 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 2913 goto error; 2914 break; 2915 case 't': 2916 flags |= ZFS_IMPORT_TEMP_NAME; 2917 if (add_prop_list_default(zpool_prop_to_name( 2918 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 2919 goto error; 2920 break; 2921 case 'T': 2922 errno = 0; 2923 txg = strtoull(optarg, &endptr, 0); 2924 if (errno != 0 || *endptr != '\0') { 2925 (void) fprintf(stderr, 2926 gettext("invalid txg value\n")); 2927 usage(B_FALSE); 2928 } 2929 rewind_policy = ZPOOL_DO_REWIND | ZPOOL_EXTREME_REWIND; 2930 break; 2931 case 'V': 2932 flags |= ZFS_IMPORT_VERBATIM; 2933 break; 2934 case 'X': 2935 xtreme_rewind = B_TRUE; 2936 break; 2937 case CHECKPOINT_OPT: 2938 flags |= ZFS_IMPORT_CHECKPOINT; 2939 break; 2940 case ':': 2941 (void) fprintf(stderr, gettext("missing argument for " 2942 "'%c' option\n"), optopt); 2943 usage(B_FALSE); 2944 break; 2945 case '?': 2946 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2947 optopt); 2948 usage(B_FALSE); 2949 } 2950 } 2951 2952 argc -= optind; 2953 argv += optind; 2954 2955 if (cachefile && nsearch != 0) { 2956 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 2957 usage(B_FALSE); 2958 } 2959 2960 if ((flags & ZFS_IMPORT_LOAD_KEYS) && (flags & ZFS_IMPORT_ONLY)) { 2961 (void) fprintf(stderr, gettext("-l is incompatible with -N\n")); 2962 usage(B_FALSE); 2963 } 2964 2965 if ((flags & ZFS_IMPORT_LOAD_KEYS) && !do_all && argc == 0) { 2966 (void) fprintf(stderr, gettext("-l is only meaningful during " 2967 "an import\n")); 2968 usage(B_FALSE); 2969 } 2970 2971 if ((dryrun || xtreme_rewind) && !do_rewind) { 2972 (void) fprintf(stderr, 2973 gettext("-n or -X only meaningful with -F\n")); 2974 usage(B_FALSE); 2975 } 2976 if (dryrun) 2977 rewind_policy = ZPOOL_TRY_REWIND; 2978 else if (do_rewind) 2979 rewind_policy = ZPOOL_DO_REWIND; 2980 if (xtreme_rewind) 2981 rewind_policy |= ZPOOL_EXTREME_REWIND; 2982 2983 /* In the future, we can capture further policy and include it here */ 2984 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 2985 nvlist_add_uint64(policy, ZPOOL_LOAD_REQUEST_TXG, txg) != 0 || 2986 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 2987 rewind_policy) != 0) 2988 goto error; 2989 2990 if (searchdirs == NULL) { 2991 searchdirs = safe_malloc(sizeof (char *)); 2992 searchdirs[0] = ZFS_DISK_ROOT; 2993 nsearch = 1; 2994 } 2995 2996 /* check argument count */ 2997 if (do_all) { 2998 if (argc != 0) { 2999 (void) fprintf(stderr, gettext("too many arguments\n")); 3000 usage(B_FALSE); 3001 } 3002 } else { 3003 if (argc > 2) { 3004 (void) fprintf(stderr, gettext("too many arguments\n")); 3005 usage(B_FALSE); 3006 } 3007 3008 /* 3009 * Check for the SYS_CONFIG privilege. We do this explicitly 3010 * here because otherwise any attempt to discover pools will 3011 * silently fail. 3012 */ 3013 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 3014 (void) fprintf(stderr, gettext("cannot " 3015 "discover pools: permission denied\n")); 3016 free(searchdirs); 3017 nvlist_free(policy); 3018 return (1); 3019 } 3020 } 3021 3022 /* 3023 * Depending on the arguments given, we do one of the following: 3024 * 3025 * <none> Iterate through all pools and display information about 3026 * each one. 3027 * 3028 * -a Iterate through all pools and try to import each one. 3029 * 3030 * <id> Find the pool that corresponds to the given GUID/pool 3031 * name and import that one. 3032 * 3033 * -D Above options applies only to destroyed pools. 3034 */ 3035 if (argc != 0) { 3036 char *endptr; 3037 3038 errno = 0; 3039 searchguid = strtoull(argv[0], &endptr, 10); 3040 if (errno != 0 || *endptr != '\0') { 3041 searchname = argv[0]; 3042 searchguid = 0; 3043 } 3044 found_config = NULL; 3045 3046 /* 3047 * User specified a name or guid. Ensure it's unique. 3048 */ 3049 target_exists_args_t search = {searchname, searchguid}; 3050 pool_exists = zpool_iter(g_zfs, name_or_guid_exists, &search); 3051 } 3052 3053 idata.path = searchdirs; 3054 idata.paths = nsearch; 3055 idata.poolname = searchname; 3056 idata.guid = searchguid; 3057 idata.cachefile = cachefile; 3058 idata.policy = policy; 3059 3060 pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops); 3061 3062 if (pools != NULL && pool_exists && 3063 (argc == 1 || strcmp(argv[0], argv[1]) == 0)) { 3064 (void) fprintf(stderr, gettext("cannot import '%s': " 3065 "a pool with that name already exists\n"), 3066 argv[0]); 3067 (void) fprintf(stderr, gettext("use the form 'zpool import " 3068 "[-t] <pool | id> <newpool>' to give it a new temporary " 3069 "or permanent name\n")); 3070 err = 1; 3071 } else if (pools == NULL && pool_exists) { 3072 (void) fprintf(stderr, gettext("cannot import '%s': " 3073 "a pool with that name is already created/imported,\n"), 3074 argv[0]); 3075 (void) fprintf(stderr, gettext("and no additional pools " 3076 "with that name were found\n")); 3077 err = 1; 3078 } else if (pools == NULL) { 3079 if (argc != 0) { 3080 (void) fprintf(stderr, gettext("cannot import '%s': " 3081 "no such pool available\n"), argv[0]); 3082 } 3083 err = 1; 3084 } 3085 3086 if (err == 1) { 3087 free(searchdirs); 3088 nvlist_free(policy); 3089 return (1); 3090 } 3091 3092 /* 3093 * At this point we have a list of import candidate configs. Even if 3094 * we were searching by pool name or guid, we still need to 3095 * post-process the list to deal with pool state and possible 3096 * duplicate names. 3097 */ 3098 err = 0; 3099 elem = NULL; 3100 first = B_TRUE; 3101 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 3102 3103 verify(nvpair_value_nvlist(elem, &config) == 0); 3104 3105 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 3106 &pool_state) == 0); 3107 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 3108 continue; 3109 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 3110 continue; 3111 3112 verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY, 3113 policy) == 0); 3114 3115 if (argc == 0) { 3116 if (first) 3117 first = B_FALSE; 3118 else if (!do_all) 3119 (void) printf("\n"); 3120 3121 if (do_all) { 3122 err |= do_import(config, NULL, mntopts, 3123 props, flags); 3124 } else { 3125 show_import(config); 3126 } 3127 } else if (searchname != NULL) { 3128 char *name; 3129 3130 /* 3131 * We are searching for a pool based on name. 3132 */ 3133 verify(nvlist_lookup_string(config, 3134 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 3135 3136 if (strcmp(name, searchname) == 0) { 3137 if (found_config != NULL) { 3138 (void) fprintf(stderr, gettext( 3139 "cannot import '%s': more than " 3140 "one matching pool\n"), searchname); 3141 (void) fprintf(stderr, gettext( 3142 "import by numeric ID instead\n")); 3143 err = B_TRUE; 3144 } 3145 found_config = config; 3146 } 3147 } else { 3148 uint64_t guid; 3149 3150 /* 3151 * Search for a pool by guid. 3152 */ 3153 verify(nvlist_lookup_uint64(config, 3154 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 3155 3156 if (guid == searchguid) 3157 found_config = config; 3158 } 3159 } 3160 3161 /* 3162 * If we were searching for a specific pool, verify that we found a 3163 * pool, and then do the import. 3164 */ 3165 if (argc != 0 && err == 0) { 3166 if (found_config == NULL) { 3167 (void) fprintf(stderr, gettext("cannot import '%s': " 3168 "no such pool available\n"), argv[0]); 3169 err = B_TRUE; 3170 } else { 3171 err |= do_import(found_config, argc == 1 ? NULL : 3172 argv[1], mntopts, props, flags); 3173 } 3174 } 3175 3176 /* 3177 * If we were just looking for pools, report an error if none were 3178 * found. 3179 */ 3180 if (argc == 0 && first) 3181 (void) fprintf(stderr, 3182 gettext("no pools available to import\n")); 3183 3184 error: 3185 nvlist_free(props); 3186 nvlist_free(pools); 3187 nvlist_free(policy); 3188 free(searchdirs); 3189 3190 return (err ? 1 : 0); 3191 } 3192 3193 /* 3194 * zpool sync [-f] [pool] ... 3195 * 3196 * -f (undocumented) force uberblock (and config including zpool cache file) 3197 * update. 3198 * 3199 * Sync the specified pool(s). 3200 * Without arguments "zpool sync" will sync all pools. 3201 * This command initiates TXG sync(s) and will return after the TXG(s) commit. 3202 * 3203 */ 3204 static int 3205 zpool_do_sync(int argc, char **argv) 3206 { 3207 int ret; 3208 boolean_t force = B_FALSE; 3209 3210 /* check options */ 3211 while ((ret = getopt(argc, argv, "f")) != -1) { 3212 switch (ret) { 3213 case 'f': 3214 force = B_TRUE; 3215 break; 3216 case '?': 3217 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3218 optopt); 3219 usage(B_FALSE); 3220 } 3221 } 3222 3223 argc -= optind; 3224 argv += optind; 3225 3226 /* if argc == 0 we will execute zpool_sync_one on all pools */ 3227 ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force); 3228 3229 return (ret); 3230 } 3231 3232 typedef struct iostat_cbdata { 3233 uint64_t cb_flags; 3234 int cb_name_flags; 3235 int cb_namewidth; 3236 int cb_iteration; 3237 char **cb_vdev_names; /* Only show these vdevs */ 3238 unsigned int cb_vdev_names_count; 3239 boolean_t cb_verbose; 3240 boolean_t cb_literal; 3241 boolean_t cb_scripted; 3242 zpool_list_t *cb_list; 3243 } iostat_cbdata_t; 3244 3245 /* iostat labels */ 3246 typedef struct name_and_columns { 3247 const char *name; /* Column name */ 3248 unsigned int columns; /* Center name to this number of columns */ 3249 } name_and_columns_t; 3250 3251 #define IOSTAT_MAX_LABELS 13 /* Max number of labels on one line */ 3252 3253 static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] = 3254 { 3255 [IOS_DEFAULT] = {{"capacity", 2}, {"operations", 2}, {"bandwidth", 2}, 3256 {NULL}}, 3257 [IOS_LATENCY] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2}, 3258 {"asyncq_wait", 2}, {"scrub"}, {"trim", 1}, {NULL}}, 3259 [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2}, 3260 {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2}, 3261 {"trimq_write", 2}, {NULL}}, 3262 [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2}, {"syncq_wait", 2}, 3263 {"asyncq_wait", 2}, {NULL}}, 3264 [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2}, 3265 {"async_read", 2}, {"async_write", 2}, {"scrub", 2}, 3266 {"trim", 2}, {NULL}}, 3267 3268 }; 3269 3270 /* Shorthand - if "columns" field not set, default to 1 column */ 3271 static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] = 3272 { 3273 [IOS_DEFAULT] = {{"alloc"}, {"free"}, {"read"}, {"write"}, {"read"}, 3274 {"write"}, {NULL}}, 3275 [IOS_LATENCY] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"}, 3276 {"write"}, {"read"}, {"write"}, {"wait"}, {"wait"}, {NULL}}, 3277 [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"}, 3278 {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, 3279 {"pend"}, {"activ"}, {NULL}}, 3280 [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"}, 3281 {"write"}, {"read"}, {"write"}, {"scrub"}, {"trim"}, {NULL}}, 3282 [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, 3283 {"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, {NULL}}, 3284 }; 3285 3286 static const char *histo_to_title[] = { 3287 [IOS_L_HISTO] = "latency", 3288 [IOS_RQ_HISTO] = "req_size", 3289 }; 3290 3291 /* 3292 * Return the number of labels in a null-terminated name_and_columns_t 3293 * array. 3294 * 3295 */ 3296 static unsigned int 3297 label_array_len(const name_and_columns_t *labels) 3298 { 3299 int i = 0; 3300 3301 while (labels[i].name) 3302 i++; 3303 3304 return (i); 3305 } 3306 3307 /* 3308 * Return the number of strings in a null-terminated string array. 3309 * For example: 3310 * 3311 * const char foo[] = {"bar", "baz", NULL} 3312 * 3313 * returns 2 3314 */ 3315 static uint64_t 3316 str_array_len(const char *array[]) 3317 { 3318 uint64_t i = 0; 3319 while (array[i]) 3320 i++; 3321 3322 return (i); 3323 } 3324 3325 3326 /* 3327 * Return a default column width for default/latency/queue columns. This does 3328 * not include histograms, which have their columns autosized. 3329 */ 3330 static unsigned int 3331 default_column_width(iostat_cbdata_t *cb, enum iostat_type type) 3332 { 3333 unsigned long column_width = 5; /* Normal niceprint */ 3334 static unsigned long widths[] = { 3335 /* 3336 * Choose some sane default column sizes for printing the 3337 * raw numbers. 3338 */ 3339 [IOS_DEFAULT] = 15, /* 1PB capacity */ 3340 [IOS_LATENCY] = 10, /* 1B ns = 10sec */ 3341 [IOS_QUEUES] = 6, /* 1M queue entries */ 3342 [IOS_L_HISTO] = 10, /* 1B ns = 10sec */ 3343 [IOS_RQ_HISTO] = 6, /* 1M queue entries */ 3344 }; 3345 3346 if (cb->cb_literal) 3347 column_width = widths[type]; 3348 3349 return (column_width); 3350 } 3351 3352 /* 3353 * Print the column labels, i.e: 3354 * 3355 * capacity operations bandwidth 3356 * alloc free read write read write ... 3357 * 3358 * If force_column_width is set, use it for the column width. If not set, use 3359 * the default column width. 3360 */ 3361 void 3362 print_iostat_labels(iostat_cbdata_t *cb, unsigned int force_column_width, 3363 const name_and_columns_t labels[][IOSTAT_MAX_LABELS]) 3364 { 3365 int i, idx, s; 3366 int text_start, rw_column_width, spaces_to_end; 3367 uint64_t flags = cb->cb_flags; 3368 uint64_t f; 3369 unsigned int column_width = force_column_width; 3370 3371 /* For each bit set in flags */ 3372 for (f = flags; f; f &= ~(1ULL << idx)) { 3373 idx = lowbit64(f) - 1; 3374 if (!force_column_width) 3375 column_width = default_column_width(cb, idx); 3376 /* Print our top labels centered over "read write" label. */ 3377 for (i = 0; i < label_array_len(labels[idx]); i++) { 3378 const char *name = labels[idx][i].name; 3379 /* 3380 * We treat labels[][].columns == 0 as shorthand 3381 * for one column. It makes writing out the label 3382 * tables more concise. 3383 */ 3384 unsigned int columns = MAX(1, labels[idx][i].columns); 3385 unsigned int slen = strlen(name); 3386 3387 rw_column_width = (column_width * columns) + 3388 (2 * (columns - 1)); 3389 3390 text_start = (int)((rw_column_width) / columns - 3391 slen / columns); 3392 if (text_start < 0) 3393 text_start = 0; 3394 3395 printf(" "); /* Two spaces between columns */ 3396 3397 /* Space from beginning of column to label */ 3398 for (s = 0; s < text_start; s++) 3399 printf(" "); 3400 3401 printf("%s", name); 3402 3403 /* Print space after label to end of column */ 3404 spaces_to_end = rw_column_width - text_start - slen; 3405 if (spaces_to_end < 0) 3406 spaces_to_end = 0; 3407 3408 for (s = 0; s < spaces_to_end; s++) 3409 printf(" "); 3410 } 3411 } 3412 } 3413 3414 /* 3415 * Utility function to print out a line of dashes like: 3416 * 3417 * -------------------------------- ----- ----- ----- ----- ----- 3418 * 3419 * ...or a dashed named-row line like: 3420 * 3421 * logs - - - - - 3422 * 3423 * @cb: iostat data 3424 * 3425 * @force_column_width If non-zero, use the value as the column width. 3426 * Otherwise use the default column widths. 3427 * 3428 * @name: Print a dashed named-row line starting 3429 * with @name. Otherwise, print a regular 3430 * dashed line. 3431 */ 3432 static void 3433 print_iostat_dashes(iostat_cbdata_t *cb, unsigned int force_column_width, 3434 const char *name) 3435 { 3436 int i; 3437 unsigned int namewidth; 3438 uint64_t flags = cb->cb_flags; 3439 uint64_t f; 3440 int idx; 3441 const name_and_columns_t *labels; 3442 const char *title; 3443 3444 3445 if (cb->cb_flags & IOS_ANYHISTO_M) { 3446 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]; 3447 } else if (cb->cb_vdev_names_count) { 3448 title = "vdev"; 3449 } else { 3450 title = "pool"; 3451 } 3452 3453 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth), 3454 name ? strlen(name) : 0); 3455 3456 3457 if (name) { 3458 printf("%-*s", namewidth, name); 3459 } else { 3460 for (i = 0; i < namewidth; i++) 3461 (void) printf("-"); 3462 } 3463 3464 /* For each bit in flags */ 3465 for (f = flags; f; f &= ~(1ULL << idx)) { 3466 unsigned int column_width; 3467 idx = lowbit64(f) - 1; 3468 if (force_column_width) 3469 column_width = force_column_width; 3470 else 3471 column_width = default_column_width(cb, idx); 3472 3473 labels = iostat_bottom_labels[idx]; 3474 for (i = 0; i < label_array_len(labels); i++) { 3475 if (name) 3476 printf(" %*s-", column_width - 1, " "); 3477 else 3478 printf(" %.*s", column_width, 3479 "--------------------"); 3480 } 3481 } 3482 } 3483 3484 3485 static void 3486 print_iostat_separator_impl(iostat_cbdata_t *cb, 3487 unsigned int force_column_width) 3488 { 3489 print_iostat_dashes(cb, force_column_width, NULL); 3490 } 3491 3492 static void 3493 print_iostat_separator(iostat_cbdata_t *cb) 3494 { 3495 print_iostat_separator_impl(cb, 0); 3496 } 3497 3498 static void 3499 print_iostat_header_impl(iostat_cbdata_t *cb, unsigned int force_column_width, 3500 const char *histo_vdev_name) 3501 { 3502 unsigned int namewidth; 3503 const char *title; 3504 3505 if (cb->cb_flags & IOS_ANYHISTO_M) { 3506 title = histo_to_title[IOS_HISTO_IDX(cb->cb_flags)]; 3507 } else if (cb->cb_vdev_names_count) { 3508 title = "vdev"; 3509 } else { 3510 title = "pool"; 3511 } 3512 3513 namewidth = MAX(MAX(strlen(title), cb->cb_namewidth), 3514 histo_vdev_name ? strlen(histo_vdev_name) : 0); 3515 3516 if (histo_vdev_name) 3517 printf("%-*s", namewidth, histo_vdev_name); 3518 else 3519 printf("%*s", namewidth, ""); 3520 3521 3522 print_iostat_labels(cb, force_column_width, iostat_top_labels); 3523 printf("\n"); 3524 3525 printf("%-*s", namewidth, title); 3526 3527 print_iostat_labels(cb, force_column_width, iostat_bottom_labels); 3528 3529 printf("\n"); 3530 3531 print_iostat_separator_impl(cb, force_column_width); 3532 3533 printf("\n"); 3534 } 3535 3536 static void 3537 print_iostat_header(iostat_cbdata_t *cb) 3538 { 3539 print_iostat_header_impl(cb, 0, NULL); 3540 } 3541 3542 /* 3543 * Display a single statistic. 3544 */ 3545 static void 3546 print_one_stat(uint64_t value, enum zfs_nicenum_format format, 3547 unsigned int column_size, boolean_t scripted) 3548 { 3549 char buf[64]; 3550 3551 zfs_nicenum_format(value, buf, sizeof (buf), format); 3552 3553 if (scripted) 3554 printf("\t%s", buf); 3555 else 3556 printf(" %*s", column_size, buf); 3557 } 3558 3559 /* 3560 * Calculate the default vdev stats 3561 * 3562 * Subtract oldvs from newvs, apply a scaling factor, and save the resulting 3563 * stats into calcvs. 3564 */ 3565 static void 3566 calc_default_iostats(vdev_stat_t *oldvs, vdev_stat_t *newvs, 3567 vdev_stat_t *calcvs) 3568 { 3569 int i; 3570 3571 memcpy(calcvs, newvs, sizeof (*calcvs)); 3572 for (i = 0; i < ARRAY_SIZE(calcvs->vs_ops); i++) 3573 calcvs->vs_ops[i] = (newvs->vs_ops[i] - oldvs->vs_ops[i]); 3574 3575 for (i = 0; i < ARRAY_SIZE(calcvs->vs_bytes); i++) 3576 calcvs->vs_bytes[i] = (newvs->vs_bytes[i] - oldvs->vs_bytes[i]); 3577 } 3578 3579 /* 3580 * Internal representation of the extended iostats data. 3581 * 3582 * The extended iostat stats are exported in nvlists as either uint64_t arrays 3583 * or single uint64_t's. We make both look like arrays to make them easier 3584 * to process. In order to make single uint64_t's look like arrays, we set 3585 * __data to the stat data, and then set *data = &__data with count = 1. Then, 3586 * we can just use *data and count. 3587 */ 3588 struct stat_array { 3589 uint64_t *data; 3590 uint_t count; /* Number of entries in data[] */ 3591 uint64_t __data; /* Only used when data is a single uint64_t */ 3592 }; 3593 3594 static uint64_t 3595 stat_histo_max(struct stat_array *nva, unsigned int len) 3596 { 3597 uint64_t max = 0; 3598 int i; 3599 for (i = 0; i < len; i++) 3600 max = MAX(max, array64_max(nva[i].data, nva[i].count)); 3601 3602 return (max); 3603 } 3604 3605 /* 3606 * Helper function to lookup a uint64_t array or uint64_t value and store its 3607 * data as a stat_array. If the nvpair is a single uint64_t value, then we make 3608 * it look like a one element array to make it easier to process. 3609 */ 3610 static int 3611 nvpair64_to_stat_array(nvlist_t *nvl, const char *name, 3612 struct stat_array *nva) 3613 { 3614 nvpair_t *tmp; 3615 int ret; 3616 3617 verify(nvlist_lookup_nvpair(nvl, name, &tmp) == 0); 3618 switch (nvpair_type(tmp)) { 3619 case DATA_TYPE_UINT64_ARRAY: 3620 ret = nvpair_value_uint64_array(tmp, &nva->data, &nva->count); 3621 break; 3622 case DATA_TYPE_UINT64: 3623 ret = nvpair_value_uint64(tmp, &nva->__data); 3624 nva->data = &nva->__data; 3625 nva->count = 1; 3626 break; 3627 default: 3628 /* Not a uint64_t */ 3629 ret = EINVAL; 3630 break; 3631 } 3632 3633 return (ret); 3634 } 3635 3636 /* 3637 * Given a list of nvlist names, look up the extended stats in newnv and oldnv, 3638 * subtract them, and return the results in a newly allocated stat_array. 3639 * You must free the returned array after you are done with it with 3640 * free_calc_stats(). 3641 * 3642 * Additionally, you can set "oldnv" to NULL if you simply want the newnv 3643 * values. 3644 */ 3645 static struct stat_array * 3646 calc_and_alloc_stats_ex(const char **names, unsigned int len, nvlist_t *oldnv, 3647 nvlist_t *newnv) 3648 { 3649 nvlist_t *oldnvx = NULL, *newnvx; 3650 struct stat_array *oldnva, *newnva, *calcnva; 3651 int i, j; 3652 unsigned int alloc_size = (sizeof (struct stat_array)) * len; 3653 3654 /* Extract our extended stats nvlist from the main list */ 3655 verify(nvlist_lookup_nvlist(newnv, ZPOOL_CONFIG_VDEV_STATS_EX, 3656 &newnvx) == 0); 3657 if (oldnv) { 3658 verify(nvlist_lookup_nvlist(oldnv, ZPOOL_CONFIG_VDEV_STATS_EX, 3659 &oldnvx) == 0); 3660 } 3661 3662 newnva = safe_malloc(alloc_size); 3663 oldnva = safe_malloc(alloc_size); 3664 calcnva = safe_malloc(alloc_size); 3665 3666 for (j = 0; j < len; j++) { 3667 verify(nvpair64_to_stat_array(newnvx, names[j], 3668 &newnva[j]) == 0); 3669 calcnva[j].count = newnva[j].count; 3670 alloc_size = calcnva[j].count * sizeof (calcnva[j].data[0]); 3671 calcnva[j].data = safe_malloc(alloc_size); 3672 memcpy(calcnva[j].data, newnva[j].data, alloc_size); 3673 3674 if (oldnvx) { 3675 verify(nvpair64_to_stat_array(oldnvx, names[j], 3676 &oldnva[j]) == 0); 3677 for (i = 0; i < oldnva[j].count; i++) 3678 calcnva[j].data[i] -= oldnva[j].data[i]; 3679 } 3680 } 3681 free(newnva); 3682 free(oldnva); 3683 return (calcnva); 3684 } 3685 3686 static void 3687 free_calc_stats(struct stat_array *nva, unsigned int len) 3688 { 3689 int i; 3690 for (i = 0; i < len; i++) 3691 free(nva[i].data); 3692 3693 free(nva); 3694 } 3695 3696 static void 3697 print_iostat_histo(struct stat_array *nva, unsigned int len, 3698 iostat_cbdata_t *cb, unsigned int column_width, unsigned int namewidth, 3699 double scale) 3700 { 3701 int i, j; 3702 char buf[6]; 3703 uint64_t val; 3704 enum zfs_nicenum_format format; 3705 unsigned int buckets; 3706 unsigned int start_bucket; 3707 3708 if (cb->cb_literal) 3709 format = ZFS_NICENUM_RAW; 3710 else 3711 format = ZFS_NICENUM_1024; 3712 3713 /* All these histos are the same size, so just use nva[0].count */ 3714 buckets = nva[0].count; 3715 3716 if (cb->cb_flags & IOS_RQ_HISTO_M) { 3717 /* Start at 512 - req size should never be lower than this */ 3718 start_bucket = 9; 3719 } else { 3720 start_bucket = 0; 3721 } 3722 3723 for (j = start_bucket; j < buckets; j++) { 3724 /* Print histogram bucket label */ 3725 if (cb->cb_flags & IOS_L_HISTO_M) { 3726 /* Ending range of this bucket */ 3727 val = (1ULL << (j + 1)) - 1; 3728 zfs_nicetime(val, buf, sizeof (buf)); 3729 } else { 3730 /* Request size (starting range of bucket) */ 3731 val = (1UL << j); 3732 zfs_nicenum(val, buf, sizeof (buf)); 3733 } 3734 3735 if (cb->cb_scripted) 3736 printf("%llu", (u_longlong_t)val); 3737 else 3738 printf("%-*s", namewidth, buf); 3739 3740 /* Print the values on the line */ 3741 for (i = 0; i < len; i++) { 3742 print_one_stat(nva[i].data[j] * scale, format, 3743 column_width, cb->cb_scripted); 3744 } 3745 printf("\n"); 3746 } 3747 } 3748 3749 static void 3750 print_solid_separator(unsigned int length) 3751 { 3752 while (length--) 3753 printf("-"); 3754 printf("\n"); 3755 } 3756 3757 static void 3758 print_iostat_histos(iostat_cbdata_t *cb, nvlist_t *oldnv, 3759 nvlist_t *newnv, double scale, const char *name) 3760 { 3761 unsigned int column_width; 3762 unsigned int namewidth; 3763 unsigned int entire_width; 3764 enum iostat_type type; 3765 struct stat_array *nva; 3766 const char **names; 3767 unsigned int names_len; 3768 3769 /* What type of histo are we? */ 3770 type = IOS_HISTO_IDX(cb->cb_flags); 3771 3772 /* Get NULL-terminated array of nvlist names for our histo */ 3773 names = vsx_type_to_nvlist[type]; 3774 names_len = str_array_len(names); /* num of names */ 3775 3776 nva = calc_and_alloc_stats_ex(names, names_len, oldnv, newnv); 3777 3778 if (cb->cb_literal) { 3779 column_width = MAX(5, 3780 (unsigned int) log10(stat_histo_max(nva, names_len)) + 1); 3781 } else { 3782 column_width = 5; 3783 } 3784 3785 namewidth = MAX(cb->cb_namewidth, 3786 strlen(histo_to_title[IOS_HISTO_IDX(cb->cb_flags)])); 3787 3788 /* 3789 * Calculate the entire line width of what we're printing. The 3790 * +2 is for the two spaces between columns: 3791 */ 3792 /* read write */ 3793 /* ----- ----- */ 3794 /* |___| <---------- column_width */ 3795 /* */ 3796 /* |__________| <--- entire_width */ 3797 /* */ 3798 entire_width = namewidth + (column_width + 2) * 3799 label_array_len(iostat_bottom_labels[type]); 3800 3801 if (cb->cb_scripted) 3802 printf("%s\n", name); 3803 else 3804 print_iostat_header_impl(cb, column_width, name); 3805 3806 print_iostat_histo(nva, names_len, cb, column_width, 3807 namewidth, scale); 3808 3809 free_calc_stats(nva, names_len); 3810 if (!cb->cb_scripted) 3811 print_solid_separator(entire_width); 3812 } 3813 3814 /* 3815 * Calculate the average latency of a power-of-two latency histogram 3816 */ 3817 static uint64_t 3818 single_histo_average(uint64_t *histo, unsigned int buckets) 3819 { 3820 int i; 3821 uint64_t count = 0, total = 0; 3822 3823 for (i = 0; i < buckets; i++) { 3824 /* 3825 * Our buckets are power-of-two latency ranges. Use the 3826 * midpoint latency of each bucket to calculate the average. 3827 * For example: 3828 * 3829 * Bucket Midpoint 3830 * 8ns-15ns: 12ns 3831 * 16ns-31ns: 24ns 3832 * ... 3833 */ 3834 if (histo[i] != 0) { 3835 total += histo[i] * (((1UL << i) + ((1UL << i)/2))); 3836 count += histo[i]; 3837 } 3838 } 3839 3840 /* Prevent divide by zero */ 3841 return (count == 0 ? 0 : total / count); 3842 } 3843 3844 static void 3845 print_iostat_queues(iostat_cbdata_t *cb, nvlist_t *oldnv, 3846 nvlist_t *newnv) 3847 { 3848 int i; 3849 uint64_t val; 3850 const char *names[] = { 3851 ZPOOL_CONFIG_VDEV_SYNC_R_PEND_QUEUE, 3852 ZPOOL_CONFIG_VDEV_SYNC_R_ACTIVE_QUEUE, 3853 ZPOOL_CONFIG_VDEV_SYNC_W_PEND_QUEUE, 3854 ZPOOL_CONFIG_VDEV_SYNC_W_ACTIVE_QUEUE, 3855 ZPOOL_CONFIG_VDEV_ASYNC_R_PEND_QUEUE, 3856 ZPOOL_CONFIG_VDEV_ASYNC_R_ACTIVE_QUEUE, 3857 ZPOOL_CONFIG_VDEV_ASYNC_W_PEND_QUEUE, 3858 ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE, 3859 ZPOOL_CONFIG_VDEV_SCRUB_PEND_QUEUE, 3860 ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE, 3861 ZPOOL_CONFIG_VDEV_TRIM_PEND_QUEUE, 3862 ZPOOL_CONFIG_VDEV_TRIM_ACTIVE_QUEUE, 3863 }; 3864 3865 struct stat_array *nva; 3866 3867 unsigned int column_width = default_column_width(cb, IOS_QUEUES); 3868 enum zfs_nicenum_format format; 3869 3870 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), NULL, newnv); 3871 3872 if (cb->cb_literal) 3873 format = ZFS_NICENUM_RAW; 3874 else 3875 format = ZFS_NICENUM_1024; 3876 3877 for (i = 0; i < ARRAY_SIZE(names); i++) { 3878 val = nva[i].data[0]; 3879 print_one_stat(val, format, column_width, cb->cb_scripted); 3880 } 3881 3882 free_calc_stats(nva, ARRAY_SIZE(names)); 3883 } 3884 3885 static void 3886 print_iostat_latency(iostat_cbdata_t *cb, nvlist_t *oldnv, 3887 nvlist_t *newnv) 3888 { 3889 int i; 3890 uint64_t val; 3891 const char *names[] = { 3892 ZPOOL_CONFIG_VDEV_TOT_R_LAT_HISTO, 3893 ZPOOL_CONFIG_VDEV_TOT_W_LAT_HISTO, 3894 ZPOOL_CONFIG_VDEV_DISK_R_LAT_HISTO, 3895 ZPOOL_CONFIG_VDEV_DISK_W_LAT_HISTO, 3896 ZPOOL_CONFIG_VDEV_SYNC_R_LAT_HISTO, 3897 ZPOOL_CONFIG_VDEV_SYNC_W_LAT_HISTO, 3898 ZPOOL_CONFIG_VDEV_ASYNC_R_LAT_HISTO, 3899 ZPOOL_CONFIG_VDEV_ASYNC_W_LAT_HISTO, 3900 ZPOOL_CONFIG_VDEV_SCRUB_LAT_HISTO, 3901 ZPOOL_CONFIG_VDEV_TRIM_LAT_HISTO, 3902 }; 3903 struct stat_array *nva; 3904 3905 unsigned int column_width = default_column_width(cb, IOS_LATENCY); 3906 enum zfs_nicenum_format format; 3907 3908 nva = calc_and_alloc_stats_ex(names, ARRAY_SIZE(names), oldnv, newnv); 3909 3910 if (cb->cb_literal) 3911 format = ZFS_NICENUM_RAWTIME; 3912 else 3913 format = ZFS_NICENUM_TIME; 3914 3915 /* Print our avg latencies on the line */ 3916 for (i = 0; i < ARRAY_SIZE(names); i++) { 3917 /* Compute average latency for a latency histo */ 3918 val = single_histo_average(nva[i].data, nva[i].count); 3919 print_one_stat(val, format, column_width, cb->cb_scripted); 3920 } 3921 free_calc_stats(nva, ARRAY_SIZE(names)); 3922 } 3923 3924 /* 3925 * Print default statistics (capacity/operations/bandwidth) 3926 */ 3927 static void 3928 print_iostat_default(vdev_stat_t *vs, iostat_cbdata_t *cb, double scale) 3929 { 3930 unsigned int column_width = default_column_width(cb, IOS_DEFAULT); 3931 enum zfs_nicenum_format format; 3932 char na; /* char to print for "not applicable" values */ 3933 3934 if (cb->cb_literal) { 3935 format = ZFS_NICENUM_RAW; 3936 na = '0'; 3937 } else { 3938 format = ZFS_NICENUM_1024; 3939 na = '-'; 3940 } 3941 3942 /* only toplevel vdevs have capacity stats */ 3943 if (vs->vs_space == 0) { 3944 if (cb->cb_scripted) 3945 printf("\t%c\t%c", na, na); 3946 else 3947 printf(" %*c %*c", column_width, na, column_width, 3948 na); 3949 } else { 3950 print_one_stat(vs->vs_alloc, format, column_width, 3951 cb->cb_scripted); 3952 print_one_stat(vs->vs_space - vs->vs_alloc, format, 3953 column_width, cb->cb_scripted); 3954 } 3955 3956 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_READ] * scale), 3957 format, column_width, cb->cb_scripted); 3958 print_one_stat((uint64_t)(vs->vs_ops[ZIO_TYPE_WRITE] * scale), 3959 format, column_width, cb->cb_scripted); 3960 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_READ] * scale), 3961 format, column_width, cb->cb_scripted); 3962 print_one_stat((uint64_t)(vs->vs_bytes[ZIO_TYPE_WRITE] * scale), 3963 format, column_width, cb->cb_scripted); 3964 } 3965 3966 static const char *class_name[] = { 3967 VDEV_ALLOC_BIAS_DEDUP, 3968 VDEV_ALLOC_BIAS_SPECIAL, 3969 VDEV_ALLOC_CLASS_LOGS 3970 }; 3971 3972 /* 3973 * Print out all the statistics for the given vdev. This can either be the 3974 * toplevel configuration, or called recursively. If 'name' is NULL, then this 3975 * is a verbose output, and we don't want to display the toplevel pool stats. 3976 * 3977 * Returns the number of stat lines printed. 3978 */ 3979 unsigned int 3980 print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 3981 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 3982 { 3983 nvlist_t **oldchild, **newchild; 3984 uint_t c, children, oldchildren; 3985 vdev_stat_t *oldvs, *newvs, *calcvs; 3986 vdev_stat_t zerovs = { 0 }; 3987 char *vname; 3988 int i; 3989 int ret = 0; 3990 uint64_t tdelta; 3991 double scale; 3992 3993 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 3994 return (0); 3995 3996 calcvs = safe_malloc(sizeof (*calcvs)); 3997 3998 if (oldnv != NULL) { 3999 verify(nvlist_lookup_uint64_array(oldnv, 4000 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0); 4001 } else { 4002 oldvs = &zerovs; 4003 } 4004 4005 /* Do we only want to see a specific vdev? */ 4006 for (i = 0; i < cb->cb_vdev_names_count; i++) { 4007 /* Yes we do. Is this the vdev? */ 4008 if (strcmp(name, cb->cb_vdev_names[i]) == 0) { 4009 /* 4010 * This is our vdev. Since it is the only vdev we 4011 * will be displaying, make depth = 0 so that it 4012 * doesn't get indented. 4013 */ 4014 depth = 0; 4015 break; 4016 } 4017 } 4018 4019 if (cb->cb_vdev_names_count && (i == cb->cb_vdev_names_count)) { 4020 /* Couldn't match the name */ 4021 goto children; 4022 } 4023 4024 4025 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS, 4026 (uint64_t **)&newvs, &c) == 0); 4027 4028 /* 4029 * Print the vdev name unless it's is a histogram. Histograms 4030 * display the vdev name in the header itself. 4031 */ 4032 if (!(cb->cb_flags & IOS_ANYHISTO_M)) { 4033 if (cb->cb_scripted) { 4034 printf("%s", name); 4035 } else { 4036 if (strlen(name) + depth > cb->cb_namewidth) 4037 (void) printf("%*s%s", depth, "", name); 4038 else 4039 (void) printf("%*s%s%*s", depth, "", name, 4040 (int)(cb->cb_namewidth - strlen(name) - 4041 depth), ""); 4042 } 4043 } 4044 4045 /* Calculate our scaling factor */ 4046 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 4047 if ((oldvs->vs_timestamp == 0) && (cb->cb_flags & IOS_ANYHISTO_M)) { 4048 /* 4049 * If we specify printing histograms with no time interval, then 4050 * print the histogram numbers over the entire lifetime of the 4051 * vdev. 4052 */ 4053 scale = 1; 4054 } else { 4055 if (tdelta == 0) 4056 scale = 1.0; 4057 else 4058 scale = (double)NANOSEC / tdelta; 4059 } 4060 4061 if (cb->cb_flags & IOS_DEFAULT_M) { 4062 calc_default_iostats(oldvs, newvs, calcvs); 4063 print_iostat_default(calcvs, cb, scale); 4064 } 4065 if (cb->cb_flags & IOS_LATENCY_M) 4066 print_iostat_latency(cb, oldnv, newnv); 4067 if (cb->cb_flags & IOS_QUEUES_M) 4068 print_iostat_queues(cb, oldnv, newnv); 4069 if (cb->cb_flags & IOS_ANYHISTO_M) { 4070 printf("\n"); 4071 print_iostat_histos(cb, oldnv, newnv, scale, name); 4072 } 4073 4074 if (!(cb->cb_flags & IOS_ANYHISTO_M)) 4075 printf("\n"); 4076 4077 ret++; 4078 4079 children: 4080 4081 free(calcvs); 4082 4083 if (!cb->cb_verbose) 4084 return (ret); 4085 4086 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 4087 &newchild, &children) != 0) 4088 return (ret); 4089 4090 if (oldnv) { 4091 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 4092 &oldchild, &oldchildren) != 0) 4093 return (ret); 4094 4095 children = MIN(oldchildren, children); 4096 } 4097 4098 /* 4099 * print normal top-level devices 4100 */ 4101 for (c = 0; c < children; c++) { 4102 uint64_t ishole = B_FALSE, islog = B_FALSE; 4103 4104 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_HOLE, 4105 &ishole); 4106 4107 (void) nvlist_lookup_uint64(newchild[c], ZPOOL_CONFIG_IS_LOG, 4108 &islog); 4109 4110 if (ishole || islog) 4111 continue; 4112 4113 if (nvlist_exists(newchild[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 4114 continue; 4115 4116 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4117 cb->cb_name_flags); 4118 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 4119 newchild[c], cb, depth + 2); 4120 free(vname); 4121 } 4122 4123 /* 4124 * print all other top-level devices 4125 */ 4126 for (uint_t n = 0; n < 3; n++) { 4127 boolean_t printed = B_FALSE; 4128 4129 for (c = 0; c < children; c++) { 4130 uint64_t islog = B_FALSE; 4131 char *bias = NULL; 4132 char *type = NULL; 4133 4134 (void) nvlist_lookup_uint64(newchild[c], 4135 ZPOOL_CONFIG_IS_LOG, &islog); 4136 if (islog) { 4137 bias = VDEV_ALLOC_CLASS_LOGS; 4138 } else { 4139 (void) nvlist_lookup_string(newchild[c], 4140 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 4141 (void) nvlist_lookup_string(newchild[c], 4142 ZPOOL_CONFIG_TYPE, &type); 4143 } 4144 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 4145 continue; 4146 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 4147 continue; 4148 4149 if (!printed) { 4150 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && 4151 !cb->cb_scripted && !cb->cb_vdev_names) { 4152 print_iostat_dashes(cb, 0, 4153 class_name[n]); 4154 } 4155 printf("\n"); 4156 printed = B_TRUE; 4157 } 4158 4159 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4160 cb->cb_name_flags); 4161 ret += print_vdev_stats(zhp, vname, oldnv ? 4162 oldchild[c] : NULL, newchild[c], cb, depth + 2); 4163 free(vname); 4164 } 4165 4166 } 4167 4168 /* 4169 * Include level 2 ARC devices in iostat output 4170 */ 4171 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 4172 &newchild, &children) != 0) 4173 return (ret); 4174 4175 if (oldnv) { 4176 if (nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 4177 &oldchild, &oldchildren) != 0) 4178 return (ret); 4179 4180 children = MIN(oldchildren, children); 4181 } 4182 4183 if (children > 0) { 4184 if ((!(cb->cb_flags & IOS_ANYHISTO_M)) && !cb->cb_scripted && 4185 !cb->cb_vdev_names) { 4186 print_iostat_dashes(cb, 0, "cache"); 4187 } 4188 printf("\n"); 4189 4190 for (c = 0; c < children; c++) { 4191 vname = zpool_vdev_name(g_zfs, zhp, newchild[c], 4192 cb->cb_name_flags); 4193 ret += print_vdev_stats(zhp, vname, oldnv ? oldchild[c] 4194 : NULL, newchild[c], cb, depth + 2); 4195 free(vname); 4196 } 4197 } 4198 4199 return (ret); 4200 } 4201 4202 static int 4203 refresh_iostat(zpool_handle_t *zhp, void *data) 4204 { 4205 iostat_cbdata_t *cb = data; 4206 boolean_t missing; 4207 4208 /* 4209 * If the pool has disappeared, remove it from the list and continue. 4210 */ 4211 if (zpool_refresh_stats(zhp, &missing) != 0) 4212 return (-1); 4213 4214 if (missing) 4215 pool_list_remove(cb->cb_list, zhp); 4216 4217 return (0); 4218 } 4219 4220 /* 4221 * Callback to print out the iostats for the given pool. 4222 */ 4223 int 4224 print_iostat(zpool_handle_t *zhp, void *data) 4225 { 4226 iostat_cbdata_t *cb = data; 4227 nvlist_t *oldconfig, *newconfig; 4228 nvlist_t *oldnvroot, *newnvroot; 4229 int ret; 4230 4231 newconfig = zpool_get_config(zhp, &oldconfig); 4232 4233 if (cb->cb_iteration == 1) 4234 oldconfig = NULL; 4235 4236 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 4237 &newnvroot) == 0); 4238 4239 if (oldconfig == NULL) 4240 oldnvroot = NULL; 4241 else 4242 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 4243 &oldnvroot) == 0); 4244 4245 ret = print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, 4246 cb, 0); 4247 if ((ret != 0) && !(cb->cb_flags & IOS_ANYHISTO_M) && 4248 !cb->cb_scripted && cb->cb_verbose && !cb->cb_vdev_names_count) { 4249 print_iostat_separator(cb); 4250 printf("\n"); 4251 } 4252 4253 return (ret); 4254 } 4255 4256 static int 4257 get_columns(void) 4258 { 4259 struct winsize ws; 4260 int columns = 80; 4261 int error; 4262 4263 if (isatty(STDOUT_FILENO)) { 4264 error = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); 4265 if (error == 0) 4266 columns = ws.ws_col; 4267 } else { 4268 columns = 999; 4269 } 4270 4271 return (columns); 4272 } 4273 4274 /* 4275 * Return the required length of the pool/vdev name column. The minimum 4276 * allowed width and output formatting flags must be provided. 4277 */ 4278 static int 4279 get_namewidth(zpool_handle_t *zhp, int min_width, int flags, boolean_t verbose) 4280 { 4281 nvlist_t *config, *nvroot; 4282 int width = min_width; 4283 4284 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 4285 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 4286 &nvroot) == 0); 4287 unsigned int poolname_len = strlen(zpool_get_name(zhp)); 4288 if (verbose == B_FALSE) { 4289 width = MAX(poolname_len, min_width); 4290 } else { 4291 width = MAX(poolname_len, 4292 max_width(zhp, nvroot, 0, min_width, flags)); 4293 } 4294 } 4295 4296 return (width); 4297 } 4298 4299 /* 4300 * Parse the input string, get the 'interval' and 'count' value if there is one. 4301 */ 4302 static void 4303 get_interval_count(int *argcp, char **argv, float *iv, 4304 unsigned long *cnt) 4305 { 4306 float interval = 0; 4307 unsigned long count = 0; 4308 int argc = *argcp, errno; 4309 4310 /* 4311 * Determine if the last argument is an integer or a pool name 4312 */ 4313 if (argc > 0 && isnumber(argv[argc - 1])) { 4314 char *end; 4315 4316 errno = 0; 4317 interval = strtof(argv[argc - 1], &end); 4318 4319 if (*end == '\0' && errno == 0) { 4320 if (interval == 0) { 4321 (void) fprintf(stderr, gettext("interval " 4322 "cannot be zero\n")); 4323 usage(B_FALSE); 4324 } 4325 /* 4326 * Ignore the last parameter 4327 */ 4328 argc--; 4329 } else { 4330 /* 4331 * If this is not a valid number, just plow on. The 4332 * user will get a more informative error message later 4333 * on. 4334 */ 4335 interval = 0; 4336 } 4337 } 4338 4339 /* 4340 * If the last argument is also an integer, then we have both a count 4341 * and an interval. 4342 */ 4343 if (argc > 0 && isnumber(argv[argc - 1])) { 4344 char *end; 4345 4346 errno = 0; 4347 count = interval; 4348 interval = strtof(argv[argc - 1], &end); 4349 4350 if (*end == '\0' && errno == 0) { 4351 if (interval == 0) { 4352 (void) fprintf(stderr, gettext("interval " 4353 "cannot be zero\n")); 4354 usage(B_FALSE); 4355 } 4356 4357 /* 4358 * Ignore the last parameter 4359 */ 4360 argc--; 4361 } else { 4362 interval = 0; 4363 } 4364 } 4365 4366 *iv = interval; 4367 *cnt = count; 4368 *argcp = argc; 4369 } 4370 4371 static void 4372 get_timestamp_arg(char c) 4373 { 4374 if (c == 'u') 4375 timestamp_fmt = UDATE; 4376 else if (c == 'd') 4377 timestamp_fmt = DDATE; 4378 else 4379 usage(B_FALSE); 4380 } 4381 4382 /* 4383 * Return stat flags that are supported by all pools by both the module and 4384 * zpool iostat. "*data" should be initialized to all 0xFFs before running. 4385 * It will get ANDed down until only the flags that are supported on all pools 4386 * remain. 4387 */ 4388 static int 4389 get_stat_flags_cb(zpool_handle_t *zhp, void *data) 4390 { 4391 uint64_t *mask = data; 4392 nvlist_t *config, *nvroot, *nvx; 4393 uint64_t flags = 0; 4394 int i, j; 4395 4396 config = zpool_get_config(zhp, NULL); 4397 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 4398 &nvroot) == 0); 4399 4400 /* Default stats are always supported, but for completeness.. */ 4401 if (nvlist_exists(nvroot, ZPOOL_CONFIG_VDEV_STATS)) 4402 flags |= IOS_DEFAULT_M; 4403 4404 /* Get our extended stats nvlist from the main list */ 4405 if (nvlist_lookup_nvlist(nvroot, ZPOOL_CONFIG_VDEV_STATS_EX, 4406 &nvx) != 0) { 4407 /* 4408 * No extended stats; they're probably running an older 4409 * module. No big deal, we support that too. 4410 */ 4411 goto end; 4412 } 4413 4414 /* For each extended stat, make sure all its nvpairs are supported */ 4415 for (j = 0; j < ARRAY_SIZE(vsx_type_to_nvlist); j++) { 4416 if (!vsx_type_to_nvlist[j][0]) 4417 continue; 4418 4419 /* Start off by assuming the flag is supported, then check */ 4420 flags |= (1ULL << j); 4421 for (i = 0; vsx_type_to_nvlist[j][i]; i++) { 4422 if (!nvlist_exists(nvx, vsx_type_to_nvlist[j][i])) { 4423 /* flag isn't supported */ 4424 flags = flags & ~(1ULL << j); 4425 break; 4426 } 4427 } 4428 } 4429 end: 4430 *mask = *mask & flags; 4431 return (0); 4432 } 4433 4434 /* 4435 * Return a bitmask of stats that are supported on all pools by both the module 4436 * and zpool iostat. 4437 */ 4438 static uint64_t 4439 get_stat_flags(zpool_list_t *list) 4440 { 4441 uint64_t mask = -1; 4442 4443 /* 4444 * get_stat_flags_cb() will lop off bits from "mask" until only the 4445 * flags that are supported on all pools remain. 4446 */ 4447 (void) pool_list_iter(list, B_FALSE, get_stat_flags_cb, &mask); 4448 return (mask); 4449 } 4450 4451 /* 4452 * Return 1 if cb_data->cb_vdev_names[0] is this vdev's name, 0 otherwise. 4453 */ 4454 static int 4455 is_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, void *cb_data) 4456 { 4457 iostat_cbdata_t *cb = cb_data; 4458 char *name; 4459 4460 name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags); 4461 4462 if (strcmp(name, cb->cb_vdev_names[0]) == 0) 4463 return (1); /* match */ 4464 4465 return (0); 4466 } 4467 4468 /* 4469 * Returns 1 if cb_data->cb_vdev_names[0] is a vdev name, 0 otherwise. 4470 */ 4471 static int 4472 is_vdev(zpool_handle_t *zhp, void *cb_data) 4473 { 4474 return (for_each_vdev(zhp, is_vdev_cb, cb_data)); 4475 } 4476 4477 /* 4478 * Check if vdevs are in a pool 4479 * 4480 * Return 1 if all argv[] strings are vdev names in pool "pool_name". Otherwise 4481 * return 0. If pool_name is NULL, then search all pools. 4482 */ 4483 static int 4484 are_vdevs_in_pool(int argc, char **argv, char *pool_name, 4485 iostat_cbdata_t *cb) 4486 { 4487 char **tmp_name; 4488 int ret = 0; 4489 int i; 4490 int pool_count = 0; 4491 4492 if ((argc == 0) || !*argv) 4493 return (0); 4494 4495 if (pool_name) 4496 pool_count = 1; 4497 4498 /* Temporarily hijack cb_vdev_names for a second... */ 4499 tmp_name = cb->cb_vdev_names; 4500 4501 /* Go though our list of prospective vdev names */ 4502 for (i = 0; i < argc; i++) { 4503 cb->cb_vdev_names = argv + i; 4504 4505 /* Is this name a vdev in our pools? */ 4506 ret = for_each_pool(pool_count, &pool_name, B_TRUE, NULL, 4507 is_vdev, cb); 4508 if (!ret) { 4509 /* No match */ 4510 break; 4511 } 4512 } 4513 4514 cb->cb_vdev_names = tmp_name; 4515 4516 return (ret); 4517 } 4518 4519 static int 4520 is_pool_cb(zpool_handle_t *zhp, void *data) 4521 { 4522 char *name = data; 4523 if (strcmp(name, zpool_get_name(zhp)) == 0) 4524 return (1); 4525 4526 return (0); 4527 } 4528 4529 /* 4530 * Do we have a pool named *name? If so, return 1, otherwise 0. 4531 */ 4532 static int 4533 is_pool(char *name) 4534 { 4535 return (for_each_pool(0, NULL, B_TRUE, NULL, is_pool_cb, name)); 4536 } 4537 4538 /* Are all our argv[] strings pool names? If so return 1, 0 otherwise. */ 4539 static int 4540 are_all_pools(int argc, char **argv) 4541 { 4542 if ((argc == 0) || !*argv) 4543 return (0); 4544 4545 while (--argc >= 0) 4546 if (!is_pool(argv[argc])) 4547 return (0); 4548 4549 return (1); 4550 } 4551 4552 /* 4553 * Helper function to print out vdev/pool names we can't resolve. Used for an 4554 * error message. 4555 */ 4556 static void 4557 error_list_unresolved_vdevs(int argc, char **argv, char *pool_name, 4558 iostat_cbdata_t *cb) 4559 { 4560 int i; 4561 char *name; 4562 char *str; 4563 for (i = 0; i < argc; i++) { 4564 name = argv[i]; 4565 4566 if (is_pool(name)) 4567 str = gettext("pool"); 4568 else if (are_vdevs_in_pool(1, &name, pool_name, cb)) 4569 str = gettext("vdev in this pool"); 4570 else if (are_vdevs_in_pool(1, &name, NULL, cb)) 4571 str = gettext("vdev in another pool"); 4572 else 4573 str = gettext("unknown"); 4574 4575 fprintf(stderr, "\t%s (%s)\n", name, str); 4576 } 4577 } 4578 4579 /* 4580 * Same as get_interval_count(), but with additional checks to not misinterpret 4581 * guids as interval/count values. Assumes VDEV_NAME_GUID is set in 4582 * cb.cb_name_flags. 4583 */ 4584 static void 4585 get_interval_count_filter_guids(int *argc, char **argv, float *interval, 4586 unsigned long *count, iostat_cbdata_t *cb) 4587 { 4588 char **tmpargv = argv; 4589 int argc_for_interval = 0; 4590 4591 /* Is the last arg an interval value? Or a guid? */ 4592 if (*argc >= 1 && !are_vdevs_in_pool(1, &argv[*argc - 1], NULL, cb)) { 4593 /* 4594 * The last arg is not a guid, so it's probably an 4595 * interval value. 4596 */ 4597 argc_for_interval++; 4598 4599 if (*argc >= 2 && 4600 !are_vdevs_in_pool(1, &argv[*argc - 2], NULL, cb)) { 4601 /* 4602 * The 2nd to last arg is not a guid, so it's probably 4603 * an interval value. 4604 */ 4605 argc_for_interval++; 4606 } 4607 } 4608 4609 /* Point to our list of possible intervals */ 4610 tmpargv = &argv[*argc - argc_for_interval]; 4611 4612 *argc = *argc - argc_for_interval; 4613 get_interval_count(&argc_for_interval, tmpargv, 4614 interval, count); 4615 } 4616 4617 /* 4618 * Floating point sleep(). Allows you to pass in a floating point value for 4619 * seconds. 4620 */ 4621 static void 4622 fsleep(float sec) 4623 { 4624 struct timespec req; 4625 req.tv_sec = floor(sec); 4626 req.tv_nsec = (sec - (float)req.tv_sec) * NANOSEC; 4627 (void) nanosleep(&req, NULL); 4628 } 4629 4630 /* 4631 * Set the minimum pool/vdev name column width. The width must be at least 10, 4632 * but may be as large as the column width - 42 so it still fits on one line. 4633 */ 4634 static int 4635 get_namewidth_iostat(zpool_handle_t *zhp, void *data) 4636 { 4637 iostat_cbdata_t *cb = data; 4638 int width, columns; 4639 4640 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 4641 cb->cb_verbose); 4642 columns = get_columns(); 4643 4644 if (width < 10) 4645 width = 10; 4646 if (width > columns - 42) 4647 width = columns - 42; 4648 4649 cb->cb_namewidth = width; 4650 4651 return (0); 4652 } 4653 4654 /* 4655 * zpool iostat [-ghHLpPvy] [[-lq]|[-r|-w]] [-n name] [-T d|u] 4656 * [[ pool ...]|[pool vdev ...]|[vdev ...]] 4657 * [interval [count]] 4658 * 4659 * -g Display guid for individual vdev name. 4660 * -L Follow links when resolving vdev path name. 4661 * -P Display full path for vdev name. 4662 * -v Display statistics for individual vdevs 4663 * -h Display help 4664 * -p Display values in parsable (exact) format. 4665 * -H Scripted mode. Don't display headers, and separate properties 4666 * by a single tab. 4667 * -l Display average latency 4668 * -q Display queue depths 4669 * -w Display latency histograms 4670 * -r Display request size histogram 4671 * -T Display a timestamp in date(1) or Unix format 4672 * -n Only print headers once 4673 * 4674 * This command can be tricky because we want to be able to deal with pool 4675 * creation/destruction as well as vdev configuration changes. The bulk of this 4676 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 4677 * on pool_list_update() to detect the addition of new pools. Configuration 4678 * changes are all handled within libzfs. 4679 */ 4680 int 4681 zpool_do_iostat(int argc, char **argv) 4682 { 4683 int c; 4684 int ret; 4685 int npools; 4686 float interval = 0; 4687 unsigned long count = 0; 4688 int winheight = 24; 4689 struct winsize win; 4690 zpool_list_t *list; 4691 boolean_t verbose = B_FALSE; 4692 boolean_t latency = B_FALSE, l_histo = B_FALSE, rq_histo = B_FALSE; 4693 boolean_t queues = B_FALSE, parseable = B_FALSE, scripted = B_FALSE; 4694 boolean_t omit_since_boot = B_FALSE; 4695 boolean_t guid = B_FALSE; 4696 boolean_t follow_links = B_FALSE; 4697 boolean_t full_name = B_FALSE; 4698 boolean_t headers_once = B_FALSE; 4699 iostat_cbdata_t cb = { 0 }; 4700 4701 /* Used for printing error message */ 4702 const char flag_to_arg[] = {[IOS_LATENCY] = 'l', [IOS_QUEUES] = 'q', 4703 [IOS_L_HISTO] = 'w', [IOS_RQ_HISTO] = 'r'}; 4704 4705 uint64_t unsupported_flags; 4706 4707 /* check options */ 4708 while ((c = getopt(argc, argv, "gLPT:vyhplqrwnH")) != -1) { 4709 switch (c) { 4710 case 'g': 4711 guid = B_TRUE; 4712 break; 4713 case 'L': 4714 follow_links = B_TRUE; 4715 break; 4716 case 'P': 4717 full_name = B_TRUE; 4718 break; 4719 case 'T': 4720 get_timestamp_arg(*optarg); 4721 break; 4722 case 'v': 4723 verbose = B_TRUE; 4724 break; 4725 case 'p': 4726 parseable = B_TRUE; 4727 break; 4728 case 'l': 4729 latency = B_TRUE; 4730 break; 4731 case 'q': 4732 queues = B_TRUE; 4733 break; 4734 case 'H': 4735 scripted = B_TRUE; 4736 break; 4737 case 'w': 4738 l_histo = B_TRUE; 4739 break; 4740 case 'r': 4741 rq_histo = B_TRUE; 4742 break; 4743 case 'y': 4744 omit_since_boot = B_TRUE; 4745 break; 4746 case 'n': 4747 headers_once = B_TRUE; 4748 break; 4749 case 'h': 4750 usage(B_FALSE); 4751 break; 4752 case '?': 4753 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 4754 optopt); 4755 usage(B_FALSE); 4756 } 4757 } 4758 4759 argc -= optind; 4760 argv += optind; 4761 4762 cb.cb_literal = parseable; 4763 cb.cb_scripted = scripted; 4764 4765 if (guid) 4766 cb.cb_name_flags |= VDEV_NAME_GUID; 4767 if (follow_links) 4768 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 4769 if (full_name) 4770 cb.cb_name_flags |= VDEV_NAME_PATH; 4771 cb.cb_iteration = 0; 4772 cb.cb_namewidth = 0; 4773 cb.cb_verbose = verbose; 4774 4775 /* Get our interval and count values (if any) */ 4776 if (guid) { 4777 get_interval_count_filter_guids(&argc, argv, &interval, 4778 &count, &cb); 4779 } else { 4780 get_interval_count(&argc, argv, &interval, &count); 4781 } 4782 4783 if (argc == 0) { 4784 /* No args, so just print the defaults. */ 4785 } else if (are_all_pools(argc, argv)) { 4786 /* All the args are pool names */ 4787 } else if (are_vdevs_in_pool(argc, argv, NULL, &cb)) { 4788 /* All the args are vdevs */ 4789 cb.cb_vdev_names = argv; 4790 cb.cb_vdev_names_count = argc; 4791 argc = 0; /* No pools to process */ 4792 } else if (are_all_pools(1, argv)) { 4793 /* The first arg is a pool name */ 4794 if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0], &cb)) { 4795 /* ...and the rest are vdev names */ 4796 cb.cb_vdev_names = argv + 1; 4797 cb.cb_vdev_names_count = argc - 1; 4798 argc = 1; /* One pool to process */ 4799 } else { 4800 fprintf(stderr, gettext("Expected either a list of ")); 4801 fprintf(stderr, gettext("pools, or list of vdevs in")); 4802 fprintf(stderr, " \"%s\", ", argv[0]); 4803 fprintf(stderr, gettext("but got:\n")); 4804 error_list_unresolved_vdevs(argc - 1, argv + 1, 4805 argv[0], &cb); 4806 fprintf(stderr, "\n"); 4807 usage(B_FALSE); 4808 return (1); 4809 } 4810 } else { 4811 /* 4812 * The args don't make sense. The first arg isn't a pool name, 4813 * nor are all the args vdevs. 4814 */ 4815 fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n")); 4816 fprintf(stderr, "\n"); 4817 return (1); 4818 } 4819 4820 if (cb.cb_vdev_names_count != 0) { 4821 /* 4822 * If user specified vdevs, it implies verbose. 4823 */ 4824 cb.cb_verbose = B_TRUE; 4825 } 4826 4827 /* 4828 * Construct the list of all interesting pools. 4829 */ 4830 ret = 0; 4831 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 4832 return (1); 4833 4834 if (pool_list_count(list) == 0 && argc != 0) { 4835 pool_list_free(list); 4836 return (1); 4837 } 4838 4839 if (pool_list_count(list) == 0 && interval == 0) { 4840 pool_list_free(list); 4841 (void) fprintf(stderr, gettext("no pools available\n")); 4842 return (1); 4843 } 4844 4845 if ((l_histo || rq_histo) && (queues || latency)) { 4846 pool_list_free(list); 4847 (void) fprintf(stderr, 4848 gettext("[-r|-w] isn't allowed with [-q|-l]\n")); 4849 usage(B_FALSE); 4850 return (1); 4851 } 4852 4853 if (l_histo && rq_histo) { 4854 pool_list_free(list); 4855 (void) fprintf(stderr, 4856 gettext("Only one of [-r|-w] can be passed at a time\n")); 4857 usage(B_FALSE); 4858 return (1); 4859 } 4860 4861 /* 4862 * Enter the main iostat loop. 4863 */ 4864 cb.cb_list = list; 4865 4866 if (l_histo) { 4867 /* 4868 * Histograms tables look out of place when you try to display 4869 * them with the other stats, so make a rule that you can only 4870 * print histograms by themselves. 4871 */ 4872 cb.cb_flags = IOS_L_HISTO_M; 4873 } else if (rq_histo) { 4874 cb.cb_flags = IOS_RQ_HISTO_M; 4875 } else { 4876 cb.cb_flags = IOS_DEFAULT_M; 4877 if (latency) 4878 cb.cb_flags |= IOS_LATENCY_M; 4879 if (queues) 4880 cb.cb_flags |= IOS_QUEUES_M; 4881 } 4882 4883 /* 4884 * See if the module supports all the stats we want to display. 4885 */ 4886 unsupported_flags = cb.cb_flags & ~get_stat_flags(list); 4887 if (unsupported_flags) { 4888 uint64_t f; 4889 int idx; 4890 fprintf(stderr, 4891 gettext("The loaded zfs module doesn't support:")); 4892 4893 /* for each bit set in unsupported_flags */ 4894 for (f = unsupported_flags; f; f &= ~(1ULL << idx)) { 4895 idx = lowbit64(f) - 1; 4896 fprintf(stderr, " -%c", flag_to_arg[idx]); 4897 } 4898 4899 fprintf(stderr, ". Try running a newer module.\n"), 4900 pool_list_free(list); 4901 4902 return (1); 4903 } 4904 4905 for (;;) { 4906 if ((npools = pool_list_count(list)) == 0) 4907 (void) fprintf(stderr, gettext("no pools available\n")); 4908 else { 4909 /* 4910 * If this is the first iteration and -y was supplied 4911 * we skip any printing. 4912 */ 4913 boolean_t skip = (omit_since_boot && 4914 cb.cb_iteration == 0); 4915 4916 /* 4917 * Refresh all statistics. This is done as an 4918 * explicit step before calculating the maximum name 4919 * width, so that any configuration changes are 4920 * properly accounted for. 4921 */ 4922 (void) pool_list_iter(list, B_FALSE, refresh_iostat, 4923 &cb); 4924 4925 /* 4926 * Iterate over all pools to determine the maximum width 4927 * for the pool / device name column across all pools. 4928 */ 4929 cb.cb_namewidth = 0; 4930 (void) pool_list_iter(list, B_FALSE, 4931 get_namewidth_iostat, &cb); 4932 4933 if (timestamp_fmt != NODATE) 4934 print_timestamp(timestamp_fmt); 4935 4936 /* 4937 * Check terminal size so we can print headers 4938 * even when terminal window has its height 4939 * changed. 4940 */ 4941 if (headers_once == B_FALSE) { 4942 if (ioctl(1, TIOCGWINSZ, &win) != -1) { 4943 if (win.ws_row <= 0) { 4944 headers_once = B_TRUE; 4945 } else { 4946 winheight = win.ws_row; 4947 } 4948 } 4949 } 4950 /* 4951 * Are we connected to TTY? If not, headers_once 4952 * should be true, to avoid breaking scripts. 4953 */ 4954 if (isatty(fileno(stdout)) == 0) 4955 headers_once = B_TRUE; 4956 4957 /* 4958 * If it's the first time and we're not skipping it, 4959 * or either skip or verbose mode, print the header. 4960 * 4961 * The histogram code explicitly prints its header on 4962 * every vdev, so skip this for histograms. 4963 */ 4964 if (((++cb.cb_iteration == 1 && !skip) || 4965 (skip != verbose) || 4966 (!headers_once && 4967 (cb.cb_iteration % winheight) == 0)) && 4968 (!(cb.cb_flags & IOS_ANYHISTO_M)) && 4969 !cb.cb_scripted) 4970 print_iostat_header(&cb); 4971 4972 if (skip) { 4973 (void) fsleep(interval); 4974 continue; 4975 } 4976 4977 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 4978 4979 /* 4980 * If there's more than one pool, and we're not in 4981 * verbose mode (which prints a separator for us), 4982 * then print a separator. 4983 * 4984 * In addition, if we're printing specific vdevs then 4985 * we also want an ending separator. 4986 */ 4987 if (((npools > 1 && !verbose && 4988 !(cb.cb_flags & IOS_ANYHISTO_M)) || 4989 (!(cb.cb_flags & IOS_ANYHISTO_M) && 4990 cb.cb_vdev_names_count)) && 4991 !cb.cb_scripted) { 4992 print_iostat_separator(&cb); 4993 printf("\n"); 4994 } 4995 } 4996 4997 /* 4998 * Flush the output so that redirection to a file isn't buffered 4999 * indefinitely. 5000 */ 5001 (void) fflush(stdout); 5002 5003 if (interval == 0) 5004 break; 5005 5006 if (count != 0 && --count == 0) 5007 break; 5008 5009 (void) fsleep(interval); 5010 } 5011 5012 pool_list_free(list); 5013 5014 return (ret); 5015 } 5016 5017 typedef struct list_cbdata { 5018 boolean_t cb_verbose; 5019 int cb_name_flags; 5020 int cb_namewidth; 5021 boolean_t cb_scripted; 5022 zprop_list_t *cb_proplist; 5023 boolean_t cb_literal; 5024 } list_cbdata_t; 5025 5026 5027 /* 5028 * Given a list of columns to display, output appropriate headers for each one. 5029 */ 5030 static void 5031 print_header(list_cbdata_t *cb) 5032 { 5033 zprop_list_t *pl = cb->cb_proplist; 5034 char headerbuf[ZPOOL_MAXPROPLEN]; 5035 const char *header; 5036 boolean_t first = B_TRUE; 5037 boolean_t right_justify; 5038 size_t width = 0; 5039 5040 for (; pl != NULL; pl = pl->pl_next) { 5041 width = pl->pl_width; 5042 if (first && cb->cb_verbose) { 5043 /* 5044 * Reset the width to accommodate the verbose listing 5045 * of devices. 5046 */ 5047 width = cb->cb_namewidth; 5048 } 5049 5050 if (!first) 5051 (void) printf(" "); 5052 else 5053 first = B_FALSE; 5054 5055 right_justify = B_FALSE; 5056 if (pl->pl_prop != ZPROP_INVAL) { 5057 header = zpool_prop_column_name(pl->pl_prop); 5058 right_justify = zpool_prop_align_right(pl->pl_prop); 5059 } else { 5060 int i; 5061 5062 for (i = 0; pl->pl_user_prop[i] != '\0'; i++) 5063 headerbuf[i] = toupper(pl->pl_user_prop[i]); 5064 headerbuf[i] = '\0'; 5065 header = headerbuf; 5066 } 5067 5068 if (pl->pl_next == NULL && !right_justify) 5069 (void) printf("%s", header); 5070 else if (right_justify) 5071 (void) printf("%*s", width, header); 5072 else 5073 (void) printf("%-*s", width, header); 5074 5075 } 5076 5077 (void) printf("\n"); 5078 } 5079 5080 /* 5081 * Given a pool and a list of properties, print out all the properties according 5082 * to the described layout. Used by zpool_do_list(). 5083 */ 5084 static void 5085 print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) 5086 { 5087 zprop_list_t *pl = cb->cb_proplist; 5088 boolean_t first = B_TRUE; 5089 char property[ZPOOL_MAXPROPLEN]; 5090 char *propstr; 5091 boolean_t right_justify; 5092 size_t width; 5093 5094 for (; pl != NULL; pl = pl->pl_next) { 5095 5096 width = pl->pl_width; 5097 if (first && cb->cb_verbose) { 5098 /* 5099 * Reset the width to accommodate the verbose listing 5100 * of devices. 5101 */ 5102 width = cb->cb_namewidth; 5103 } 5104 5105 if (!first) { 5106 if (cb->cb_scripted) 5107 (void) printf("\t"); 5108 else 5109 (void) printf(" "); 5110 } else { 5111 first = B_FALSE; 5112 } 5113 5114 right_justify = B_FALSE; 5115 if (pl->pl_prop != ZPROP_INVAL) { 5116 if (zpool_get_prop(zhp, pl->pl_prop, property, 5117 sizeof (property), NULL, cb->cb_literal) != 0) 5118 propstr = "-"; 5119 else 5120 propstr = property; 5121 5122 right_justify = zpool_prop_align_right(pl->pl_prop); 5123 } else if ((zpool_prop_feature(pl->pl_user_prop) || 5124 zpool_prop_unsupported(pl->pl_user_prop)) && 5125 zpool_prop_get_feature(zhp, pl->pl_user_prop, property, 5126 sizeof (property)) == 0) { 5127 propstr = property; 5128 } else { 5129 propstr = "-"; 5130 } 5131 5132 5133 /* 5134 * If this is being called in scripted mode, or if this is the 5135 * last column and it is left-justified, don't include a width 5136 * format specifier. 5137 */ 5138 if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify)) 5139 (void) printf("%s", propstr); 5140 else if (right_justify) 5141 (void) printf("%*s", width, propstr); 5142 else 5143 (void) printf("%-*s", width, propstr); 5144 } 5145 5146 (void) printf("\n"); 5147 } 5148 5149 static void 5150 print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted, 5151 boolean_t valid) 5152 { 5153 char propval[64]; 5154 boolean_t fixed; 5155 size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL); 5156 5157 switch (prop) { 5158 case ZPOOL_PROP_EXPANDSZ: 5159 case ZPOOL_PROP_CHECKPOINT: 5160 if (value == 0) 5161 (void) strlcpy(propval, "-", sizeof (propval)); 5162 else 5163 zfs_nicenum(value, propval, sizeof (propval)); 5164 break; 5165 case ZPOOL_PROP_FRAGMENTATION: 5166 if (value == ZFS_FRAG_INVALID) { 5167 (void) strlcpy(propval, "-", sizeof (propval)); 5168 } else { 5169 (void) snprintf(propval, sizeof (propval), "%llu%%", 5170 value); 5171 } 5172 break; 5173 case ZPOOL_PROP_CAPACITY: 5174 (void) snprintf(propval, sizeof (propval), 5175 value < 1000 ? "%1.2f%%" : value < 10000 ? 5176 "%2.1f%%" : "%3.0f%%", value / 100.0); 5177 break; 5178 default: 5179 zfs_nicenum(value, propval, sizeof (propval)); 5180 } 5181 5182 if (!valid) 5183 (void) strlcpy(propval, "-", sizeof (propval)); 5184 5185 if (scripted) 5186 (void) printf("\t%s", propval); 5187 else 5188 (void) printf(" %*s", width, propval); 5189 } 5190 5191 /* 5192 * print static default line per vdev 5193 */ 5194 void 5195 print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 5196 list_cbdata_t *cb, int depth) 5197 { 5198 nvlist_t **child; 5199 vdev_stat_t *vs; 5200 uint_t c, children; 5201 char *vname; 5202 boolean_t scripted = cb->cb_scripted; 5203 uint64_t islog = B_FALSE; 5204 char *dashes = "%-*s - - - - - -\n"; 5205 5206 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, 5207 (uint64_t **)&vs, &c) == 0); 5208 5209 if (name != NULL) { 5210 boolean_t toplevel = (vs->vs_space != 0); 5211 uint64_t cap; 5212 5213 if (strcmp(name, VDEV_TYPE_INDIRECT) == 0) 5214 return; 5215 5216 if (scripted) 5217 (void) printf("\t%s", name); 5218 else if (strlen(name) + depth > cb->cb_namewidth) 5219 (void) printf("%*s%s", depth, "", name); 5220 else 5221 (void) printf("%*s%s%*s", depth, "", name, 5222 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 5223 5224 /* 5225 * Print the properties for the individual vdevs. Some 5226 * properties are only applicable to toplevel vdevs. The 5227 * 'toplevel' boolean value is passed to the print_one_column() 5228 * to indicate that the value is valid. 5229 */ 5230 print_one_column(ZPOOL_PROP_SIZE, vs->vs_space, scripted, 5231 toplevel); 5232 print_one_column(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, scripted, 5233 toplevel); 5234 print_one_column(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc, 5235 scripted, toplevel); 5236 print_one_column(ZPOOL_PROP_CHECKPOINT, 5237 vs->vs_checkpoint_space, scripted, toplevel); 5238 print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, scripted, 5239 B_TRUE); 5240 print_one_column(ZPOOL_PROP_FRAGMENTATION, 5241 vs->vs_fragmentation, scripted, 5242 (vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel)); 5243 cap = (vs->vs_space == 0) ? 0 : 5244 (vs->vs_alloc * 10000 / vs->vs_space); 5245 print_one_column(ZPOOL_PROP_CAPACITY, cap, scripted, toplevel); 5246 (void) printf("\n"); 5247 } 5248 5249 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 5250 &child, &children) != 0) 5251 return; 5252 5253 /* list the normal vdevs first */ 5254 for (c = 0; c < children; c++) { 5255 uint64_t ishole = B_FALSE; 5256 5257 if (nvlist_lookup_uint64(child[c], 5258 ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole) 5259 continue; 5260 5261 if (nvlist_lookup_uint64(child[c], 5262 ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) 5263 continue; 5264 5265 if (nvlist_exists(child[c], ZPOOL_CONFIG_ALLOCATION_BIAS)) 5266 continue; 5267 5268 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5269 cb->cb_name_flags); 5270 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5271 free(vname); 5272 } 5273 5274 /* list the classes: 'logs', 'dedup', and 'special' */ 5275 for (uint_t n = 0; n < 3; n++) { 5276 boolean_t printed = B_FALSE; 5277 5278 for (c = 0; c < children; c++) { 5279 char *bias = NULL; 5280 char *type = NULL; 5281 5282 if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 5283 &islog) == 0 && islog) { 5284 bias = VDEV_ALLOC_CLASS_LOGS; 5285 } else { 5286 (void) nvlist_lookup_string(child[c], 5287 ZPOOL_CONFIG_ALLOCATION_BIAS, &bias); 5288 (void) nvlist_lookup_string(child[c], 5289 ZPOOL_CONFIG_TYPE, &type); 5290 } 5291 if (bias == NULL || strcmp(bias, class_name[n]) != 0) 5292 continue; 5293 if (!islog && strcmp(type, VDEV_TYPE_INDIRECT) == 0) 5294 continue; 5295 5296 if (!printed) { 5297 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5298 (void) printf(dashes, cb->cb_namewidth, 5299 class_name[n]); 5300 printed = B_TRUE; 5301 } 5302 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5303 cb->cb_name_flags); 5304 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5305 free(vname); 5306 } 5307 } 5308 5309 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 5310 &child, &children) == 0 && children > 0) { 5311 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5312 (void) printf(dashes, cb->cb_namewidth, "cache"); 5313 for (c = 0; c < children; c++) { 5314 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5315 cb->cb_name_flags); 5316 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5317 free(vname); 5318 } 5319 } 5320 5321 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child, 5322 &children) == 0 && children > 0) { 5323 /* LINTED E_SEC_PRINTF_VAR_FMT */ 5324 (void) printf(dashes, cb->cb_namewidth, "spare"); 5325 for (c = 0; c < children; c++) { 5326 vname = zpool_vdev_name(g_zfs, zhp, child[c], 5327 cb->cb_name_flags); 5328 print_list_stats(zhp, vname, child[c], cb, depth + 2); 5329 free(vname); 5330 } 5331 } 5332 } 5333 5334 /* 5335 * Generic callback function to list a pool. 5336 */ 5337 int 5338 list_callback(zpool_handle_t *zhp, void *data) 5339 { 5340 list_cbdata_t *cbp = data; 5341 nvlist_t *config; 5342 nvlist_t *nvroot; 5343 5344 config = zpool_get_config(zhp, NULL); 5345 5346 if (cbp->cb_verbose) { 5347 config = zpool_get_config(zhp, NULL); 5348 5349 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 5350 &nvroot) == 0); 5351 } 5352 5353 if (cbp->cb_verbose) 5354 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 5355 cbp->cb_name_flags); 5356 5357 print_pool(zhp, cbp); 5358 5359 if (cbp->cb_verbose) 5360 print_list_stats(zhp, NULL, nvroot, cbp, 0); 5361 5362 return (0); 5363 } 5364 5365 /* 5366 * Set the minimum pool/vdev name column width. The width must be at least 9, 5367 * but may be as large as needed. 5368 */ 5369 static int 5370 get_namewidth_list(zpool_handle_t *zhp, void *data) 5371 { 5372 list_cbdata_t *cb = data; 5373 int width; 5374 5375 width = get_namewidth(zhp, cb->cb_namewidth, cb->cb_name_flags, 5376 cb->cb_verbose); 5377 5378 if (width < 9) 5379 width = 9; 5380 5381 cb->cb_namewidth = width; 5382 5383 return (0); 5384 } 5385 5386 /* 5387 * zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] 5388 * 5389 * -g Display guid for individual vdev name. 5390 * -H Scripted mode. Don't display headers, and separate properties 5391 * by a single tab. 5392 * -L Follow links when resolving vdev path name. 5393 * -o List of properties to display. Defaults to 5394 * "name,size,allocated,free,expandsize,fragmentation,capacity," 5395 * "dedupratio,health,altroot" 5396 * -p Diplay values in parsable (exact) format. 5397 * -P Display full path for vdev name. 5398 * -T Display a timestamp in date(1) or Unix format 5399 * 5400 * List all pools in the system, whether or not they're healthy. Output space 5401 * statistics for each one, as well as health status summary. 5402 */ 5403 int 5404 zpool_do_list(int argc, char **argv) 5405 { 5406 int c; 5407 int ret; 5408 list_cbdata_t cb = { 0 }; 5409 static char default_props[] = 5410 "name,size,allocated,free,checkpoint,expandsize,fragmentation," 5411 "capacity,dedupratio,health,altroot"; 5412 char *props = default_props; 5413 float interval = 0; 5414 unsigned long count = 0; 5415 zpool_list_t *list; 5416 boolean_t first = B_TRUE; 5417 5418 /* check options */ 5419 while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) { 5420 switch (c) { 5421 case 'g': 5422 cb.cb_name_flags |= VDEV_NAME_GUID; 5423 break; 5424 case 'H': 5425 cb.cb_scripted = B_TRUE; 5426 break; 5427 case 'L': 5428 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 5429 break; 5430 case 'o': 5431 props = optarg; 5432 break; 5433 case 'P': 5434 cb.cb_name_flags |= VDEV_NAME_PATH; 5435 break; 5436 case 'p': 5437 cb.cb_literal = B_TRUE; 5438 break; 5439 case 'T': 5440 get_timestamp_arg(*optarg); 5441 break; 5442 case 'v': 5443 cb.cb_verbose = B_TRUE; 5444 cb.cb_namewidth = 8; /* 8 until precalc is avail */ 5445 break; 5446 case ':': 5447 (void) fprintf(stderr, gettext("missing argument for " 5448 "'%c' option\n"), optopt); 5449 usage(B_FALSE); 5450 break; 5451 case '?': 5452 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5453 optopt); 5454 usage(B_FALSE); 5455 } 5456 } 5457 5458 argc -= optind; 5459 argv += optind; 5460 5461 get_interval_count(&argc, argv, &interval, &count); 5462 5463 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 5464 usage(B_FALSE); 5465 5466 for (;;) { 5467 if ((list = pool_list_get(argc, argv, &cb.cb_proplist, 5468 &ret)) == NULL) 5469 return (1); 5470 5471 if (pool_list_count(list) == 0) 5472 break; 5473 5474 cb.cb_namewidth = 0; 5475 (void) pool_list_iter(list, B_FALSE, get_namewidth_list, &cb); 5476 5477 if (timestamp_fmt != NODATE) 5478 print_timestamp(timestamp_fmt); 5479 5480 if (!cb.cb_scripted && (first || cb.cb_verbose)) { 5481 print_header(&cb); 5482 first = B_FALSE; 5483 } 5484 ret = pool_list_iter(list, B_TRUE, list_callback, &cb); 5485 5486 if (interval == 0) 5487 break; 5488 5489 if (count != 0 && --count == 0) 5490 break; 5491 5492 pool_list_free(list); 5493 (void) fsleep(interval); 5494 } 5495 5496 if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) { 5497 (void) printf(gettext("no pools available\n")); 5498 ret = 0; 5499 } 5500 5501 pool_list_free(list); 5502 zprop_free_list(cb.cb_proplist); 5503 return (ret); 5504 } 5505 5506 static int 5507 zpool_do_attach_or_replace(int argc, char **argv, int replacing) 5508 { 5509 boolean_t force = B_FALSE; 5510 int c; 5511 nvlist_t *nvroot; 5512 char *poolname, *old_disk, *new_disk; 5513 zpool_handle_t *zhp; 5514 zpool_boot_label_t boot_type; 5515 uint64_t boot_size; 5516 nvlist_t *props = NULL; 5517 char *propval; 5518 int ret; 5519 5520 /* check options */ 5521 while ((c = getopt(argc, argv, "fo:")) != -1) { 5522 switch (c) { 5523 case 'f': 5524 force = B_TRUE; 5525 break; 5526 case 'o': 5527 if ((propval = strchr(optarg, '=')) == NULL) { 5528 (void) fprintf(stderr, gettext("missing " 5529 "'=' for -o option\n")); 5530 usage(B_FALSE); 5531 } 5532 *propval = '\0'; 5533 propval++; 5534 5535 if ((strcmp(optarg, ZPOOL_CONFIG_ASHIFT) != 0) || 5536 (add_prop_list(optarg, propval, &props, B_TRUE))) 5537 usage(B_FALSE); 5538 break; 5539 case '?': 5540 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5541 optopt); 5542 usage(B_FALSE); 5543 } 5544 } 5545 5546 argc -= optind; 5547 argv += optind; 5548 5549 /* get pool name and check number of arguments */ 5550 if (argc < 1) { 5551 (void) fprintf(stderr, gettext("missing pool name argument\n")); 5552 usage(B_FALSE); 5553 } 5554 5555 poolname = argv[0]; 5556 5557 if (argc < 2) { 5558 (void) fprintf(stderr, 5559 gettext("missing <device> specification\n")); 5560 usage(B_FALSE); 5561 } 5562 5563 old_disk = argv[1]; 5564 5565 if (argc < 3) { 5566 if (!replacing) { 5567 (void) fprintf(stderr, 5568 gettext("missing <new_device> specification\n")); 5569 usage(B_FALSE); 5570 } 5571 new_disk = old_disk; 5572 argc -= 1; 5573 argv += 1; 5574 } else { 5575 new_disk = argv[2]; 5576 argc -= 2; 5577 argv += 2; 5578 } 5579 5580 if (argc > 1) { 5581 (void) fprintf(stderr, gettext("too many arguments\n")); 5582 usage(B_FALSE); 5583 } 5584 5585 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5586 return (1); 5587 5588 if (zpool_get_config(zhp, NULL) == NULL) { 5589 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 5590 poolname); 5591 zpool_close(zhp); 5592 return (1); 5593 } 5594 5595 if (zpool_is_bootable(zhp)) 5596 boot_type = ZPOOL_COPY_BOOT_LABEL; 5597 else 5598 boot_type = ZPOOL_NO_BOOT_LABEL; 5599 5600 boot_size = zpool_get_prop_int(zhp, ZPOOL_PROP_BOOTSIZE, NULL); 5601 5602 /* unless manually specified use "ashift" pool property (if set) */ 5603 if (!nvlist_exists(props, ZPOOL_CONFIG_ASHIFT)) { 5604 int intval; 5605 zprop_source_t src; 5606 char strval[ZPOOL_MAXPROPLEN]; 5607 5608 intval = zpool_get_prop_int(zhp, ZPOOL_PROP_ASHIFT, &src); 5609 if (src != ZPROP_SRC_DEFAULT) { 5610 (void) sprintf(strval, "%" PRId32, intval); 5611 verify(add_prop_list(ZPOOL_CONFIG_ASHIFT, strval, 5612 &props, B_TRUE) == 0); 5613 } 5614 } 5615 5616 nvroot = make_root_vdev(zhp, props, force, B_FALSE, replacing, B_FALSE, 5617 boot_type, boot_size, argc, argv); 5618 if (nvroot == NULL) { 5619 zpool_close(zhp); 5620 return (1); 5621 } 5622 5623 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 5624 5625 nvlist_free(nvroot); 5626 zpool_close(zhp); 5627 5628 return (ret); 5629 } 5630 5631 /* 5632 * zpool replace [-f] <pool> <device> <new_device> 5633 * 5634 * -f Force attach, even if <new_device> appears to be in use. 5635 * 5636 * Replace <device> with <new_device>. 5637 */ 5638 /* ARGSUSED */ 5639 int 5640 zpool_do_replace(int argc, char **argv) 5641 { 5642 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 5643 } 5644 5645 /* 5646 * zpool attach [-f] [-o property=value] <pool> <device> <new_device> 5647 * 5648 * -f Force attach, even if <new_device> appears to be in use. 5649 * -o Set property=value. 5650 * 5651 * Attach <new_device> to the mirror containing <device>. If <device> is not 5652 * part of a mirror, then <device> will be transformed into a mirror of 5653 * <device> and <new_device>. In either case, <new_device> will begin life 5654 * with a DTL of [0, now], and will immediately begin to resilver itself. 5655 */ 5656 int 5657 zpool_do_attach(int argc, char **argv) 5658 { 5659 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 5660 } 5661 5662 /* 5663 * zpool detach [-f] <pool> <device> 5664 * 5665 * -f Force detach of <device>, even if DTLs argue against it 5666 * (not supported yet) 5667 * 5668 * Detach a device from a mirror. The operation will be refused if <device> 5669 * is the last device in the mirror, or if the DTLs indicate that this device 5670 * has the only valid copy of some data. 5671 */ 5672 /* ARGSUSED */ 5673 int 5674 zpool_do_detach(int argc, char **argv) 5675 { 5676 int c; 5677 char *poolname, *path; 5678 zpool_handle_t *zhp; 5679 int ret; 5680 5681 /* check options */ 5682 while ((c = getopt(argc, argv, "f")) != -1) { 5683 switch (c) { 5684 case 'f': 5685 case '?': 5686 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5687 optopt); 5688 usage(B_FALSE); 5689 } 5690 } 5691 5692 argc -= optind; 5693 argv += optind; 5694 5695 /* get pool name and check number of arguments */ 5696 if (argc < 1) { 5697 (void) fprintf(stderr, gettext("missing pool name argument\n")); 5698 usage(B_FALSE); 5699 } 5700 5701 if (argc < 2) { 5702 (void) fprintf(stderr, 5703 gettext("missing <device> specification\n")); 5704 usage(B_FALSE); 5705 } 5706 5707 poolname = argv[0]; 5708 path = argv[1]; 5709 5710 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5711 return (1); 5712 5713 ret = zpool_vdev_detach(zhp, path); 5714 5715 zpool_close(zhp); 5716 5717 return (ret); 5718 } 5719 5720 /* 5721 * zpool split [-gLnP] [-o prop=val] ... 5722 * [-o mntopt] ... 5723 * [-R altroot] <pool> <newpool> [<device> ...] 5724 * 5725 * -g Display guid for individual vdev name. 5726 * -L Follow links when resolving vdev path name. 5727 * -n Do not split the pool, but display the resulting layout if 5728 * it were to be split. 5729 * -o Set property=value, or set mount options. 5730 * -P Display full path for vdev name. 5731 * -R Mount the split-off pool under an alternate root. 5732 * -l Load encryption keys while importing. 5733 * 5734 * Splits the named pool and gives it the new pool name. Devices to be split 5735 * off may be listed, provided that no more than one device is specified 5736 * per top-level vdev mirror. The newly split pool is left in an exported 5737 * state unless -R is specified. 5738 * 5739 * Restrictions: the top-level of the pool pool must only be made up of 5740 * mirrors; all devices in the pool must be healthy; no device may be 5741 * undergoing a resilvering operation. 5742 */ 5743 int 5744 zpool_do_split(int argc, char **argv) 5745 { 5746 char *srcpool, *newpool, *propval; 5747 char *mntopts = NULL; 5748 splitflags_t flags; 5749 int c, ret = 0; 5750 boolean_t loadkeys = B_FALSE; 5751 zpool_handle_t *zhp; 5752 nvlist_t *config, *props = NULL; 5753 5754 flags.dryrun = B_FALSE; 5755 flags.import = B_FALSE; 5756 flags.name_flags = 0; 5757 5758 /* check options */ 5759 while ((c = getopt(argc, argv, ":gLR:lno:P")) != -1) { 5760 switch (c) { 5761 case 'g': 5762 flags.name_flags |= VDEV_NAME_GUID; 5763 break; 5764 case 'L': 5765 flags.name_flags |= VDEV_NAME_FOLLOW_LINKS; 5766 break; 5767 case 'R': 5768 flags.import = B_TRUE; 5769 if (add_prop_list( 5770 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), optarg, 5771 &props, B_TRUE) != 0) { 5772 nvlist_free(props); 5773 usage(B_FALSE); 5774 } 5775 break; 5776 case 'l': 5777 loadkeys = B_TRUE; 5778 break; 5779 case 'n': 5780 flags.dryrun = B_TRUE; 5781 break; 5782 case 'o': 5783 if ((propval = strchr(optarg, '=')) != NULL) { 5784 *propval = '\0'; 5785 propval++; 5786 if (add_prop_list(optarg, propval, 5787 &props, B_TRUE) != 0) { 5788 nvlist_free(props); 5789 usage(B_FALSE); 5790 } 5791 } else { 5792 mntopts = optarg; 5793 } 5794 break; 5795 case 'P': 5796 flags.name_flags |= VDEV_NAME_PATH; 5797 break; 5798 case ':': 5799 (void) fprintf(stderr, gettext("missing argument for " 5800 "'%c' option\n"), optopt); 5801 usage(B_FALSE); 5802 break; 5803 case '?': 5804 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5805 optopt); 5806 usage(B_FALSE); 5807 break; 5808 } 5809 } 5810 5811 if (!flags.import && mntopts != NULL) { 5812 (void) fprintf(stderr, gettext("setting mntopts is only " 5813 "valid when importing the pool\n")); 5814 usage(B_FALSE); 5815 } 5816 5817 if (!flags.import && loadkeys) { 5818 (void) fprintf(stderr, gettext("loading keys is only " 5819 "valid when importing the pool\n")); 5820 usage(B_FALSE); 5821 } 5822 5823 argc -= optind; 5824 argv += optind; 5825 5826 if (argc < 1) { 5827 (void) fprintf(stderr, gettext("Missing pool name\n")); 5828 usage(B_FALSE); 5829 } 5830 if (argc < 2) { 5831 (void) fprintf(stderr, gettext("Missing new pool name\n")); 5832 usage(B_FALSE); 5833 } 5834 5835 srcpool = argv[0]; 5836 newpool = argv[1]; 5837 5838 argc -= 2; 5839 argv += 2; 5840 5841 if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) 5842 return (1); 5843 5844 config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv); 5845 if (config == NULL) { 5846 ret = 1; 5847 } else { 5848 if (flags.dryrun) { 5849 (void) printf(gettext("would create '%s' with the " 5850 "following layout:\n\n"), newpool); 5851 print_vdev_tree(NULL, newpool, config, 0, "", 5852 flags.name_flags); 5853 } 5854 nvlist_free(config); 5855 } 5856 5857 zpool_close(zhp); 5858 5859 if (ret != 0 || flags.dryrun || !flags.import) 5860 return (ret); 5861 5862 /* 5863 * The split was successful. Now we need to open the new 5864 * pool and import it. 5865 */ 5866 if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) 5867 return (1); 5868 5869 if (loadkeys) { 5870 ret = zfs_crypto_attempt_load_keys(g_zfs, newpool); 5871 if (ret != 0) 5872 ret = 1; 5873 } 5874 5875 if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL && 5876 zpool_enable_datasets(zhp, mntopts, 0) != 0) { 5877 ret = 1; 5878 (void) fprintf(stderr, gettext("Split was successful, but " 5879 "the datasets could not all be mounted\n")); 5880 (void) fprintf(stderr, gettext("Try doing '%s' with a " 5881 "different altroot\n"), "zpool import"); 5882 } 5883 zpool_close(zhp); 5884 5885 return (ret); 5886 } 5887 5888 5889 5890 /* 5891 * zpool online <pool> <device> ... 5892 */ 5893 int 5894 zpool_do_online(int argc, char **argv) 5895 { 5896 int c, i; 5897 char *poolname; 5898 zpool_handle_t *zhp; 5899 int ret = 0; 5900 vdev_state_t newstate; 5901 int flags = 0; 5902 5903 /* check options */ 5904 while ((c = getopt(argc, argv, "et")) != -1) { 5905 switch (c) { 5906 case 'e': 5907 flags |= ZFS_ONLINE_EXPAND; 5908 break; 5909 case 't': 5910 case '?': 5911 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5912 optopt); 5913 usage(B_FALSE); 5914 } 5915 } 5916 5917 argc -= optind; 5918 argv += optind; 5919 5920 /* get pool name and check number of arguments */ 5921 if (argc < 1) { 5922 (void) fprintf(stderr, gettext("missing pool name\n")); 5923 usage(B_FALSE); 5924 } 5925 if (argc < 2) { 5926 (void) fprintf(stderr, gettext("missing device name\n")); 5927 usage(B_FALSE); 5928 } 5929 5930 poolname = argv[0]; 5931 5932 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 5933 return (1); 5934 5935 for (i = 1; i < argc; i++) { 5936 if (zpool_vdev_online(zhp, argv[i], flags, &newstate) == 0) { 5937 if (newstate != VDEV_STATE_HEALTHY) { 5938 (void) printf(gettext("warning: device '%s' " 5939 "onlined, but remains in faulted state\n"), 5940 argv[i]); 5941 if (newstate == VDEV_STATE_FAULTED) 5942 (void) printf(gettext("use 'zpool " 5943 "clear' to restore a faulted " 5944 "device\n")); 5945 else 5946 (void) printf(gettext("use 'zpool " 5947 "replace' to replace devices " 5948 "that are no longer present\n")); 5949 } 5950 } else { 5951 ret = 1; 5952 } 5953 } 5954 5955 zpool_close(zhp); 5956 5957 return (ret); 5958 } 5959 5960 /* 5961 * zpool offline [-ft] <pool> <device> ... 5962 * 5963 * -f Force the device into the offline state, even if doing 5964 * so would appear to compromise pool availability. 5965 * (not supported yet) 5966 * 5967 * -t Only take the device off-line temporarily. The offline 5968 * state will not be persistent across reboots. 5969 */ 5970 /* ARGSUSED */ 5971 int 5972 zpool_do_offline(int argc, char **argv) 5973 { 5974 int c, i; 5975 char *poolname; 5976 zpool_handle_t *zhp; 5977 int ret = 0; 5978 boolean_t istmp = B_FALSE; 5979 5980 /* check options */ 5981 while ((c = getopt(argc, argv, "ft")) != -1) { 5982 switch (c) { 5983 case 't': 5984 istmp = B_TRUE; 5985 break; 5986 case 'f': 5987 case '?': 5988 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 5989 optopt); 5990 usage(B_FALSE); 5991 } 5992 } 5993 5994 argc -= optind; 5995 argv += optind; 5996 5997 /* get pool name and check number of arguments */ 5998 if (argc < 1) { 5999 (void) fprintf(stderr, gettext("missing pool name\n")); 6000 usage(B_FALSE); 6001 } 6002 if (argc < 2) { 6003 (void) fprintf(stderr, gettext("missing device name\n")); 6004 usage(B_FALSE); 6005 } 6006 6007 poolname = argv[0]; 6008 6009 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6010 return (1); 6011 6012 for (i = 1; i < argc; i++) { 6013 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 6014 ret = 1; 6015 } 6016 6017 zpool_close(zhp); 6018 6019 return (ret); 6020 } 6021 6022 /* 6023 * zpool clear <pool> [device] 6024 * 6025 * Clear all errors associated with a pool or a particular device. 6026 */ 6027 int 6028 zpool_do_clear(int argc, char **argv) 6029 { 6030 int c; 6031 int ret = 0; 6032 boolean_t dryrun = B_FALSE; 6033 boolean_t do_rewind = B_FALSE; 6034 boolean_t xtreme_rewind = B_FALSE; 6035 uint32_t rewind_policy = ZPOOL_NO_REWIND; 6036 nvlist_t *policy = NULL; 6037 zpool_handle_t *zhp; 6038 char *pool, *device; 6039 6040 /* check options */ 6041 while ((c = getopt(argc, argv, "FnX")) != -1) { 6042 switch (c) { 6043 case 'F': 6044 do_rewind = B_TRUE; 6045 break; 6046 case 'n': 6047 dryrun = B_TRUE; 6048 break; 6049 case 'X': 6050 xtreme_rewind = B_TRUE; 6051 break; 6052 case '?': 6053 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6054 optopt); 6055 usage(B_FALSE); 6056 } 6057 } 6058 6059 argc -= optind; 6060 argv += optind; 6061 6062 if (argc < 1) { 6063 (void) fprintf(stderr, gettext("missing pool name\n")); 6064 usage(B_FALSE); 6065 } 6066 6067 if (argc > 2) { 6068 (void) fprintf(stderr, gettext("too many arguments\n")); 6069 usage(B_FALSE); 6070 } 6071 6072 if ((dryrun || xtreme_rewind) && !do_rewind) { 6073 (void) fprintf(stderr, 6074 gettext("-n or -X only meaningful with -F\n")); 6075 usage(B_FALSE); 6076 } 6077 if (dryrun) 6078 rewind_policy = ZPOOL_TRY_REWIND; 6079 else if (do_rewind) 6080 rewind_policy = ZPOOL_DO_REWIND; 6081 if (xtreme_rewind) 6082 rewind_policy |= ZPOOL_EXTREME_REWIND; 6083 6084 /* In future, further rewind policy choices can be passed along here */ 6085 if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || 6086 nvlist_add_uint32(policy, ZPOOL_LOAD_REWIND_POLICY, 6087 rewind_policy) != 0) { 6088 return (1); 6089 } 6090 6091 pool = argv[0]; 6092 device = argc == 2 ? argv[1] : NULL; 6093 6094 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 6095 nvlist_free(policy); 6096 return (1); 6097 } 6098 6099 if (zpool_clear(zhp, device, policy) != 0) 6100 ret = 1; 6101 6102 zpool_close(zhp); 6103 6104 nvlist_free(policy); 6105 6106 return (ret); 6107 } 6108 6109 /* 6110 * zpool reguid <pool> 6111 */ 6112 int 6113 zpool_do_reguid(int argc, char **argv) 6114 { 6115 int c; 6116 char *poolname; 6117 zpool_handle_t *zhp; 6118 int ret = 0; 6119 6120 /* check options */ 6121 while ((c = getopt(argc, argv, "")) != -1) { 6122 switch (c) { 6123 case '?': 6124 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6125 optopt); 6126 usage(B_FALSE); 6127 } 6128 } 6129 6130 argc -= optind; 6131 argv += optind; 6132 6133 /* get pool name and check number of arguments */ 6134 if (argc < 1) { 6135 (void) fprintf(stderr, gettext("missing pool name\n")); 6136 usage(B_FALSE); 6137 } 6138 6139 if (argc > 1) { 6140 (void) fprintf(stderr, gettext("too many arguments\n")); 6141 usage(B_FALSE); 6142 } 6143 6144 poolname = argv[0]; 6145 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 6146 return (1); 6147 6148 ret = zpool_reguid(zhp); 6149 6150 zpool_close(zhp); 6151 return (ret); 6152 } 6153 6154 6155 /* 6156 * zpool reopen <pool> 6157 * 6158 * Reopen the pool so that the kernel can update the sizes of all vdevs. 6159 */ 6160 int 6161 zpool_do_reopen(int argc, char **argv) 6162 { 6163 int c; 6164 int ret = 0; 6165 zpool_handle_t *zhp; 6166 char *pool; 6167 6168 /* check options */ 6169 while ((c = getopt(argc, argv, "")) != -1) { 6170 switch (c) { 6171 case '?': 6172 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6173 optopt); 6174 usage(B_FALSE); 6175 } 6176 } 6177 6178 argc--; 6179 argv++; 6180 6181 if (argc < 1) { 6182 (void) fprintf(stderr, gettext("missing pool name\n")); 6183 usage(B_FALSE); 6184 } 6185 6186 if (argc > 1) { 6187 (void) fprintf(stderr, gettext("too many arguments\n")); 6188 usage(B_FALSE); 6189 } 6190 6191 pool = argv[0]; 6192 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 6193 return (1); 6194 6195 ret = zpool_reopen(zhp); 6196 zpool_close(zhp); 6197 return (ret); 6198 } 6199 6200 typedef struct scrub_cbdata { 6201 int cb_type; 6202 int cb_argc; 6203 char **cb_argv; 6204 pool_scrub_cmd_t cb_scrub_cmd; 6205 } scrub_cbdata_t; 6206 6207 static boolean_t 6208 zpool_has_checkpoint(zpool_handle_t *zhp) 6209 { 6210 nvlist_t *config, *nvroot; 6211 6212 config = zpool_get_config(zhp, NULL); 6213 6214 if (config != NULL) { 6215 pool_checkpoint_stat_t *pcs = NULL; 6216 uint_t c; 6217 6218 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 6219 (void) nvlist_lookup_uint64_array(nvroot, 6220 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 6221 6222 if (pcs == NULL || pcs->pcs_state == CS_NONE) 6223 return (B_FALSE); 6224 6225 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS || 6226 pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 6227 return (B_TRUE); 6228 } 6229 6230 return (B_FALSE); 6231 } 6232 6233 int 6234 scrub_callback(zpool_handle_t *zhp, void *data) 6235 { 6236 scrub_cbdata_t *cb = data; 6237 int err; 6238 6239 /* 6240 * Ignore faulted pools. 6241 */ 6242 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 6243 (void) fprintf(stderr, gettext("cannot scan '%s': pool is " 6244 "currently unavailable\n"), zpool_get_name(zhp)); 6245 return (1); 6246 } 6247 6248 err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd); 6249 6250 if (err == 0 && zpool_has_checkpoint(zhp) && 6251 cb->cb_type == POOL_SCAN_SCRUB) { 6252 (void) printf(gettext("warning: will not scrub state that " 6253 "belongs to the checkpoint of pool '%s'\n"), 6254 zpool_get_name(zhp)); 6255 } 6256 6257 return (err != 0); 6258 } 6259 6260 /* 6261 * zpool scrub [-s | -p] <pool> ... 6262 * 6263 * -s Stop. Stops any in-progress scrub. 6264 * -p Pause. Pause in-progress scrub. 6265 */ 6266 int 6267 zpool_do_scrub(int argc, char **argv) 6268 { 6269 int c; 6270 scrub_cbdata_t cb; 6271 6272 cb.cb_type = POOL_SCAN_SCRUB; 6273 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 6274 6275 /* check options */ 6276 while ((c = getopt(argc, argv, "sp")) != -1) { 6277 switch (c) { 6278 case 's': 6279 cb.cb_type = POOL_SCAN_NONE; 6280 break; 6281 case 'p': 6282 cb.cb_scrub_cmd = POOL_SCRUB_PAUSE; 6283 break; 6284 case '?': 6285 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6286 optopt); 6287 usage(B_FALSE); 6288 } 6289 } 6290 6291 if (cb.cb_type == POOL_SCAN_NONE && 6292 cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) { 6293 (void) fprintf(stderr, gettext("invalid option combination: " 6294 "-s and -p are mutually exclusive\n")); 6295 usage(B_FALSE); 6296 } 6297 6298 cb.cb_argc = argc; 6299 cb.cb_argv = argv; 6300 argc -= optind; 6301 argv += optind; 6302 6303 if (argc < 1) { 6304 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6305 usage(B_FALSE); 6306 } 6307 6308 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 6309 } 6310 6311 /* 6312 * zpool resilver <pool> ... 6313 * 6314 * Restarts any in-progress resilver 6315 */ 6316 int 6317 zpool_do_resilver(int argc, char **argv) 6318 { 6319 int c; 6320 scrub_cbdata_t cb; 6321 6322 cb.cb_type = POOL_SCAN_RESILVER; 6323 cb.cb_scrub_cmd = POOL_SCRUB_NORMAL; 6324 cb.cb_argc = argc; 6325 cb.cb_argv = argv; 6326 6327 /* check options */ 6328 while ((c = getopt(argc, argv, "")) != -1) { 6329 switch (c) { 6330 case '?': 6331 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 6332 optopt); 6333 usage(B_FALSE); 6334 } 6335 } 6336 6337 argc -= optind; 6338 argv += optind; 6339 6340 if (argc < 1) { 6341 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6342 usage(B_FALSE); 6343 } 6344 6345 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 6346 } 6347 6348 /* 6349 * zpool trim [-d] [-r <rate>] [-c | -s] <pool> [<device> ...] 6350 * 6351 * -c Cancel. Ends any in-progress trim. 6352 * -d Secure trim. Requires kernel and device support. 6353 * -r <rate> Sets the TRIM rate in bytes (per second). Supports 6354 * adding a multiplier suffix such as 'k' or 'm'. 6355 * -s Suspend. TRIM can then be restarted with no flags. 6356 */ 6357 int 6358 zpool_do_trim(int argc, char **argv) 6359 { 6360 struct option long_options[] = { 6361 {"cancel", no_argument, NULL, 'c'}, 6362 {"secure", no_argument, NULL, 'd'}, 6363 {"rate", required_argument, NULL, 'r'}, 6364 {"suspend", no_argument, NULL, 's'}, 6365 {0, 0, 0, 0} 6366 }; 6367 6368 pool_trim_func_t cmd_type = POOL_TRIM_START; 6369 uint64_t rate = 0; 6370 boolean_t secure = B_FALSE; 6371 6372 int c; 6373 while ((c = getopt_long(argc, argv, "cdr:s", long_options, NULL)) 6374 != -1) { 6375 switch (c) { 6376 case 'c': 6377 if (cmd_type != POOL_TRIM_START && 6378 cmd_type != POOL_TRIM_CANCEL) { 6379 (void) fprintf(stderr, gettext("-c cannot be " 6380 "combined with other options\n")); 6381 usage(B_FALSE); 6382 } 6383 cmd_type = POOL_TRIM_CANCEL; 6384 break; 6385 case 'd': 6386 if (cmd_type != POOL_TRIM_START) { 6387 (void) fprintf(stderr, gettext("-d cannot be " 6388 "combined with the -c or -s options\n")); 6389 usage(B_FALSE); 6390 } 6391 secure = B_TRUE; 6392 break; 6393 case 'r': 6394 if (cmd_type != POOL_TRIM_START) { 6395 (void) fprintf(stderr, gettext("-r cannot be " 6396 "combined with the -c or -s options\n")); 6397 usage(B_FALSE); 6398 } 6399 if (zfs_nicestrtonum(NULL, optarg, &rate) == -1) { 6400 (void) fprintf(stderr, 6401 gettext("invalid value for rate\n")); 6402 usage(B_FALSE); 6403 } 6404 break; 6405 case 's': 6406 if (cmd_type != POOL_TRIM_START && 6407 cmd_type != POOL_TRIM_SUSPEND) { 6408 (void) fprintf(stderr, gettext("-s cannot be " 6409 "combined with other options\n")); 6410 usage(B_FALSE); 6411 } 6412 cmd_type = POOL_TRIM_SUSPEND; 6413 break; 6414 case '?': 6415 if (optopt != 0) { 6416 (void) fprintf(stderr, 6417 gettext("invalid option '%c'\n"), optopt); 6418 } else { 6419 (void) fprintf(stderr, 6420 gettext("invalid option '%s'\n"), 6421 argv[optind - 1]); 6422 } 6423 usage(B_FALSE); 6424 } 6425 } 6426 6427 argc -= optind; 6428 argv += optind; 6429 6430 if (argc < 1) { 6431 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6432 usage(B_FALSE); 6433 return (-1); 6434 } 6435 6436 char *poolname = argv[0]; 6437 zpool_handle_t *zhp = zpool_open(g_zfs, poolname); 6438 if (zhp == NULL) 6439 return (-1); 6440 6441 trimflags_t trim_flags = { 6442 .secure = secure, 6443 .rate = rate, 6444 }; 6445 6446 nvlist_t *vdevs = fnvlist_alloc(); 6447 if (argc == 1) { 6448 /* no individual leaf vdevs specified, so add them all */ 6449 nvlist_t *config = zpool_get_config(zhp, NULL); 6450 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 6451 ZPOOL_CONFIG_VDEV_TREE); 6452 zpool_collect_leaves(zhp, nvroot, vdevs); 6453 trim_flags.fullpool = B_TRUE; 6454 } else { 6455 trim_flags.fullpool = B_FALSE; 6456 for (int i = 1; i < argc; i++) { 6457 fnvlist_add_boolean(vdevs, argv[i]); 6458 } 6459 } 6460 6461 int error = zpool_trim(zhp, cmd_type, vdevs, &trim_flags); 6462 6463 fnvlist_free(vdevs); 6464 zpool_close(zhp); 6465 6466 return (error); 6467 } 6468 6469 /* 6470 * zpool initialize [-c | -s] <pool> [<vdev> ...] 6471 * Initialize all unused blocks in the specified vdevs, or all vdevs in the pool 6472 * if none specified. 6473 * 6474 * -c Cancel. Ends active initializing. 6475 * -s Suspend. Initializing can then be restarted with no flags. 6476 */ 6477 int 6478 zpool_do_initialize(int argc, char **argv) 6479 { 6480 int c; 6481 char *poolname; 6482 zpool_handle_t *zhp; 6483 nvlist_t *vdevs; 6484 int err = 0; 6485 6486 struct option long_options[] = { 6487 {"cancel", no_argument, NULL, 'c'}, 6488 {"suspend", no_argument, NULL, 's'}, 6489 {0, 0, 0, 0} 6490 }; 6491 6492 pool_initialize_func_t cmd_type = POOL_INITIALIZE_START; 6493 while ((c = getopt_long(argc, argv, "cs", long_options, NULL)) != -1) { 6494 switch (c) { 6495 case 'c': 6496 if (cmd_type != POOL_INITIALIZE_START && 6497 cmd_type != POOL_INITIALIZE_CANCEL) { 6498 (void) fprintf(stderr, gettext("-c cannot be " 6499 "combined with other options\n")); 6500 usage(B_FALSE); 6501 } 6502 cmd_type = POOL_INITIALIZE_CANCEL; 6503 break; 6504 case 's': 6505 if (cmd_type != POOL_INITIALIZE_START && 6506 cmd_type != POOL_INITIALIZE_SUSPEND) { 6507 (void) fprintf(stderr, gettext("-s cannot be " 6508 "combined with other options\n")); 6509 usage(B_FALSE); 6510 } 6511 cmd_type = POOL_INITIALIZE_SUSPEND; 6512 break; 6513 case '?': 6514 if (optopt != 0) { 6515 (void) fprintf(stderr, 6516 gettext("invalid option '%c'\n"), optopt); 6517 } else { 6518 (void) fprintf(stderr, 6519 gettext("invalid option '%s'\n"), 6520 argv[optind - 1]); 6521 } 6522 usage(B_FALSE); 6523 } 6524 } 6525 6526 argc -= optind; 6527 argv += optind; 6528 6529 if (argc < 1) { 6530 (void) fprintf(stderr, gettext("missing pool name argument\n")); 6531 usage(B_FALSE); 6532 return (-1); 6533 } 6534 6535 poolname = argv[0]; 6536 zhp = zpool_open(g_zfs, poolname); 6537 if (zhp == NULL) 6538 return (-1); 6539 6540 vdevs = fnvlist_alloc(); 6541 if (argc == 1) { 6542 /* no individual leaf vdevs specified, so add them all */ 6543 nvlist_t *config = zpool_get_config(zhp, NULL); 6544 nvlist_t *nvroot = fnvlist_lookup_nvlist(config, 6545 ZPOOL_CONFIG_VDEV_TREE); 6546 zpool_collect_leaves(zhp, nvroot, vdevs); 6547 } else { 6548 for (int i = 1; i < argc; i++) { 6549 fnvlist_add_boolean(vdevs, argv[i]); 6550 } 6551 } 6552 6553 err = zpool_initialize(zhp, cmd_type, vdevs); 6554 6555 fnvlist_free(vdevs); 6556 zpool_close(zhp); 6557 6558 return (err); 6559 } 6560 6561 /* 6562 * Print out detailed scrub status. 6563 */ 6564 static void 6565 print_scan_status(pool_scan_stat_t *ps) 6566 { 6567 time_t start, end, pause; 6568 uint64_t total_secs_left; 6569 uint64_t elapsed, secs_left, mins_left, hours_left, days_left; 6570 uint64_t pass_scanned, scanned, pass_issued, issued, total; 6571 uint_t scan_rate, issue_rate; 6572 double fraction_done; 6573 char processed_buf[7], scanned_buf[7], issued_buf[7], total_buf[7]; 6574 char srate_buf[7], irate_buf[7]; 6575 6576 (void) printf(gettext(" scan: ")); 6577 6578 /* If there's never been a scan, there's not much to say. */ 6579 if (ps == NULL || ps->pss_func == POOL_SCAN_NONE || 6580 ps->pss_func >= POOL_SCAN_FUNCS) { 6581 (void) printf(gettext("none requested\n")); 6582 return; 6583 } 6584 6585 start = ps->pss_start_time; 6586 end = ps->pss_end_time; 6587 pause = ps->pss_pass_scrub_pause; 6588 6589 zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf)); 6590 6591 assert(ps->pss_func == POOL_SCAN_SCRUB || 6592 ps->pss_func == POOL_SCAN_RESILVER); 6593 6594 /* 6595 * Scan is finished or canceled. 6596 */ 6597 if (ps->pss_state == DSS_FINISHED) { 6598 total_secs_left = end - start; 6599 days_left = total_secs_left / 60 / 60 / 24; 6600 hours_left = (total_secs_left / 60 / 60) % 24; 6601 mins_left = (total_secs_left / 60) % 60; 6602 secs_left = (total_secs_left % 60); 6603 6604 if (ps->pss_func == POOL_SCAN_SCRUB) { 6605 (void) printf(gettext("scrub repaired %s " 6606 "in %llu days %02llu:%02llu:%02llu " 6607 "with %llu errors on %s"), processed_buf, 6608 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6609 (u_longlong_t)mins_left, (u_longlong_t)secs_left, 6610 (u_longlong_t)ps->pss_errors, ctime(&end)); 6611 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6612 (void) printf(gettext("resilvered %s " 6613 "in %llu days %02llu:%02llu:%02llu " 6614 "with %llu errors on %s"), processed_buf, 6615 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6616 (u_longlong_t)mins_left, (u_longlong_t)secs_left, 6617 (u_longlong_t)ps->pss_errors, ctime(&end)); 6618 } 6619 return; 6620 } else if (ps->pss_state == DSS_CANCELED) { 6621 if (ps->pss_func == POOL_SCAN_SCRUB) { 6622 (void) printf(gettext("scrub canceled on %s"), 6623 ctime(&end)); 6624 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6625 (void) printf(gettext("resilver canceled on %s"), 6626 ctime(&end)); 6627 } 6628 return; 6629 } 6630 6631 assert(ps->pss_state == DSS_SCANNING); 6632 6633 /* Scan is in progress. Resilvers can't be paused. */ 6634 if (ps->pss_func == POOL_SCAN_SCRUB) { 6635 if (pause == 0) { 6636 (void) printf(gettext("scrub in progress since %s"), 6637 ctime(&start)); 6638 } else { 6639 (void) printf(gettext("scrub paused since %s"), 6640 ctime(&pause)); 6641 (void) printf(gettext("\tscrub started on %s"), 6642 ctime(&start)); 6643 } 6644 } else if (ps->pss_func == POOL_SCAN_RESILVER) { 6645 (void) printf(gettext("resilver in progress since %s"), 6646 ctime(&start)); 6647 } 6648 6649 scanned = ps->pss_examined; 6650 pass_scanned = ps->pss_pass_exam; 6651 issued = ps->pss_issued; 6652 pass_issued = ps->pss_pass_issued; 6653 total = ps->pss_to_examine; 6654 6655 /* we are only done with a block once we have issued the IO for it */ 6656 fraction_done = (double)issued / total; 6657 6658 /* elapsed time for this pass, rounding up to 1 if it's 0 */ 6659 elapsed = time(NULL) - ps->pss_pass_start; 6660 elapsed -= ps->pss_pass_scrub_spent_paused; 6661 elapsed = (elapsed != 0) ? elapsed : 1; 6662 6663 scan_rate = pass_scanned / elapsed; 6664 issue_rate = pass_issued / elapsed; 6665 total_secs_left = (issue_rate != 0 && total >= issued) ? 6666 ((total - issued) / issue_rate) : UINT64_MAX; 6667 6668 days_left = total_secs_left / 60 / 60 / 24; 6669 hours_left = (total_secs_left / 60 / 60) % 24; 6670 mins_left = (total_secs_left / 60) % 60; 6671 secs_left = (total_secs_left % 60); 6672 6673 /* format all of the numbers we will be reporting */ 6674 zfs_nicenum(scanned, scanned_buf, sizeof (scanned_buf)); 6675 zfs_nicenum(issued, issued_buf, sizeof (issued_buf)); 6676 zfs_nicenum(total, total_buf, sizeof (total_buf)); 6677 zfs_nicenum(scan_rate, srate_buf, sizeof (srate_buf)); 6678 zfs_nicenum(issue_rate, irate_buf, sizeof (irate_buf)); 6679 6680 /* do not print estimated time if we have a paused scrub */ 6681 if (pause == 0) { 6682 (void) printf(gettext("\t%s scanned at %s/s, " 6683 "%s issued at %s/s, %s total\n"), 6684 scanned_buf, srate_buf, issued_buf, irate_buf, total_buf); 6685 } else { 6686 (void) printf(gettext("\t%s scanned, %s issued, %s total\n"), 6687 scanned_buf, issued_buf, total_buf); 6688 } 6689 6690 if (ps->pss_func == POOL_SCAN_RESILVER) { 6691 (void) printf(gettext("\t%s resilvered, %.2f%% done"), 6692 processed_buf, 100 * fraction_done); 6693 } else if (ps->pss_func == POOL_SCAN_SCRUB) { 6694 (void) printf(gettext("\t%s repaired, %.2f%% done"), 6695 processed_buf, 100 * fraction_done); 6696 } 6697 6698 if (pause == 0) { 6699 if (total_secs_left != UINT64_MAX && 6700 issue_rate >= 10 * 1024 * 1024) { 6701 (void) printf(gettext(", %llu days " 6702 "%02llu:%02llu:%02llu to go\n"), 6703 (u_longlong_t)days_left, (u_longlong_t)hours_left, 6704 (u_longlong_t)mins_left, (u_longlong_t)secs_left); 6705 } else { 6706 (void) printf(gettext(", no estimated " 6707 "completion time\n")); 6708 } 6709 } else { 6710 (void) printf(gettext("\n")); 6711 } 6712 } 6713 6714 /* 6715 * As we don't scrub checkpointed blocks, we want to warn the 6716 * user that we skipped scanning some blocks if a checkpoint exists 6717 * or existed at any time during the scan. 6718 */ 6719 static void 6720 print_checkpoint_scan_warning(pool_scan_stat_t *ps, pool_checkpoint_stat_t *pcs) 6721 { 6722 if (ps == NULL || pcs == NULL) 6723 return; 6724 6725 if (pcs->pcs_state == CS_NONE || 6726 pcs->pcs_state == CS_CHECKPOINT_DISCARDING) 6727 return; 6728 6729 assert(pcs->pcs_state == CS_CHECKPOINT_EXISTS); 6730 6731 if (ps->pss_state == DSS_NONE) 6732 return; 6733 6734 if ((ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) && 6735 ps->pss_end_time < pcs->pcs_start_time) 6736 return; 6737 6738 if (ps->pss_state == DSS_FINISHED || ps->pss_state == DSS_CANCELED) { 6739 (void) printf(gettext(" scan warning: skipped blocks " 6740 "that are only referenced by the checkpoint.\n")); 6741 } else { 6742 assert(ps->pss_state == DSS_SCANNING); 6743 (void) printf(gettext(" scan warning: skipping blocks " 6744 "that are only referenced by the checkpoint.\n")); 6745 } 6746 } 6747 6748 /* 6749 * Print out detailed removal status. 6750 */ 6751 static void 6752 print_removal_status(zpool_handle_t *zhp, pool_removal_stat_t *prs) 6753 { 6754 char copied_buf[7], examined_buf[7], total_buf[7], rate_buf[7]; 6755 time_t start, end; 6756 nvlist_t *config, *nvroot; 6757 nvlist_t **child; 6758 uint_t children; 6759 char *vdev_name; 6760 6761 if (prs == NULL || prs->prs_state == DSS_NONE) 6762 return; 6763 6764 /* 6765 * Determine name of vdev. 6766 */ 6767 config = zpool_get_config(zhp, NULL); 6768 nvroot = fnvlist_lookup_nvlist(config, 6769 ZPOOL_CONFIG_VDEV_TREE); 6770 verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 6771 &child, &children) == 0); 6772 assert(prs->prs_removing_vdev < children); 6773 vdev_name = zpool_vdev_name(g_zfs, zhp, 6774 child[prs->prs_removing_vdev], B_TRUE); 6775 6776 (void) printf(gettext("remove: ")); 6777 6778 start = prs->prs_start_time; 6779 end = prs->prs_end_time; 6780 zfs_nicenum(prs->prs_copied, copied_buf, sizeof (copied_buf)); 6781 6782 /* 6783 * Removal is finished or canceled. 6784 */ 6785 if (prs->prs_state == DSS_FINISHED) { 6786 uint64_t minutes_taken = (end - start) / 60; 6787 6788 (void) printf(gettext("Removal of vdev %llu copied %s " 6789 "in %lluh%um, completed on %s"), 6790 (longlong_t)prs->prs_removing_vdev, 6791 copied_buf, 6792 (u_longlong_t)(minutes_taken / 60), 6793 (uint_t)(minutes_taken % 60), 6794 ctime((time_t *)&end)); 6795 } else if (prs->prs_state == DSS_CANCELED) { 6796 (void) printf(gettext("Removal of %s canceled on %s"), 6797 vdev_name, ctime(&end)); 6798 } else { 6799 uint64_t copied, total, elapsed, mins_left, hours_left; 6800 double fraction_done; 6801 uint_t rate; 6802 6803 assert(prs->prs_state == DSS_SCANNING); 6804 6805 /* 6806 * Removal is in progress. 6807 */ 6808 (void) printf(gettext( 6809 "Evacuation of %s in progress since %s"), 6810 vdev_name, ctime(&start)); 6811 6812 copied = prs->prs_copied > 0 ? prs->prs_copied : 1; 6813 total = prs->prs_to_copy; 6814 fraction_done = (double)copied / total; 6815 6816 /* elapsed time for this pass */ 6817 elapsed = time(NULL) - prs->prs_start_time; 6818 elapsed = elapsed > 0 ? elapsed : 1; 6819 rate = copied / elapsed; 6820 rate = rate > 0 ? rate : 1; 6821 mins_left = ((total - copied) / rate) / 60; 6822 hours_left = mins_left / 60; 6823 6824 zfs_nicenum(copied, examined_buf, sizeof (examined_buf)); 6825 zfs_nicenum(total, total_buf, sizeof (total_buf)); 6826 zfs_nicenum(rate, rate_buf, sizeof (rate_buf)); 6827 6828 /* 6829 * do not print estimated time if hours_left is more than 6830 * 30 days 6831 */ 6832 (void) printf(gettext(" %s copied out of %s at %s/s, " 6833 "%.2f%% done"), 6834 examined_buf, total_buf, rate_buf, 100 * fraction_done); 6835 if (hours_left < (30 * 24)) { 6836 (void) printf(gettext(", %lluh%um to go\n"), 6837 (u_longlong_t)hours_left, (uint_t)(mins_left % 60)); 6838 } else { 6839 (void) printf(gettext( 6840 ", (copy is slow, no estimated time)\n")); 6841 } 6842 } 6843 6844 if (prs->prs_mapping_memory > 0) { 6845 char mem_buf[7]; 6846 zfs_nicenum(prs->prs_mapping_memory, mem_buf, sizeof (mem_buf)); 6847 (void) printf(gettext(" %s memory used for " 6848 "removed device mappings\n"), 6849 mem_buf); 6850 } 6851 } 6852 6853 static void 6854 print_checkpoint_status(pool_checkpoint_stat_t *pcs) 6855 { 6856 time_t start; 6857 char space_buf[7]; 6858 6859 if (pcs == NULL || pcs->pcs_state == CS_NONE) 6860 return; 6861 6862 (void) printf(gettext("checkpoint: ")); 6863 6864 start = pcs->pcs_start_time; 6865 zfs_nicenum(pcs->pcs_space, space_buf, sizeof (space_buf)); 6866 6867 if (pcs->pcs_state == CS_CHECKPOINT_EXISTS) { 6868 char *date = ctime(&start); 6869 6870 /* 6871 * ctime() adds a newline at the end of the generated 6872 * string, thus the weird format specifier and the 6873 * strlen() call used to chop it off from the output. 6874 */ 6875 (void) printf(gettext("created %.*s, consumes %s\n"), 6876 strlen(date) - 1, date, space_buf); 6877 return; 6878 } 6879 6880 assert(pcs->pcs_state == CS_CHECKPOINT_DISCARDING); 6881 6882 (void) printf(gettext("discarding, %s remaining.\n"), 6883 space_buf); 6884 } 6885 6886 static void 6887 print_error_log(zpool_handle_t *zhp) 6888 { 6889 nvlist_t *nverrlist = NULL; 6890 nvpair_t *elem; 6891 char *pathname; 6892 size_t len = MAXPATHLEN * 2; 6893 6894 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 6895 (void) printf("errors: List of errors unavailable " 6896 "(insufficient privileges)\n"); 6897 return; 6898 } 6899 6900 (void) printf("errors: Permanent errors have been " 6901 "detected in the following files:\n\n"); 6902 6903 pathname = safe_malloc(len); 6904 elem = NULL; 6905 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 6906 nvlist_t *nv; 6907 uint64_t dsobj, obj; 6908 6909 verify(nvpair_value_nvlist(elem, &nv) == 0); 6910 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 6911 &dsobj) == 0); 6912 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 6913 &obj) == 0); 6914 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 6915 (void) printf("%7s %s\n", "", pathname); 6916 } 6917 free(pathname); 6918 nvlist_free(nverrlist); 6919 } 6920 6921 static void 6922 print_spares(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **spares, 6923 uint_t nspares) 6924 { 6925 uint_t i; 6926 char *name; 6927 6928 if (nspares == 0) 6929 return; 6930 6931 (void) printf(gettext("\tspares\n")); 6932 6933 for (i = 0; i < nspares; i++) { 6934 name = zpool_vdev_name(g_zfs, zhp, spares[i], 6935 cb->cb_name_flags); 6936 print_status_config(zhp, cb, name, spares[i], 2, B_TRUE); 6937 free(name); 6938 } 6939 } 6940 6941 static void 6942 print_l2cache(zpool_handle_t *zhp, status_cbdata_t *cb, nvlist_t **l2cache, 6943 uint_t nl2cache) 6944 { 6945 uint_t i; 6946 char *name; 6947 6948 if (nl2cache == 0) 6949 return; 6950 6951 (void) printf(gettext("\tcache\n")); 6952 6953 for (i = 0; i < nl2cache; i++) { 6954 name = zpool_vdev_name(g_zfs, zhp, l2cache[i], 6955 cb->cb_name_flags); 6956 print_status_config(zhp, cb, name, l2cache[i], 2, B_FALSE); 6957 free(name); 6958 } 6959 } 6960 6961 static void 6962 print_dedup_stats(nvlist_t *config) 6963 { 6964 ddt_histogram_t *ddh; 6965 ddt_stat_t *dds; 6966 ddt_object_t *ddo; 6967 uint_t c; 6968 6969 /* 6970 * If the pool was faulted then we may not have been able to 6971 * obtain the config. Otherwise, if we have anything in the dedup 6972 * table continue processing the stats. 6973 */ 6974 if (nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, 6975 (uint64_t **)&ddo, &c) != 0) 6976 return; 6977 6978 (void) printf("\n"); 6979 (void) printf(gettext(" dedup: ")); 6980 if (ddo->ddo_count == 0) { 6981 (void) printf(gettext("no DDT entries\n")); 6982 return; 6983 } 6984 6985 (void) printf("DDT entries %llu, size %llu on disk, %llu in core\n", 6986 (u_longlong_t)ddo->ddo_count, 6987 (u_longlong_t)ddo->ddo_dspace, 6988 (u_longlong_t)ddo->ddo_mspace); 6989 6990 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, 6991 (uint64_t **)&dds, &c) == 0); 6992 verify(nvlist_lookup_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, 6993 (uint64_t **)&ddh, &c) == 0); 6994 zpool_dump_ddt(dds, ddh); 6995 } 6996 6997 /* 6998 * Display a summary of pool status. Displays a summary such as: 6999 * 7000 * pool: tank 7001 * status: DEGRADED 7002 * reason: One or more devices ... 7003 * see: http://illumos.org/msg/ZFS-xxxx-01 7004 * config: 7005 * mirror DEGRADED 7006 * c1t0d0 OK 7007 * c2t0d0 UNAVAIL 7008 * 7009 * When given the '-v' option, we print out the complete config. If the '-e' 7010 * option is specified, then we print out error rate information as well. 7011 */ 7012 int 7013 status_callback(zpool_handle_t *zhp, void *data) 7014 { 7015 status_cbdata_t *cbp = data; 7016 nvlist_t *config, *nvroot; 7017 char *msgid; 7018 int reason; 7019 zpool_errata_t errata; 7020 const char *health; 7021 uint_t c; 7022 vdev_stat_t *vs; 7023 7024 config = zpool_get_config(zhp, NULL); 7025 reason = zpool_get_status(zhp, &msgid, &errata); 7026 7027 cbp->cb_count++; 7028 7029 /* 7030 * If we were given 'zpool status -x', only report those pools with 7031 * problems. 7032 */ 7033 if (cbp->cb_explain && 7034 (reason == ZPOOL_STATUS_OK || 7035 reason == ZPOOL_STATUS_VERSION_OLDER || 7036 reason == ZPOOL_STATUS_FEAT_DISABLED)) { 7037 if (!cbp->cb_allpools) { 7038 (void) printf(gettext("pool '%s' is healthy\n"), 7039 zpool_get_name(zhp)); 7040 if (cbp->cb_first) 7041 cbp->cb_first = B_FALSE; 7042 } 7043 return (0); 7044 } 7045 7046 if (cbp->cb_first) 7047 cbp->cb_first = B_FALSE; 7048 else 7049 (void) printf("\n"); 7050 7051 nvroot = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE); 7052 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, 7053 (uint64_t **)&vs, &c) == 0); 7054 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 7055 7056 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 7057 (void) printf(gettext(" state: %s\n"), health); 7058 7059 switch (reason) { 7060 case ZPOOL_STATUS_MISSING_DEV_R: 7061 (void) printf(gettext("status: One or more devices could not " 7062 "be opened. Sufficient replicas exist for\n\tthe pool to " 7063 "continue functioning in a degraded state.\n")); 7064 (void) printf(gettext("action: Attach the missing device and " 7065 "online it using 'zpool online'.\n")); 7066 break; 7067 7068 case ZPOOL_STATUS_MISSING_DEV_NR: 7069 (void) printf(gettext("status: One or more devices could not " 7070 "be opened. There are insufficient\n\treplicas for the " 7071 "pool to continue functioning.\n")); 7072 (void) printf(gettext("action: Attach the missing device and " 7073 "online it using 'zpool online'.\n")); 7074 break; 7075 7076 case ZPOOL_STATUS_CORRUPT_LABEL_R: 7077 (void) printf(gettext("status: One or more devices could not " 7078 "be used because the label is missing or\n\tinvalid. " 7079 "Sufficient replicas exist for the pool to continue\n\t" 7080 "functioning in a degraded state.\n")); 7081 (void) printf(gettext("action: Replace the device using " 7082 "'zpool replace'.\n")); 7083 break; 7084 7085 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 7086 (void) printf(gettext("status: One or more devices could not " 7087 "be used because the label is missing \n\tor invalid. " 7088 "There are insufficient replicas for the pool to " 7089 "continue\n\tfunctioning.\n")); 7090 zpool_explain_recover(zpool_get_handle(zhp), 7091 zpool_get_name(zhp), reason, config); 7092 break; 7093 7094 case ZPOOL_STATUS_FAILING_DEV: 7095 (void) printf(gettext("status: One or more devices has " 7096 "experienced an unrecoverable error. An\n\tattempt was " 7097 "made to correct the error. Applications are " 7098 "unaffected.\n")); 7099 (void) printf(gettext("action: Determine if the device needs " 7100 "to be replaced, and clear the errors\n\tusing " 7101 "'zpool clear' or replace the device with 'zpool " 7102 "replace'.\n")); 7103 break; 7104 7105 case ZPOOL_STATUS_OFFLINE_DEV: 7106 (void) printf(gettext("status: One or more devices has " 7107 "been taken offline by the administrator.\n\tSufficient " 7108 "replicas exist for the pool to continue functioning in " 7109 "a\n\tdegraded state.\n")); 7110 (void) printf(gettext("action: Online the device using " 7111 "'zpool online' or replace the device with\n\t'zpool " 7112 "replace'.\n")); 7113 break; 7114 7115 case ZPOOL_STATUS_REMOVED_DEV: 7116 (void) printf(gettext("status: One or more devices has " 7117 "been removed by the administrator.\n\tSufficient " 7118 "replicas exist for the pool to continue functioning in " 7119 "a\n\tdegraded state.\n")); 7120 (void) printf(gettext("action: Online the device using " 7121 "'zpool online' or replace the device with\n\t'zpool " 7122 "replace'.\n")); 7123 break; 7124 7125 case ZPOOL_STATUS_RESILVERING: 7126 (void) printf(gettext("status: One or more devices is " 7127 "currently being resilvered. The pool will\n\tcontinue " 7128 "to function, possibly in a degraded state.\n")); 7129 (void) printf(gettext("action: Wait for the resilver to " 7130 "complete.\n")); 7131 break; 7132 7133 case ZPOOL_STATUS_CORRUPT_DATA: 7134 (void) printf(gettext("status: One or more devices has " 7135 "experienced an error resulting in data\n\tcorruption. " 7136 "Applications may be affected.\n")); 7137 (void) printf(gettext("action: Restore the file in question " 7138 "if possible. Otherwise restore the\n\tentire pool from " 7139 "backup.\n")); 7140 break; 7141 7142 case ZPOOL_STATUS_CORRUPT_POOL: 7143 (void) printf(gettext("status: The pool metadata is corrupted " 7144 "and the pool cannot be opened.\n")); 7145 zpool_explain_recover(zpool_get_handle(zhp), 7146 zpool_get_name(zhp), reason, config); 7147 break; 7148 7149 case ZPOOL_STATUS_VERSION_OLDER: 7150 (void) printf(gettext("status: The pool is formatted using a " 7151 "legacy on-disk format. The pool can\n\tstill be used, " 7152 "but some features are unavailable.\n")); 7153 (void) printf(gettext("action: Upgrade the pool using 'zpool " 7154 "upgrade'. Once this is done, the\n\tpool will no longer " 7155 "be accessible on software that does not support feature\n" 7156 "\tflags.\n")); 7157 break; 7158 7159 case ZPOOL_STATUS_VERSION_NEWER: 7160 (void) printf(gettext("status: The pool has been upgraded to a " 7161 "newer, incompatible on-disk version.\n\tThe pool cannot " 7162 "be accessed on this system.\n")); 7163 (void) printf(gettext("action: Access the pool from a system " 7164 "running more recent software, or\n\trestore the pool from " 7165 "backup.\n")); 7166 break; 7167 7168 case ZPOOL_STATUS_FEAT_DISABLED: 7169 (void) printf(gettext("status: Some supported features are not " 7170 "enabled on the pool. The pool can\n\tstill be used, but " 7171 "some features are unavailable.\n")); 7172 (void) printf(gettext("action: Enable all features using " 7173 "'zpool upgrade'. Once this is done,\n\tthe pool may no " 7174 "longer be accessible by software that does not support\n\t" 7175 "the features. See zpool-features(5) for details.\n")); 7176 break; 7177 7178 case ZPOOL_STATUS_UNSUP_FEAT_READ: 7179 (void) printf(gettext("status: The pool cannot be accessed on " 7180 "this system because it uses the\n\tfollowing feature(s) " 7181 "not supported on this system:\n")); 7182 zpool_print_unsup_feat(config); 7183 (void) printf("\n"); 7184 (void) printf(gettext("action: Access the pool from a system " 7185 "that supports the required feature(s),\n\tor restore the " 7186 "pool from backup.\n")); 7187 break; 7188 7189 case ZPOOL_STATUS_UNSUP_FEAT_WRITE: 7190 (void) printf(gettext("status: The pool can only be accessed " 7191 "in read-only mode on this system. It\n\tcannot be " 7192 "accessed in read-write mode because it uses the " 7193 "following\n\tfeature(s) not supported on this system:\n")); 7194 zpool_print_unsup_feat(config); 7195 (void) printf("\n"); 7196 (void) printf(gettext("action: The pool cannot be accessed in " 7197 "read-write mode. Import the pool with\n" 7198 "\t\"-o readonly=on\", access the pool from a system that " 7199 "supports the\n\trequired feature(s), or restore the " 7200 "pool from backup.\n")); 7201 break; 7202 7203 case ZPOOL_STATUS_FAULTED_DEV_R: 7204 (void) printf(gettext("status: One or more devices are " 7205 "faulted in response to persistent errors.\n\tSufficient " 7206 "replicas exist for the pool to continue functioning " 7207 "in a\n\tdegraded state.\n")); 7208 (void) printf(gettext("action: Replace the faulted device, " 7209 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 7210 break; 7211 7212 case ZPOOL_STATUS_FAULTED_DEV_NR: 7213 (void) printf(gettext("status: One or more devices are " 7214 "faulted in response to persistent errors. There are " 7215 "insufficient replicas for the pool to\n\tcontinue " 7216 "functioning.\n")); 7217 (void) printf(gettext("action: Destroy and re-create the pool " 7218 "from a backup source. Manually marking the device\n" 7219 "\trepaired using 'zpool clear' may allow some data " 7220 "to be recovered.\n")); 7221 break; 7222 7223 case ZPOOL_STATUS_IO_FAILURE_MMP: 7224 (void) printf(gettext("status: The pool is suspended because " 7225 "multihost writes failed or were delayed;\n\tanother " 7226 "system could import the pool undetected.\n")); 7227 (void) printf(gettext("action: Make sure the pool's devices " 7228 "are connected, then reboot your system and\n\timport the " 7229 "pool.\n")); 7230 break; 7231 7232 case ZPOOL_STATUS_IO_FAILURE_WAIT: 7233 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 7234 (void) printf(gettext("status: One or more devices are " 7235 "faulted in response to IO failures.\n")); 7236 (void) printf(gettext("action: Make sure the affected devices " 7237 "are connected, then run 'zpool clear'.\n")); 7238 break; 7239 7240 case ZPOOL_STATUS_BAD_LOG: 7241 (void) printf(gettext("status: An intent log record " 7242 "could not be read.\n" 7243 "\tWaiting for adminstrator intervention to fix the " 7244 "faulted pool.\n")); 7245 (void) printf(gettext("action: Either restore the affected " 7246 "device(s) and run 'zpool online',\n" 7247 "\tor ignore the intent log records by running " 7248 "'zpool clear'.\n")); 7249 break; 7250 7251 case ZPOOL_STATUS_ERRATA: 7252 (void) printf(gettext("status: Errata #%d detected.\n"), 7253 errata); 7254 7255 switch (errata) { 7256 case ZPOOL_ERRATA_NONE: 7257 break; 7258 7259 case ZPOOL_ERRATA_ZOL_2094_SCRUB: 7260 (void) printf(gettext("action: To correct the issue " 7261 "run 'zpool scrub'.\n")); 7262 break; 7263 7264 case ZPOOL_ERRATA_ZOL_6845_ENCRYPTION: 7265 (void) printf(gettext("\tExisting encrypted datasets " 7266 "contain an on-disk incompatibility\n\twhich " 7267 "needs to be corrected.\n")); 7268 (void) printf(gettext("action: To correct the issue " 7269 "backup existing encrypted datasets to new\n\t" 7270 "encrypted datasets and destroy the old ones. " 7271 "'zfs mount -o ro' can\n\tbe used to temporarily " 7272 "mount existing encrypted datasets readonly.\n")); 7273 break; 7274 7275 case ZPOOL_ERRATA_ZOL_8308_ENCRYPTION: 7276 (void) printf(gettext("\tExisting encrypted datasets " 7277 "contain an on-disk incompatibility\n\twhich " 7278 "needs to be corrected.\n")); 7279 (void) printf(gettext("action: To correct the issue " 7280 "enable the bookmark_v2 feature and " 7281 "backup\n\tany existing encrypted datasets to " 7282 "new encrypted datasets and\n\tdestroy the old " 7283 "ones. If this pool does not contain any\n\t" 7284 "encrypted datasets, simply enable the " 7285 "bookmark_v2 feature\n")); 7286 break; 7287 7288 default: 7289 /* 7290 * All errata which allow the pool to be imported 7291 * must contain an action message. 7292 */ 7293 assert(0); 7294 } 7295 break; 7296 7297 default: 7298 /* 7299 * The remaining errors can't actually be generated, yet. 7300 */ 7301 assert(reason == ZPOOL_STATUS_OK); 7302 } 7303 7304 if (msgid != NULL) 7305 (void) printf(gettext(" see: http://illumos.org/msg/%s\n"), 7306 msgid); 7307 7308 if (config != NULL) { 7309 uint64_t nerr; 7310 nvlist_t **spares, **l2cache; 7311 uint_t nspares, nl2cache; 7312 pool_checkpoint_stat_t *pcs = NULL; 7313 pool_scan_stat_t *ps = NULL; 7314 pool_removal_stat_t *prs = NULL; 7315 7316 (void) nvlist_lookup_uint64_array(nvroot, 7317 ZPOOL_CONFIG_CHECKPOINT_STATS, (uint64_t **)&pcs, &c); 7318 (void) nvlist_lookup_uint64_array(nvroot, 7319 ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c); 7320 (void) nvlist_lookup_uint64_array(nvroot, 7321 ZPOOL_CONFIG_REMOVAL_STATS, (uint64_t **)&prs, &c); 7322 7323 print_scan_status(ps); 7324 print_checkpoint_scan_warning(ps, pcs); 7325 print_removal_status(zhp, prs); 7326 print_checkpoint_status(pcs); 7327 7328 cbp->cb_namewidth = max_width(zhp, nvroot, 0, 0, 7329 cbp->cb_name_flags); 7330 if (cbp->cb_namewidth < 10) 7331 cbp->cb_namewidth = 10; 7332 7333 (void) printf(gettext("config:\n\n")); 7334 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), 7335 cbp->cb_namewidth, "NAME", "STATE", "READ", "WRITE", 7336 "CKSUM"); 7337 7338 if (cbp->cb_print_slow_ios) 7339 (void) printf(" %5s", gettext("SLOW")); 7340 7341 print_status_config(zhp, cbp, zpool_get_name(zhp), nvroot, 0, 7342 B_FALSE); 7343 7344 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_DEDUP); 7345 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_BIAS_SPECIAL); 7346 print_class_vdevs(zhp, cbp, nvroot, VDEV_ALLOC_CLASS_LOGS); 7347 7348 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 7349 &l2cache, &nl2cache) == 0) 7350 print_l2cache(zhp, cbp, l2cache, nl2cache); 7351 7352 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 7353 &spares, &nspares) == 0) 7354 print_spares(zhp, cbp, spares, nspares); 7355 7356 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 7357 &nerr) == 0) { 7358 nvlist_t *nverrlist = NULL; 7359 7360 /* 7361 * If the approximate error count is small, get a 7362 * precise count by fetching the entire log and 7363 * uniquifying the results. 7364 */ 7365 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 7366 zpool_get_errlog(zhp, &nverrlist) == 0) { 7367 nvpair_t *elem; 7368 7369 elem = NULL; 7370 nerr = 0; 7371 while ((elem = nvlist_next_nvpair(nverrlist, 7372 elem)) != NULL) { 7373 nerr++; 7374 } 7375 } 7376 nvlist_free(nverrlist); 7377 7378 (void) printf("\n"); 7379 7380 if (nerr == 0) 7381 (void) printf(gettext("errors: No known data " 7382 "errors\n")); 7383 else if (!cbp->cb_verbose) 7384 (void) printf(gettext("errors: %llu data " 7385 "errors, use '-v' for a list\n"), 7386 (u_longlong_t)nerr); 7387 else 7388 print_error_log(zhp); 7389 } 7390 7391 if (cbp->cb_dedup_stats) 7392 print_dedup_stats(config); 7393 } else { 7394 (void) printf(gettext("config: The configuration cannot be " 7395 "determined.\n")); 7396 } 7397 7398 return (0); 7399 } 7400 7401 /* 7402 * zpool status [-igLpPstvx] [-T d|u] [pool] ... [interval [count]] 7403 * 7404 * -i Display vdev initialization status. 7405 * -g Display guid for individual vdev name. 7406 * -L Follow links when resolving vdev path name. 7407 * -p Display values in parsable (exact) format. 7408 * -P Display full path for vdev name. 7409 * -s Display slow IOs column. 7410 * -v Display complete error logs 7411 * -x Display only pools with potential problems 7412 * -D Display dedup status (undocumented) 7413 * -t Display vdev TRIM status. 7414 * -T Display a timestamp in date(1) or Unix format 7415 * 7416 * Describes the health status of all pools or some subset. 7417 */ 7418 int 7419 zpool_do_status(int argc, char **argv) 7420 { 7421 int c; 7422 int ret; 7423 float interval = 0; 7424 unsigned long count = 0; 7425 status_cbdata_t cb = { 0 }; 7426 7427 /* check options */ 7428 while ((c = getopt(argc, argv, "igLpPsvxDtT:")) != -1) { 7429 switch (c) { 7430 case 'i': 7431 cb.cb_print_vdev_init = B_TRUE; 7432 break; 7433 case 'g': 7434 cb.cb_name_flags |= VDEV_NAME_GUID; 7435 break; 7436 case 'L': 7437 cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS; 7438 break; 7439 case 'p': 7440 cb.cb_literal = B_TRUE; 7441 break; 7442 case 'P': 7443 cb.cb_name_flags |= VDEV_NAME_PATH; 7444 break; 7445 case 's': 7446 cb.cb_print_slow_ios = B_TRUE; 7447 break; 7448 case 'v': 7449 cb.cb_verbose = B_TRUE; 7450 break; 7451 case 'x': 7452 cb.cb_explain = B_TRUE; 7453 break; 7454 case 'D': 7455 cb.cb_dedup_stats = B_TRUE; 7456 break; 7457 case 't': 7458 cb.cb_print_vdev_trim = B_TRUE; 7459 break; 7460 case 'T': 7461 get_timestamp_arg(*optarg); 7462 break; 7463 case '?': 7464 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7465 optopt); 7466 usage(B_FALSE); 7467 } 7468 } 7469 7470 argc -= optind; 7471 argv += optind; 7472 7473 get_interval_count(&argc, argv, &interval, &count); 7474 7475 if (argc == 0) 7476 cb.cb_allpools = B_TRUE; 7477 7478 cb.cb_first = B_TRUE; 7479 cb.cb_print_status = B_TRUE; 7480 7481 for (;;) { 7482 if (timestamp_fmt != NODATE) 7483 print_timestamp(timestamp_fmt); 7484 7485 ret = for_each_pool(argc, argv, B_TRUE, NULL, 7486 status_callback, &cb); 7487 7488 if (argc == 0 && cb.cb_count == 0) 7489 (void) printf(gettext("no pools available\n")); 7490 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 7491 (void) printf(gettext("all pools are healthy\n")); 7492 7493 if (ret != 0) 7494 return (ret); 7495 7496 if (interval == 0) 7497 break; 7498 7499 if (count != 0 && --count == 0) 7500 break; 7501 7502 (void) fsleep(interval); 7503 } 7504 7505 return (0); 7506 } 7507 7508 typedef struct upgrade_cbdata { 7509 int cb_first; 7510 int cb_argc; 7511 uint64_t cb_version; 7512 char **cb_argv; 7513 } upgrade_cbdata_t; 7514 7515 static int 7516 upgrade_version(zpool_handle_t *zhp, uint64_t version) 7517 { 7518 int ret; 7519 nvlist_t *config; 7520 uint64_t oldversion; 7521 7522 config = zpool_get_config(zhp, NULL); 7523 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7524 &oldversion) == 0); 7525 7526 assert(SPA_VERSION_IS_SUPPORTED(oldversion)); 7527 assert(oldversion < version); 7528 7529 ret = zpool_upgrade(zhp, version); 7530 if (ret != 0) 7531 return (ret); 7532 7533 if (version >= SPA_VERSION_FEATURES) { 7534 (void) printf(gettext("Successfully upgraded " 7535 "'%s' from version %llu to feature flags.\n"), 7536 zpool_get_name(zhp), oldversion); 7537 } else { 7538 (void) printf(gettext("Successfully upgraded " 7539 "'%s' from version %llu to version %llu.\n"), 7540 zpool_get_name(zhp), oldversion, version); 7541 } 7542 7543 return (0); 7544 } 7545 7546 static int 7547 upgrade_enable_all(zpool_handle_t *zhp, int *countp) 7548 { 7549 int i, ret, count; 7550 boolean_t firstff = B_TRUE; 7551 nvlist_t *enabled = zpool_get_features(zhp); 7552 7553 count = 0; 7554 for (i = 0; i < SPA_FEATURES; i++) { 7555 const char *fname = spa_feature_table[i].fi_uname; 7556 const char *fguid = spa_feature_table[i].fi_guid; 7557 if (!nvlist_exists(enabled, fguid)) { 7558 char *propname; 7559 verify(-1 != asprintf(&propname, "feature@%s", fname)); 7560 ret = zpool_set_prop(zhp, propname, 7561 ZFS_FEATURE_ENABLED); 7562 if (ret != 0) { 7563 free(propname); 7564 return (ret); 7565 } 7566 count++; 7567 7568 if (firstff) { 7569 (void) printf(gettext("Enabled the " 7570 "following features on '%s':\n"), 7571 zpool_get_name(zhp)); 7572 firstff = B_FALSE; 7573 } 7574 (void) printf(gettext(" %s\n"), fname); 7575 free(propname); 7576 } 7577 } 7578 7579 if (countp != NULL) 7580 *countp = count; 7581 return (0); 7582 } 7583 7584 static int 7585 upgrade_cb(zpool_handle_t *zhp, void *arg) 7586 { 7587 upgrade_cbdata_t *cbp = arg; 7588 nvlist_t *config; 7589 uint64_t version; 7590 boolean_t printnl = B_FALSE; 7591 int ret; 7592 7593 config = zpool_get_config(zhp, NULL); 7594 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7595 &version) == 0); 7596 7597 assert(SPA_VERSION_IS_SUPPORTED(version)); 7598 7599 if (version < cbp->cb_version) { 7600 cbp->cb_first = B_FALSE; 7601 ret = upgrade_version(zhp, cbp->cb_version); 7602 if (ret != 0) 7603 return (ret); 7604 printnl = B_TRUE; 7605 7606 /* 7607 * If they did "zpool upgrade -a", then we could 7608 * be doing ioctls to different pools. We need 7609 * to log this history once to each pool, and bypass 7610 * the normal history logging that happens in main(). 7611 */ 7612 (void) zpool_log_history(g_zfs, history_str); 7613 log_history = B_FALSE; 7614 } 7615 7616 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 7617 int count; 7618 ret = upgrade_enable_all(zhp, &count); 7619 if (ret != 0) 7620 return (ret); 7621 7622 if (count > 0) { 7623 cbp->cb_first = B_FALSE; 7624 printnl = B_TRUE; 7625 } 7626 } 7627 7628 if (printnl) { 7629 (void) printf(gettext("\n")); 7630 } 7631 7632 return (0); 7633 } 7634 7635 static int 7636 upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) 7637 { 7638 upgrade_cbdata_t *cbp = arg; 7639 nvlist_t *config; 7640 uint64_t version; 7641 7642 config = zpool_get_config(zhp, NULL); 7643 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7644 &version) == 0); 7645 7646 assert(SPA_VERSION_IS_SUPPORTED(version)); 7647 7648 if (version < SPA_VERSION_FEATURES) { 7649 if (cbp->cb_first) { 7650 (void) printf(gettext("The following pools are " 7651 "formatted with legacy version numbers and can\n" 7652 "be upgraded to use feature flags. After " 7653 "being upgraded, these pools\nwill no " 7654 "longer be accessible by software that does not " 7655 "support feature\nflags.\n\n")); 7656 (void) printf(gettext("VER POOL\n")); 7657 (void) printf(gettext("--- ------------\n")); 7658 cbp->cb_first = B_FALSE; 7659 } 7660 7661 (void) printf("%2llu %s\n", (u_longlong_t)version, 7662 zpool_get_name(zhp)); 7663 } 7664 7665 return (0); 7666 } 7667 7668 static int 7669 upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) 7670 { 7671 upgrade_cbdata_t *cbp = arg; 7672 nvlist_t *config; 7673 uint64_t version; 7674 7675 config = zpool_get_config(zhp, NULL); 7676 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 7677 &version) == 0); 7678 7679 if (version >= SPA_VERSION_FEATURES) { 7680 int i; 7681 boolean_t poolfirst = B_TRUE; 7682 nvlist_t *enabled = zpool_get_features(zhp); 7683 7684 for (i = 0; i < SPA_FEATURES; i++) { 7685 const char *fguid = spa_feature_table[i].fi_guid; 7686 const char *fname = spa_feature_table[i].fi_uname; 7687 if (!nvlist_exists(enabled, fguid)) { 7688 if (cbp->cb_first) { 7689 (void) printf(gettext("\nSome " 7690 "supported features are not " 7691 "enabled on the following pools. " 7692 "Once a\nfeature is enabled the " 7693 "pool may become incompatible with " 7694 "software\nthat does not support " 7695 "the feature. See " 7696 "zpool-features(5) for " 7697 "details.\n\n")); 7698 (void) printf(gettext("POOL " 7699 "FEATURE\n")); 7700 (void) printf(gettext("------" 7701 "---------\n")); 7702 cbp->cb_first = B_FALSE; 7703 } 7704 7705 if (poolfirst) { 7706 (void) printf(gettext("%s\n"), 7707 zpool_get_name(zhp)); 7708 poolfirst = B_FALSE; 7709 } 7710 7711 (void) printf(gettext(" %s\n"), fname); 7712 } 7713 } 7714 } 7715 7716 return (0); 7717 } 7718 7719 /* ARGSUSED */ 7720 static int 7721 upgrade_one(zpool_handle_t *zhp, void *data) 7722 { 7723 boolean_t printnl = B_FALSE; 7724 upgrade_cbdata_t *cbp = data; 7725 uint64_t cur_version; 7726 int ret; 7727 7728 if (strcmp("log", zpool_get_name(zhp)) == 0) { 7729 (void) printf(gettext("'log' is now a reserved word\n" 7730 "Pool 'log' must be renamed using export and import" 7731 " to upgrade.\n")); 7732 return (1); 7733 } 7734 7735 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 7736 if (cur_version > cbp->cb_version) { 7737 (void) printf(gettext("Pool '%s' is already formatted " 7738 "using more current version '%llu'.\n\n"), 7739 zpool_get_name(zhp), cur_version); 7740 return (0); 7741 } 7742 7743 if (cbp->cb_version != SPA_VERSION && cur_version == cbp->cb_version) { 7744 (void) printf(gettext("Pool '%s' is already formatted " 7745 "using version %llu.\n\n"), zpool_get_name(zhp), 7746 cbp->cb_version); 7747 return (0); 7748 } 7749 7750 if (cur_version != cbp->cb_version) { 7751 printnl = B_TRUE; 7752 ret = upgrade_version(zhp, cbp->cb_version); 7753 if (ret != 0) 7754 return (ret); 7755 } 7756 7757 if (cbp->cb_version >= SPA_VERSION_FEATURES) { 7758 int count = 0; 7759 ret = upgrade_enable_all(zhp, &count); 7760 if (ret != 0) 7761 return (ret); 7762 7763 if (count != 0) { 7764 printnl = B_TRUE; 7765 } else if (cur_version == SPA_VERSION) { 7766 (void) printf(gettext("Pool '%s' already has all " 7767 "supported features enabled.\n"), 7768 zpool_get_name(zhp)); 7769 } 7770 } 7771 7772 if (printnl) { 7773 (void) printf(gettext("\n")); 7774 } 7775 7776 return (0); 7777 } 7778 7779 /* 7780 * zpool upgrade 7781 * zpool upgrade -v 7782 * zpool upgrade [-V version] <-a | pool ...> 7783 * 7784 * With no arguments, display downrev'd ZFS pool available for upgrade. 7785 * Individual pools can be upgraded by specifying the pool, and '-a' will 7786 * upgrade all pools. 7787 */ 7788 int 7789 zpool_do_upgrade(int argc, char **argv) 7790 { 7791 int c; 7792 upgrade_cbdata_t cb = { 0 }; 7793 int ret = 0; 7794 boolean_t showversions = B_FALSE; 7795 boolean_t upgradeall = B_FALSE; 7796 char *end; 7797 7798 7799 /* check options */ 7800 while ((c = getopt(argc, argv, ":avV:")) != -1) { 7801 switch (c) { 7802 case 'a': 7803 upgradeall = B_TRUE; 7804 break; 7805 case 'v': 7806 showversions = B_TRUE; 7807 break; 7808 case 'V': 7809 cb.cb_version = strtoll(optarg, &end, 10); 7810 if (*end != '\0' || 7811 !SPA_VERSION_IS_SUPPORTED(cb.cb_version)) { 7812 (void) fprintf(stderr, 7813 gettext("invalid version '%s'\n"), optarg); 7814 usage(B_FALSE); 7815 } 7816 break; 7817 case ':': 7818 (void) fprintf(stderr, gettext("missing argument for " 7819 "'%c' option\n"), optopt); 7820 usage(B_FALSE); 7821 break; 7822 case '?': 7823 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 7824 optopt); 7825 usage(B_FALSE); 7826 } 7827 } 7828 7829 cb.cb_argc = argc; 7830 cb.cb_argv = argv; 7831 argc -= optind; 7832 argv += optind; 7833 7834 if (cb.cb_version == 0) { 7835 cb.cb_version = SPA_VERSION; 7836 } else if (!upgradeall && argc == 0) { 7837 (void) fprintf(stderr, gettext("-V option is " 7838 "incompatible with other arguments\n")); 7839 usage(B_FALSE); 7840 } 7841 7842 if (showversions) { 7843 if (upgradeall || argc != 0) { 7844 (void) fprintf(stderr, gettext("-v option is " 7845 "incompatible with other arguments\n")); 7846 usage(B_FALSE); 7847 } 7848 } else if (upgradeall) { 7849 if (argc != 0) { 7850 (void) fprintf(stderr, gettext("-a option should not " 7851 "be used along with a pool name\n")); 7852 usage(B_FALSE); 7853 } 7854 } 7855 7856 (void) printf(gettext("This system supports ZFS pool feature " 7857 "flags.\n\n")); 7858 if (showversions) { 7859 int i; 7860 7861 (void) printf(gettext("The following features are " 7862 "supported:\n\n")); 7863 (void) printf(gettext("FEAT DESCRIPTION\n")); 7864 (void) printf("----------------------------------------------" 7865 "---------------\n"); 7866 for (i = 0; i < SPA_FEATURES; i++) { 7867 zfeature_info_t *fi = &spa_feature_table[i]; 7868 const char *ro = 7869 (fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ? 7870 " (read-only compatible)" : ""; 7871 7872 (void) printf("%-37s%s\n", fi->fi_uname, ro); 7873 (void) printf(" %s\n", fi->fi_desc); 7874 } 7875 (void) printf("\n"); 7876 7877 (void) printf(gettext("The following legacy versions are also " 7878 "supported:\n\n")); 7879 (void) printf(gettext("VER DESCRIPTION\n")); 7880 (void) printf("--- -----------------------------------------" 7881 "---------------\n"); 7882 (void) printf(gettext(" 1 Initial ZFS version\n")); 7883 (void) printf(gettext(" 2 Ditto blocks " 7884 "(replicated metadata)\n")); 7885 (void) printf(gettext(" 3 Hot spares and double parity " 7886 "RAID-Z\n")); 7887 (void) printf(gettext(" 4 zpool history\n")); 7888 (void) printf(gettext(" 5 Compression using the gzip " 7889 "algorithm\n")); 7890 (void) printf(gettext(" 6 bootfs pool property\n")); 7891 (void) printf(gettext(" 7 Separate intent log devices\n")); 7892 (void) printf(gettext(" 8 Delegated administration\n")); 7893 (void) printf(gettext(" 9 refquota and refreservation " 7894 "properties\n")); 7895 (void) printf(gettext(" 10 Cache devices\n")); 7896 (void) printf(gettext(" 11 Improved scrub performance\n")); 7897 (void) printf(gettext(" 12 Snapshot properties\n")); 7898 (void) printf(gettext(" 13 snapused property\n")); 7899 (void) printf(gettext(" 14 passthrough-x aclinherit\n")); 7900 (void) printf(gettext(" 15 user/group space accounting\n")); 7901 (void) printf(gettext(" 16 stmf property support\n")); 7902 (void) printf(gettext(" 17 Triple-parity RAID-Z\n")); 7903 (void) printf(gettext(" 18 Snapshot user holds\n")); 7904 (void) printf(gettext(" 19 Log device removal\n")); 7905 (void) printf(gettext(" 20 Compression using zle " 7906 "(zero-length encoding)\n")); 7907 (void) printf(gettext(" 21 Deduplication\n")); 7908 (void) printf(gettext(" 22 Received properties\n")); 7909 (void) printf(gettext(" 23 Slim ZIL\n")); 7910 (void) printf(gettext(" 24 System attributes\n")); 7911 (void) printf(gettext(" 25 Improved scrub stats\n")); 7912 (void) printf(gettext(" 26 Improved snapshot deletion " 7913 "performance\n")); 7914 (void) printf(gettext(" 27 Improved snapshot creation " 7915 "performance\n")); 7916 (void) printf(gettext(" 28 Multiple vdev replacements\n")); 7917 (void) printf(gettext("\nFor more information on a particular " 7918 "version, including supported releases,\n")); 7919 (void) printf(gettext("see the ZFS Administration Guide.\n\n")); 7920 } else if (argc == 0 && upgradeall) { 7921 cb.cb_first = B_TRUE; 7922 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 7923 if (ret == 0 && cb.cb_first) { 7924 if (cb.cb_version == SPA_VERSION) { 7925 (void) printf(gettext("All pools are already " 7926 "formatted using feature flags.\n\n")); 7927 (void) printf(gettext("Every feature flags " 7928 "pool already has all supported features " 7929 "enabled.\n")); 7930 } else { 7931 (void) printf(gettext("All pools are already " 7932 "formatted with version %llu or higher.\n"), 7933 cb.cb_version); 7934 } 7935 } 7936 } else if (argc == 0) { 7937 cb.cb_first = B_TRUE; 7938 ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); 7939 assert(ret == 0); 7940 7941 if (cb.cb_first) { 7942 (void) printf(gettext("All pools are formatted " 7943 "using feature flags.\n\n")); 7944 } else { 7945 (void) printf(gettext("\nUse 'zpool upgrade -v' " 7946 "for a list of available legacy versions.\n")); 7947 } 7948 7949 cb.cb_first = B_TRUE; 7950 ret = zpool_iter(g_zfs, upgrade_list_disabled_cb, &cb); 7951 assert(ret == 0); 7952 7953 if (cb.cb_first) { 7954 (void) printf(gettext("Every feature flags pool has " 7955 "all supported features enabled.\n")); 7956 } else { 7957 (void) printf(gettext("\n")); 7958 } 7959 } else { 7960 ret = for_each_pool(argc, argv, B_FALSE, NULL, 7961 upgrade_one, &cb); 7962 } 7963 7964 return (ret); 7965 } 7966 7967 typedef struct hist_cbdata { 7968 boolean_t first; 7969 boolean_t longfmt; 7970 boolean_t internal; 7971 } hist_cbdata_t; 7972 7973 static void 7974 print_history_records(nvlist_t *nvhis, hist_cbdata_t *cb) 7975 { 7976 nvlist_t **records; 7977 uint_t numrecords; 7978 int i; 7979 7980 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 7981 &records, &numrecords) == 0); 7982 for (i = 0; i < numrecords; i++) { 7983 nvlist_t *rec = records[i]; 7984 char tbuf[30] = ""; 7985 7986 if (nvlist_exists(rec, ZPOOL_HIST_TIME)) { 7987 time_t tsec; 7988 struct tm t; 7989 7990 tsec = fnvlist_lookup_uint64(records[i], 7991 ZPOOL_HIST_TIME); 7992 (void) localtime_r(&tsec, &t); 7993 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 7994 } 7995 7996 if (nvlist_exists(rec, ZPOOL_HIST_CMD)) { 7997 (void) printf("%s %s", tbuf, 7998 fnvlist_lookup_string(rec, ZPOOL_HIST_CMD)); 7999 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_EVENT)) { 8000 int ievent = 8001 fnvlist_lookup_uint64(rec, ZPOOL_HIST_INT_EVENT); 8002 if (!cb->internal) 8003 continue; 8004 if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) { 8005 (void) printf("%s unrecognized record:\n", 8006 tbuf); 8007 dump_nvlist(rec, 4); 8008 continue; 8009 } 8010 (void) printf("%s [internal %s txg:%lld] %s", tbuf, 8011 zfs_history_event_names[ievent], 8012 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 8013 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_STR)); 8014 } else if (nvlist_exists(rec, ZPOOL_HIST_INT_NAME)) { 8015 if (!cb->internal) 8016 continue; 8017 (void) printf("%s [txg:%lld] %s", tbuf, 8018 fnvlist_lookup_uint64(rec, ZPOOL_HIST_TXG), 8019 fnvlist_lookup_string(rec, ZPOOL_HIST_INT_NAME)); 8020 if (nvlist_exists(rec, ZPOOL_HIST_DSNAME)) { 8021 (void) printf(" %s (%llu)", 8022 fnvlist_lookup_string(rec, 8023 ZPOOL_HIST_DSNAME), 8024 fnvlist_lookup_uint64(rec, 8025 ZPOOL_HIST_DSID)); 8026 } 8027 (void) printf(" %s", fnvlist_lookup_string(rec, 8028 ZPOOL_HIST_INT_STR)); 8029 } else if (nvlist_exists(rec, ZPOOL_HIST_IOCTL)) { 8030 if (!cb->internal) 8031 continue; 8032 (void) printf("%s ioctl %s\n", tbuf, 8033 fnvlist_lookup_string(rec, ZPOOL_HIST_IOCTL)); 8034 if (nvlist_exists(rec, ZPOOL_HIST_INPUT_NVL)) { 8035 (void) printf(" input:\n"); 8036 dump_nvlist(fnvlist_lookup_nvlist(rec, 8037 ZPOOL_HIST_INPUT_NVL), 8); 8038 } 8039 if (nvlist_exists(rec, ZPOOL_HIST_OUTPUT_NVL)) { 8040 (void) printf(" output:\n"); 8041 dump_nvlist(fnvlist_lookup_nvlist(rec, 8042 ZPOOL_HIST_OUTPUT_NVL), 8); 8043 } 8044 if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) { 8045 (void) printf(" errno: %lld\n", 8046 fnvlist_lookup_int64(rec, 8047 ZPOOL_HIST_ERRNO)); 8048 } 8049 } else { 8050 if (!cb->internal) 8051 continue; 8052 (void) printf("%s unrecognized record:\n", tbuf); 8053 dump_nvlist(rec, 4); 8054 } 8055 8056 if (!cb->longfmt) { 8057 (void) printf("\n"); 8058 continue; 8059 } 8060 (void) printf(" ["); 8061 if (nvlist_exists(rec, ZPOOL_HIST_WHO)) { 8062 uid_t who = fnvlist_lookup_uint64(rec, ZPOOL_HIST_WHO); 8063 struct passwd *pwd = getpwuid(who); 8064 (void) printf("user %d ", (int)who); 8065 if (pwd != NULL) 8066 (void) printf("(%s) ", pwd->pw_name); 8067 } 8068 if (nvlist_exists(rec, ZPOOL_HIST_HOST)) { 8069 (void) printf("on %s", 8070 fnvlist_lookup_string(rec, ZPOOL_HIST_HOST)); 8071 } 8072 if (nvlist_exists(rec, ZPOOL_HIST_ZONE)) { 8073 (void) printf(":%s", 8074 fnvlist_lookup_string(rec, ZPOOL_HIST_ZONE)); 8075 } 8076 (void) printf("]"); 8077 (void) printf("\n"); 8078 } 8079 } 8080 8081 /* 8082 * Print out the command history for a specific pool. 8083 */ 8084 static int 8085 get_history_one(zpool_handle_t *zhp, void *data) 8086 { 8087 nvlist_t *nvhis; 8088 int ret; 8089 hist_cbdata_t *cb = (hist_cbdata_t *)data; 8090 uint64_t off = 0; 8091 boolean_t eof = B_FALSE; 8092 8093 cb->first = B_FALSE; 8094 8095 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 8096 8097 while (!eof) { 8098 if ((ret = zpool_get_history(zhp, &nvhis, &off, &eof)) != 0) 8099 return (ret); 8100 8101 print_history_records(nvhis, cb); 8102 nvlist_free(nvhis); 8103 } 8104 (void) printf("\n"); 8105 8106 return (ret); 8107 } 8108 8109 /* 8110 * zpool history <pool> 8111 * 8112 * Displays the history of commands that modified pools. 8113 */ 8114 int 8115 zpool_do_history(int argc, char **argv) 8116 { 8117 hist_cbdata_t cbdata = { 0 }; 8118 int ret; 8119 int c; 8120 8121 cbdata.first = B_TRUE; 8122 /* check options */ 8123 while ((c = getopt(argc, argv, "li")) != -1) { 8124 switch (c) { 8125 case 'l': 8126 cbdata.longfmt = B_TRUE; 8127 break; 8128 case 'i': 8129 cbdata.internal = B_TRUE; 8130 break; 8131 case '?': 8132 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8133 optopt); 8134 usage(B_FALSE); 8135 } 8136 } 8137 argc -= optind; 8138 argv += optind; 8139 8140 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 8141 &cbdata); 8142 8143 if (argc == 0 && cbdata.first == B_TRUE) { 8144 (void) printf(gettext("no pools available\n")); 8145 return (0); 8146 } 8147 8148 return (ret); 8149 } 8150 8151 static int 8152 get_callback(zpool_handle_t *zhp, void *data) 8153 { 8154 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 8155 char value[MAXNAMELEN]; 8156 zprop_source_t srctype; 8157 zprop_list_t *pl; 8158 8159 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 8160 8161 /* 8162 * Skip the special fake placeholder. This will also skip 8163 * over the name property when 'all' is specified. 8164 */ 8165 if (pl->pl_prop == ZPOOL_PROP_NAME && 8166 pl == cbp->cb_proplist) 8167 continue; 8168 8169 if (pl->pl_prop == ZPROP_INVAL && 8170 (zpool_prop_feature(pl->pl_user_prop) || 8171 zpool_prop_unsupported(pl->pl_user_prop))) { 8172 srctype = ZPROP_SRC_LOCAL; 8173 8174 if (zpool_prop_get_feature(zhp, pl->pl_user_prop, 8175 value, sizeof (value)) == 0) { 8176 zprop_print_one_property(zpool_get_name(zhp), 8177 cbp, pl->pl_user_prop, value, srctype, 8178 NULL, NULL); 8179 } 8180 } else { 8181 if (zpool_get_prop(zhp, pl->pl_prop, value, 8182 sizeof (value), &srctype, cbp->cb_literal) != 0) 8183 continue; 8184 8185 zprop_print_one_property(zpool_get_name(zhp), cbp, 8186 zpool_prop_to_name(pl->pl_prop), value, srctype, 8187 NULL, NULL); 8188 } 8189 } 8190 return (0); 8191 } 8192 8193 /* 8194 * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... 8195 * 8196 * -H Scripted mode. Don't display headers, and separate properties 8197 * by a single tab. 8198 * -o List of columns to display. Defaults to 8199 * "name,property,value,source". 8200 * -p Diplay values in parsable (exact) format. 8201 * 8202 * Get properties of pools in the system. Output space statistics 8203 * for each one as well as other attributes. 8204 */ 8205 int 8206 zpool_do_get(int argc, char **argv) 8207 { 8208 zprop_get_cbdata_t cb = { 0 }; 8209 zprop_list_t fake_name = { 0 }; 8210 int ret; 8211 int c, i; 8212 char *value; 8213 8214 cb.cb_first = B_TRUE; 8215 8216 /* 8217 * Set up default columns and sources. 8218 */ 8219 cb.cb_sources = ZPROP_SRC_ALL; 8220 cb.cb_columns[0] = GET_COL_NAME; 8221 cb.cb_columns[1] = GET_COL_PROPERTY; 8222 cb.cb_columns[2] = GET_COL_VALUE; 8223 cb.cb_columns[3] = GET_COL_SOURCE; 8224 cb.cb_type = ZFS_TYPE_POOL; 8225 8226 /* check options */ 8227 while ((c = getopt(argc, argv, ":Hpo:")) != -1) { 8228 switch (c) { 8229 case 'p': 8230 cb.cb_literal = B_TRUE; 8231 break; 8232 case 'H': 8233 cb.cb_scripted = B_TRUE; 8234 break; 8235 case 'o': 8236 bzero(&cb.cb_columns, sizeof (cb.cb_columns)); 8237 i = 0; 8238 while (*optarg != '\0') { 8239 static char *col_subopts[] = 8240 { "name", "property", "value", "source", 8241 "all", NULL }; 8242 8243 if (i == ZFS_GET_NCOLS) { 8244 (void) fprintf(stderr, gettext("too " 8245 "many fields given to -o " 8246 "option\n")); 8247 usage(B_FALSE); 8248 } 8249 8250 switch (getsubopt(&optarg, col_subopts, 8251 &value)) { 8252 case 0: 8253 cb.cb_columns[i++] = GET_COL_NAME; 8254 break; 8255 case 1: 8256 cb.cb_columns[i++] = GET_COL_PROPERTY; 8257 break; 8258 case 2: 8259 cb.cb_columns[i++] = GET_COL_VALUE; 8260 break; 8261 case 3: 8262 cb.cb_columns[i++] = GET_COL_SOURCE; 8263 break; 8264 case 4: 8265 if (i > 0) { 8266 (void) fprintf(stderr, 8267 gettext("\"all\" conflicts " 8268 "with specific fields " 8269 "given to -o option\n")); 8270 usage(B_FALSE); 8271 } 8272 cb.cb_columns[0] = GET_COL_NAME; 8273 cb.cb_columns[1] = GET_COL_PROPERTY; 8274 cb.cb_columns[2] = GET_COL_VALUE; 8275 cb.cb_columns[3] = GET_COL_SOURCE; 8276 i = ZFS_GET_NCOLS; 8277 break; 8278 default: 8279 (void) fprintf(stderr, 8280 gettext("invalid column name " 8281 "'%s'\n"), value); 8282 usage(B_FALSE); 8283 } 8284 } 8285 break; 8286 case '?': 8287 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8288 optopt); 8289 usage(B_FALSE); 8290 } 8291 } 8292 8293 argc -= optind; 8294 argv += optind; 8295 8296 if (argc < 1) { 8297 (void) fprintf(stderr, gettext("missing property " 8298 "argument\n")); 8299 usage(B_FALSE); 8300 } 8301 8302 if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, 8303 ZFS_TYPE_POOL) != 0) 8304 usage(B_FALSE); 8305 8306 argc--; 8307 argv++; 8308 8309 if (cb.cb_proplist != NULL) { 8310 fake_name.pl_prop = ZPOOL_PROP_NAME; 8311 fake_name.pl_width = strlen(gettext("NAME")); 8312 fake_name.pl_next = cb.cb_proplist; 8313 cb.cb_proplist = &fake_name; 8314 } 8315 8316 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 8317 get_callback, &cb); 8318 8319 if (cb.cb_proplist == &fake_name) 8320 zprop_free_list(fake_name.pl_next); 8321 else 8322 zprop_free_list(cb.cb_proplist); 8323 8324 return (ret); 8325 } 8326 8327 typedef struct set_cbdata { 8328 char *cb_propname; 8329 char *cb_value; 8330 boolean_t cb_any_successful; 8331 } set_cbdata_t; 8332 8333 int 8334 set_callback(zpool_handle_t *zhp, void *data) 8335 { 8336 int error; 8337 set_cbdata_t *cb = (set_cbdata_t *)data; 8338 8339 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 8340 8341 if (!error) 8342 cb->cb_any_successful = B_TRUE; 8343 8344 return (error); 8345 } 8346 8347 int 8348 zpool_do_set(int argc, char **argv) 8349 { 8350 set_cbdata_t cb = { 0 }; 8351 int error; 8352 8353 if (argc > 1 && argv[1][0] == '-') { 8354 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 8355 argv[1][1]); 8356 usage(B_FALSE); 8357 } 8358 8359 if (argc < 2) { 8360 (void) fprintf(stderr, gettext("missing property=value " 8361 "argument\n")); 8362 usage(B_FALSE); 8363 } 8364 8365 if (argc < 3) { 8366 (void) fprintf(stderr, gettext("missing pool name\n")); 8367 usage(B_FALSE); 8368 } 8369 8370 if (argc > 3) { 8371 (void) fprintf(stderr, gettext("too many pool names\n")); 8372 usage(B_FALSE); 8373 } 8374 8375 cb.cb_propname = argv[1]; 8376 cb.cb_value = strchr(cb.cb_propname, '='); 8377 if (cb.cb_value == NULL) { 8378 (void) fprintf(stderr, gettext("missing value in " 8379 "property=value argument\n")); 8380 usage(B_FALSE); 8381 } 8382 8383 *(cb.cb_value) = '\0'; 8384 cb.cb_value++; 8385 8386 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 8387 set_callback, &cb); 8388 8389 return (error); 8390 } 8391 8392 static int 8393 find_command_idx(char *command, int *idx) 8394 { 8395 int i; 8396 8397 for (i = 0; i < NCOMMAND; i++) { 8398 if (command_table[i].name == NULL) 8399 continue; 8400 8401 if (strcmp(command, command_table[i].name) == 0) { 8402 *idx = i; 8403 return (0); 8404 } 8405 } 8406 return (1); 8407 } 8408 8409 int 8410 main(int argc, char **argv) 8411 { 8412 int ret = 0; 8413 int i; 8414 char *cmdname; 8415 8416 (void) setlocale(LC_ALL, ""); 8417 (void) textdomain(TEXT_DOMAIN); 8418 8419 if ((g_zfs = libzfs_init()) == NULL) { 8420 (void) fprintf(stderr, gettext("internal error: failed to " 8421 "initialize ZFS library\n")); 8422 return (1); 8423 } 8424 8425 libzfs_print_on_error(g_zfs, B_TRUE); 8426 8427 opterr = 0; 8428 8429 /* 8430 * Make sure the user has specified some command. 8431 */ 8432 if (argc < 2) { 8433 (void) fprintf(stderr, gettext("missing command\n")); 8434 usage(B_FALSE); 8435 } 8436 8437 cmdname = argv[1]; 8438 8439 /* 8440 * Special case '-?' 8441 */ 8442 if (strcmp(cmdname, "-?") == 0) 8443 usage(B_TRUE); 8444 8445 zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); 8446 8447 /* 8448 * Run the appropriate command. 8449 */ 8450 if (find_command_idx(cmdname, &i) == 0) { 8451 current_command = &command_table[i]; 8452 ret = command_table[i].func(argc - 1, argv + 1); 8453 } else if (strchr(cmdname, '=')) { 8454 verify(find_command_idx("set", &i) == 0); 8455 current_command = &command_table[i]; 8456 ret = command_table[i].func(argc, argv); 8457 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 8458 /* 8459 * 'freeze' is a vile debugging abomination, so we treat 8460 * it as such. 8461 */ 8462 char buf[16384]; 8463 int fd = open(ZFS_DEV, O_RDWR); 8464 (void) strcpy((void *)buf, argv[2]); 8465 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 8466 } else { 8467 (void) fprintf(stderr, gettext("unrecognized " 8468 "command '%s'\n"), cmdname); 8469 usage(B_FALSE); 8470 } 8471 8472 if (ret == 0 && log_history) 8473 (void) zpool_log_history(g_zfs, history_str); 8474 8475 libzfs_fini(g_zfs); 8476 8477 /* 8478 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 8479 * for the purposes of running ::findleaks. 8480 */ 8481 if (getenv("ZFS_ABORT") != NULL) { 8482 (void) printf("dumping core by request\n"); 8483 abort(); 8484 } 8485 8486 return (ret); 8487 }