zpool_main.c revision 207672
1280288Sjkim/* 2280288Sjkim * CDDL HEADER START 3280288Sjkim * 4280288Sjkim * The contents of this file are subject to the terms of the 5280288Sjkim * Common Development and Distribution License (the "License"). 6280288Sjkim * You may not use this file except in compliance with the License. 7280288Sjkim * 8280288Sjkim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9280288Sjkim * or http://www.opensolaris.org/os/licensing. 10280288Sjkim * See the License for the specific language governing permissions 11280288Sjkim * and limitations under the License. 12280288Sjkim * 13280288Sjkim * When distributing Covered Code, include this CDDL HEADER in each 14280288Sjkim * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15280288Sjkim * If applicable, add the following below this CDDL HEADER, with the 16280288Sjkim * fields enclosed by brackets "[]" replaced with your own identifying 17280288Sjkim * information: Portions Copyright [yyyy] [name of copyright owner] 18280288Sjkim * 19280288Sjkim * CDDL HEADER END 20280288Sjkim */ 21280288Sjkim 22280288Sjkim/* 23280288Sjkim * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24280288Sjkim * Use is subject to license terms. 25280288Sjkim */ 26280288Sjkim 27280288Sjkim#include <solaris.h> 28280288Sjkim#include <assert.h> 29280288Sjkim#include <ctype.h> 30280288Sjkim#include <dirent.h> 31280288Sjkim#include <errno.h> 32280288Sjkim#include <fcntl.h> 33280288Sjkim#include <libgen.h> 34280288Sjkim#include <libintl.h> 35280288Sjkim#include <libuutil.h> 36280288Sjkim#include <locale.h> 37280288Sjkim#include <stdio.h> 38280288Sjkim#include <stdlib.h> 39280288Sjkim#include <string.h> 40280288Sjkim#include <strings.h> 41280288Sjkim#include <unistd.h> 42280288Sjkim#include <priv.h> 43280288Sjkim#include <pwd.h> 44280288Sjkim#include <zone.h> 45280288Sjkim#include <sys/time.h> 46280288Sjkim#include <sys/fs/zfs.h> 47280288Sjkim 48280288Sjkim#include <sys/stat.h> 49280288Sjkim 50280288Sjkim#include <libzfs.h> 51280288Sjkim 52280288Sjkim#include "zpool_util.h" 53280288Sjkim#include "zfs_comutil.h" 54280288Sjkim 55280288Sjkimstatic int zpool_do_create(int, char **); 56280288Sjkimstatic int zpool_do_destroy(int, char **); 57280288Sjkim 58280288Sjkimstatic int zpool_do_add(int, char **); 59280288Sjkimstatic int zpool_do_remove(int, char **); 60280288Sjkim 61280288Sjkimstatic int zpool_do_list(int, char **); 62280288Sjkimstatic int zpool_do_iostat(int, char **); 63280288Sjkimstatic int zpool_do_status(int, char **); 64280288Sjkim 65280288Sjkimstatic int zpool_do_online(int, char **); 66280288Sjkimstatic int zpool_do_offline(int, char **); 67280288Sjkimstatic int zpool_do_clear(int, char **); 68280288Sjkim 69280288Sjkimstatic int zpool_do_attach(int, char **); 70280288Sjkimstatic int zpool_do_detach(int, char **); 71280288Sjkimstatic int zpool_do_replace(int, char **); 72280288Sjkim 73280288Sjkimstatic int zpool_do_scrub(int, char **); 74280288Sjkim 75280288Sjkimstatic int zpool_do_import(int, char **); 76280288Sjkimstatic int zpool_do_export(int, char **); 77280288Sjkim 78280288Sjkimstatic int zpool_do_upgrade(int, char **); 79280288Sjkim 80280288Sjkimstatic int zpool_do_history(int, char **); 81280288Sjkim 82280288Sjkimstatic int zpool_do_get(int, char **); 83280288Sjkimstatic int zpool_do_set(int, char **); 84280288Sjkim 85280288Sjkim/* 86280288Sjkim * These libumem hooks provide a reasonable set of defaults for the allocator's 87280288Sjkim * debugging facilities. 88280288Sjkim */ 89280288Sjkim 90280288Sjkim#ifdef DEBUG 91280288Sjkimconst char * 92280288Sjkim_umem_debug_init(void) 93280288Sjkim{ 94280288Sjkim return ("default,verbose"); /* $UMEM_DEBUG setting */ 95280288Sjkim} 96280288Sjkim 97280288Sjkimconst char * 98280288Sjkim_umem_logging_init(void) 99280288Sjkim{ 100280288Sjkim return ("fail,contents"); /* $UMEM_LOGGING setting */ 101280288Sjkim} 102280288Sjkim#endif 103280288Sjkim 104280288Sjkimtypedef enum { 105280288Sjkim HELP_ADD, 106280288Sjkim HELP_ATTACH, 107280288Sjkim HELP_CLEAR, 108280288Sjkim HELP_CREATE, 109280288Sjkim HELP_DESTROY, 110280288Sjkim HELP_DETACH, 111280288Sjkim HELP_EXPORT, 112280288Sjkim HELP_HISTORY, 113280288Sjkim HELP_IMPORT, 114280288Sjkim HELP_IOSTAT, 115280288Sjkim HELP_LIST, 116280288Sjkim HELP_OFFLINE, 117280288Sjkim HELP_ONLINE, 118280288Sjkim HELP_REPLACE, 119280288Sjkim HELP_REMOVE, 120280288Sjkim HELP_SCRUB, 121280288Sjkim HELP_STATUS, 122280288Sjkim HELP_UPGRADE, 123280288Sjkim HELP_GET, 124280288Sjkim HELP_SET 125280288Sjkim} zpool_help_t; 126280288Sjkim 127280288Sjkim 128280288Sjkimtypedef struct zpool_command { 129280288Sjkim const char *name; 130280288Sjkim int (*func)(int, char **); 131280288Sjkim zpool_help_t usage; 132280288Sjkim} zpool_command_t; 133280288Sjkim 134280288Sjkim/* 135280288Sjkim * Master command table. Each ZFS command has a name, associated function, and 136280288Sjkim * usage message. The usage messages need to be internationalized, so we have 137280288Sjkim * to have a function to return the usage message based on a command index. 138280288Sjkim * 139280288Sjkim * These commands are organized according to how they are displayed in the usage 140280288Sjkim * message. An empty command (one with a NULL name) indicates an empty line in 141280288Sjkim * the generic usage message. 142280288Sjkim */ 143280288Sjkimstatic zpool_command_t command_table[] = { 144280288Sjkim { "create", zpool_do_create, HELP_CREATE }, 145280288Sjkim { "destroy", zpool_do_destroy, HELP_DESTROY }, 146280288Sjkim { NULL }, 147280288Sjkim { "add", zpool_do_add, HELP_ADD }, 148280288Sjkim { "remove", zpool_do_remove, HELP_REMOVE }, 149280288Sjkim { NULL }, 150280288Sjkim { "list", zpool_do_list, HELP_LIST }, 151280288Sjkim { "iostat", zpool_do_iostat, HELP_IOSTAT }, 152280288Sjkim { "status", zpool_do_status, HELP_STATUS }, 153280288Sjkim { NULL }, 154280288Sjkim { "online", zpool_do_online, HELP_ONLINE }, 155280288Sjkim { "offline", zpool_do_offline, HELP_OFFLINE }, 156280288Sjkim { "clear", zpool_do_clear, HELP_CLEAR }, 157280288Sjkim { NULL }, 158280288Sjkim { "attach", zpool_do_attach, HELP_ATTACH }, 159280288Sjkim { "detach", zpool_do_detach, HELP_DETACH }, 160280288Sjkim { "replace", zpool_do_replace, HELP_REPLACE }, 161280288Sjkim { NULL }, 162280288Sjkim { "scrub", zpool_do_scrub, HELP_SCRUB }, 163280288Sjkim { NULL }, 164280288Sjkim { "import", zpool_do_import, HELP_IMPORT }, 165280288Sjkim { "export", zpool_do_export, HELP_EXPORT }, 166280288Sjkim { "upgrade", zpool_do_upgrade, HELP_UPGRADE }, 167280288Sjkim { NULL }, 168280288Sjkim { "history", zpool_do_history, HELP_HISTORY }, 169280288Sjkim { "get", zpool_do_get, HELP_GET }, 170280288Sjkim { "set", zpool_do_set, HELP_SET }, 171280288Sjkim}; 172280288Sjkim 173280288Sjkim#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) 174280288Sjkim 175280288Sjkimzpool_command_t *current_command; 176280288Sjkimstatic char history_str[HIS_MAX_RECORD_LEN]; 177280288Sjkim 178280288Sjkimstatic const char * 179280288Sjkimget_usage(zpool_help_t idx) { 180280288Sjkim switch (idx) { 181280288Sjkim case HELP_ADD: 182280288Sjkim return (gettext("\tadd [-fn] <pool> <vdev> ...\n")); 183280288Sjkim case HELP_ATTACH: 184280288Sjkim return (gettext("\tattach [-f] <pool> <device> " 185280288Sjkim "<new-device>\n")); 186280288Sjkim case HELP_CLEAR: 187280288Sjkim return (gettext("\tclear <pool> [device]\n")); 188280288Sjkim case HELP_CREATE: 189280288Sjkim return (gettext("\tcreate [-fn] [-o property=value] ... \n" 190280288Sjkim "\t [-O file-system-property=value] ... \n" 191280288Sjkim "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n")); 192280288Sjkim case HELP_DESTROY: 193280288Sjkim return (gettext("\tdestroy [-f] <pool>\n")); 194280288Sjkim case HELP_DETACH: 195280288Sjkim return (gettext("\tdetach <pool> <device>\n")); 196280288Sjkim case HELP_EXPORT: 197280288Sjkim return (gettext("\texport [-f] <pool> ...\n")); 198280288Sjkim case HELP_HISTORY: 199280288Sjkim return (gettext("\thistory [-il] [<pool>] ...\n")); 200280288Sjkim case HELP_IMPORT: 201280288Sjkim return (gettext("\timport [-d dir] [-D]\n" 202280288Sjkim "\timport [-o mntopts] [-o property=value] ... \n" 203280288Sjkim "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n" 204280288Sjkim "\timport [-o mntopts] [-o property=value] ... \n" 205280288Sjkim "\t [-d dir | -c cachefile] [-D] [-f] [-R root] " 206280288Sjkim "<pool | id> [newpool]\n")); 207280288Sjkim case HELP_IOSTAT: 208280288Sjkim return (gettext("\tiostat [-v] [pool] ... [interval " 209280288Sjkim "[count]]\n")); 210280288Sjkim case HELP_LIST: 211280288Sjkim return (gettext("\tlist [-H] [-o property[,...]] " 212280288Sjkim "[pool] ...\n")); 213280288Sjkim case HELP_OFFLINE: 214280288Sjkim return (gettext("\toffline [-t] <pool> <device> ...\n")); 215280288Sjkim case HELP_ONLINE: 216280288Sjkim return (gettext("\tonline <pool> <device> ...\n")); 217280288Sjkim case HELP_REPLACE: 218280288Sjkim return (gettext("\treplace [-f] <pool> <device> " 219280288Sjkim "[new-device]\n")); 220280288Sjkim case HELP_REMOVE: 221280288Sjkim return (gettext("\tremove <pool> <device> ...\n")); 222280288Sjkim case HELP_SCRUB: 223280288Sjkim return (gettext("\tscrub [-s] <pool> ...\n")); 224280288Sjkim case HELP_STATUS: 225280288Sjkim return (gettext("\tstatus [-vx] [pool] ...\n")); 226280288Sjkim case HELP_UPGRADE: 227280288Sjkim return (gettext("\tupgrade\n" 228280288Sjkim "\tupgrade -v\n" 229280288Sjkim "\tupgrade [-V version] <-a | pool ...>\n")); 230280288Sjkim case HELP_GET: 231280288Sjkim return (gettext("\tget <\"all\" | property[,...]> " 232280288Sjkim "<pool> ...\n")); 233280288Sjkim case HELP_SET: 234280288Sjkim return (gettext("\tset <property=value> <pool> \n")); 235280288Sjkim } 236280288Sjkim 237280288Sjkim abort(); 238280288Sjkim /* NOTREACHED */ 239280288Sjkim} 240280288Sjkim 241280288Sjkim 242280288Sjkim/* 243280288Sjkim * Callback routine that will print out a pool property value. 244280288Sjkim */ 245280288Sjkimstatic int 246280288Sjkimprint_prop_cb(int prop, void *cb) 247280288Sjkim{ 248280288Sjkim FILE *fp = cb; 249280288Sjkim 250280288Sjkim (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop)); 251280288Sjkim 252280288Sjkim if (zpool_prop_readonly(prop)) 253280288Sjkim (void) fprintf(fp, " NO "); 254280288Sjkim else 255280288Sjkim (void) fprintf(fp, " YES "); 256280288Sjkim 257280288Sjkim if (zpool_prop_values(prop) == NULL) 258280288Sjkim (void) fprintf(fp, "-\n"); 259280288Sjkim else 260280288Sjkim (void) fprintf(fp, "%s\n", zpool_prop_values(prop)); 261280288Sjkim 262280288Sjkim return (ZPROP_CONT); 263280288Sjkim} 264280288Sjkim 265280288Sjkim/* 266280288Sjkim * Display usage message. If we're inside a command, display only the usage for 267280288Sjkim * that command. Otherwise, iterate over the entire command table and display 268280288Sjkim * a complete usage message. 269280288Sjkim */ 270280288Sjkimvoid 271280288Sjkimusage(boolean_t requested) 272280288Sjkim{ 273280288Sjkim FILE *fp = requested ? stdout : stderr; 274280288Sjkim 275280288Sjkim if (current_command == NULL) { 276280288Sjkim int i; 277280288Sjkim 278280288Sjkim (void) fprintf(fp, gettext("usage: zpool command args ...\n")); 279280288Sjkim (void) fprintf(fp, 280280288Sjkim gettext("where 'command' is one of the following:\n\n")); 281280288Sjkim 282280288Sjkim for (i = 0; i < NCOMMAND; i++) { 283280288Sjkim if (command_table[i].name == NULL) 284280288Sjkim (void) fprintf(fp, "\n"); 285280288Sjkim else 286280288Sjkim (void) fprintf(fp, "%s", 287280288Sjkim get_usage(command_table[i].usage)); 288280288Sjkim } 289280288Sjkim } else { 290280288Sjkim (void) fprintf(fp, gettext("usage:\n")); 291280288Sjkim (void) fprintf(fp, "%s", get_usage(current_command->usage)); 292280288Sjkim } 293280288Sjkim 294280288Sjkim if (current_command != NULL && 295280288Sjkim ((strcmp(current_command->name, "set") == 0) || 296280288Sjkim (strcmp(current_command->name, "get") == 0) || 297280288Sjkim (strcmp(current_command->name, "list") == 0))) { 298280288Sjkim 299280288Sjkim (void) fprintf(fp, 300280288Sjkim gettext("\nthe following properties are supported:\n")); 301280288Sjkim 302280288Sjkim (void) fprintf(fp, "\n\t%-13s %s %s\n\n", 303280288Sjkim "PROPERTY", "EDIT", "VALUES"); 304280288Sjkim 305280288Sjkim /* Iterate over all properties */ 306280288Sjkim (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE, 307280288Sjkim ZFS_TYPE_POOL); 308280288Sjkim } 309280288Sjkim 310280288Sjkim /* 311280288Sjkim * See comments at end of main(). 312280288Sjkim */ 313280288Sjkim if (getenv("ZFS_ABORT") != NULL) { 314280288Sjkim (void) printf("dumping core by request\n"); 315280288Sjkim abort(); 316280288Sjkim } 317280288Sjkim 318280288Sjkim exit(requested ? 0 : 2); 319280288Sjkim} 320280288Sjkim 321280288Sjkimvoid 322280288Sjkimprint_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent, 323280288Sjkim boolean_t print_logs) 324280288Sjkim{ 325280288Sjkim nvlist_t **child; 326280288Sjkim uint_t c, children; 327280288Sjkim char *vname; 328280288Sjkim 329280288Sjkim if (name != NULL) 330280288Sjkim (void) printf("\t%*s%s\n", indent, "", name); 331280288Sjkim 332280288Sjkim if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 333280288Sjkim &child, &children) != 0) 334280288Sjkim return; 335280288Sjkim 336280288Sjkim for (c = 0; c < children; c++) { 337280288Sjkim uint64_t is_log = B_FALSE; 338280288Sjkim 339280288Sjkim (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 340280288Sjkim &is_log); 341280288Sjkim if ((is_log && !print_logs) || (!is_log && print_logs)) 342280288Sjkim continue; 343280288Sjkim 344280288Sjkim vname = zpool_vdev_name(g_zfs, zhp, child[c]); 345280288Sjkim print_vdev_tree(zhp, vname, child[c], indent + 2, 346280288Sjkim B_FALSE); 347280288Sjkim free(vname); 348280288Sjkim } 349280288Sjkim} 350280288Sjkim 351280288Sjkim/* 352280288Sjkim * Add a property pair (name, string-value) into a property nvlist. 353280288Sjkim */ 354280288Sjkimstatic int 355280288Sjkimadd_prop_list(const char *propname, char *propval, nvlist_t **props, 356280288Sjkim boolean_t poolprop) 357280288Sjkim{ 358280288Sjkim zpool_prop_t prop = ZPROP_INVAL; 359280288Sjkim zfs_prop_t fprop; 360280288Sjkim nvlist_t *proplist; 361280288Sjkim const char *normnm; 362280288Sjkim char *strval; 363280288Sjkim 364280288Sjkim if (*props == NULL && 365280288Sjkim nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) { 366280288Sjkim (void) fprintf(stderr, 367280288Sjkim gettext("internal error: out of memory\n")); 368280288Sjkim return (1); 369280288Sjkim } 370280288Sjkim 371280288Sjkim proplist = *props; 372280288Sjkim 373280288Sjkim if (poolprop) { 374280288Sjkim if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) { 375280288Sjkim (void) fprintf(stderr, gettext("property '%s' is " 376280288Sjkim "not a valid pool property\n"), propname); 377280288Sjkim return (2); 378280288Sjkim } 379280288Sjkim normnm = zpool_prop_to_name(prop); 380280288Sjkim } else { 381280288Sjkim if ((fprop = zfs_name_to_prop(propname)) == ZPROP_INVAL) { 382280288Sjkim (void) fprintf(stderr, gettext("property '%s' is " 383280288Sjkim "not a valid file system property\n"), propname); 384280288Sjkim return (2); 385280288Sjkim } 386280288Sjkim normnm = zfs_prop_to_name(fprop); 387280288Sjkim } 388280288Sjkim 389280288Sjkim if (nvlist_lookup_string(proplist, normnm, &strval) == 0 && 390280288Sjkim prop != ZPOOL_PROP_CACHEFILE) { 391280288Sjkim (void) fprintf(stderr, gettext("property '%s' " 392280288Sjkim "specified multiple times\n"), propname); 393280288Sjkim return (2); 394280288Sjkim } 395280288Sjkim 396280288Sjkim if (nvlist_add_string(proplist, normnm, propval) != 0) { 397280288Sjkim (void) fprintf(stderr, gettext("internal " 398280288Sjkim "error: out of memory\n")); 399280288Sjkim return (1); 400280288Sjkim } 401280288Sjkim 402280288Sjkim return (0); 403280288Sjkim} 404280288Sjkim 405280288Sjkim/* 406280288Sjkim * zpool add [-fn] <pool> <vdev> ... 407280288Sjkim * 408280288Sjkim * -f Force addition of devices, even if they appear in use 409280288Sjkim * -n Do not add the devices, but display the resulting layout if 410280288Sjkim * they were to be added. 411280288Sjkim * 412280288Sjkim * Adds the given vdevs to 'pool'. As with create, the bulk of this work is 413280288Sjkim * handled by get_vdev_spec(), which constructs the nvlist needed to pass to 414280288Sjkim * libzfs. 415280288Sjkim */ 416280288Sjkimint 417280288Sjkimzpool_do_add(int argc, char **argv) 418280288Sjkim{ 419280288Sjkim boolean_t force = B_FALSE; 420280288Sjkim boolean_t dryrun = B_FALSE; 421280288Sjkim int c; 422280288Sjkim nvlist_t *nvroot; 423280288Sjkim char *poolname; 424280288Sjkim int ret; 425280288Sjkim zpool_handle_t *zhp; 426280288Sjkim nvlist_t *config; 427280288Sjkim 428280288Sjkim /* check options */ 429280288Sjkim while ((c = getopt(argc, argv, "fn")) != -1) { 430280288Sjkim switch (c) { 431280288Sjkim case 'f': 432280288Sjkim force = B_TRUE; 433280288Sjkim break; 434280288Sjkim case 'n': 435280288Sjkim dryrun = B_TRUE; 436280288Sjkim break; 437280288Sjkim case '?': 438280288Sjkim (void) fprintf(stderr, gettext("invalid option '%c'\n"), 439280288Sjkim optopt); 440280288Sjkim usage(B_FALSE); 441280288Sjkim } 442280288Sjkim } 443280288Sjkim 444280288Sjkim argc -= optind; 445280288Sjkim argv += optind; 446280288Sjkim 447280288Sjkim /* get pool name and check number of arguments */ 448280288Sjkim if (argc < 1) { 449280288Sjkim (void) fprintf(stderr, gettext("missing pool name argument\n")); 450280288Sjkim usage(B_FALSE); 451280288Sjkim } 452280288Sjkim if (argc < 2) { 453280288Sjkim (void) fprintf(stderr, gettext("missing vdev specification\n")); 454280288Sjkim usage(B_FALSE); 455280288Sjkim } 456280288Sjkim 457280288Sjkim poolname = argv[0]; 458280288Sjkim 459280288Sjkim argc--; 460280288Sjkim argv++; 461280288Sjkim 462280288Sjkim if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 463280288Sjkim return (1); 464280288Sjkim 465280288Sjkim if ((config = zpool_get_config(zhp, NULL)) == NULL) { 466280288Sjkim (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 467280288Sjkim poolname); 468280288Sjkim zpool_close(zhp); 469280288Sjkim return (1); 470280288Sjkim } 471280288Sjkim 472280288Sjkim /* pass off to get_vdev_spec for processing */ 473280288Sjkim nvroot = make_root_vdev(zhp, force, !force, B_FALSE, dryrun, 474280288Sjkim argc, argv); 475280288Sjkim if (nvroot == NULL) { 476280288Sjkim zpool_close(zhp); 477280288Sjkim return (1); 478280288Sjkim } 479280288Sjkim 480280288Sjkim if (dryrun) { 481280288Sjkim nvlist_t *poolnvroot; 482280288Sjkim 483280288Sjkim verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 484280288Sjkim &poolnvroot) == 0); 485280288Sjkim 486280288Sjkim (void) printf(gettext("would update '%s' to the following " 487280288Sjkim "configuration:\n"), zpool_get_name(zhp)); 488280288Sjkim 489280288Sjkim /* print original main pool and new tree */ 490 print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE); 491 print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE); 492 493 /* Do the same for the logs */ 494 if (num_logs(poolnvroot) > 0) { 495 print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE); 496 print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE); 497 } else if (num_logs(nvroot) > 0) { 498 print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE); 499 } 500 501 ret = 0; 502 } else { 503 ret = (zpool_add(zhp, nvroot) != 0); 504 } 505 506 nvlist_free(nvroot); 507 zpool_close(zhp); 508 509 return (ret); 510} 511 512/* 513 * zpool remove <pool> <vdev> ... 514 * 515 * Removes the given vdev from the pool. Currently, this only supports removing 516 * spares and cache devices from the pool. Eventually, we'll want to support 517 * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs. 518 */ 519int 520zpool_do_remove(int argc, char **argv) 521{ 522 char *poolname; 523 int i, ret = 0; 524 zpool_handle_t *zhp; 525 526 argc--; 527 argv++; 528 529 /* get pool name and check number of arguments */ 530 if (argc < 1) { 531 (void) fprintf(stderr, gettext("missing pool name argument\n")); 532 usage(B_FALSE); 533 } 534 if (argc < 2) { 535 (void) fprintf(stderr, gettext("missing device\n")); 536 usage(B_FALSE); 537 } 538 539 poolname = argv[0]; 540 541 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 542 return (1); 543 544 for (i = 1; i < argc; i++) { 545 if (zpool_vdev_remove(zhp, argv[i]) != 0) 546 ret = 1; 547 } 548 549 return (ret); 550} 551 552/* 553 * zpool create [-fn] [-o property=value] ... 554 * [-O file-system-property=value] ... 555 * [-R root] [-m mountpoint] <pool> <dev> ... 556 * 557 * -f Force creation, even if devices appear in use 558 * -n Do not create the pool, but display the resulting layout if it 559 * were to be created. 560 * -R Create a pool under an alternate root 561 * -m Set default mountpoint for the root dataset. By default it's 562 * '/<pool>' 563 * -o Set property=value. 564 * -O Set fsproperty=value in the pool's root file system 565 * 566 * Creates the named pool according to the given vdev specification. The 567 * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once 568 * we get the nvlist back from get_vdev_spec(), we either print out the contents 569 * (if '-n' was specified), or pass it to libzfs to do the creation. 570 */ 571int 572zpool_do_create(int argc, char **argv) 573{ 574 boolean_t force = B_FALSE; 575 boolean_t dryrun = B_FALSE; 576 int c; 577 nvlist_t *nvroot = NULL; 578 char *poolname; 579 int ret = 1; 580 char *altroot = NULL; 581 char *mountpoint = NULL; 582 nvlist_t *fsprops = NULL; 583 nvlist_t *props = NULL; 584 char *propval; 585 586 /* check options */ 587 while ((c = getopt(argc, argv, ":fnR:m:o:O:")) != -1) { 588 switch (c) { 589 case 'f': 590 force = B_TRUE; 591 break; 592 case 'n': 593 dryrun = B_TRUE; 594 break; 595 case 'R': 596 altroot = optarg; 597 if (add_prop_list(zpool_prop_to_name( 598 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 599 goto errout; 600 if (nvlist_lookup_string(props, 601 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 602 &propval) == 0) 603 break; 604 if (add_prop_list(zpool_prop_to_name( 605 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 606 goto errout; 607 break; 608 case 'm': 609 mountpoint = optarg; 610 break; 611 case 'o': 612 if ((propval = strchr(optarg, '=')) == NULL) { 613 (void) fprintf(stderr, gettext("missing " 614 "'=' for -o option\n")); 615 goto errout; 616 } 617 *propval = '\0'; 618 propval++; 619 620 if (add_prop_list(optarg, propval, &props, B_TRUE)) 621 goto errout; 622 break; 623 case 'O': 624 if ((propval = strchr(optarg, '=')) == NULL) { 625 (void) fprintf(stderr, gettext("missing " 626 "'=' for -O option\n")); 627 goto errout; 628 } 629 *propval = '\0'; 630 propval++; 631 632 if (add_prop_list(optarg, propval, &fsprops, B_FALSE)) 633 goto errout; 634 break; 635 case ':': 636 (void) fprintf(stderr, gettext("missing argument for " 637 "'%c' option\n"), optopt); 638 goto badusage; 639 case '?': 640 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 641 optopt); 642 goto badusage; 643 } 644 } 645 646 argc -= optind; 647 argv += optind; 648 649 /* get pool name and check number of arguments */ 650 if (argc < 1) { 651 (void) fprintf(stderr, gettext("missing pool name argument\n")); 652 goto badusage; 653 } 654 if (argc < 2) { 655 (void) fprintf(stderr, gettext("missing vdev specification\n")); 656 goto badusage; 657 } 658 659 poolname = argv[0]; 660 661 /* 662 * As a special case, check for use of '/' in the name, and direct the 663 * user to use 'zfs create' instead. 664 */ 665 if (strchr(poolname, '/') != NULL) { 666 (void) fprintf(stderr, gettext("cannot create '%s': invalid " 667 "character '/' in pool name\n"), poolname); 668 (void) fprintf(stderr, gettext("use 'zfs create' to " 669 "create a dataset\n")); 670 goto errout; 671 } 672 673 /* pass off to get_vdev_spec for bulk processing */ 674 nvroot = make_root_vdev(NULL, force, !force, B_FALSE, dryrun, 675 argc - 1, argv + 1); 676 if (nvroot == NULL) 677 goto errout; 678 679 /* make_root_vdev() allows 0 toplevel children if there are spares */ 680 if (!zfs_allocatable_devs(nvroot)) { 681 (void) fprintf(stderr, gettext("invalid vdev " 682 "specification: at least one toplevel vdev must be " 683 "specified\n")); 684 goto errout; 685 } 686 687 688 if (altroot != NULL && altroot[0] != '/') { 689 (void) fprintf(stderr, gettext("invalid alternate root '%s': " 690 "must be an absolute path\n"), altroot); 691 goto errout; 692 } 693 694 /* 695 * Check the validity of the mountpoint and direct the user to use the 696 * '-m' mountpoint option if it looks like its in use. 697 */ 698 if (mountpoint == NULL || 699 (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 && 700 strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) { 701 char buf[MAXPATHLEN]; 702 DIR *dirp; 703 704 if (mountpoint && mountpoint[0] != '/') { 705 (void) fprintf(stderr, gettext("invalid mountpoint " 706 "'%s': must be an absolute path, 'legacy', or " 707 "'none'\n"), mountpoint); 708 goto errout; 709 } 710 711 if (mountpoint == NULL) { 712 if (altroot != NULL) 713 (void) snprintf(buf, sizeof (buf), "%s/%s", 714 altroot, poolname); 715 else 716 (void) snprintf(buf, sizeof (buf), "/%s", 717 poolname); 718 } else { 719 if (altroot != NULL) 720 (void) snprintf(buf, sizeof (buf), "%s%s", 721 altroot, mountpoint); 722 else 723 (void) snprintf(buf, sizeof (buf), "%s", 724 mountpoint); 725 } 726 727 if ((dirp = opendir(buf)) == NULL && errno != ENOENT) { 728 (void) fprintf(stderr, gettext("mountpoint '%s' : " 729 "%s\n"), buf, strerror(errno)); 730 (void) fprintf(stderr, gettext("use '-m' " 731 "option to provide a different default\n")); 732 goto errout; 733 } else if (dirp) { 734 int count = 0; 735 736 while (count < 3 && readdir(dirp) != NULL) 737 count++; 738 (void) closedir(dirp); 739 740 if (count > 2) { 741 (void) fprintf(stderr, gettext("mountpoint " 742 "'%s' exists and is not empty\n"), buf); 743 (void) fprintf(stderr, gettext("use '-m' " 744 "option to provide a " 745 "different default\n")); 746 goto errout; 747 } 748 } 749 } 750 751 if (dryrun) { 752 /* 753 * For a dry run invocation, print out a basic message and run 754 * through all the vdevs in the list and print out in an 755 * appropriate hierarchy. 756 */ 757 (void) printf(gettext("would create '%s' with the " 758 "following layout:\n\n"), poolname); 759 760 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE); 761 if (num_logs(nvroot) > 0) 762 print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE); 763 764 ret = 0; 765 } else { 766 /* 767 * Hand off to libzfs. 768 */ 769 if (zpool_create(g_zfs, poolname, 770 nvroot, props, fsprops) == 0) { 771 zfs_handle_t *pool = zfs_open(g_zfs, poolname, 772 ZFS_TYPE_FILESYSTEM); 773 if (pool != NULL) { 774 if (mountpoint != NULL) 775 verify(zfs_prop_set(pool, 776 zfs_prop_to_name( 777 ZFS_PROP_MOUNTPOINT), 778 mountpoint) == 0); 779 if (zfs_mount(pool, NULL, 0) == 0) 780 ret = zfs_shareall(pool); 781 zfs_close(pool); 782 } 783 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) { 784 (void) fprintf(stderr, gettext("pool name may have " 785 "been omitted\n")); 786 } 787 } 788 789errout: 790 nvlist_free(nvroot); 791 nvlist_free(fsprops); 792 nvlist_free(props); 793 return (ret); 794badusage: 795 nvlist_free(fsprops); 796 nvlist_free(props); 797 usage(B_FALSE); 798 return (2); 799} 800 801/* 802 * zpool destroy <pool> 803 * 804 * -f Forcefully unmount any datasets 805 * 806 * Destroy the given pool. Automatically unmounts any datasets in the pool. 807 */ 808int 809zpool_do_destroy(int argc, char **argv) 810{ 811 boolean_t force = B_FALSE; 812 int c; 813 char *pool; 814 zpool_handle_t *zhp; 815 int ret; 816 817 /* check options */ 818 while ((c = getopt(argc, argv, "f")) != -1) { 819 switch (c) { 820 case 'f': 821 force = B_TRUE; 822 break; 823 case '?': 824 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 825 optopt); 826 usage(B_FALSE); 827 } 828 } 829 830 argc -= optind; 831 argv += optind; 832 833 /* check arguments */ 834 if (argc < 1) { 835 (void) fprintf(stderr, gettext("missing pool argument\n")); 836 usage(B_FALSE); 837 } 838 if (argc > 1) { 839 (void) fprintf(stderr, gettext("too many arguments\n")); 840 usage(B_FALSE); 841 } 842 843 pool = argv[0]; 844 845 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) { 846 /* 847 * As a special case, check for use of '/' in the name, and 848 * direct the user to use 'zfs destroy' instead. 849 */ 850 if (strchr(pool, '/') != NULL) 851 (void) fprintf(stderr, gettext("use 'zfs destroy' to " 852 "destroy a dataset\n")); 853 return (1); 854 } 855 856 if (zpool_disable_datasets(zhp, force) != 0) { 857 (void) fprintf(stderr, gettext("could not destroy '%s': " 858 "could not unmount datasets\n"), zpool_get_name(zhp)); 859 return (1); 860 } 861 862 ret = (zpool_destroy(zhp) != 0); 863 864 zpool_close(zhp); 865 866 return (ret); 867} 868 869/* 870 * zpool export [-f] <pool> ... 871 * 872 * -f Forcefully unmount datasets 873 * 874 * Export the given pools. By default, the command will attempt to cleanly 875 * unmount any active datasets within the pool. If the '-f' flag is specified, 876 * then the datasets will be forcefully unmounted. 877 */ 878int 879zpool_do_export(int argc, char **argv) 880{ 881 boolean_t force = B_FALSE; 882 boolean_t hardforce = B_FALSE; 883 int c; 884 zpool_handle_t *zhp; 885 int ret; 886 int i; 887 888 /* check options */ 889 while ((c = getopt(argc, argv, "fF")) != -1) { 890 switch (c) { 891 case 'f': 892 force = B_TRUE; 893 break; 894 case 'F': 895 hardforce = B_TRUE; 896 break; 897 case '?': 898 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 899 optopt); 900 usage(B_FALSE); 901 } 902 } 903 904 argc -= optind; 905 argv += optind; 906 907 /* check arguments */ 908 if (argc < 1) { 909 (void) fprintf(stderr, gettext("missing pool argument\n")); 910 usage(B_FALSE); 911 } 912 913 ret = 0; 914 for (i = 0; i < argc; i++) { 915 if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) { 916 ret = 1; 917 continue; 918 } 919 920 if (zpool_disable_datasets(zhp, force) != 0) { 921 ret = 1; 922 zpool_close(zhp); 923 continue; 924 } 925 926 if (hardforce) { 927 if (zpool_export_force(zhp) != 0) 928 ret = 1; 929 } else if (zpool_export(zhp, force) != 0) { 930 ret = 1; 931 } 932 933 zpool_close(zhp); 934 } 935 936 return (ret); 937} 938 939/* 940 * Given a vdev configuration, determine the maximum width needed for the device 941 * name column. 942 */ 943static int 944max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max) 945{ 946 char *name = zpool_vdev_name(g_zfs, zhp, nv); 947 nvlist_t **child; 948 uint_t c, children; 949 int ret; 950 951 if (strlen(name) + depth > max) 952 max = strlen(name) + depth; 953 954 free(name); 955 956 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 957 &child, &children) == 0) { 958 for (c = 0; c < children; c++) 959 if ((ret = max_width(zhp, child[c], depth + 2, 960 max)) > max) 961 max = ret; 962 } 963 964 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 965 &child, &children) == 0) { 966 for (c = 0; c < children; c++) 967 if ((ret = max_width(zhp, child[c], depth + 2, 968 max)) > max) 969 max = ret; 970 } 971 972 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 973 &child, &children) == 0) { 974 for (c = 0; c < children; c++) 975 if ((ret = max_width(zhp, child[c], depth + 2, 976 max)) > max) 977 max = ret; 978 } 979 980 981 return (max); 982} 983 984 985/* 986 * Print the configuration of an exported pool. Iterate over all vdevs in the 987 * pool, printing out the name and status for each one. 988 */ 989void 990print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth, 991 boolean_t print_logs) 992{ 993 nvlist_t **child; 994 uint_t c, children; 995 vdev_stat_t *vs; 996 char *type, *vname; 997 998 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0); 999 if (strcmp(type, VDEV_TYPE_MISSING) == 0) 1000 return; 1001 1002 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 1003 (uint64_t **)&vs, &c) == 0); 1004 1005 (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name); 1006 (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux)); 1007 1008 if (vs->vs_aux != 0) { 1009 (void) printf(" "); 1010 1011 switch (vs->vs_aux) { 1012 case VDEV_AUX_OPEN_FAILED: 1013 (void) printf(gettext("cannot open")); 1014 break; 1015 1016 case VDEV_AUX_BAD_GUID_SUM: 1017 (void) printf(gettext("missing device")); 1018 break; 1019 1020 case VDEV_AUX_NO_REPLICAS: 1021 (void) printf(gettext("insufficient replicas")); 1022 break; 1023 1024 case VDEV_AUX_VERSION_NEWER: 1025 (void) printf(gettext("newer version")); 1026 break; 1027 1028 case VDEV_AUX_ERR_EXCEEDED: 1029 (void) printf(gettext("too many errors")); 1030 break; 1031 1032 default: 1033 (void) printf(gettext("corrupted data")); 1034 break; 1035 } 1036 } 1037 (void) printf("\n"); 1038 1039 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1040 &child, &children) != 0) 1041 return; 1042 1043 for (c = 0; c < children; c++) { 1044 uint64_t is_log = B_FALSE; 1045 1046 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 1047 &is_log); 1048 if ((is_log && !print_logs) || (!is_log && print_logs)) 1049 continue; 1050 1051 vname = zpool_vdev_name(g_zfs, NULL, child[c]); 1052 print_import_config(vname, child[c], 1053 namewidth, depth + 2, B_FALSE); 1054 free(vname); 1055 } 1056 1057 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1058 &child, &children) == 0) { 1059 (void) printf(gettext("\tcache\n")); 1060 for (c = 0; c < children; c++) { 1061 vname = zpool_vdev_name(g_zfs, NULL, child[c]); 1062 (void) printf("\t %s\n", vname); 1063 free(vname); 1064 } 1065 } 1066 1067 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, 1068 &child, &children) == 0) { 1069 (void) printf(gettext("\tspares\n")); 1070 for (c = 0; c < children; c++) { 1071 vname = zpool_vdev_name(g_zfs, NULL, child[c]); 1072 (void) printf("\t %s\n", vname); 1073 free(vname); 1074 } 1075 } 1076} 1077 1078/* 1079 * Display the status for the given pool. 1080 */ 1081static void 1082show_import(nvlist_t *config) 1083{ 1084 uint64_t pool_state; 1085 vdev_stat_t *vs; 1086 char *name; 1087 uint64_t guid; 1088 char *msgid; 1089 nvlist_t *nvroot; 1090 int reason; 1091 const char *health; 1092 uint_t vsc; 1093 int namewidth; 1094 1095 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1096 &name) == 0); 1097 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 1098 &guid) == 0); 1099 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1100 &pool_state) == 0); 1101 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1102 &nvroot) == 0); 1103 1104 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 1105 (uint64_t **)&vs, &vsc) == 0); 1106 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 1107 1108 reason = zpool_import_status(config, &msgid); 1109 1110 (void) printf(gettext(" pool: %s\n"), name); 1111 (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid); 1112 (void) printf(gettext(" state: %s"), health); 1113 if (pool_state == POOL_STATE_DESTROYED) 1114 (void) printf(gettext(" (DESTROYED)")); 1115 (void) printf("\n"); 1116 1117 switch (reason) { 1118 case ZPOOL_STATUS_MISSING_DEV_R: 1119 case ZPOOL_STATUS_MISSING_DEV_NR: 1120 case ZPOOL_STATUS_BAD_GUID_SUM: 1121 (void) printf(gettext("status: One or more devices are missing " 1122 "from the system.\n")); 1123 break; 1124 1125 case ZPOOL_STATUS_CORRUPT_LABEL_R: 1126 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 1127 (void) printf(gettext("status: One or more devices contains " 1128 "corrupted data.\n")); 1129 break; 1130 1131 case ZPOOL_STATUS_CORRUPT_DATA: 1132 (void) printf(gettext("status: The pool data is corrupted.\n")); 1133 break; 1134 1135 case ZPOOL_STATUS_OFFLINE_DEV: 1136 (void) printf(gettext("status: One or more devices " 1137 "are offlined.\n")); 1138 break; 1139 1140 case ZPOOL_STATUS_CORRUPT_POOL: 1141 (void) printf(gettext("status: The pool metadata is " 1142 "corrupted.\n")); 1143 break; 1144 1145 case ZPOOL_STATUS_VERSION_OLDER: 1146 (void) printf(gettext("status: The pool is formatted using an " 1147 "older on-disk version.\n")); 1148 break; 1149 1150 case ZPOOL_STATUS_VERSION_NEWER: 1151 (void) printf(gettext("status: The pool is formatted using an " 1152 "incompatible version.\n")); 1153 break; 1154 1155 case ZPOOL_STATUS_HOSTID_MISMATCH: 1156 (void) printf(gettext("status: The pool was last accessed by " 1157 "another system.\n")); 1158 break; 1159 1160 case ZPOOL_STATUS_FAULTED_DEV_R: 1161 case ZPOOL_STATUS_FAULTED_DEV_NR: 1162 (void) printf(gettext("status: One or more devices are " 1163 "faulted.\n")); 1164 break; 1165 1166 case ZPOOL_STATUS_BAD_LOG: 1167 (void) printf(gettext("status: An intent log record cannot be " 1168 "read.\n")); 1169 break; 1170 1171 default: 1172 /* 1173 * No other status can be seen when importing pools. 1174 */ 1175 assert(reason == ZPOOL_STATUS_OK); 1176 } 1177 1178 /* 1179 * Print out an action according to the overall state of the pool. 1180 */ 1181 if (vs->vs_state == VDEV_STATE_HEALTHY) { 1182 if (reason == ZPOOL_STATUS_VERSION_OLDER) 1183 (void) printf(gettext("action: The pool can be " 1184 "imported using its name or numeric identifier, " 1185 "though\n\tsome features will not be available " 1186 "without an explicit 'zpool upgrade'.\n")); 1187 else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) 1188 (void) printf(gettext("action: The pool can be " 1189 "imported using its name or numeric " 1190 "identifier and\n\tthe '-f' flag.\n")); 1191 else 1192 (void) printf(gettext("action: The pool can be " 1193 "imported using its name or numeric " 1194 "identifier.\n")); 1195 } else if (vs->vs_state == VDEV_STATE_DEGRADED) { 1196 (void) printf(gettext("action: The pool can be imported " 1197 "despite missing or damaged devices. The\n\tfault " 1198 "tolerance of the pool may be compromised if imported.\n")); 1199 } else { 1200 switch (reason) { 1201 case ZPOOL_STATUS_VERSION_NEWER: 1202 (void) printf(gettext("action: The pool cannot be " 1203 "imported. Access the pool on a system running " 1204 "newer\n\tsoftware, or recreate the pool from " 1205 "backup.\n")); 1206 break; 1207 case ZPOOL_STATUS_MISSING_DEV_R: 1208 case ZPOOL_STATUS_MISSING_DEV_NR: 1209 case ZPOOL_STATUS_BAD_GUID_SUM: 1210 (void) printf(gettext("action: The pool cannot be " 1211 "imported. Attach the missing\n\tdevices and try " 1212 "again.\n")); 1213 break; 1214 default: 1215 (void) printf(gettext("action: The pool cannot be " 1216 "imported due to damaged devices or data.\n")); 1217 } 1218 } 1219 1220 /* 1221 * If the state is "closed" or "can't open", and the aux state 1222 * is "corrupt data": 1223 */ 1224 if (((vs->vs_state == VDEV_STATE_CLOSED) || 1225 (vs->vs_state == VDEV_STATE_CANT_OPEN)) && 1226 (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) { 1227 if (pool_state == POOL_STATE_DESTROYED) 1228 (void) printf(gettext("\tThe pool was destroyed, " 1229 "but can be imported using the '-Df' flags.\n")); 1230 else if (pool_state != POOL_STATE_EXPORTED) 1231 (void) printf(gettext("\tThe pool may be active on " 1232 "another system, but can be imported using\n\t" 1233 "the '-f' flag.\n")); 1234 } 1235 1236 if (msgid != NULL) 1237 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 1238 msgid); 1239 1240 (void) printf(gettext("config:\n\n")); 1241 1242 namewidth = max_width(NULL, nvroot, 0, 0); 1243 if (namewidth < 10) 1244 namewidth = 10; 1245 1246 print_import_config(name, nvroot, namewidth, 0, B_FALSE); 1247 if (num_logs(nvroot) > 0) { 1248 (void) printf(gettext("\tlogs\n")); 1249 print_import_config(name, nvroot, namewidth, 0, B_TRUE); 1250 } 1251 1252 if (reason == ZPOOL_STATUS_BAD_GUID_SUM) { 1253 (void) printf(gettext("\n\tAdditional devices are known to " 1254 "be part of this pool, though their\n\texact " 1255 "configuration cannot be determined.\n")); 1256 } 1257} 1258 1259/* 1260 * Perform the import for the given configuration. This passes the heavy 1261 * lifting off to zpool_import_props(), and then mounts the datasets contained 1262 * within the pool. 1263 */ 1264static int 1265do_import(nvlist_t *config, const char *newname, const char *mntopts, 1266 int force, nvlist_t *props, boolean_t allowfaulted) 1267{ 1268 zpool_handle_t *zhp; 1269 char *name; 1270 uint64_t state; 1271 uint64_t version; 1272 int error = 0; 1273 1274 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 1275 &name) == 0); 1276 1277 verify(nvlist_lookup_uint64(config, 1278 ZPOOL_CONFIG_POOL_STATE, &state) == 0); 1279 verify(nvlist_lookup_uint64(config, 1280 ZPOOL_CONFIG_VERSION, &version) == 0); 1281 if (version > SPA_VERSION) { 1282 (void) fprintf(stderr, gettext("cannot import '%s': pool " 1283 "is formatted using a newer ZFS version\n"), name); 1284 return (1); 1285 } else if (state != POOL_STATE_EXPORTED && !force) { 1286 uint64_t hostid; 1287 1288 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, 1289 &hostid) == 0) { 1290 if ((unsigned long)hostid != gethostid()) { 1291 char *hostname; 1292 uint64_t timestamp; 1293 time_t t; 1294 1295 verify(nvlist_lookup_string(config, 1296 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); 1297 verify(nvlist_lookup_uint64(config, 1298 ZPOOL_CONFIG_TIMESTAMP, ×tamp) == 0); 1299 t = timestamp; 1300 (void) fprintf(stderr, gettext("cannot import " 1301 "'%s': pool may be in use from other " 1302 "system, it was last accessed by %s " 1303 "(hostid: 0x%lx) on %s"), name, hostname, 1304 (unsigned long)hostid, 1305 asctime(localtime(&t))); 1306 (void) fprintf(stderr, gettext("use '-f' to " 1307 "import anyway\n")); 1308 return (1); 1309 } 1310 } else { 1311 (void) fprintf(stderr, gettext("cannot import '%s': " 1312 "pool may be in use from other system\n"), name); 1313 (void) fprintf(stderr, gettext("use '-f' to import " 1314 "anyway\n")); 1315 return (1); 1316 } 1317 } 1318 1319 if (zpool_import_props(g_zfs, config, newname, props, 1320 allowfaulted) != 0) 1321 return (1); 1322 1323 if (newname != NULL) 1324 name = (char *)newname; 1325 1326 verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL); 1327 1328 if (zpool_enable_datasets(zhp, mntopts, 0) != 0) { 1329 zpool_close(zhp); 1330 return (1); 1331 } 1332 1333 zpool_close(zhp); 1334 return (error); 1335} 1336 1337/* 1338 * zpool import [-d dir] [-D] 1339 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1340 * [-d dir | -c cachefile] [-f] -a 1341 * import [-o mntopts] [-o prop=value] ... [-R root] [-D] 1342 * [-d dir | -c cachefile] [-f] <pool | id> [newpool] 1343 * 1344 * -c Read pool information from a cachefile instead of searching 1345 * devices. 1346 * 1347 * -d Scan in a specific directory, other than /dev/dsk. More than 1348 * one directory can be specified using multiple '-d' options. 1349 * 1350 * -D Scan for previously destroyed pools or import all or only 1351 * specified destroyed pools. 1352 * 1353 * -R Temporarily import the pool, with all mountpoints relative to 1354 * the given root. The pool will remain exported when the machine 1355 * is rebooted. 1356 * 1357 * -f Force import, even if it appears that the pool is active. 1358 * 1359 * -F Import even in the presence of faulted vdevs. This is an 1360 * intentionally undocumented option for testing purposes, and 1361 * treats the pool configuration as complete, leaving any bad 1362 * vdevs in the FAULTED state. 1363 * 1364 * -a Import all pools found. 1365 * 1366 * -o Set property=value and/or temporary mount options (without '='). 1367 * 1368 * The import command scans for pools to import, and import pools based on pool 1369 * name and GUID. The pool can also be renamed as part of the import process. 1370 */ 1371int 1372zpool_do_import(int argc, char **argv) 1373{ 1374 char **searchdirs = NULL; 1375 int nsearch = 0; 1376 int c; 1377 int err; 1378 nvlist_t *pools = NULL; 1379 boolean_t do_all = B_FALSE; 1380 boolean_t do_destroyed = B_FALSE; 1381 char *mntopts = NULL; 1382 boolean_t do_force = B_FALSE; 1383 nvpair_t *elem; 1384 nvlist_t *config; 1385 uint64_t searchguid = 0; 1386 char *searchname = NULL; 1387 char *propval; 1388 nvlist_t *found_config; 1389 nvlist_t *props = NULL; 1390 boolean_t first; 1391 boolean_t allow_faulted = B_FALSE; 1392 uint64_t pool_state; 1393 char *cachefile = NULL; 1394 1395 /* check options */ 1396 while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) { 1397 switch (c) { 1398 case 'a': 1399 do_all = B_TRUE; 1400 break; 1401 case 'c': 1402 cachefile = optarg; 1403 break; 1404 case 'd': 1405 if (searchdirs == NULL) { 1406 searchdirs = safe_malloc(sizeof (char *)); 1407 } else { 1408 char **tmp = safe_malloc((nsearch + 1) * 1409 sizeof (char *)); 1410 bcopy(searchdirs, tmp, nsearch * 1411 sizeof (char *)); 1412 free(searchdirs); 1413 searchdirs = tmp; 1414 } 1415 searchdirs[nsearch++] = optarg; 1416 break; 1417 case 'D': 1418 do_destroyed = B_TRUE; 1419 break; 1420 case 'f': 1421 do_force = B_TRUE; 1422 break; 1423 case 'F': 1424 allow_faulted = B_TRUE; 1425 break; 1426 case 'o': 1427 if ((propval = strchr(optarg, '=')) != NULL) { 1428 *propval = '\0'; 1429 propval++; 1430 if (add_prop_list(optarg, propval, 1431 &props, B_TRUE)) 1432 goto error; 1433 } else { 1434 mntopts = optarg; 1435 } 1436 break; 1437 case 'R': 1438 if (add_prop_list(zpool_prop_to_name( 1439 ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE)) 1440 goto error; 1441 if (nvlist_lookup_string(props, 1442 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), 1443 &propval) == 0) 1444 break; 1445 if (add_prop_list(zpool_prop_to_name( 1446 ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE)) 1447 goto error; 1448 break; 1449 case ':': 1450 (void) fprintf(stderr, gettext("missing argument for " 1451 "'%c' option\n"), optopt); 1452 usage(B_FALSE); 1453 break; 1454 case '?': 1455 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1456 optopt); 1457 usage(B_FALSE); 1458 } 1459 } 1460 1461 argc -= optind; 1462 argv += optind; 1463 1464 if (cachefile && nsearch != 0) { 1465 (void) fprintf(stderr, gettext("-c is incompatible with -d\n")); 1466 usage(B_FALSE); 1467 } 1468 1469 if (searchdirs == NULL) { 1470 searchdirs = safe_malloc(sizeof (char *)); 1471 searchdirs[0] = "/dev/dsk"; 1472 nsearch = 1; 1473 } 1474 1475 /* check argument count */ 1476 if (do_all) { 1477 if (argc != 0) { 1478 (void) fprintf(stderr, gettext("too many arguments\n")); 1479 usage(B_FALSE); 1480 } 1481 } else { 1482 if (argc > 2) { 1483 (void) fprintf(stderr, gettext("too many arguments\n")); 1484 usage(B_FALSE); 1485 } 1486 1487 /* 1488 * Check for the SYS_CONFIG privilege. We do this explicitly 1489 * here because otherwise any attempt to discover pools will 1490 * silently fail. 1491 */ 1492 if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) { 1493 (void) fprintf(stderr, gettext("cannot " 1494 "discover pools: permission denied\n")); 1495 free(searchdirs); 1496 return (1); 1497 } 1498 } 1499 1500 /* 1501 * Depending on the arguments given, we do one of the following: 1502 * 1503 * <none> Iterate through all pools and display information about 1504 * each one. 1505 * 1506 * -a Iterate through all pools and try to import each one. 1507 * 1508 * <id> Find the pool that corresponds to the given GUID/pool 1509 * name and import that one. 1510 * 1511 * -D Above options applies only to destroyed pools. 1512 */ 1513 if (argc != 0) { 1514 char *endptr; 1515 1516 errno = 0; 1517 searchguid = strtoull(argv[0], &endptr, 10); 1518 if (errno != 0 || *endptr != '\0') 1519 searchname = argv[0]; 1520 found_config = NULL; 1521 } 1522 1523 if (cachefile) { 1524 pools = zpool_find_import_cached(g_zfs, cachefile, searchname, 1525 searchguid); 1526 } else if (searchname != NULL) { 1527 pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs, 1528 searchname); 1529 } else { 1530 /* 1531 * It's OK to search by guid even if searchguid is 0. 1532 */ 1533 pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs, 1534 searchguid); 1535 } 1536 1537 if (pools == NULL) { 1538 if (argc != 0) { 1539 (void) fprintf(stderr, gettext("cannot import '%s': " 1540 "no such pool available\n"), argv[0]); 1541 } 1542 free(searchdirs); 1543 return (1); 1544 } 1545 1546 /* 1547 * At this point we have a list of import candidate configs. Even if 1548 * we were searching by pool name or guid, we still need to 1549 * post-process the list to deal with pool state and possible 1550 * duplicate names. 1551 */ 1552 err = 0; 1553 elem = NULL; 1554 first = B_TRUE; 1555 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 1556 1557 verify(nvpair_value_nvlist(elem, &config) == 0); 1558 1559 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 1560 &pool_state) == 0); 1561 if (!do_destroyed && pool_state == POOL_STATE_DESTROYED) 1562 continue; 1563 if (do_destroyed && pool_state != POOL_STATE_DESTROYED) 1564 continue; 1565 1566 if (argc == 0) { 1567 if (first) 1568 first = B_FALSE; 1569 else if (!do_all) 1570 (void) printf("\n"); 1571 1572 if (do_all) 1573 err |= do_import(config, NULL, mntopts, 1574 do_force, props, allow_faulted); 1575 else 1576 show_import(config); 1577 } else if (searchname != NULL) { 1578 char *name; 1579 1580 /* 1581 * We are searching for a pool based on name. 1582 */ 1583 verify(nvlist_lookup_string(config, 1584 ZPOOL_CONFIG_POOL_NAME, &name) == 0); 1585 1586 if (strcmp(name, searchname) == 0) { 1587 if (found_config != NULL) { 1588 (void) fprintf(stderr, gettext( 1589 "cannot import '%s': more than " 1590 "one matching pool\n"), searchname); 1591 (void) fprintf(stderr, gettext( 1592 "import by numeric ID instead\n")); 1593 err = B_TRUE; 1594 } 1595 found_config = config; 1596 } 1597 } else { 1598 uint64_t guid; 1599 1600 /* 1601 * Search for a pool by guid. 1602 */ 1603 verify(nvlist_lookup_uint64(config, 1604 ZPOOL_CONFIG_POOL_GUID, &guid) == 0); 1605 1606 if (guid == searchguid) 1607 found_config = config; 1608 } 1609 } 1610 1611 /* 1612 * If we were searching for a specific pool, verify that we found a 1613 * pool, and then do the import. 1614 */ 1615 if (argc != 0 && err == 0) { 1616 if (found_config == NULL) { 1617 (void) fprintf(stderr, gettext("cannot import '%s': " 1618 "no such pool available\n"), argv[0]); 1619 err = B_TRUE; 1620 } else { 1621 err |= do_import(found_config, argc == 1 ? NULL : 1622 argv[1], mntopts, do_force, props, allow_faulted); 1623 } 1624 } 1625 1626 /* 1627 * If we were just looking for pools, report an error if none were 1628 * found. 1629 */ 1630 if (argc == 0 && first) 1631 (void) fprintf(stderr, 1632 gettext("no pools available to import\n")); 1633 1634error: 1635 nvlist_free(props); 1636 nvlist_free(pools); 1637 free(searchdirs); 1638 1639 return (err ? 1 : 0); 1640} 1641 1642typedef struct iostat_cbdata { 1643 zpool_list_t *cb_list; 1644 int cb_verbose; 1645 int cb_iteration; 1646 int cb_namewidth; 1647} iostat_cbdata_t; 1648 1649static void 1650print_iostat_separator(iostat_cbdata_t *cb) 1651{ 1652 int i = 0; 1653 1654 for (i = 0; i < cb->cb_namewidth; i++) 1655 (void) printf("-"); 1656 (void) printf(" ----- ----- ----- ----- ----- -----\n"); 1657} 1658 1659static void 1660print_iostat_header(iostat_cbdata_t *cb) 1661{ 1662 (void) printf("%*s capacity operations bandwidth\n", 1663 cb->cb_namewidth, ""); 1664 (void) printf("%-*s used avail read write read write\n", 1665 cb->cb_namewidth, "pool"); 1666 print_iostat_separator(cb); 1667} 1668 1669/* 1670 * Display a single statistic. 1671 */ 1672static void 1673print_one_stat(uint64_t value) 1674{ 1675 char buf[64]; 1676 1677 zfs_nicenum(value, buf, sizeof (buf)); 1678 (void) printf(" %5s", buf); 1679} 1680 1681/* 1682 * Print out all the statistics for the given vdev. This can either be the 1683 * toplevel configuration, or called recursively. If 'name' is NULL, then this 1684 * is a verbose output, and we don't want to display the toplevel pool stats. 1685 */ 1686void 1687print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, 1688 nvlist_t *newnv, iostat_cbdata_t *cb, int depth) 1689{ 1690 nvlist_t **oldchild, **newchild; 1691 uint_t c, children; 1692 vdev_stat_t *oldvs, *newvs; 1693 vdev_stat_t zerovs = { 0 }; 1694 uint64_t tdelta; 1695 double scale; 1696 char *vname; 1697 1698 if (oldnv != NULL) { 1699 verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS, 1700 (uint64_t **)&oldvs, &c) == 0); 1701 } else { 1702 oldvs = &zerovs; 1703 } 1704 1705 verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS, 1706 (uint64_t **)&newvs, &c) == 0); 1707 1708 if (strlen(name) + depth > cb->cb_namewidth) 1709 (void) printf("%*s%s", depth, "", name); 1710 else 1711 (void) printf("%*s%s%*s", depth, "", name, 1712 (int)(cb->cb_namewidth - strlen(name) - depth), ""); 1713 1714 tdelta = newvs->vs_timestamp - oldvs->vs_timestamp; 1715 1716 if (tdelta == 0) 1717 scale = 1.0; 1718 else 1719 scale = (double)NANOSEC / tdelta; 1720 1721 /* only toplevel vdevs have capacity stats */ 1722 if (newvs->vs_space == 0) { 1723 (void) printf(" - -"); 1724 } else { 1725 print_one_stat(newvs->vs_alloc); 1726 print_one_stat(newvs->vs_space - newvs->vs_alloc); 1727 } 1728 1729 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] - 1730 oldvs->vs_ops[ZIO_TYPE_READ]))); 1731 1732 print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] - 1733 oldvs->vs_ops[ZIO_TYPE_WRITE]))); 1734 1735 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] - 1736 oldvs->vs_bytes[ZIO_TYPE_READ]))); 1737 1738 print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] - 1739 oldvs->vs_bytes[ZIO_TYPE_WRITE]))); 1740 1741 (void) printf("\n"); 1742 1743 if (!cb->cb_verbose) 1744 return; 1745 1746 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN, 1747 &newchild, &children) != 0) 1748 return; 1749 1750 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN, 1751 &oldchild, &c) != 0) 1752 return; 1753 1754 for (c = 0; c < children; c++) { 1755 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1756 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1757 newchild[c], cb, depth + 2); 1758 free(vname); 1759 } 1760 1761 /* 1762 * Include level 2 ARC devices in iostat output 1763 */ 1764 if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE, 1765 &newchild, &children) != 0) 1766 return; 1767 1768 if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE, 1769 &oldchild, &c) != 0) 1770 return; 1771 1772 if (children > 0) { 1773 (void) printf("%-*s - - - - - " 1774 "-\n", cb->cb_namewidth, "cache"); 1775 for (c = 0; c < children; c++) { 1776 vname = zpool_vdev_name(g_zfs, zhp, newchild[c]); 1777 print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL, 1778 newchild[c], cb, depth + 2); 1779 free(vname); 1780 } 1781 } 1782} 1783 1784static int 1785refresh_iostat(zpool_handle_t *zhp, void *data) 1786{ 1787 iostat_cbdata_t *cb = data; 1788 boolean_t missing; 1789 1790 /* 1791 * If the pool has disappeared, remove it from the list and continue. 1792 */ 1793 if (zpool_refresh_stats(zhp, &missing) != 0) 1794 return (-1); 1795 1796 if (missing) 1797 pool_list_remove(cb->cb_list, zhp); 1798 1799 return (0); 1800} 1801 1802/* 1803 * Callback to print out the iostats for the given pool. 1804 */ 1805int 1806print_iostat(zpool_handle_t *zhp, void *data) 1807{ 1808 iostat_cbdata_t *cb = data; 1809 nvlist_t *oldconfig, *newconfig; 1810 nvlist_t *oldnvroot, *newnvroot; 1811 1812 newconfig = zpool_get_config(zhp, &oldconfig); 1813 1814 if (cb->cb_iteration == 1) 1815 oldconfig = NULL; 1816 1817 verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE, 1818 &newnvroot) == 0); 1819 1820 if (oldconfig == NULL) 1821 oldnvroot = NULL; 1822 else 1823 verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE, 1824 &oldnvroot) == 0); 1825 1826 /* 1827 * Print out the statistics for the pool. 1828 */ 1829 print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0); 1830 1831 if (cb->cb_verbose) 1832 print_iostat_separator(cb); 1833 1834 return (0); 1835} 1836 1837int 1838get_namewidth(zpool_handle_t *zhp, void *data) 1839{ 1840 iostat_cbdata_t *cb = data; 1841 nvlist_t *config, *nvroot; 1842 1843 if ((config = zpool_get_config(zhp, NULL)) != NULL) { 1844 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 1845 &nvroot) == 0); 1846 if (!cb->cb_verbose) 1847 cb->cb_namewidth = strlen(zpool_get_name(zhp)); 1848 else 1849 cb->cb_namewidth = max_width(zhp, nvroot, 0, 0); 1850 } 1851 1852 /* 1853 * The width must fall into the range [10,38]. The upper limit is the 1854 * maximum we can have and still fit in 80 columns. 1855 */ 1856 if (cb->cb_namewidth < 10) 1857 cb->cb_namewidth = 10; 1858 if (cb->cb_namewidth > 38) 1859 cb->cb_namewidth = 38; 1860 1861 return (0); 1862} 1863 1864/* 1865 * zpool iostat [-v] [pool] ... [interval [count]] 1866 * 1867 * -v Display statistics for individual vdevs 1868 * 1869 * This command can be tricky because we want to be able to deal with pool 1870 * creation/destruction as well as vdev configuration changes. The bulk of this 1871 * processing is handled by the pool_list_* routines in zpool_iter.c. We rely 1872 * on pool_list_update() to detect the addition of new pools. Configuration 1873 * changes are all handled within libzfs. 1874 */ 1875int 1876zpool_do_iostat(int argc, char **argv) 1877{ 1878 int c; 1879 int ret; 1880 int npools; 1881 unsigned long interval = 0, count = 0; 1882 zpool_list_t *list; 1883 boolean_t verbose = B_FALSE; 1884 iostat_cbdata_t cb; 1885 1886 /* check options */ 1887 while ((c = getopt(argc, argv, "v")) != -1) { 1888 switch (c) { 1889 case 'v': 1890 verbose = B_TRUE; 1891 break; 1892 case '?': 1893 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 1894 optopt); 1895 usage(B_FALSE); 1896 } 1897 } 1898 1899 argc -= optind; 1900 argv += optind; 1901 1902 /* 1903 * Determine if the last argument is an integer or a pool name 1904 */ 1905 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1906 char *end; 1907 1908 errno = 0; 1909 interval = strtoul(argv[argc - 1], &end, 10); 1910 1911 if (*end == '\0' && errno == 0) { 1912 if (interval == 0) { 1913 (void) fprintf(stderr, gettext("interval " 1914 "cannot be zero\n")); 1915 usage(B_FALSE); 1916 } 1917 1918 /* 1919 * Ignore the last parameter 1920 */ 1921 argc--; 1922 } else { 1923 /* 1924 * If this is not a valid number, just plow on. The 1925 * user will get a more informative error message later 1926 * on. 1927 */ 1928 interval = 0; 1929 } 1930 } 1931 1932 /* 1933 * If the last argument is also an integer, then we have both a count 1934 * and an integer. 1935 */ 1936 if (argc > 0 && isdigit(argv[argc - 1][0])) { 1937 char *end; 1938 1939 errno = 0; 1940 count = interval; 1941 interval = strtoul(argv[argc - 1], &end, 10); 1942 1943 if (*end == '\0' && errno == 0) { 1944 if (interval == 0) { 1945 (void) fprintf(stderr, gettext("interval " 1946 "cannot be zero\n")); 1947 usage(B_FALSE); 1948 } 1949 1950 /* 1951 * Ignore the last parameter 1952 */ 1953 argc--; 1954 } else { 1955 interval = 0; 1956 } 1957 } 1958 1959 /* 1960 * Construct the list of all interesting pools. 1961 */ 1962 ret = 0; 1963 if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL) 1964 return (1); 1965 1966 if (pool_list_count(list) == 0 && argc != 0) { 1967 pool_list_free(list); 1968 return (1); 1969 } 1970 1971 if (pool_list_count(list) == 0 && interval == 0) { 1972 pool_list_free(list); 1973 (void) fprintf(stderr, gettext("no pools available\n")); 1974 return (1); 1975 } 1976 1977 /* 1978 * Enter the main iostat loop. 1979 */ 1980 cb.cb_list = list; 1981 cb.cb_verbose = verbose; 1982 cb.cb_iteration = 0; 1983 cb.cb_namewidth = 0; 1984 1985 for (;;) { 1986 pool_list_update(list); 1987 1988 if ((npools = pool_list_count(list)) == 0) 1989 break; 1990 1991 /* 1992 * Refresh all statistics. This is done as an explicit step 1993 * before calculating the maximum name width, so that any 1994 * configuration changes are properly accounted for. 1995 */ 1996 (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb); 1997 1998 /* 1999 * Iterate over all pools to determine the maximum width 2000 * for the pool / device name column across all pools. 2001 */ 2002 cb.cb_namewidth = 0; 2003 (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb); 2004 2005 /* 2006 * If it's the first time, or verbose mode, print the header. 2007 */ 2008 if (++cb.cb_iteration == 1 || verbose) 2009 print_iostat_header(&cb); 2010 2011 (void) pool_list_iter(list, B_FALSE, print_iostat, &cb); 2012 2013 /* 2014 * If there's more than one pool, and we're not in verbose mode 2015 * (which prints a separator for us), then print a separator. 2016 */ 2017 if (npools > 1 && !verbose) 2018 print_iostat_separator(&cb); 2019 2020 if (verbose) 2021 (void) printf("\n"); 2022 2023 /* 2024 * Flush the output so that redirection to a file isn't buffered 2025 * indefinitely. 2026 */ 2027 (void) fflush(stdout); 2028 2029 if (interval == 0) 2030 break; 2031 2032 if (count != 0 && --count == 0) 2033 break; 2034 2035 (void) sleep(interval); 2036 } 2037 2038 pool_list_free(list); 2039 2040 return (ret); 2041} 2042 2043typedef struct list_cbdata { 2044 boolean_t cb_scripted; 2045 boolean_t cb_first; 2046 zprop_list_t *cb_proplist; 2047} list_cbdata_t; 2048 2049/* 2050 * Given a list of columns to display, output appropriate headers for each one. 2051 */ 2052static void 2053print_header(zprop_list_t *pl) 2054{ 2055 const char *header; 2056 boolean_t first = B_TRUE; 2057 boolean_t right_justify; 2058 2059 for (; pl != NULL; pl = pl->pl_next) { 2060 if (pl->pl_prop == ZPROP_INVAL) 2061 continue; 2062 2063 if (!first) 2064 (void) printf(" "); 2065 else 2066 first = B_FALSE; 2067 2068 header = zpool_prop_column_name(pl->pl_prop); 2069 right_justify = zpool_prop_align_right(pl->pl_prop); 2070 2071 if (pl->pl_next == NULL && !right_justify) 2072 (void) printf("%s", header); 2073 else if (right_justify) 2074 (void) printf("%*s", pl->pl_width, header); 2075 else 2076 (void) printf("%-*s", pl->pl_width, header); 2077 } 2078 2079 (void) printf("\n"); 2080} 2081 2082/* 2083 * Given a pool and a list of properties, print out all the properties according 2084 * to the described layout. 2085 */ 2086static void 2087print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted) 2088{ 2089 boolean_t first = B_TRUE; 2090 char property[ZPOOL_MAXPROPLEN]; 2091 char *propstr; 2092 boolean_t right_justify; 2093 int width; 2094 2095 for (; pl != NULL; pl = pl->pl_next) { 2096 if (!first) { 2097 if (scripted) 2098 (void) printf("\t"); 2099 else 2100 (void) printf(" "); 2101 } else { 2102 first = B_FALSE; 2103 } 2104 2105 right_justify = B_FALSE; 2106 if (pl->pl_prop != ZPROP_INVAL) { 2107 if (zpool_get_prop(zhp, pl->pl_prop, property, 2108 sizeof (property), NULL) != 0) 2109 propstr = "-"; 2110 else 2111 propstr = property; 2112 2113 right_justify = zpool_prop_align_right(pl->pl_prop); 2114 } else { 2115 propstr = "-"; 2116 } 2117 2118 width = pl->pl_width; 2119 2120 /* 2121 * If this is being called in scripted mode, or if this is the 2122 * last column and it is left-justified, don't include a width 2123 * format specifier. 2124 */ 2125 if (scripted || (pl->pl_next == NULL && !right_justify)) 2126 (void) printf("%s", propstr); 2127 else if (right_justify) 2128 (void) printf("%*s", width, propstr); 2129 else 2130 (void) printf("%-*s", width, propstr); 2131 } 2132 2133 (void) printf("\n"); 2134} 2135 2136/* 2137 * Generic callback function to list a pool. 2138 */ 2139int 2140list_callback(zpool_handle_t *zhp, void *data) 2141{ 2142 list_cbdata_t *cbp = data; 2143 2144 if (cbp->cb_first) { 2145 if (!cbp->cb_scripted) 2146 print_header(cbp->cb_proplist); 2147 cbp->cb_first = B_FALSE; 2148 } 2149 2150 print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted); 2151 2152 return (0); 2153} 2154 2155/* 2156 * zpool list [-H] [-o prop[,prop]*] [pool] ... 2157 * 2158 * -H Scripted mode. Don't display headers, and separate properties 2159 * by a single tab. 2160 * -o List of properties to display. Defaults to 2161 * "name,size,used,available,capacity,health,altroot" 2162 * 2163 * List all pools in the system, whether or not they're healthy. Output space 2164 * statistics for each one, as well as health status summary. 2165 */ 2166int 2167zpool_do_list(int argc, char **argv) 2168{ 2169 int c; 2170 int ret; 2171 list_cbdata_t cb = { 0 }; 2172 static char default_props[] = 2173 "name,size,used,available,capacity,health,altroot"; 2174 char *props = default_props; 2175 2176 /* check options */ 2177 while ((c = getopt(argc, argv, ":Ho:")) != -1) { 2178 switch (c) { 2179 case 'H': 2180 cb.cb_scripted = B_TRUE; 2181 break; 2182 case 'o': 2183 props = optarg; 2184 break; 2185 case ':': 2186 (void) fprintf(stderr, gettext("missing argument for " 2187 "'%c' option\n"), optopt); 2188 usage(B_FALSE); 2189 break; 2190 case '?': 2191 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2192 optopt); 2193 usage(B_FALSE); 2194 } 2195 } 2196 2197 argc -= optind; 2198 argv += optind; 2199 2200 if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0) 2201 usage(B_FALSE); 2202 2203 cb.cb_first = B_TRUE; 2204 2205 ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, 2206 list_callback, &cb); 2207 2208 zprop_free_list(cb.cb_proplist); 2209 2210 if (argc == 0 && cb.cb_first && !cb.cb_scripted) { 2211 (void) printf(gettext("no pools available\n")); 2212 return (0); 2213 } 2214 2215 return (ret); 2216} 2217 2218static nvlist_t * 2219zpool_get_vdev_by_name(nvlist_t *nv, char *name) 2220{ 2221 nvlist_t **child; 2222 uint_t c, children; 2223 nvlist_t *match; 2224 char *path; 2225 2226 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2227 &child, &children) != 0) { 2228 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2229 if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0) 2230 name += sizeof(_PATH_DEV)-1; 2231 if (strncmp(path, _PATH_DEV, sizeof(_PATH_DEV)-1) == 0) 2232 path += sizeof(_PATH_DEV)-1; 2233 if (strcmp(name, path) == 0) 2234 return (nv); 2235 return (NULL); 2236 } 2237 2238 for (c = 0; c < children; c++) 2239 if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL) 2240 return (match); 2241 2242 return (NULL); 2243} 2244 2245static int 2246zpool_do_attach_or_replace(int argc, char **argv, int replacing) 2247{ 2248 boolean_t force = B_FALSE; 2249 int c; 2250 nvlist_t *nvroot; 2251 char *poolname, *old_disk, *new_disk; 2252 zpool_handle_t *zhp; 2253 int ret; 2254 2255 /* check options */ 2256 while ((c = getopt(argc, argv, "f")) != -1) { 2257 switch (c) { 2258 case 'f': 2259 force = B_TRUE; 2260 break; 2261 case '?': 2262 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2263 optopt); 2264 usage(B_FALSE); 2265 } 2266 } 2267 2268 argc -= optind; 2269 argv += optind; 2270 2271 /* get pool name and check number of arguments */ 2272 if (argc < 1) { 2273 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2274 usage(B_FALSE); 2275 } 2276 2277 poolname = argv[0]; 2278 2279 if (argc < 2) { 2280 (void) fprintf(stderr, 2281 gettext("missing <device> specification\n")); 2282 usage(B_FALSE); 2283 } 2284 2285 old_disk = argv[1]; 2286 2287 if (argc < 3) { 2288 if (!replacing) { 2289 (void) fprintf(stderr, 2290 gettext("missing <new_device> specification\n")); 2291 usage(B_FALSE); 2292 } 2293 new_disk = old_disk; 2294 argc -= 1; 2295 argv += 1; 2296 } else { 2297 new_disk = argv[2]; 2298 argc -= 2; 2299 argv += 2; 2300 } 2301 2302 if (argc > 1) { 2303 (void) fprintf(stderr, gettext("too many arguments\n")); 2304 usage(B_FALSE); 2305 } 2306 2307 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2308 return (1); 2309 2310 if (zpool_get_config(zhp, NULL) == NULL) { 2311 (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"), 2312 poolname); 2313 zpool_close(zhp); 2314 return (1); 2315 } 2316 2317 nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, B_FALSE, 2318 argc, argv); 2319 if (nvroot == NULL) { 2320 zpool_close(zhp); 2321 return (1); 2322 } 2323 2324 ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing); 2325 2326 nvlist_free(nvroot); 2327 zpool_close(zhp); 2328 2329 return (ret); 2330} 2331 2332/* 2333 * zpool replace [-f] <pool> <device> <new_device> 2334 * 2335 * -f Force attach, even if <new_device> appears to be in use. 2336 * 2337 * Replace <device> with <new_device>. 2338 */ 2339/* ARGSUSED */ 2340int 2341zpool_do_replace(int argc, char **argv) 2342{ 2343 return (zpool_do_attach_or_replace(argc, argv, B_TRUE)); 2344} 2345 2346/* 2347 * zpool attach [-f] <pool> <device> <new_device> 2348 * 2349 * -f Force attach, even if <new_device> appears to be in use. 2350 * 2351 * Attach <new_device> to the mirror containing <device>. If <device> is not 2352 * part of a mirror, then <device> will be transformed into a mirror of 2353 * <device> and <new_device>. In either case, <new_device> will begin life 2354 * with a DTL of [0, now], and will immediately begin to resilver itself. 2355 */ 2356int 2357zpool_do_attach(int argc, char **argv) 2358{ 2359 return (zpool_do_attach_or_replace(argc, argv, B_FALSE)); 2360} 2361 2362/* 2363 * zpool detach [-f] <pool> <device> 2364 * 2365 * -f Force detach of <device>, even if DTLs argue against it 2366 * (not supported yet) 2367 * 2368 * Detach a device from a mirror. The operation will be refused if <device> 2369 * is the last device in the mirror, or if the DTLs indicate that this device 2370 * has the only valid copy of some data. 2371 */ 2372/* ARGSUSED */ 2373int 2374zpool_do_detach(int argc, char **argv) 2375{ 2376 int c; 2377 char *poolname, *path; 2378 zpool_handle_t *zhp; 2379 int ret; 2380 2381 /* check options */ 2382 while ((c = getopt(argc, argv, "f")) != -1) { 2383 switch (c) { 2384 case 'f': 2385 case '?': 2386 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2387 optopt); 2388 usage(B_FALSE); 2389 } 2390 } 2391 2392 argc -= optind; 2393 argv += optind; 2394 2395 /* get pool name and check number of arguments */ 2396 if (argc < 1) { 2397 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2398 usage(B_FALSE); 2399 } 2400 2401 if (argc < 2) { 2402 (void) fprintf(stderr, 2403 gettext("missing <device> specification\n")); 2404 usage(B_FALSE); 2405 } 2406 2407 poolname = argv[0]; 2408 path = argv[1]; 2409 2410 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2411 return (1); 2412 2413 ret = zpool_vdev_detach(zhp, path); 2414 2415 zpool_close(zhp); 2416 2417 return (ret); 2418} 2419 2420/* 2421 * zpool online <pool> <device> ... 2422 */ 2423int 2424zpool_do_online(int argc, char **argv) 2425{ 2426 int c, i; 2427 char *poolname; 2428 zpool_handle_t *zhp; 2429 int ret = 0; 2430 vdev_state_t newstate; 2431 2432 /* check options */ 2433 while ((c = getopt(argc, argv, "t")) != -1) { 2434 switch (c) { 2435 case 't': 2436 case '?': 2437 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2438 optopt); 2439 usage(B_FALSE); 2440 } 2441 } 2442 2443 argc -= optind; 2444 argv += optind; 2445 2446 /* get pool name and check number of arguments */ 2447 if (argc < 1) { 2448 (void) fprintf(stderr, gettext("missing pool name\n")); 2449 usage(B_FALSE); 2450 } 2451 if (argc < 2) { 2452 (void) fprintf(stderr, gettext("missing device name\n")); 2453 usage(B_FALSE); 2454 } 2455 2456 poolname = argv[0]; 2457 2458 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2459 return (1); 2460 2461 for (i = 1; i < argc; i++) { 2462 if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) { 2463 if (newstate != VDEV_STATE_HEALTHY) { 2464 (void) printf(gettext("warning: device '%s' " 2465 "onlined, but remains in faulted state\n"), 2466 argv[i]); 2467 if (newstate == VDEV_STATE_FAULTED) 2468 (void) printf(gettext("use 'zpool " 2469 "clear' to restore a faulted " 2470 "device\n")); 2471 else 2472 (void) printf(gettext("use 'zpool " 2473 "replace' to replace devices " 2474 "that are no longer present\n")); 2475 } 2476 } else { 2477 ret = 1; 2478 } 2479 } 2480 2481 zpool_close(zhp); 2482 2483 return (ret); 2484} 2485 2486/* 2487 * zpool offline [-ft] <pool> <device> ... 2488 * 2489 * -f Force the device into the offline state, even if doing 2490 * so would appear to compromise pool availability. 2491 * (not supported yet) 2492 * 2493 * -t Only take the device off-line temporarily. The offline 2494 * state will not be persistent across reboots. 2495 */ 2496/* ARGSUSED */ 2497int 2498zpool_do_offline(int argc, char **argv) 2499{ 2500 int c, i; 2501 char *poolname; 2502 zpool_handle_t *zhp; 2503 int ret = 0; 2504 boolean_t istmp = B_FALSE; 2505 2506 /* check options */ 2507 while ((c = getopt(argc, argv, "ft")) != -1) { 2508 switch (c) { 2509 case 't': 2510 istmp = B_TRUE; 2511 break; 2512 case 'f': 2513 case '?': 2514 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2515 optopt); 2516 usage(B_FALSE); 2517 } 2518 } 2519 2520 argc -= optind; 2521 argv += optind; 2522 2523 /* get pool name and check number of arguments */ 2524 if (argc < 1) { 2525 (void) fprintf(stderr, gettext("missing pool name\n")); 2526 usage(B_FALSE); 2527 } 2528 if (argc < 2) { 2529 (void) fprintf(stderr, gettext("missing device name\n")); 2530 usage(B_FALSE); 2531 } 2532 2533 poolname = argv[0]; 2534 2535 if ((zhp = zpool_open(g_zfs, poolname)) == NULL) 2536 return (1); 2537 2538 for (i = 1; i < argc; i++) { 2539 if (zpool_vdev_offline(zhp, argv[i], istmp) != 0) 2540 ret = 1; 2541 } 2542 2543 zpool_close(zhp); 2544 2545 return (ret); 2546} 2547 2548/* 2549 * zpool clear <pool> [device] 2550 * 2551 * Clear all errors associated with a pool or a particular device. 2552 */ 2553int 2554zpool_do_clear(int argc, char **argv) 2555{ 2556 int ret = 0; 2557 zpool_handle_t *zhp; 2558 char *pool, *device; 2559 2560 if (argc < 2) { 2561 (void) fprintf(stderr, gettext("missing pool name\n")); 2562 usage(B_FALSE); 2563 } 2564 2565 if (argc > 3) { 2566 (void) fprintf(stderr, gettext("too many arguments\n")); 2567 usage(B_FALSE); 2568 } 2569 2570 pool = argv[1]; 2571 device = argc == 3 ? argv[2] : NULL; 2572 2573 if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) 2574 return (1); 2575 2576 if (zpool_clear(zhp, device) != 0) 2577 ret = 1; 2578 2579 zpool_close(zhp); 2580 2581 return (ret); 2582} 2583 2584typedef struct scrub_cbdata { 2585 int cb_type; 2586 int cb_argc; 2587 char **cb_argv; 2588} scrub_cbdata_t; 2589 2590int 2591scrub_callback(zpool_handle_t *zhp, void *data) 2592{ 2593 scrub_cbdata_t *cb = data; 2594 int err; 2595 2596 /* 2597 * Ignore faulted pools. 2598 */ 2599 if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { 2600 (void) fprintf(stderr, gettext("cannot scrub '%s': pool is " 2601 "currently unavailable\n"), zpool_get_name(zhp)); 2602 return (1); 2603 } 2604 2605 err = zpool_scrub(zhp, cb->cb_type); 2606 2607 return (err != 0); 2608} 2609 2610/* 2611 * zpool scrub [-s] <pool> ... 2612 * 2613 * -s Stop. Stops any in-progress scrub. 2614 */ 2615int 2616zpool_do_scrub(int argc, char **argv) 2617{ 2618 int c; 2619 scrub_cbdata_t cb; 2620 2621 cb.cb_type = POOL_SCRUB_EVERYTHING; 2622 2623 /* check options */ 2624 while ((c = getopt(argc, argv, "s")) != -1) { 2625 switch (c) { 2626 case 's': 2627 cb.cb_type = POOL_SCRUB_NONE; 2628 break; 2629 case '?': 2630 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 2631 optopt); 2632 usage(B_FALSE); 2633 } 2634 } 2635 2636 cb.cb_argc = argc; 2637 cb.cb_argv = argv; 2638 argc -= optind; 2639 argv += optind; 2640 2641 if (argc < 1) { 2642 (void) fprintf(stderr, gettext("missing pool name argument\n")); 2643 usage(B_FALSE); 2644 } 2645 2646 return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb)); 2647} 2648 2649typedef struct status_cbdata { 2650 int cb_count; 2651 boolean_t cb_allpools; 2652 boolean_t cb_verbose; 2653 boolean_t cb_explain; 2654 boolean_t cb_first; 2655} status_cbdata_t; 2656 2657/* 2658 * Print out detailed scrub status. 2659 */ 2660void 2661print_scrub_status(nvlist_t *nvroot) 2662{ 2663 vdev_stat_t *vs; 2664 uint_t vsc; 2665 time_t start, end, now; 2666 double fraction_done; 2667 uint64_t examined, total, minutes_left, minutes_taken; 2668 char *scrub_type; 2669 2670 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 2671 (uint64_t **)&vs, &vsc) == 0); 2672 2673 /* 2674 * If there's never been a scrub, there's not much to say. 2675 */ 2676 if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) { 2677 (void) printf(gettext("none requested\n")); 2678 return; 2679 } 2680 2681 scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2682 "resilver" : "scrub"; 2683 2684 start = vs->vs_scrub_start; 2685 end = vs->vs_scrub_end; 2686 now = time(NULL); 2687 examined = vs->vs_scrub_examined; 2688 total = vs->vs_alloc; 2689 2690 if (end != 0) { 2691 minutes_taken = (uint64_t)((end - start) / 60); 2692 2693 (void) printf(gettext("%s %s after %lluh%um with %llu errors " 2694 "on %s"), 2695 scrub_type, vs->vs_scrub_complete ? "completed" : "stopped", 2696 (u_longlong_t)(minutes_taken / 60), 2697 (uint_t)(minutes_taken % 60), 2698 (u_longlong_t)vs->vs_scrub_errors, ctime(&end)); 2699 return; 2700 } 2701 2702 if (examined == 0) 2703 examined = 1; 2704 if (examined > total) 2705 total = examined; 2706 2707 fraction_done = (double)examined / total; 2708 minutes_left = (uint64_t)((now - start) * 2709 (1 - fraction_done) / fraction_done / 60); 2710 minutes_taken = (uint64_t)((now - start) / 60); 2711 2712 (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, " 2713 "%lluh%um to go\n"), 2714 scrub_type, (u_longlong_t)(minutes_taken / 60), 2715 (uint_t)(minutes_taken % 60), 100 * fraction_done, 2716 (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60)); 2717} 2718 2719typedef struct spare_cbdata { 2720 uint64_t cb_guid; 2721 zpool_handle_t *cb_zhp; 2722} spare_cbdata_t; 2723 2724static boolean_t 2725find_vdev(nvlist_t *nv, uint64_t search) 2726{ 2727 uint64_t guid; 2728 nvlist_t **child; 2729 uint_t c, children; 2730 2731 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 && 2732 search == guid) 2733 return (B_TRUE); 2734 2735 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2736 &child, &children) == 0) { 2737 for (c = 0; c < children; c++) 2738 if (find_vdev(child[c], search)) 2739 return (B_TRUE); 2740 } 2741 2742 return (B_FALSE); 2743} 2744 2745static int 2746find_spare(zpool_handle_t *zhp, void *data) 2747{ 2748 spare_cbdata_t *cbp = data; 2749 nvlist_t *config, *nvroot; 2750 2751 config = zpool_get_config(zhp, NULL); 2752 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 2753 &nvroot) == 0); 2754 2755 if (find_vdev(nvroot, cbp->cb_guid)) { 2756 cbp->cb_zhp = zhp; 2757 return (1); 2758 } 2759 2760 zpool_close(zhp); 2761 return (0); 2762} 2763 2764/* 2765 * Print out configuration state as requested by status_callback. 2766 */ 2767void 2768print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv, 2769 int namewidth, int depth, boolean_t isspare, boolean_t print_logs) 2770{ 2771 nvlist_t **child; 2772 uint_t c, children; 2773 vdev_stat_t *vs; 2774 char rbuf[6], wbuf[6], cbuf[6], repaired[7]; 2775 char *vname; 2776 uint64_t notpresent; 2777 spare_cbdata_t cb; 2778 char *state; 2779 2780 verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS, 2781 (uint64_t **)&vs, &c) == 0); 2782 2783 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 2784 &child, &children) != 0) 2785 children = 0; 2786 2787 state = zpool_state_to_name(vs->vs_state, vs->vs_aux); 2788 if (isspare) { 2789 /* 2790 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for 2791 * online drives. 2792 */ 2793 if (vs->vs_aux == VDEV_AUX_SPARED) 2794 state = "INUSE"; 2795 else if (vs->vs_state == VDEV_STATE_HEALTHY) 2796 state = "AVAIL"; 2797 } 2798 2799 (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth, 2800 name, state); 2801 2802 if (!isspare) { 2803 zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf)); 2804 zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf)); 2805 zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf)); 2806 (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf); 2807 } 2808 2809 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, 2810 ¬present) == 0) { 2811 char *path; 2812 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0); 2813 (void) printf(" was %s", path); 2814 } else if (vs->vs_aux != 0) { 2815 (void) printf(" "); 2816 2817 switch (vs->vs_aux) { 2818 case VDEV_AUX_OPEN_FAILED: 2819 (void) printf(gettext("cannot open")); 2820 break; 2821 2822 case VDEV_AUX_BAD_GUID_SUM: 2823 (void) printf(gettext("missing device")); 2824 break; 2825 2826 case VDEV_AUX_NO_REPLICAS: 2827 (void) printf(gettext("insufficient replicas")); 2828 break; 2829 2830 case VDEV_AUX_VERSION_NEWER: 2831 (void) printf(gettext("newer version")); 2832 break; 2833 2834 case VDEV_AUX_SPARED: 2835 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, 2836 &cb.cb_guid) == 0); 2837 if (zpool_iter(g_zfs, find_spare, &cb) == 1) { 2838 if (strcmp(zpool_get_name(cb.cb_zhp), 2839 zpool_get_name(zhp)) == 0) 2840 (void) printf(gettext("currently in " 2841 "use")); 2842 else 2843 (void) printf(gettext("in use by " 2844 "pool '%s'"), 2845 zpool_get_name(cb.cb_zhp)); 2846 zpool_close(cb.cb_zhp); 2847 } else { 2848 (void) printf(gettext("currently in use")); 2849 } 2850 break; 2851 2852 case VDEV_AUX_ERR_EXCEEDED: 2853 (void) printf(gettext("too many errors")); 2854 break; 2855 2856 case VDEV_AUX_IO_FAILURE: 2857 (void) printf(gettext("experienced I/O failures")); 2858 break; 2859 2860 case VDEV_AUX_BAD_LOG: 2861 (void) printf(gettext("bad intent log")); 2862 break; 2863 2864 default: 2865 (void) printf(gettext("corrupted data")); 2866 break; 2867 } 2868 } else if (vs->vs_scrub_repaired != 0 && children == 0) { 2869 /* 2870 * Report bytes resilvered/repaired on leaf devices. 2871 */ 2872 zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired)); 2873 (void) printf(gettext(" %s %s"), repaired, 2874 (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ? 2875 "resilvered" : "repaired"); 2876 } 2877 2878 (void) printf("\n"); 2879 2880 for (c = 0; c < children; c++) { 2881 uint64_t is_log = B_FALSE; 2882 2883 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG, 2884 &is_log); 2885 if ((is_log && !print_logs) || (!is_log && print_logs)) 2886 continue; 2887 vname = zpool_vdev_name(g_zfs, zhp, child[c]); 2888 print_status_config(zhp, vname, child[c], 2889 namewidth, depth + 2, isspare, B_FALSE); 2890 free(vname); 2891 } 2892} 2893 2894static void 2895print_error_log(zpool_handle_t *zhp) 2896{ 2897 nvlist_t *nverrlist = NULL; 2898 nvpair_t *elem; 2899 char *pathname; 2900 size_t len = MAXPATHLEN * 2; 2901 2902 if (zpool_get_errlog(zhp, &nverrlist) != 0) { 2903 (void) printf("errors: List of errors unavailable " 2904 "(insufficient privileges)\n"); 2905 return; 2906 } 2907 2908 (void) printf("errors: Permanent errors have been " 2909 "detected in the following files:\n\n"); 2910 2911 pathname = safe_malloc(len); 2912 elem = NULL; 2913 while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) { 2914 nvlist_t *nv; 2915 uint64_t dsobj, obj; 2916 2917 verify(nvpair_value_nvlist(elem, &nv) == 0); 2918 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET, 2919 &dsobj) == 0); 2920 verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT, 2921 &obj) == 0); 2922 zpool_obj_to_path(zhp, dsobj, obj, pathname, len); 2923 (void) printf("%7s %s\n", "", pathname); 2924 } 2925 free(pathname); 2926 nvlist_free(nverrlist); 2927} 2928 2929static void 2930print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares, 2931 int namewidth) 2932{ 2933 uint_t i; 2934 char *name; 2935 2936 if (nspares == 0) 2937 return; 2938 2939 (void) printf(gettext("\tspares\n")); 2940 2941 for (i = 0; i < nspares; i++) { 2942 name = zpool_vdev_name(g_zfs, zhp, spares[i]); 2943 print_status_config(zhp, name, spares[i], 2944 namewidth, 2, B_TRUE, B_FALSE); 2945 free(name); 2946 } 2947} 2948 2949static void 2950print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache, 2951 int namewidth) 2952{ 2953 uint_t i; 2954 char *name; 2955 2956 if (nl2cache == 0) 2957 return; 2958 2959 (void) printf(gettext("\tcache\n")); 2960 2961 for (i = 0; i < nl2cache; i++) { 2962 name = zpool_vdev_name(g_zfs, zhp, l2cache[i]); 2963 print_status_config(zhp, name, l2cache[i], 2964 namewidth, 2, B_FALSE, B_FALSE); 2965 free(name); 2966 } 2967} 2968 2969/* 2970 * Display a summary of pool status. Displays a summary such as: 2971 * 2972 * pool: tank 2973 * status: DEGRADED 2974 * reason: One or more devices ... 2975 * see: http://www.sun.com/msg/ZFS-xxxx-01 2976 * config: 2977 * mirror DEGRADED 2978 * c1t0d0 OK 2979 * c2t0d0 UNAVAIL 2980 * 2981 * When given the '-v' option, we print out the complete config. If the '-e' 2982 * option is specified, then we print out error rate information as well. 2983 */ 2984int 2985status_callback(zpool_handle_t *zhp, void *data) 2986{ 2987 status_cbdata_t *cbp = data; 2988 nvlist_t *config, *nvroot; 2989 char *msgid; 2990 int reason; 2991 const char *health; 2992 uint_t c; 2993 vdev_stat_t *vs; 2994 2995 config = zpool_get_config(zhp, NULL); 2996 reason = zpool_get_status(zhp, &msgid); 2997 2998 cbp->cb_count++; 2999 3000 /* 3001 * If we were given 'zpool status -x', only report those pools with 3002 * problems. 3003 */ 3004 if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) { 3005 if (!cbp->cb_allpools) { 3006 (void) printf(gettext("pool '%s' is healthy\n"), 3007 zpool_get_name(zhp)); 3008 if (cbp->cb_first) 3009 cbp->cb_first = B_FALSE; 3010 } 3011 return (0); 3012 } 3013 3014 if (cbp->cb_first) 3015 cbp->cb_first = B_FALSE; 3016 else 3017 (void) printf("\n"); 3018 3019 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 3020 &nvroot) == 0); 3021 verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS, 3022 (uint64_t **)&vs, &c) == 0); 3023 health = zpool_state_to_name(vs->vs_state, vs->vs_aux); 3024 3025 (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp)); 3026 (void) printf(gettext(" state: %s\n"), health); 3027 3028 switch (reason) { 3029 case ZPOOL_STATUS_MISSING_DEV_R: 3030 (void) printf(gettext("status: One or more devices could not " 3031 "be opened. Sufficient replicas exist for\n\tthe pool to " 3032 "continue functioning in a degraded state.\n")); 3033 (void) printf(gettext("action: Attach the missing device and " 3034 "online it using 'zpool online'.\n")); 3035 break; 3036 3037 case ZPOOL_STATUS_MISSING_DEV_NR: 3038 (void) printf(gettext("status: One or more devices could not " 3039 "be opened. There are insufficient\n\treplicas for the " 3040 "pool to continue functioning.\n")); 3041 (void) printf(gettext("action: Attach the missing device and " 3042 "online it using 'zpool online'.\n")); 3043 break; 3044 3045 case ZPOOL_STATUS_CORRUPT_LABEL_R: 3046 (void) printf(gettext("status: One or more devices could not " 3047 "be used because the label is missing or\n\tinvalid. " 3048 "Sufficient replicas exist for the pool to continue\n\t" 3049 "functioning in a degraded state.\n")); 3050 (void) printf(gettext("action: Replace the device using " 3051 "'zpool replace'.\n")); 3052 break; 3053 3054 case ZPOOL_STATUS_CORRUPT_LABEL_NR: 3055 (void) printf(gettext("status: One or more devices could not " 3056 "be used because the label is missing \n\tor invalid. " 3057 "There are insufficient replicas for the pool to " 3058 "continue\n\tfunctioning.\n")); 3059 (void) printf(gettext("action: Destroy and re-create the pool " 3060 "from a backup source.\n")); 3061 break; 3062 3063 case ZPOOL_STATUS_FAILING_DEV: 3064 (void) printf(gettext("status: One or more devices has " 3065 "experienced an unrecoverable error. An\n\tattempt was " 3066 "made to correct the error. Applications are " 3067 "unaffected.\n")); 3068 (void) printf(gettext("action: Determine if the device needs " 3069 "to be replaced, and clear the errors\n\tusing " 3070 "'zpool clear' or replace the device with 'zpool " 3071 "replace'.\n")); 3072 break; 3073 3074 case ZPOOL_STATUS_OFFLINE_DEV: 3075 (void) printf(gettext("status: One or more devices has " 3076 "been taken offline by the administrator.\n\tSufficient " 3077 "replicas exist for the pool to continue functioning in " 3078 "a\n\tdegraded state.\n")); 3079 (void) printf(gettext("action: Online the device using " 3080 "'zpool online' or replace the device with\n\t'zpool " 3081 "replace'.\n")); 3082 break; 3083 3084 case ZPOOL_STATUS_RESILVERING: 3085 (void) printf(gettext("status: One or more devices is " 3086 "currently being resilvered. The pool will\n\tcontinue " 3087 "to function, possibly in a degraded state.\n")); 3088 (void) printf(gettext("action: Wait for the resilver to " 3089 "complete.\n")); 3090 break; 3091 3092 case ZPOOL_STATUS_CORRUPT_DATA: 3093 (void) printf(gettext("status: One or more devices has " 3094 "experienced an error resulting in data\n\tcorruption. " 3095 "Applications may be affected.\n")); 3096 (void) printf(gettext("action: Restore the file in question " 3097 "if possible. Otherwise restore the\n\tentire pool from " 3098 "backup.\n")); 3099 break; 3100 3101 case ZPOOL_STATUS_CORRUPT_POOL: 3102 (void) printf(gettext("status: The pool metadata is corrupted " 3103 "and the pool cannot be opened.\n")); 3104 (void) printf(gettext("action: Destroy and re-create the pool " 3105 "from a backup source.\n")); 3106 break; 3107 3108 case ZPOOL_STATUS_VERSION_OLDER: 3109 (void) printf(gettext("status: The pool is formatted using an " 3110 "older on-disk format. The pool can\n\tstill be used, but " 3111 "some features are unavailable.\n")); 3112 (void) printf(gettext("action: Upgrade the pool using 'zpool " 3113 "upgrade'. Once this is done, the\n\tpool will no longer " 3114 "be accessible on older software versions.\n")); 3115 break; 3116 3117 case ZPOOL_STATUS_VERSION_NEWER: 3118 (void) printf(gettext("status: The pool has been upgraded to a " 3119 "newer, incompatible on-disk version.\n\tThe pool cannot " 3120 "be accessed on this system.\n")); 3121 (void) printf(gettext("action: Access the pool from a system " 3122 "running more recent software, or\n\trestore the pool from " 3123 "backup.\n")); 3124 break; 3125 3126 case ZPOOL_STATUS_FAULTED_DEV_R: 3127 (void) printf(gettext("status: One or more devices are " 3128 "faulted in response to persistent errors.\n\tSufficient " 3129 "replicas exist for the pool to continue functioning " 3130 "in a\n\tdegraded state.\n")); 3131 (void) printf(gettext("action: Replace the faulted device, " 3132 "or use 'zpool clear' to mark the device\n\trepaired.\n")); 3133 break; 3134 3135 case ZPOOL_STATUS_FAULTED_DEV_NR: 3136 (void) printf(gettext("status: One or more devices are " 3137 "faulted in response to persistent errors. There are " 3138 "insufficient replicas for the pool to\n\tcontinue " 3139 "functioning.\n")); 3140 (void) printf(gettext("action: Destroy and re-create the pool " 3141 "from a backup source. Manually marking the device\n" 3142 "\trepaired using 'zpool clear' may allow some data " 3143 "to be recovered.\n")); 3144 break; 3145 3146 case ZPOOL_STATUS_IO_FAILURE_WAIT: 3147 case ZPOOL_STATUS_IO_FAILURE_CONTINUE: 3148 (void) printf(gettext("status: One or more devices are " 3149 "faulted in response to IO failures.\n")); 3150 (void) printf(gettext("action: Make sure the affected devices " 3151 "are connected, then run 'zpool clear'.\n")); 3152 break; 3153 3154 case ZPOOL_STATUS_BAD_LOG: 3155 (void) printf(gettext("status: An intent log record " 3156 "could not be read.\n" 3157 "\tWaiting for adminstrator intervention to fix the " 3158 "faulted pool.\n")); 3159 (void) printf(gettext("action: Either restore the affected " 3160 "device(s) and run 'zpool online',\n" 3161 "\tor ignore the intent log records by running " 3162 "'zpool clear'.\n")); 3163 break; 3164 3165 default: 3166 /* 3167 * The remaining errors can't actually be generated, yet. 3168 */ 3169 assert(reason == ZPOOL_STATUS_OK); 3170 } 3171 3172 if (msgid != NULL) 3173 (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"), 3174 msgid); 3175 3176 if (config != NULL) { 3177 int namewidth; 3178 uint64_t nerr; 3179 nvlist_t **spares, **l2cache; 3180 uint_t nspares, nl2cache; 3181 3182 3183 (void) printf(gettext(" scrub: ")); 3184 print_scrub_status(nvroot); 3185 3186 namewidth = max_width(zhp, nvroot, 0, 0); 3187 if (namewidth < 10) 3188 namewidth = 10; 3189 3190 (void) printf(gettext("config:\n\n")); 3191 (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth, 3192 "NAME", "STATE", "READ", "WRITE", "CKSUM"); 3193 print_status_config(zhp, zpool_get_name(zhp), nvroot, 3194 namewidth, 0, B_FALSE, B_FALSE); 3195 if (num_logs(nvroot) > 0) 3196 print_status_config(zhp, "logs", nvroot, namewidth, 0, 3197 B_FALSE, B_TRUE); 3198 3199 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 3200 &l2cache, &nl2cache) == 0) 3201 print_l2cache(zhp, l2cache, nl2cache, namewidth); 3202 3203 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 3204 &spares, &nspares) == 0) 3205 print_spares(zhp, spares, nspares, namewidth); 3206 3207 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT, 3208 &nerr) == 0) { 3209 nvlist_t *nverrlist = NULL; 3210 3211 /* 3212 * If the approximate error count is small, get a 3213 * precise count by fetching the entire log and 3214 * uniquifying the results. 3215 */ 3216 if (nerr > 0 && nerr < 100 && !cbp->cb_verbose && 3217 zpool_get_errlog(zhp, &nverrlist) == 0) { 3218 nvpair_t *elem; 3219 3220 elem = NULL; 3221 nerr = 0; 3222 while ((elem = nvlist_next_nvpair(nverrlist, 3223 elem)) != NULL) { 3224 nerr++; 3225 } 3226 } 3227 nvlist_free(nverrlist); 3228 3229 (void) printf("\n"); 3230 3231 if (nerr == 0) 3232 (void) printf(gettext("errors: No known data " 3233 "errors\n")); 3234 else if (!cbp->cb_verbose) 3235 (void) printf(gettext("errors: %llu data " 3236 "errors, use '-v' for a list\n"), 3237 (u_longlong_t)nerr); 3238 else 3239 print_error_log(zhp); 3240 } 3241 } else { 3242 (void) printf(gettext("config: The configuration cannot be " 3243 "determined.\n")); 3244 } 3245 3246 return (0); 3247} 3248 3249/* 3250 * zpool status [-vx] [pool] ... 3251 * 3252 * -v Display complete error logs 3253 * -x Display only pools with potential problems 3254 * 3255 * Describes the health status of all pools or some subset. 3256 */ 3257int 3258zpool_do_status(int argc, char **argv) 3259{ 3260 int c; 3261 int ret; 3262 status_cbdata_t cb = { 0 }; 3263 3264 /* check options */ 3265 while ((c = getopt(argc, argv, "vx")) != -1) { 3266 switch (c) { 3267 case 'v': 3268 cb.cb_verbose = B_TRUE; 3269 break; 3270 case 'x': 3271 cb.cb_explain = B_TRUE; 3272 break; 3273 case '?': 3274 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3275 optopt); 3276 usage(B_FALSE); 3277 } 3278 } 3279 3280 argc -= optind; 3281 argv += optind; 3282 3283 cb.cb_first = B_TRUE; 3284 3285 if (argc == 0) 3286 cb.cb_allpools = B_TRUE; 3287 3288 ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb); 3289 3290 if (argc == 0 && cb.cb_count == 0) 3291 (void) printf(gettext("no pools available\n")); 3292 else if (cb.cb_explain && cb.cb_first && cb.cb_allpools) 3293 (void) printf(gettext("all pools are healthy\n")); 3294 3295 return (ret); 3296} 3297 3298typedef struct upgrade_cbdata { 3299 int cb_all; 3300 int cb_first; 3301 int cb_newer; 3302 int cb_argc; 3303 uint64_t cb_version; 3304 char **cb_argv; 3305} upgrade_cbdata_t; 3306 3307static int 3308upgrade_cb(zpool_handle_t *zhp, void *arg) 3309{ 3310 upgrade_cbdata_t *cbp = arg; 3311 nvlist_t *config; 3312 uint64_t version; 3313 int ret = 0; 3314 3315 config = zpool_get_config(zhp, NULL); 3316 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, 3317 &version) == 0); 3318 3319 if (!cbp->cb_newer && version < SPA_VERSION) { 3320 if (!cbp->cb_all) { 3321 if (cbp->cb_first) { 3322 (void) printf(gettext("The following pools are " 3323 "out of date, and can be upgraded. After " 3324 "being\nupgraded, these pools will no " 3325 "longer be accessible by older software " 3326 "versions.\n\n")); 3327 (void) printf(gettext("VER POOL\n")); 3328 (void) printf(gettext("--- ------------\n")); 3329 cbp->cb_first = B_FALSE; 3330 } 3331 3332 (void) printf("%2llu %s\n", (u_longlong_t)version, 3333 zpool_get_name(zhp)); 3334 } else { 3335 cbp->cb_first = B_FALSE; 3336 ret = zpool_upgrade(zhp, cbp->cb_version); 3337 if (!ret) { 3338 (void) printf(gettext("Successfully upgraded " 3339 "'%s'\n\n"), zpool_get_name(zhp)); 3340 } 3341 } 3342 } else if (cbp->cb_newer && version > SPA_VERSION) { 3343 assert(!cbp->cb_all); 3344 3345 if (cbp->cb_first) { 3346 (void) printf(gettext("The following pools are " 3347 "formatted using a newer software version and\n" 3348 "cannot be accessed on the current system.\n\n")); 3349 (void) printf(gettext("VER POOL\n")); 3350 (void) printf(gettext("--- ------------\n")); 3351 cbp->cb_first = B_FALSE; 3352 } 3353 3354 (void) printf("%2llu %s\n", (u_longlong_t)version, 3355 zpool_get_name(zhp)); 3356 } 3357 3358 zpool_close(zhp); 3359 return (ret); 3360} 3361 3362/* ARGSUSED */ 3363static int 3364upgrade_one(zpool_handle_t *zhp, void *data) 3365{ 3366 upgrade_cbdata_t *cbp = data; 3367 uint64_t cur_version; 3368 int ret; 3369 3370 if (strcmp("log", zpool_get_name(zhp)) == 0) { 3371 (void) printf(gettext("'log' is now a reserved word\n" 3372 "Pool 'log' must be renamed using export and import" 3373 " to upgrade.\n")); 3374 return (1); 3375 } 3376 3377 cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL); 3378 if (cur_version > cbp->cb_version) { 3379 (void) printf(gettext("Pool '%s' is already formatted " 3380 "using more current version '%llu'.\n"), 3381 zpool_get_name(zhp), cur_version); 3382 return (0); 3383 } 3384 if (cur_version == cbp->cb_version) { 3385 (void) printf(gettext("Pool '%s' is already formatted " 3386 "using the current version.\n"), zpool_get_name(zhp)); 3387 return (0); 3388 } 3389 3390 ret = zpool_upgrade(zhp, cbp->cb_version); 3391 3392 if (!ret) { 3393 (void) printf(gettext("Successfully upgraded '%s' " 3394 "from version %llu to version %llu\n\n"), 3395 zpool_get_name(zhp), (u_longlong_t)cur_version, 3396 (u_longlong_t)cbp->cb_version); 3397 } 3398 3399 return (ret != 0); 3400} 3401 3402/* 3403 * zpool upgrade 3404 * zpool upgrade -v 3405 * zpool upgrade [-V version] <-a | pool ...> 3406 * 3407 * With no arguments, display downrev'd ZFS pool available for upgrade. 3408 * Individual pools can be upgraded by specifying the pool, and '-a' will 3409 * upgrade all pools. 3410 */ 3411int 3412zpool_do_upgrade(int argc, char **argv) 3413{ 3414 int c; 3415 upgrade_cbdata_t cb = { 0 }; 3416 int ret = 0; 3417 boolean_t showversions = B_FALSE; 3418 char *end; 3419 3420 3421 /* check options */ 3422 while ((c = getopt(argc, argv, "avV:")) != -1) { 3423 switch (c) { 3424 case 'a': 3425 cb.cb_all = B_TRUE; 3426 break; 3427 case 'v': 3428 showversions = B_TRUE; 3429 break; 3430 case 'V': 3431 cb.cb_version = strtoll(optarg, &end, 10); 3432 if (*end != '\0' || cb.cb_version > SPA_VERSION || 3433 cb.cb_version < SPA_VERSION_1) { 3434 (void) fprintf(stderr, 3435 gettext("invalid version '%s'\n"), optarg); 3436 usage(B_FALSE); 3437 } 3438 break; 3439 case '?': 3440 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3441 optopt); 3442 usage(B_FALSE); 3443 } 3444 } 3445 3446 cb.cb_argc = argc; 3447 cb.cb_argv = argv; 3448 argc -= optind; 3449 argv += optind; 3450 3451 if (cb.cb_version == 0) { 3452 cb.cb_version = SPA_VERSION; 3453 } else if (!cb.cb_all && argc == 0) { 3454 (void) fprintf(stderr, gettext("-V option is " 3455 "incompatible with other arguments\n")); 3456 usage(B_FALSE); 3457 } 3458 3459 if (showversions) { 3460 if (cb.cb_all || argc != 0) { 3461 (void) fprintf(stderr, gettext("-v option is " 3462 "incompatible with other arguments\n")); 3463 usage(B_FALSE); 3464 } 3465 } else if (cb.cb_all) { 3466 if (argc != 0) { 3467 (void) fprintf(stderr, gettext("-a option should not " 3468 "be used along with a pool name\n")); 3469 usage(B_FALSE); 3470 } 3471 } 3472 3473 (void) printf(gettext("This system is currently running " 3474 "ZFS pool version %llu.\n\n"), SPA_VERSION); 3475 cb.cb_first = B_TRUE; 3476 if (showversions) { 3477 (void) printf(gettext("The following versions are " 3478 "supported:\n\n")); 3479 (void) printf(gettext("VER DESCRIPTION\n")); 3480 (void) printf("--- -----------------------------------------" 3481 "---------------\n"); 3482 (void) printf(gettext(" 1 Initial ZFS version\n")); 3483 (void) printf(gettext(" 2 Ditto blocks " 3484 "(replicated metadata)\n")); 3485 (void) printf(gettext(" 3 Hot spares and double parity " 3486 "RAID-Z\n")); 3487 (void) printf(gettext(" 4 zpool history\n")); 3488 (void) printf(gettext(" 5 Compression using the gzip " 3489 "algorithm\n")); 3490 (void) printf(gettext(" 6 bootfs pool property\n")); 3491 (void) printf(gettext(" 7 Separate intent log devices\n")); 3492 (void) printf(gettext(" 8 Delegated administration\n")); 3493 (void) printf(gettext(" 9 refquota and refreservation " 3494 "properties\n")); 3495 (void) printf(gettext(" 10 Cache devices\n")); 3496 (void) printf(gettext(" 11 Improved scrub performance\n")); 3497 (void) printf(gettext(" 12 Snapshot properties\n")); 3498 (void) printf(gettext(" 13 snapused property\n")); 3499 (void) printf(gettext(" 14 passthrough-x aclinherit " 3500 "support\n")); 3501 (void) printf(gettext("For more information on a particular " 3502 "version, including supported releases, see:\n\n")); 3503 (void) printf("http://www.opensolaris.org/os/community/zfs/" 3504 "version/N\n\n"); 3505 (void) printf(gettext("Where 'N' is the version number.\n")); 3506 } else if (argc == 0) { 3507 int notfound; 3508 3509 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3510 notfound = cb.cb_first; 3511 3512 if (!cb.cb_all && ret == 0) { 3513 if (!cb.cb_first) 3514 (void) printf("\n"); 3515 cb.cb_first = B_TRUE; 3516 cb.cb_newer = B_TRUE; 3517 ret = zpool_iter(g_zfs, upgrade_cb, &cb); 3518 if (!cb.cb_first) { 3519 notfound = B_FALSE; 3520 (void) printf("\n"); 3521 } 3522 } 3523 3524 if (ret == 0) { 3525 if (notfound) 3526 (void) printf(gettext("All pools are formatted " 3527 "using this version.\n")); 3528 else if (!cb.cb_all) 3529 (void) printf(gettext("Use 'zpool upgrade -v' " 3530 "for a list of available versions and " 3531 "their associated\nfeatures.\n")); 3532 } 3533 } else { 3534 ret = for_each_pool(argc, argv, B_FALSE, NULL, 3535 upgrade_one, &cb); 3536 } 3537 3538 return (ret); 3539} 3540 3541typedef struct hist_cbdata { 3542 boolean_t first; 3543 int longfmt; 3544 int internal; 3545} hist_cbdata_t; 3546 3547char *hist_event_table[LOG_END] = { 3548 "invalid event", 3549 "pool create", 3550 "vdev add", 3551 "pool remove", 3552 "pool destroy", 3553 "pool export", 3554 "pool import", 3555 "vdev attach", 3556 "vdev replace", 3557 "vdev detach", 3558 "vdev online", 3559 "vdev offline", 3560 "vdev upgrade", 3561 "pool clear", 3562 "pool scrub", 3563 "pool property set", 3564 "create", 3565 "clone", 3566 "destroy", 3567 "destroy_begin_sync", 3568 "inherit", 3569 "property set", 3570 "quota set", 3571 "permission update", 3572 "permission remove", 3573 "permission who remove", 3574 "promote", 3575 "receive", 3576 "rename", 3577 "reservation set", 3578 "replay_inc_sync", 3579 "replay_full_sync", 3580 "rollback", 3581 "snapshot", 3582 "filesystem version upgrade", 3583 "refquota set", 3584 "refreservation set", 3585 "pool scrub done", 3586}; 3587 3588/* 3589 * Print out the command history for a specific pool. 3590 */ 3591static int 3592get_history_one(zpool_handle_t *zhp, void *data) 3593{ 3594 nvlist_t *nvhis; 3595 nvlist_t **records; 3596 uint_t numrecords; 3597 char *cmdstr; 3598 char *pathstr; 3599 uint64_t dst_time; 3600 time_t tsec; 3601 struct tm t; 3602 char tbuf[30]; 3603 int ret, i; 3604 uint64_t who; 3605 struct passwd *pwd; 3606 char *hostname; 3607 char *zonename; 3608 char internalstr[MAXPATHLEN]; 3609 hist_cbdata_t *cb = (hist_cbdata_t *)data; 3610 uint64_t txg; 3611 uint64_t ievent; 3612 3613 cb->first = B_FALSE; 3614 3615 (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp)); 3616 3617 if ((ret = zpool_get_history(zhp, &nvhis)) != 0) 3618 return (ret); 3619 3620 verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD, 3621 &records, &numrecords) == 0); 3622 for (i = 0; i < numrecords; i++) { 3623 if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME, 3624 &dst_time) != 0) 3625 continue; 3626 3627 /* is it an internal event or a standard event? */ 3628 if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD, 3629 &cmdstr) != 0) { 3630 if (cb->internal == 0) 3631 continue; 3632 3633 if (nvlist_lookup_uint64(records[i], 3634 ZPOOL_HIST_INT_EVENT, &ievent) != 0) 3635 continue; 3636 verify(nvlist_lookup_uint64(records[i], 3637 ZPOOL_HIST_TXG, &txg) == 0); 3638 verify(nvlist_lookup_string(records[i], 3639 ZPOOL_HIST_INT_STR, &pathstr) == 0); 3640 if (ievent >= LOG_END) 3641 continue; 3642 (void) snprintf(internalstr, 3643 sizeof (internalstr), 3644 "[internal %s txg:%lld] %s", 3645 hist_event_table[ievent], txg, 3646 pathstr); 3647 cmdstr = internalstr; 3648 } 3649 tsec = dst_time; 3650 (void) localtime_r(&tsec, &t); 3651 (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); 3652 (void) printf("%s %s", tbuf, cmdstr); 3653 3654 if (!cb->longfmt) { 3655 (void) printf("\n"); 3656 continue; 3657 } 3658 (void) printf(" ["); 3659 if (nvlist_lookup_uint64(records[i], 3660 ZPOOL_HIST_WHO, &who) == 0) { 3661 pwd = getpwuid((uid_t)who); 3662 if (pwd) 3663 (void) printf("user %s on", 3664 pwd->pw_name); 3665 else 3666 (void) printf("user %d on", 3667 (int)who); 3668 } else { 3669 (void) printf(gettext("no info]\n")); 3670 continue; 3671 } 3672 if (nvlist_lookup_string(records[i], 3673 ZPOOL_HIST_HOST, &hostname) == 0) { 3674 (void) printf(" %s", hostname); 3675 } 3676 if (nvlist_lookup_string(records[i], 3677 ZPOOL_HIST_ZONE, &zonename) == 0) { 3678 (void) printf(":%s", zonename); 3679 } 3680 3681 (void) printf("]"); 3682 (void) printf("\n"); 3683 } 3684 (void) printf("\n"); 3685 nvlist_free(nvhis); 3686 3687 return (ret); 3688} 3689 3690/* 3691 * zpool history <pool> 3692 * 3693 * Displays the history of commands that modified pools. 3694 */ 3695 3696 3697int 3698zpool_do_history(int argc, char **argv) 3699{ 3700 hist_cbdata_t cbdata = { 0 }; 3701 int ret; 3702 int c; 3703 3704 cbdata.first = B_TRUE; 3705 /* check options */ 3706 while ((c = getopt(argc, argv, "li")) != -1) { 3707 switch (c) { 3708 case 'l': 3709 cbdata.longfmt = 1; 3710 break; 3711 case 'i': 3712 cbdata.internal = 1; 3713 break; 3714 case '?': 3715 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3716 optopt); 3717 usage(B_FALSE); 3718 } 3719 } 3720 argc -= optind; 3721 argv += optind; 3722 3723 ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one, 3724 &cbdata); 3725 3726 if (argc == 0 && cbdata.first == B_TRUE) { 3727 (void) printf(gettext("no pools available\n")); 3728 return (0); 3729 } 3730 3731 return (ret); 3732} 3733 3734static int 3735get_callback(zpool_handle_t *zhp, void *data) 3736{ 3737 zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data; 3738 char value[MAXNAMELEN]; 3739 zprop_source_t srctype; 3740 zprop_list_t *pl; 3741 3742 for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 3743 3744 /* 3745 * Skip the special fake placeholder. This will also skip 3746 * over the name property when 'all' is specified. 3747 */ 3748 if (pl->pl_prop == ZPOOL_PROP_NAME && 3749 pl == cbp->cb_proplist) 3750 continue; 3751 3752 if (zpool_get_prop(zhp, pl->pl_prop, 3753 value, sizeof (value), &srctype) != 0) 3754 continue; 3755 3756 zprop_print_one_property(zpool_get_name(zhp), cbp, 3757 zpool_prop_to_name(pl->pl_prop), value, srctype, NULL); 3758 } 3759 return (0); 3760} 3761 3762int 3763zpool_do_get(int argc, char **argv) 3764{ 3765 zprop_get_cbdata_t cb = { 0 }; 3766 zprop_list_t fake_name = { 0 }; 3767 int ret; 3768 3769 if (argc < 3) 3770 usage(B_FALSE); 3771 3772 cb.cb_first = B_TRUE; 3773 cb.cb_sources = ZPROP_SRC_ALL; 3774 cb.cb_columns[0] = GET_COL_NAME; 3775 cb.cb_columns[1] = GET_COL_PROPERTY; 3776 cb.cb_columns[2] = GET_COL_VALUE; 3777 cb.cb_columns[3] = GET_COL_SOURCE; 3778 cb.cb_type = ZFS_TYPE_POOL; 3779 3780 if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist, 3781 ZFS_TYPE_POOL) != 0) 3782 usage(B_FALSE); 3783 3784 if (cb.cb_proplist != NULL) { 3785 fake_name.pl_prop = ZPOOL_PROP_NAME; 3786 fake_name.pl_width = strlen(gettext("NAME")); 3787 fake_name.pl_next = cb.cb_proplist; 3788 cb.cb_proplist = &fake_name; 3789 } 3790 3791 ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist, 3792 get_callback, &cb); 3793 3794 if (cb.cb_proplist == &fake_name) 3795 zprop_free_list(fake_name.pl_next); 3796 else 3797 zprop_free_list(cb.cb_proplist); 3798 3799 return (ret); 3800} 3801 3802typedef struct set_cbdata { 3803 char *cb_propname; 3804 char *cb_value; 3805 boolean_t cb_any_successful; 3806} set_cbdata_t; 3807 3808int 3809set_callback(zpool_handle_t *zhp, void *data) 3810{ 3811 int error; 3812 set_cbdata_t *cb = (set_cbdata_t *)data; 3813 3814 error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value); 3815 3816 if (!error) 3817 cb->cb_any_successful = B_TRUE; 3818 3819 return (error); 3820} 3821 3822int 3823zpool_do_set(int argc, char **argv) 3824{ 3825 set_cbdata_t cb = { 0 }; 3826 int error; 3827 3828 if (argc > 1 && argv[1][0] == '-') { 3829 (void) fprintf(stderr, gettext("invalid option '%c'\n"), 3830 argv[1][1]); 3831 usage(B_FALSE); 3832 } 3833 3834 if (argc < 2) { 3835 (void) fprintf(stderr, gettext("missing property=value " 3836 "argument\n")); 3837 usage(B_FALSE); 3838 } 3839 3840 if (argc < 3) { 3841 (void) fprintf(stderr, gettext("missing pool name\n")); 3842 usage(B_FALSE); 3843 } 3844 3845 if (argc > 3) { 3846 (void) fprintf(stderr, gettext("too many pool names\n")); 3847 usage(B_FALSE); 3848 } 3849 3850 cb.cb_propname = argv[1]; 3851 cb.cb_value = strchr(cb.cb_propname, '='); 3852 if (cb.cb_value == NULL) { 3853 (void) fprintf(stderr, gettext("missing value in " 3854 "property=value argument\n")); 3855 usage(B_FALSE); 3856 } 3857 3858 *(cb.cb_value) = '\0'; 3859 cb.cb_value++; 3860 3861 error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL, 3862 set_callback, &cb); 3863 3864 return (error); 3865} 3866 3867static int 3868find_command_idx(char *command, int *idx) 3869{ 3870 int i; 3871 3872 for (i = 0; i < NCOMMAND; i++) { 3873 if (command_table[i].name == NULL) 3874 continue; 3875 3876 if (strcmp(command, command_table[i].name) == 0) { 3877 *idx = i; 3878 return (0); 3879 } 3880 } 3881 return (1); 3882} 3883 3884int 3885main(int argc, char **argv) 3886{ 3887 int ret; 3888 int i; 3889 char *cmdname; 3890 3891 (void) setlocale(LC_ALL, ""); 3892 (void) textdomain(TEXT_DOMAIN); 3893 3894 if ((g_zfs = libzfs_init()) == NULL) { 3895 (void) fprintf(stderr, gettext("internal error: failed to " 3896 "initialize ZFS library\n")); 3897 return (1); 3898 } 3899 3900 libzfs_print_on_error(g_zfs, B_TRUE); 3901 3902 opterr = 0; 3903 3904 /* 3905 * Make sure the user has specified some command. 3906 */ 3907 if (argc < 2) { 3908 (void) fprintf(stderr, gettext("missing command\n")); 3909 usage(B_FALSE); 3910 } 3911 3912 cmdname = argv[1]; 3913 3914 /* 3915 * Special case '-?' 3916 */ 3917 if (strcmp(cmdname, "-?") == 0) 3918 usage(B_TRUE); 3919 3920 zpool_set_history_str("zpool", argc, argv, history_str); 3921 verify(zpool_stage_history(g_zfs, history_str) == 0); 3922 3923 /* 3924 * Run the appropriate command. 3925 */ 3926 if (find_command_idx(cmdname, &i) == 0) { 3927 current_command = &command_table[i]; 3928 ret = command_table[i].func(argc - 1, argv + 1); 3929 } else if (strchr(cmdname, '=')) { 3930 verify(find_command_idx("set", &i) == 0); 3931 current_command = &command_table[i]; 3932 ret = command_table[i].func(argc, argv); 3933 } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) { 3934 /* 3935 * 'freeze' is a vile debugging abomination, so we treat 3936 * it as such. 3937 */ 3938 char buf[16384]; 3939 int fd = open(ZFS_DEV, O_RDWR); 3940 (void) strcpy((void *)buf, argv[2]); 3941 return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf)); 3942 } else { 3943 (void) fprintf(stderr, gettext("unrecognized " 3944 "command '%s'\n"), cmdname); 3945 usage(B_FALSE); 3946 } 3947 3948 libzfs_fini(g_zfs); 3949 3950 /* 3951 * The 'ZFS_ABORT' environment variable causes us to dump core on exit 3952 * for the purposes of running ::findleaks. 3953 */ 3954 if (getenv("ZFS_ABORT") != NULL) { 3955 (void) printf("dumping core by request\n"); 3956 abort(); 3957 } 3958 3959 return (ret); 3960} 3961