zpool_main.c revision 24e697d414a4df0377b91a2875f029e7b5f97247
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * Common Development and Distribution License (the "License").
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <assert.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <ctype.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <dirent.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <fcntl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libgen.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libintl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libuutil.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <locale.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdio.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdlib.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <string.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <strings.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <unistd.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <priv.h>
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks#include <pwd.h>
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks#include <zone.h>
b1b8ab34de515a5e83206da22c3d7e563241b021lling#include <sys/fs/zfs.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/stat.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libzfs.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "zpool_util.h"
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin#include "zfs_comutil.h"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_create(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_destroy(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_add(int, char **);
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic int zpool_do_remove(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_list(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_iostat(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_status(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_online(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_offline(int, char **);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockstatic int zpool_do_clear(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_attach(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_detach(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_replace(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_scrub(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_import(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_export(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockstatic int zpool_do_upgrade(int, char **);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
06eeb2ad640ce72d394ac521094bed7681044408ekstatic int zpool_do_history(int, char **);
06eeb2ad640ce72d394ac521094bed7681044408ek
b1b8ab34de515a5e83206da22c3d7e563241b021llingstatic int zpool_do_get(int, char **);
b1b8ab34de515a5e83206da22c3d7e563241b021llingstatic int zpool_do_set(int, char **);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * These libumem hooks provide a reasonable set of defaults for the allocator's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * debugging facilities.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
99653d4ee642c6528e88224f12409a5f23060994eschrock_umem_debug_init(void)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ("default,verbose"); /* $UMEM_DEBUG setting */
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrens_umem_logging_init(void)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ("fail,contents"); /* $UMEM_LOGGING setting */
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
65cd9f2809a015b46790a9c5c2ef992d56177624eschrocktypedef enum {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_ADD,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_ATTACH,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock HELP_CLEAR,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_CREATE,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_DESTROY,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_DETACH,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_EXPORT,
06eeb2ad640ce72d394ac521094bed7681044408ek HELP_HISTORY,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_IMPORT,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_IOSTAT,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_LIST,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_OFFLINE,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_ONLINE,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_REPLACE,
99653d4ee642c6528e88224f12409a5f23060994eschrock HELP_REMOVE,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock HELP_SCRUB,
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock HELP_STATUS,
b1b8ab34de515a5e83206da22c3d7e563241b021lling HELP_UPGRADE,
b1b8ab34de515a5e83206da22c3d7e563241b021lling HELP_GET,
b1b8ab34de515a5e83206da22c3d7e563241b021lling HELP_SET
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock} zpool_help_t;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct zpool_command {
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int (*func)(int, char **);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock zpool_help_t usage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} zpool_command_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Master command table. Each ZFS command has a name, associated function, and
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * usage message. The usage messages need to be internationalized, so we have
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * to have a function to return the usage message based on a command index.
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock *
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * These commands are organized according to how they are displayed in the usage
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * message. An empty command (one with a NULL name) indicates an empty line in
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * the generic usage message.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic zpool_command_t command_table[] = {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "create", zpool_do_create, HELP_CREATE },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "destroy", zpool_do_destroy, HELP_DESTROY },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "add", zpool_do_add, HELP_ADD },
99653d4ee642c6528e88224f12409a5f23060994eschrock { "remove", zpool_do_remove, HELP_REMOVE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "list", zpool_do_list, HELP_LIST },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "iostat", zpool_do_iostat, HELP_IOSTAT },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "status", zpool_do_status, HELP_STATUS },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "online", zpool_do_online, HELP_ONLINE },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "offline", zpool_do_offline, HELP_OFFLINE },
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock { "clear", zpool_do_clear, HELP_CLEAR },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "attach", zpool_do_attach, HELP_ATTACH },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "detach", zpool_do_detach, HELP_DETACH },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "replace", zpool_do_replace, HELP_REPLACE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "scrub", zpool_do_scrub, HELP_SCRUB },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "import", zpool_do_import, HELP_IMPORT },
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock { "export", zpool_do_export, HELP_EXPORT },
06eeb2ad640ce72d394ac521094bed7681044408ek { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
06eeb2ad640ce72d394ac521094bed7681044408ek { NULL },
b1b8ab34de515a5e83206da22c3d7e563241b021lling { "history", zpool_do_history, HELP_HISTORY },
b1b8ab34de515a5e83206da22c3d7e563241b021lling { "get", zpool_do_get, HELP_GET },
b1b8ab34de515a5e83206da22c3d7e563241b021lling { "set", zpool_do_set, HELP_SET },
fa9e4066f08beec538e775443c5be79dd423fcabahrens};
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_command_t *current_command;
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ekstatic char history_str[HIS_MAX_RECORD_LEN];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
65cd9f2809a015b46790a9c5c2ef992d56177624eschrockstatic const char *
65cd9f2809a015b46790a9c5c2ef992d56177624eschrockget_usage(zpool_help_t idx) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock switch (idx) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_ADD:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_ATTACH:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tattach [-f] <pool> <device> "
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens "<new-device>\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case HELP_CLEAR:
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (gettext("\tclear <pool> [device]\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_CREATE:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("\tcreate [-fn] [-o property=value] ... \n"
990b4856d0eaada6f8140335733a1b1771ed2746lling "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_DESTROY:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tdestroy [-f] <pool>\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_DETACH:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tdetach <pool> <device>\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_EXPORT:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\texport [-f] <pool> ...\n"));
06eeb2ad640ce72d394ac521094bed7681044408ek case HELP_HISTORY:
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks return (gettext("\thistory [-il] [<pool>] ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_IMPORT:
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm return (gettext("\timport [-d dir] [-D]\n"
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "\timport [-o mntopts] [-o property=value] ... \n"
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "\timport [-o mntopts] [-o property=value] ... \n"
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "<pool | id> [newpool]\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_IOSTAT:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tiostat [-v] [pool] ... [interval "
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock "[count]]\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_LIST:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("\tlist [-H] [-o property[,...]] "
990b4856d0eaada6f8140335733a1b1771ed2746lling "[pool] ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_OFFLINE:
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling return (gettext("\toffline [-t] <pool> <device> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_ONLINE:
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling return (gettext("\tonline <pool> <device> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_REPLACE:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\treplace [-f] <pool> <device> "
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens "[new-device]\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock case HELP_REMOVE:
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (gettext("\tremove <pool> <device> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_SCRUB:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tscrub [-s] <pool> ...\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock case HELP_STATUS:
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (gettext("\tstatus [-vx] [pool] ...\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case HELP_UPGRADE:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (gettext("\tupgrade\n"
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "\tupgrade -v\n"
990b4856d0eaada6f8140335733a1b1771ed2746lling "\tupgrade [-V version] <-a | pool ...>\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling case HELP_GET:
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens return (gettext("\tget <\"all\" | property[,...]> "
b1b8ab34de515a5e83206da22c3d7e563241b021lling "<pool> ...\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling case HELP_SET:
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (gettext("\tset <property=value> <pool> \n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock }
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock abort();
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock /* NOTREACHED */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock}
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b1b8ab34de515a5e83206da22c3d7e563241b021lling/*
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Callback routine that will print out a pool property value.
b1b8ab34de515a5e83206da22c3d7e563241b021lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic int
990b4856d0eaada6f8140335733a1b1771ed2746llingprint_prop_cb(int prop, void *cb)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
b1b8ab34de515a5e83206da22c3d7e563241b021lling FILE *fp = cb;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_prop_readonly(prop))
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(fp, " NO ");
990b4856d0eaada6f8140335733a1b1771ed2746lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(fp, " YES ");
990b4856d0eaada6f8140335733a1b1771ed2746lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (zpool_prop_values(prop) == NULL)
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(fp, "-\n");
b1b8ab34de515a5e83206da22c3d7e563241b021lling else
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (ZPROP_CONT);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Display usage message. If we're inside a command, display only the usage for
fa9e4066f08beec538e775443c5be79dd423fcabahrens * that command. Otherwise, iterate over the entire command table and display
fa9e4066f08beec538e775443c5be79dd423fcabahrens * a complete usage message.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
99653d4ee642c6528e88224f12409a5f23060994eschrockusage(boolean_t requested)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens FILE *fp = requested ? stdout : stderr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (current_command == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, gettext("usage: zpool command args ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("where 'command' is one of the following:\n\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < NCOMMAND; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (command_table[i].name == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "%s",
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock get_usage(command_table[i].usage));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, gettext("usage:\n"));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock (void) fprintf(fp, "%s", get_usage(current_command->usage));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (current_command != NULL &&
b1b8ab34de515a5e83206da22c3d7e563241b021lling ((strcmp(current_command->name, "set") == 0) ||
990b4856d0eaada6f8140335733a1b1771ed2746lling (strcmp(current_command->name, "get") == 0) ||
990b4856d0eaada6f8140335733a1b1771ed2746lling (strcmp(current_command->name, "list") == 0))) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(fp,
b1b8ab34de515a5e83206da22c3d7e563241b021lling gettext("\nthe following properties are supported:\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(fp, "\n\t%-13s %s %s\n\n",
990b4856d0eaada6f8140335733a1b1771ed2746lling "PROPERTY", "EDIT", "VALUES");
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling /* Iterate over all properties */
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
990b4856d0eaada6f8140335733a1b1771ed2746lling ZFS_TYPE_POOL);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock /*
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * See comments at end of main().
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock */
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (getenv("ZFS_ABORT") != NULL) {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) printf("dumping core by request\n");
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock abort();
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock }
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens exit(requested ? 0 : 2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinprint_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin boolean_t print_logs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock char *vname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (name != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t%*s%s\n", indent, "", name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock for (c = 0; c < children; c++) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin uint64_t is_log = B_FALSE;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin &is_log);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if ((is_log && !print_logs) || (!is_log && print_logs))
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin continue;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
99653d4ee642c6528e88224f12409a5f23060994eschrock vname = zpool_vdev_name(g_zfs, zhp, child[c]);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, vname, child[c], indent + 2,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin B_FALSE);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock free(vname);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Add a property pair (name, string-value) into a property nvlist.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic int
990b4856d0eaada6f8140335733a1b1771ed2746llingadd_prop_list(const char *propname, char *propval, nvlist_t **props)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling char *strval;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *proplist;
990b4856d0eaada6f8140335733a1b1771ed2746lling zpool_prop_t prop;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (*props == NULL &&
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr,
990b4856d0eaada6f8140335733a1b1771ed2746lling gettext("internal error: out of memory\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling return (1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling proplist = *props;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr, gettext("property '%s' is "
990b4856d0eaada6f8140335733a1b1771ed2746lling "not a valid pool property\n"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (2);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /* Use normalized property name for nvlist operations */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_string(proplist, zpool_prop_to_name(prop),
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock &strval) == 0 && prop != ZPOOL_PROP_CACHEFILE) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr, gettext("property '%s' "
990b4856d0eaada6f8140335733a1b1771ed2746lling "specified multiple times\n"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (2);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_add_string(proplist, zpool_prop_to_name(prop),
990b4856d0eaada6f8140335733a1b1771ed2746lling propval) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr, gettext("internal "
990b4856d0eaada6f8140335733a1b1771ed2746lling "error: out of memory\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling return (1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool add [-fn] <pool> <vdev> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force addition of devices, even if they appear in use
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -n Do not add the devices, but display the resulting layout if
fa9e4066f08beec538e775443c5be79dd423fcabahrens * they were to be added.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Adds the given vdevs to 'pool'. As with create, the bulk of this work is
fa9e4066f08beec538e775443c5be79dd423fcabahrens * handled by get_vdev_spec(), which constructs the nvlist needed to pass to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * libzfs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_add(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t force = B_FALSE;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t dryrun = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *config;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "fn")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'n':
99653d4ee642c6528e88224f12409a5f23060994eschrock dryrun = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing vdev specification\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock if ((config = zpool_get_config(zhp, NULL)) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* pass off to get_vdev_spec for processing */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor nvroot = make_root_vdev(zhp, force, !force, B_FALSE, argc, argv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvroot == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dryrun) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *poolnvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &poolnvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("would update '%s' to the following "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "configuration:\n"), zpool_get_name(zhp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin /* print original main pool and new tree */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin /* Do the same for the logs */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (num_logs(poolnvroot) > 0) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin } else if (num_logs(nvroot) > 0) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = (zpool_add(zhp, nvroot) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_free(nvroot);
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (ret);
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock/*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * zpool remove <pool> <vdev> ...
99653d4ee642c6528e88224f12409a5f23060994eschrock *
99653d4ee642c6528e88224f12409a5f23060994eschrock * Removes the given vdev from the pool. Currently, this only supports removing
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * spares and cache devices from the pool. Eventually, we'll want to support
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrockint
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_do_remove(int argc, char **argv)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock char *poolname;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan int i, ret = 0;
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_handle_t *zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock argc--;
99653d4ee642c6528e88224f12409a5f23060994eschrock argv++;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock /* get pool name and check number of arguments */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (argc < 1) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) fprintf(stderr, gettext("missing pool name argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock if (argc < 2) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) fprintf(stderr, gettext("missing device\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock poolname = argv[0];
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (1);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (i = 1; i < argc; i++) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (zpool_vdev_remove(zhp, argv[i]) != 0)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan ret = 1;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint]
990b4856d0eaada6f8140335733a1b1771ed2746lling * <pool> <dev> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force creation, even if devices appear in use
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -n Do not create the pool, but display the resulting layout if it
fa9e4066f08beec538e775443c5be79dd423fcabahrens * were to be created.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -R Create a pool under an alternate root
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -m Set default mountpoint for the root dataset. By default it's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * '/<pool>'
990b4856d0eaada6f8140335733a1b1771ed2746lling * -o Set property=value.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Creates the named pool according to the given vdev specification. The
fa9e4066f08beec538e775443c5be79dd423fcabahrens * bulk of the vdev processing is done in get_vdev_spec() in zpool_vdev.c. Once
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we get the nvlist back from get_vdev_spec(), we either print out the contents
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (if '-n' was specified), or pass it to libzfs to do the creation.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_create(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t force = B_FALSE;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t dryrun = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *nvroot = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
990b4856d0eaada6f8140335733a1b1771ed2746lling int ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *altroot = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *mountpoint = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *props = NULL;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock char *propval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
990b4856d0eaada6f8140335733a1b1771ed2746lling while ((c = getopt(argc, argv, ":fnR:m:o:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'n':
99653d4ee642c6528e88224f12409a5f23060994eschrock dryrun = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'R':
fa9e4066f08beec538e775443c5be79dd423fcabahrens altroot = optarg;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(zpool_prop_to_name(
990b4856d0eaada6f8140335733a1b1771ed2746lling ZPOOL_PROP_ALTROOT), optarg, &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (nvlist_lookup_string(props,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock &propval) == 0)
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(zpool_prop_to_name(
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock ZPOOL_PROP_CACHEFILE), "none", &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'm':
fa9e4066f08beec538e775443c5be79dd423fcabahrens mountpoint = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case 'o':
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((propval = strchr(optarg, '=')) == NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr, gettext("missing "
990b4856d0eaada6f8140335733a1b1771ed2746lling "'=' for -o option\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling *propval = '\0';
990b4856d0eaada6f8140335733a1b1771ed2746lling propval++;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(optarg, propval, &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing vdev specification\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * As a special case, check for use of '/' in the name, and direct the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * user to use 'zfs create' instead.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strchr(poolname, '/') != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot create '%s': invalid "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "character '/' in pool name\n"), poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("use 'zfs create' to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "create a dataset\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* pass off to get_vdev_spec for bulk processing */
99653d4ee642c6528e88224f12409a5f23060994eschrock nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
99653d4ee642c6528e88224f12409a5f23060994eschrock argv + 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvroot == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock /* make_root_vdev() allows 0 toplevel children if there are spares */
b7b97454b9b1f6625e7e655e9651e744a8dee09dperrin if (!zfs_allocatable_devs(nvroot)) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) fprintf(stderr, gettext("invalid vdev "
99653d4ee642c6528e88224f12409a5f23060994eschrock "specification: at least one toplevel vdev must be "
99653d4ee642c6528e88224f12409a5f23060994eschrock "specified\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (altroot != NULL && altroot[0] != '/') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid alternate root '%s': "
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "must be an absolute path\n"), altroot);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check the validity of the mountpoint and direct the user to use the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * '-m' mountpoint option if it looks like its in use.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mountpoint == NULL ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0 &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) != 0)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char buf[MAXPATHLEN];
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh DIR *dirp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mountpoint && mountpoint[0] != '/') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid mountpoint "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%s': must be an absolute path, 'legacy', or "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'none'\n"), mountpoint);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mountpoint == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (altroot != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, sizeof (buf), "%s/%s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens altroot, poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, sizeof (buf), "/%s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (altroot != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, sizeof (buf), "%s%s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens altroot, mountpoint);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf, sizeof (buf), "%s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens mountpoint);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh if ((dirp = opendir(buf)) == NULL && errno != ENOENT) {
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh (void) fprintf(stderr, gettext("mountpoint '%s' : "
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh "%s\n"), buf, strerror(errno));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("use '-m' "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "option to provide a different default\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh } else if (dirp) {
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh int count = 0;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh while (count < 3 && readdir(dirp) != NULL)
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh count++;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh (void) closedir(dirp);
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh if (count > 2) {
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh (void) fprintf(stderr, gettext("mountpoint "
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh "'%s' exists and is not empty\n"), buf);
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh (void) fprintf(stderr, gettext("use '-m' "
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh "option to provide a "
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh "different default\n"));
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh goto errout;
11022c7cf39f3b863e749f3866f6ddcb445c2d05timh }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (dryrun) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For a dry run invocation, print out a basic message and run
fa9e4066f08beec538e775443c5be79dd423fcabahrens * through all the vdevs in the list and print out in an
fa9e4066f08beec538e775443c5be79dd423fcabahrens * appropriate hierarchy.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("would create '%s' with the "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "following layout:\n\n"), poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (num_logs(nvroot) > 0)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Hand off to libzfs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_create(g_zfs, poolname, nvroot, props) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_handle_t *pool = zfs_open(g_zfs, poolname,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZFS_TYPE_FILESYSTEM);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mountpoint != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(zfs_prop_set(pool,
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zfs_prop_to_name(
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock ZFS_PROP_MOUNTPOINT),
fa9e4066f08beec538e775443c5be79dd423fcabahrens mountpoint) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zfs_mount(pool, NULL, 0) == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = zfs_shareall(pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_close(pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
99653d4ee642c6528e88224f12409a5f23060994eschrock } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) fprintf(stderr, gettext("pool name may have "
99653d4ee642c6528e88224f12409a5f23060994eschrock "been omitted\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746llingerrout:
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock nvlist_free(nvroot);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock nvlist_free(props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
990b4856d0eaada6f8140335733a1b1771ed2746llingbadusage:
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(props);
990b4856d0eaada6f8140335733a1b1771ed2746lling usage(B_FALSE);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool destroy <pool>
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Forcefully unmount any datasets
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Destroy the given pool. Automatically unmounts any datasets in the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_destroy(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *pool;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "f")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * As a special case, check for use of '/' in the name, and
fa9e4066f08beec538e775443c5be79dd423fcabahrens * direct the user to use 'zfs destroy' instead.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strchr(pool, '/') != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("use 'zfs destroy' to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "destroy a dataset\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl if (zpool_disable_datasets(zhp, force) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("could not destroy '%s': "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "could not unmount datasets\n"), zpool_get_name(zhp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = (zpool_destroy(zhp) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool export [-f] <pool> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Forcefully unmount datasets
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Export the given pools. By default, the command will attempt to cleanly
fa9e4066f08beec538e775443c5be79dd423fcabahrens * unmount any active datasets within the pool. If the '-f' flag is specified,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * then the datasets will be forcefully unmounted.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_export(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "f")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < argc; i++) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl if (zpool_disable_datasets(zhp, force) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_export(zhp) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a vdev configuration, determine the maximum width needed for the device
fa9e4066f08beec538e775443c5be79dd423fcabahrens * name column.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockmax_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock char *name = zpool_vdev_name(g_zfs, zhp, nv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strlen(name) + depth > max)
fa9e4066f08beec538e775443c5be79dd423fcabahrens max = strlen(name) + depth;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock free(name);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock &child, &children) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++)
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((ret = max_width(zhp, child[c], depth + 2,
99653d4ee642c6528e88224f12409a5f23060994eschrock max)) > max)
99653d4ee642c6528e88224f12409a5f23060994eschrock max = ret;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &child, &children) == 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if ((ret = max_width(zhp, child[c], depth + 2,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan max)) > max)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan max = ret;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
99653d4ee642c6528e88224f12409a5f23060994eschrock &child, &children) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++)
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((ret = max_width(zhp, child[c], depth + 2,
99653d4ee642c6528e88224f12409a5f23060994eschrock max)) > max)
99653d4ee642c6528e88224f12409a5f23060994eschrock max = ret;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (max);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print the configuration of an exported pool. Iterate over all vdevs in the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * pool, printing out the name and status for each one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
8654d0253136055bd4cc2423d87378e8a37f2eb5perrinprint_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin boolean_t print_logs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *vs;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock char *type, *vname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strcmp(type, VDEV_TYPE_MISSING) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&vs, &c) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (vs->vs_aux != 0) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(" ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (vs->vs_aux) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_OPEN_FAILED:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("cannot open"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_BAD_GUID_SUM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("missing device"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_NO_REPLICAS:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("insufficient replicas"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case VDEV_AUX_VERSION_NEWER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("newer version"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case VDEV_AUX_ERR_EXCEEDED:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("too many errors"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("corrupted data"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock for (c = 0; c < children; c++) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin uint64_t is_log = B_FALSE;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin &is_log);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if ((is_log && !print_logs) || (!is_log && print_logs))
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin continue;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
99653d4ee642c6528e88224f12409a5f23060994eschrock vname = zpool_vdev_name(g_zfs, NULL, child[c]);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock print_import_config(vname, child[c],
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin namewidth, depth + 2, B_FALSE);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock free(vname);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &child, &children) == 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf(gettext("\tcache\n"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan vname = zpool_vdev_name(g_zfs, NULL, child[c]);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf("\t %s\n", vname);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan free(vname);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &child, &children) == 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf(gettext("\tspares\n"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan vname = zpool_vdev_name(g_zfs, NULL, child[c]);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf("\t %s\n", vname);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan free(vname);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Display the status for the given pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensshow_import(nvlist_t *config)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t pool_state;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *vs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t guid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *msgid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int reason;
46657f8d750bdb71753495ce2919170f126b8e34mmusante const char *health;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t vsc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int namewidth;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &name) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &pool_state) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &nvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&vs, &vsc) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens reason = zpool_import_status(config, &msgid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
46657f8d750bdb71753495ce2919170f126b8e34mmusante (void) printf(gettext(" pool: %s\n"), name);
46657f8d750bdb71753495ce2919170f126b8e34mmusante (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
46657f8d750bdb71753495ce2919170f126b8e34mmusante (void) printf(gettext(" state: %s"), health);
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm if (pool_state == POOL_STATE_DESTROYED)
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) printf(gettext(" (DESTROYED)"));
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (reason) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_MISSING_DEV_R:
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_MISSING_DEV_NR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_BAD_GUID_SUM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices are missing "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "from the system.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_LABEL_R:
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_LABEL_NR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices contains "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "corrupted data.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_DATA:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: The pool data is corrupted.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling case ZPOOL_STATUS_OFFLINE_DEV:
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling (void) printf(gettext("status: One or more devices "
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling "are offlined.\n"));
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling break;
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ZPOOL_STATUS_CORRUPT_POOL:
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("status: The pool metadata is "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "corrupted.\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_VERSION_OLDER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("status: The pool is formatted using an "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "older on-disk version.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_VERSION_NEWER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("status: The pool is formatted using an "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "incompatible version.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek case ZPOOL_STATUS_HOSTID_MISMATCH:
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) printf(gettext("status: The pool was last accessed by "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "another system.\n"));
95173954d2b811ceb583a9012c3b16e1d0dd6438ek break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case ZPOOL_STATUS_FAULTED_DEV_R:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case ZPOOL_STATUS_FAULTED_DEV_NR:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("status: One or more devices are "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "faulted.\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * No other status can be seen when importing pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens assert(reason == ZPOOL_STATUS_OK);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out an action according to the overall state of the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
46657f8d750bdb71753495ce2919170f126b8e34mmusante if (vs->vs_state == VDEV_STATE_HEALTHY) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (reason == ZPOOL_STATUS_VERSION_OLDER)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("action: The pool can be "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "imported using its name or numeric identifier, "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "though\n\tsome features will not be available "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "without an explicit 'zpool upgrade'.\n"));
95173954d2b811ceb583a9012c3b16e1d0dd6438ek else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) printf(gettext("action: The pool can be "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "imported using its name or numeric "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "identifier and\n\tthe '-f' flag.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("action: The pool can be "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "imported using its name or numeric "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "identifier.\n"));
46657f8d750bdb71753495ce2919170f126b8e34mmusante } else if (vs->vs_state == VDEV_STATE_DEGRADED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool can be imported "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "despite missing or damaged devices. The\n\tfault "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "tolerance of the pool may be compromised if imported.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock switch (reason) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_VERSION_NEWER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("action: The pool cannot be "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "imported. Access the pool on a system running "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "newer\n\tsoftware, or recreate the pool from "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "backup.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_MISSING_DEV_R:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_MISSING_DEV_NR:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_BAD_GUID_SUM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported. Attach the missing\n\tdevices and try "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "again.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported due to damaged devices or data.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
46657f8d750bdb71753495ce2919170f126b8e34mmusante /*
46657f8d750bdb71753495ce2919170f126b8e34mmusante * If the state is "closed" or "can't open", and the aux state
46657f8d750bdb71753495ce2919170f126b8e34mmusante * is "corrupt data":
46657f8d750bdb71753495ce2919170f126b8e34mmusante */
46657f8d750bdb71753495ce2919170f126b8e34mmusante if (((vs->vs_state == VDEV_STATE_CLOSED) ||
46657f8d750bdb71753495ce2919170f126b8e34mmusante (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
46657f8d750bdb71753495ce2919170f126b8e34mmusante (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (pool_state == POOL_STATE_DESTROYED)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("\tThe pool was destroyed, "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "but can be imported using the '-Df' flags.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock else if (pool_state != POOL_STATE_EXPORTED)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("\tThe pool may be active on "
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek "another system, but can be imported using\n\t"
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "the '-f' flag.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (msgid != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens msgid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("config:\n\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock namewidth = max_width(NULL, nvroot, 0, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (namewidth < 10)
fa9e4066f08beec538e775443c5be79dd423fcabahrens namewidth = 10;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_import_config(name, nvroot, namewidth, 0, B_FALSE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (num_logs(nvroot) > 0) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) printf(gettext("\tlogs\n"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_import_config(name, nvroot, namewidth, 0, B_TRUE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
46657f8d750bdb71753495ce2919170f126b8e34mmusante (void) printf(gettext("\n\tAdditional devices are known to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "be part of this pool, though their\n\texact "
46657f8d750bdb71753495ce2919170f126b8e34mmusante "configuration cannot be determined.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Perform the import for the given configuration. This passes the heavy
990b4856d0eaada6f8140335733a1b1771ed2746lling * lifting off to zpool_import_props(), and then mounts the datasets contained
990b4856d0eaada6f8140335733a1b1771ed2746lling * within the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensdo_import(nvlist_t *config, const char *newname, const char *mntopts,
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock int force, nvlist_t *props, boolean_t allowfaulted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t state;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock uint64_t version;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks int error = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &name) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_POOL_STATE, &state) == 0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock verify(nvlist_lookup_uint64(config,
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock ZPOOL_CONFIG_VERSION, &version) == 0);
e7437265dc2a4920c197ed4337665539d358b22cahrens if (version > SPA_VERSION) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) fprintf(stderr, gettext("cannot import '%s': pool "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "is formatted using a newer ZFS version\n"), name);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (1);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock } else if (state != POOL_STATE_EXPORTED && !force) {
95173954d2b811ceb583a9012c3b16e1d0dd6438ek uint64_t hostid;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek
95173954d2b811ceb583a9012c3b16e1d0dd6438ek if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
95173954d2b811ceb583a9012c3b16e1d0dd6438ek &hostid) == 0) {
95173954d2b811ceb583a9012c3b16e1d0dd6438ek if ((unsigned long)hostid != gethostid()) {
95173954d2b811ceb583a9012c3b16e1d0dd6438ek char *hostname;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek uint64_t timestamp;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek time_t t;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek
95173954d2b811ceb583a9012c3b16e1d0dd6438ek verify(nvlist_lookup_string(config,
95173954d2b811ceb583a9012c3b16e1d0dd6438ek ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
95173954d2b811ceb583a9012c3b16e1d0dd6438ek verify(nvlist_lookup_uint64(config,
95173954d2b811ceb583a9012c3b16e1d0dd6438ek ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
95173954d2b811ceb583a9012c3b16e1d0dd6438ek t = timestamp;
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) fprintf(stderr, gettext("cannot import "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "'%s': pool may be in use from other "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "system, it was last accessed by %s "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "(hostid: 0x%lx) on %s"), name, hostname,
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (unsigned long)hostid,
95173954d2b811ceb583a9012c3b16e1d0dd6438ek asctime(localtime(&t)));
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) fprintf(stderr, gettext("use '-f' to "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "import anyway\n"));
95173954d2b811ceb583a9012c3b16e1d0dd6438ek return (1);
95173954d2b811ceb583a9012c3b16e1d0dd6438ek }
95173954d2b811ceb583a9012c3b16e1d0dd6438ek } else {
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) fprintf(stderr, gettext("cannot import '%s': "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "pool may be in use from other system\n"), name);
95173954d2b811ceb583a9012c3b16e1d0dd6438ek (void) fprintf(stderr, gettext("use '-f' to import "
95173954d2b811ceb583a9012c3b16e1d0dd6438ek "anyway\n"));
95173954d2b811ceb583a9012c3b16e1d0dd6438ek return (1);
95173954d2b811ceb583a9012c3b16e1d0dd6438ek }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock if (zpool_import_props(g_zfs, config, newname, props,
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock allowfaulted) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newname != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens name = (char *)newname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock verify((zhp = zpool_open_canfail(g_zfs, name)) != NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm * zpool import [-d dir] [-D]
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * [-d dir | -c cachefile] [-f] -a
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock *
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * -c Read pool information from a cachefile instead of searching
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock * devices.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -d Scan in a specific directory, other than /dev/dsk. More than
fa9e4066f08beec538e775443c5be79dd423fcabahrens * one directory can be specified using multiple '-d' options.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm * -D Scan for previously destroyed pools or import all or only
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm * specified destroyed pools.
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -R Temporarily import the pool, with all mountpoints relative to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the given root. The pool will remain exported when the machine
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is rebooted.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force import, even if it appears that the pool is active.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock * -F Import even in the presence of faulted vdevs. This is an
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock * intentionally undocumented option for testing purposes, and
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock * treats the pool configuration as complete, leaving any bad
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock * vdevs in the FAULTED state.
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -a Import all pools found.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
990b4856d0eaada6f8140335733a1b1771ed2746lling * -o Set property=value and/or temporary mount options (without '=').
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The import command scans for pools to import, and import pools based on pool
fa9e4066f08beec538e775443c5be79dd423fcabahrens * name and GUID. The pool can also be renamed as part of the import process.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_import(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **searchdirs = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int nsearch = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int err;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock nvlist_t *pools = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t do_all = B_FALSE;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t do_destroyed = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *mntopts = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t do_force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvpair_t *elem;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *config;
24e697d414a4df0377b91a2875f029e7b5f97247ck uint64_t searchguid = 0;
24e697d414a4df0377b91a2875f029e7b5f97247ck char *searchname = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling char *propval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *found_config;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks nvlist_t *props = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t first;
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock boolean_t allow_faulted = B_FALSE;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm uint64_t pool_state;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock char *cachefile = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock while ((c = getopt(argc, argv, ":ac:d:DfFo:p:R:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'a':
99653d4ee642c6528e88224f12409a5f23060994eschrock do_all = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock case 'c':
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock cachefile = optarg;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'd':
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (searchdirs == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs = safe_malloc(sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **tmp = safe_malloc((nsearch + 1) *
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens bcopy(searchdirs, tmp, nsearch *
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs = tmp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs[nsearch++] = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm case 'D':
99653d4ee642c6528e88224f12409a5f23060994eschrock do_destroyed = B_TRUE;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock do_force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock case 'F':
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock allow_faulted = B_TRUE;
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'o':
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((propval = strchr(optarg, '=')) != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling *propval = '\0';
990b4856d0eaada6f8140335733a1b1771ed2746lling propval++;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(optarg, propval, &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling mntopts = optarg;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'R':
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(zpool_prop_to_name(
990b4856d0eaada6f8140335733a1b1771ed2746lling ZPOOL_PROP_ALTROOT), optarg, &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (nvlist_lookup_string(props,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock &propval) == 0)
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (add_prop_list(zpool_prop_to_name(
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock ZPOOL_PROP_CACHEFILE), "none", &props))
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (cachefile && nsearch != 0) {
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock usage(B_FALSE);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock }
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (searchdirs == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs = safe_malloc(sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs[0] = "/dev/dsk";
fa9e4066f08beec538e775443c5be79dd423fcabahrens nsearch = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check argument count */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (do_all) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check for the SYS_CONFIG privilege. We do this explicitly
fa9e4066f08beec538e775443c5be79dd423fcabahrens * here because otherwise any attempt to discover pools will
fa9e4066f08beec538e775443c5be79dd423fcabahrens * silently fail.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0 && !priv_ineffect(PRIV_SYS_CONFIG)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "discover pools: permission denied\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock free(searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Depending on the arguments given, we do one of the following:
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <none> Iterate through all pools and display information about
fa9e4066f08beec538e775443c5be79dd423fcabahrens * each one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -a Iterate through all pools and try to import each one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <id> Find the pool that corresponds to the given GUID/pool
fa9e4066f08beec538e775443c5be79dd423fcabahrens * name and import that one.
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm *
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm * -D Above options applies only to destroyed pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *endptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchguid = strtoull(argv[0], &endptr, 10);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (errno != 0 || *endptr != '\0')
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens found_config = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
24e697d414a4df0377b91a2875f029e7b5f97247ck if (cachefile) {
24e697d414a4df0377b91a2875f029e7b5f97247ck pools = zpool_find_import_cached(g_zfs, cachefile, B_FALSE,
24e697d414a4df0377b91a2875f029e7b5f97247ck searchname, searchguid);
24e697d414a4df0377b91a2875f029e7b5f97247ck } else if (searchname != NULL) {
24e697d414a4df0377b91a2875f029e7b5f97247ck pools = zpool_find_import_byname(g_zfs, nsearch, searchdirs,
24e697d414a4df0377b91a2875f029e7b5f97247ck searchname);
24e697d414a4df0377b91a2875f029e7b5f97247ck } else {
24e697d414a4df0377b91a2875f029e7b5f97247ck /*
24e697d414a4df0377b91a2875f029e7b5f97247ck * It's OK to search by guid even if searchguid is 0.
24e697d414a4df0377b91a2875f029e7b5f97247ck */
24e697d414a4df0377b91a2875f029e7b5f97247ck pools = zpool_find_import_byguid(g_zfs, nsearch, searchdirs,
24e697d414a4df0377b91a2875f029e7b5f97247ck searchguid);
24e697d414a4df0377b91a2875f029e7b5f97247ck }
24e697d414a4df0377b91a2875f029e7b5f97247ck
24e697d414a4df0377b91a2875f029e7b5f97247ck if (pools == NULL) {
24e697d414a4df0377b91a2875f029e7b5f97247ck if (argc != 0) {
24e697d414a4df0377b91a2875f029e7b5f97247ck (void) fprintf(stderr, gettext("cannot import '%s': "
24e697d414a4df0377b91a2875f029e7b5f97247ck "no such pool available\n"), argv[0]);
24e697d414a4df0377b91a2875f029e7b5f97247ck }
24e697d414a4df0377b91a2875f029e7b5f97247ck free(searchdirs);
24e697d414a4df0377b91a2875f029e7b5f97247ck return (1);
24e697d414a4df0377b91a2875f029e7b5f97247ck }
24e697d414a4df0377b91a2875f029e7b5f97247ck
24e697d414a4df0377b91a2875f029e7b5f97247ck /*
24e697d414a4df0377b91a2875f029e7b5f97247ck * At this point we have a list of import candidate configs. Even if
24e697d414a4df0377b91a2875f029e7b5f97247ck * we were searching by pool name or guid, we still need to
24e697d414a4df0377b91a2875f029e7b5f97247ck * post-process the list to deal with pool state and possible
24e697d414a4df0377b91a2875f029e7b5f97247ck * duplicate names.
24e697d414a4df0377b91a2875f029e7b5f97247ck */
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens elem = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvpair_value_nvlist(elem, &config) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm &pool_state) == 0);
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm continue;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm continue;
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (first)
99653d4ee642c6528e88224f12409a5f23060994eschrock first = B_FALSE;
3bb79bece53191f2cf27aa61a72ea1784a7ce700eschrock else if (!do_all)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (do_all)
fa9e4066f08beec538e775443c5be79dd423fcabahrens err |= do_import(config, NULL, mntopts,
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock do_force, props, allow_faulted);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens show_import(config);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (searchname != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We are searching for a pool based on name.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_POOL_NAME, &name) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strcmp(name, searchname) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (found_config != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext(
fa9e4066f08beec538e775443c5be79dd423fcabahrens "cannot import '%s': more than "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "one matching pool\n"), searchname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext(
fa9e4066f08beec538e775443c5be79dd423fcabahrens "import by numeric ID instead\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock err = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens found_config = config;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t guid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Search for a pool by guid.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (guid == searchguid)
fa9e4066f08beec538e775443c5be79dd423fcabahrens found_config = config;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we were searching for a specific pool, verify that we found a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * pool, and then do the import.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc != 0 && err == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (found_config == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot import '%s': "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "no such pool available\n"), argv[0]);
99653d4ee642c6528e88224f12409a5f23060994eschrock err = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens err |= do_import(found_config, argc == 1 ? NULL :
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock argv[1], mntopts, do_force, props, allow_faulted);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we were just looking for pools, report an error if none were
fa9e4066f08beec538e775443c5be79dd423fcabahrens * found.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0 && first)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("no pools available to import\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarkserror:
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock nvlist_free(props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(pools);
99653d4ee642c6528e88224f12409a5f23060994eschrock free(searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (err ? 1 : 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct iostat_cbdata {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_list_t *cb_list;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_verbose;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_iteration;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_namewidth;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} iostat_cbdata_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_iostat_separator(iostat_cbdata_t *cb)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < cb->cb_namewidth; i++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("-");
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ----- ----- ----- ----- ----- -----\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_iostat_header(iostat_cbdata_t *cb)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%*s capacity operations bandwidth\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb->cb_namewidth, "");
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%-*s used avail read write read write\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb->cb_namewidth, "pool");
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_iostat_separator(cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Display a single statistic.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_one_stat(uint64_t value)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char buf[64];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_nicenum(value, buf, sizeof (buf));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" %5s", buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out all the statistics for the given vdev. This can either be the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * toplevel configuration, or called recursively. If 'name' is NULL, then this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is a verbose output, and we don't want to display the toplevel pool stats.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockprint_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock nvlist_t *newnv, iostat_cbdata_t *cb, int depth)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **oldchild, **newchild;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *oldvs, *newvs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t zerovs = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t tdelta;
fa9e4066f08beec538e775443c5be79dd423fcabahrens double scale;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock char *vname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (oldnv != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&oldvs, &c) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldvs = &zerovs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&newvs, &c) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strlen(name) + depth > cb->cb_namewidth)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%*s%s", depth, "", name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%*s%s%*s", depth, "", name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (int)(cb->cb_namewidth - strlen(name) - depth), "");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens tdelta = newvs->vs_timestamp - oldvs->vs_timestamp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (tdelta == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens scale = 1.0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens scale = (double)NANOSEC / tdelta;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* only toplevel vdevs have capacity stats */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newvs->vs_space == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" - -");
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat(newvs->vs_alloc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat(newvs->vs_space - newvs->vs_alloc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_READ] -
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldvs->vs_ops[ZIO_TYPE_READ])));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat((uint64_t)(scale * (newvs->vs_ops[ZIO_TYPE_WRITE] -
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldvs->vs_ops[ZIO_TYPE_WRITE])));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_READ] -
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldvs->vs_bytes[ZIO_TYPE_READ])));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_one_stat((uint64_t)(scale * (newvs->vs_bytes[ZIO_TYPE_WRITE] -
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldvs->vs_bytes[ZIO_TYPE_WRITE])));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!cb->cb_verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &newchild, &children) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &oldchild, &c) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock for (c = 0; c < children; c++) {
99653d4ee642c6528e88224f12409a5f23060994eschrock vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock newchild[c], cb, depth + 2);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock free(vname);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan /*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Include level 2 ARC devices in iostat output
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan */
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(newnv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &newchild, &children) != 0)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &oldchild, &c) != 0)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (children > 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf("%-*s - - - - - "
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "-\n", cb->cb_namewidth, "cache");
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan newchild[c], cb, depth + 2);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan free(vname);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrockstatic int
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrockrefresh_iostat(zpool_handle_t *zhp, void *data)
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock{
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock iostat_cbdata_t *cb = data;
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock boolean_t missing;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock /*
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * If the pool has disappeared, remove it from the list and continue.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock */
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (zpool_refresh_stats(zhp, &missing) != 0)
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (-1);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (missing)
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock pool_list_remove(cb->cb_list, zhp);
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock return (0);
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock}
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Callback to print out the iostats for the given pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_iostat(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens iostat_cbdata_t *cb = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *oldconfig, *newconfig;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *oldnvroot, *newnvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock newconfig = zpool_get_config(zhp, &oldconfig);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock if (cb->cb_iteration == 1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldconfig = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &newnvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock if (oldconfig == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldnvroot = NULL;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock else
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock &oldnvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out the statistics for the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock print_vdev_stats(zhp, zpool_get_name(zhp), oldnvroot, newnvroot, cb, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cb->cb_verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_iostat_separator(cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensget_namewidth(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens iostat_cbdata_t *cb = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *config, *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock if ((config = zpool_get_config(zhp, NULL)) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &nvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!cb->cb_verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb->cb_namewidth = strlen(zpool_get_name(zhp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock cb->cb_namewidth = max_width(zhp, nvroot, 0, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The width must fall into the range [10,38]. The upper limit is the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * maximum we can have and still fit in 80 columns.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cb->cb_namewidth < 10)
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb->cb_namewidth = 10;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cb->cb_namewidth > 38)
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb->cb_namewidth = 38;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool iostat [-v] [pool] ... [interval [count]]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -v Display statistics for individual vdevs
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This command can be tricky because we want to be able to deal with pool
fa9e4066f08beec538e775443c5be79dd423fcabahrens * creation/destruction as well as vdev configuration changes. The bulk of this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * processing is handled by the pool_list_* routines in zpool_iter.c. We rely
fa9e4066f08beec538e775443c5be79dd423fcabahrens * on pool_list_update() to detect the addition of new pools. Configuration
fa9e4066f08beec538e775443c5be79dd423fcabahrens * changes are all handled within libzfs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_iostat(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int npools;
fa9e4066f08beec538e775443c5be79dd423fcabahrens unsigned long interval = 0, count = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_list_t *list;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t verbose = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens iostat_cbdata_t cb;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "v")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'v':
99653d4ee642c6528e88224f12409a5f23060994eschrock verbose = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine if the last argument is an integer or a pool name
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 0 && isdigit(argv[argc - 1][0])) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *end;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens interval = strtoul(argv[argc - 1], &end, 10);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*end == '\0' && errno == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (interval == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("interval "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "cannot be zero\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Ignore the last parameter
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If this is not a valid number, just plow on. The
fa9e4066f08beec538e775443c5be79dd423fcabahrens * user will get a more informative error message later
fa9e4066f08beec538e775443c5be79dd423fcabahrens * on.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens interval = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the last argument is also an integer, then we have both a count
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and an integer.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 0 && isdigit(argv[argc - 1][0])) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *end;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens errno = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens count = interval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens interval = strtoul(argv[argc - 1], &end, 10);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*end == '\0' && errno == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (interval == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("interval "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "cannot be zero\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Ignore the last parameter
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens interval = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Construct the list of all interesting pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (pool_list_count(list) == 0 && argc != 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock pool_list_free(list);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool_list_count(list) == 0 && interval == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock pool_list_free(list);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("no pools available\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Enter the main iostat loop.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_list = list;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_verbose = verbose;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_iteration = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_namewidth = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (;;) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool_list_update(list);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((npools = pool_list_count(list)) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock /*
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * Refresh all statistics. This is done as an explicit step
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * before calculating the maximum name width, so that any
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * configuration changes are properly accounted for.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Iterate over all pools to determine the maximum width
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for the pool / device name column across all pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_namewidth = 0;
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If it's the first time, or verbose mode, print the header.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (++cb.cb_iteration == 1 || verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_iostat_header(&cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) pool_list_iter(list, B_FALSE, print_iostat, &cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If there's more than one pool, and we're not in verbose mode
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (which prints a separator for us), then print a separator.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (npools > 1 && !verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_iostat_separator(&cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (verbose)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock /*
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock * Flush the output so that redirection to a file isn't buffered
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock * indefinitely.
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock */
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock (void) fflush(stdout);
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (interval == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (count != 0 && --count == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sleep(interval);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool_list_free(list);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct list_cbdata {
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t cb_scripted;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t cb_first;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_list_t *cb_proplist;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} list_cbdata_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a list of columns to display, output appropriate headers for each one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic void
990b4856d0eaada6f8140335733a1b1771ed2746llingprint_header(zprop_list_t *pl)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
990b4856d0eaada6f8140335733a1b1771ed2746lling const char *header;
990b4856d0eaada6f8140335733a1b1771ed2746lling boolean_t first = B_TRUE;
990b4856d0eaada6f8140335733a1b1771ed2746lling boolean_t right_justify;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling for (; pl != NULL; pl = pl->pl_next) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (pl->pl_prop == ZPROP_INVAL)
990b4856d0eaada6f8140335733a1b1771ed2746lling continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling if (!first)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
990b4856d0eaada6f8140335733a1b1771ed2746lling first = B_FALSE;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling header = zpool_prop_column_name(pl->pl_prop);
990b4856d0eaada6f8140335733a1b1771ed2746lling right_justify = zpool_prop_align_right(pl->pl_prop);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling if (pl->pl_next == NULL && !right_justify)
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%s", header);
990b4856d0eaada6f8140335733a1b1771ed2746lling else if (right_justify)
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%*s", pl->pl_width, header);
990b4856d0eaada6f8140335733a1b1771ed2746lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%-*s", pl->pl_width, header);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Given a pool and a list of properties, print out all the properties according
990b4856d0eaada6f8140335733a1b1771ed2746lling * to the described layout.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic void
990b4856d0eaada6f8140335733a1b1771ed2746llingprint_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
990b4856d0eaada6f8140335733a1b1771ed2746lling boolean_t first = B_TRUE;
990b4856d0eaada6f8140335733a1b1771ed2746lling char property[ZPOOL_MAXPROPLEN];
990b4856d0eaada6f8140335733a1b1771ed2746lling char *propstr;
990b4856d0eaada6f8140335733a1b1771ed2746lling boolean_t right_justify;
990b4856d0eaada6f8140335733a1b1771ed2746lling int width;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling for (; pl != NULL; pl = pl->pl_next) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (!first) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (scripted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ");
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling right_justify = B_FALSE;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (pl->pl_prop != ZPROP_INVAL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_get_prop(zhp, pl->pl_prop, property,
990b4856d0eaada6f8140335733a1b1771ed2746lling sizeof (property), NULL) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling propstr = "-";
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
990b4856d0eaada6f8140335733a1b1771ed2746lling propstr = property;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling right_justify = zpool_prop_align_right(pl->pl_prop);
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling propstr = "-";
990b4856d0eaada6f8140335733a1b1771ed2746lling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling width = pl->pl_width;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * If this is being called in scripted mode, or if this is the
990b4856d0eaada6f8140335733a1b1771ed2746lling * last column and it is left-justified, don't include a width
990b4856d0eaada6f8140335733a1b1771ed2746lling * format specifier.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (scripted || (pl->pl_next == NULL && !right_justify))
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%s", propstr);
990b4856d0eaada6f8140335733a1b1771ed2746lling else if (right_justify)
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%*s", width, propstr);
990b4856d0eaada6f8140335733a1b1771ed2746lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("%-*s", width, propstr);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf("\n");
990b4856d0eaada6f8140335733a1b1771ed2746lling}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Generic callback function to list a pool.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingint
990b4856d0eaada6f8140335733a1b1771ed2746llinglist_callback(zpool_handle_t *zhp, void *data)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling list_cbdata_t *cbp = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling if (cbp->cb_first) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (!cbp->cb_scripted)
990b4856d0eaada6f8140335733a1b1771ed2746lling print_header(cbp->cb_proplist);
990b4856d0eaada6f8140335733a1b1771ed2746lling cbp->cb_first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool list [-H] [-o prop[,prop]*] [pool] ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
990b4856d0eaada6f8140335733a1b1771ed2746lling * -H Scripted mode. Don't display headers, and separate properties
990b4856d0eaada6f8140335733a1b1771ed2746lling * by a single tab.
990b4856d0eaada6f8140335733a1b1771ed2746lling * -o List of properties to display. Defaults to
990b4856d0eaada6f8140335733a1b1771ed2746lling * "name,size,used,available,capacity,health,altroot"
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * List all pools in the system, whether or not they're healthy. Output space
fa9e4066f08beec538e775443c5be79dd423fcabahrens * statistics for each one, as well as health status summary.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_list(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens list_cbdata_t cb = { 0 };
990b4856d0eaada6f8140335733a1b1771ed2746lling static char default_props[] =
990b4856d0eaada6f8140335733a1b1771ed2746lling "name,size,used,available,capacity,health,altroot";
990b4856d0eaada6f8140335733a1b1771ed2746lling char *props = default_props;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, ":Ho:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'H':
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_scripted = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'o':
990b4856d0eaada6f8140335733a1b1771ed2746lling props = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
990b4856d0eaada6f8140335733a1b1771ed2746lling list_callback, &cb);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_free_list(cb.cb_proplist);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fce7d82b2f44c64aedba1312d169198f858de333mmusante if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("no pools available\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic nvlist_t *
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_get_vdev_by_name(nvlist_t *nv, char *name)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *match;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *path;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strncmp(name, "/dev/dsk/", 9) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens name += 9;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strncmp(path, "/dev/dsk/", 9) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens path += 9;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strcmp(name, path) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (nv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((match = zpool_get_vdev_by_name(child[c], name)) != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (match);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_attach_or_replace(int argc, char **argv, int replacing)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname, *old_disk, *new_disk;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "f")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
99653d4ee642c6528e88224f12409a5f23060994eschrock force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <device> specification\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens old_disk = argv[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 3) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!replacing) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <new_device> specification\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens new_disk = old_disk;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens new_disk = argv[2];
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += 2;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (zpool_get_config(zhp, NULL) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvroot == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_free(nvroot);
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool replace [-f] <pool> <device> <new_device>
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force attach, even if <new_device> appears to be in use.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Replace <device> with <new_device>.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_replace(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool attach [-f] <pool> <device> <new_device>
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force attach, even if <new_device> appears to be in use.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Attach <new_device> to the mirror containing <device>. If <device> is not
fa9e4066f08beec538e775443c5be79dd423fcabahrens * part of a mirror, then <device> will be transformed into a mirror of
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <device> and <new_device>. In either case, <new_device> will begin life
fa9e4066f08beec538e775443c5be79dd423fcabahrens * with a DTL of [0, now], and will immediately begin to resilver itself.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_attach(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zpool_do_attach_or_replace(argc, argv, B_FALSE));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool detach [-f] <pool> <device>
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force detach of <device>, even if DTLs argue against it
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (not supported yet)
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Detach a device from a mirror. The operation will be refused if <device>
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is the last device in the mirror, or if the DTLs indicate that this device
fa9e4066f08beec538e775443c5be79dd423fcabahrens * has the only valid copy of some data.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_detach(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname, *path;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "f")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <device> specification\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens path = argv[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = zpool_vdev_detach(zhp, path);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * zpool online <pool> <device> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_online(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c, i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret = 0;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock vdev_state_t newstate;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "t")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 't':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing device name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock for (i = 1; i < argc; i++) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (newstate != VDEV_STATE_HEALTHY) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("warning: device '%s' "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "onlined, but remains in faulted state\n"),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock argv[i]);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (newstate == VDEV_STATE_FAULTED)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("use 'zpool "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "clear' to restore a faulted "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "device\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock else
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("use 'zpool "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "replace' to replace devices "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "that are no longer present\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * zpool offline [-ft] <pool> <device> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -f Force the device into the offline state, even if doing
fa9e4066f08beec538e775443c5be79dd423fcabahrens * so would appear to compromise pool availability.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (not supported yet)
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -t Only take the device off-line temporarily. The offline
fa9e4066f08beec538e775443c5be79dd423fcabahrens * state will not be persistent across reboots.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_offline(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c, i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock int ret = 0;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t istmp = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "ft")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 't':
99653d4ee642c6528e88224f12409a5f23060994eschrock istmp = B_TRUE;
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling break;
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing device name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock for (i = 1; i < argc; i++) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock/*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * zpool clear <pool> [device]
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock *
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Clear all errors associated with a pool or a particular device.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockint
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockzpool_do_clear(int argc, char **argv)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock int ret = 0;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zpool_handle_t *zhp;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char *pool, *device;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (argc < 2) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) fprintf(stderr, gettext("missing pool name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (argc > 3) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) fprintf(stderr, gettext("too many arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock pool = argv[1];
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock device = argc == 3 ? argv[2] : NULL;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open(g_zfs, pool)) == NULL)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (zpool_clear(zhp, device) != 0)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock ret = 1;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zpool_close(zhp);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (ret);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct scrub_cbdata {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_type;
06eeb2ad640ce72d394ac521094bed7681044408ek int cb_argc;
06eeb2ad640ce72d394ac521094bed7681044408ek char **cb_argv;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} scrub_cbdata_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensscrub_callback(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens scrub_cbdata_t *cb = data;
06eeb2ad640ce72d394ac521094bed7681044408ek int err;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Ignore faulted pools.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "currently unavailable\n"), zpool_get_name(zhp));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
06eeb2ad640ce72d394ac521094bed7681044408ek err = zpool_scrub(zhp, cb->cb_type);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek return (err != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool scrub [-s] <pool> ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -s Stop. Stops any in-progress scrub.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_scrub(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens scrub_cbdata_t cb;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_type = POOL_SCRUB_EVERYTHING;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "s")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 's':
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_type = POOL_SCRUB_NONE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
06eeb2ad640ce72d394ac521094bed7681044408ek cb.cb_argc = argc;
06eeb2ad640ce72d394ac521094bed7681044408ek cb.cb_argv = argv;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct status_cbdata {
99653d4ee642c6528e88224f12409a5f23060994eschrock int cb_count;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock boolean_t cb_allpools;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t cb_verbose;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t cb_explain;
99653d4ee642c6528e88224f12409a5f23060994eschrock boolean_t cb_first;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} status_cbdata_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out detailed scrub status.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_scrub_status(nvlist_t *nvroot)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *vs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t vsc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens time_t start, end, now;
fa9e4066f08beec538e775443c5be79dd423fcabahrens double fraction_done;
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek uint64_t examined, total, minutes_left, minutes_taken;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *scrub_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&vs, &vsc) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If there's never been a scrub, there's not much to say.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("none requested\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
fa9e4066f08beec538e775443c5be79dd423fcabahrens "resilver" : "scrub";
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens start = vs->vs_scrub_start;
fa9e4066f08beec538e775443c5be79dd423fcabahrens end = vs->vs_scrub_end;
fa9e4066f08beec538e775443c5be79dd423fcabahrens now = time(NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens examined = vs->vs_scrub_examined;
fa9e4066f08beec538e775443c5be79dd423fcabahrens total = vs->vs_alloc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (end != 0) {
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek minutes_taken = (uint64_t)((end - start) / 60);
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek (void) printf(gettext("%s %s after %lluh%um with %llu errors "
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek "on %s"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek (u_longlong_t)(minutes_taken / 60),
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek (uint_t)(minutes_taken % 60),
fa9e4066f08beec538e775443c5be79dd423fcabahrens (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (examined == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens examined = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (examined > total)
fa9e4066f08beec538e775443c5be79dd423fcabahrens total = examined;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens fraction_done = (double)examined / total;
fa9e4066f08beec538e775443c5be79dd423fcabahrens minutes_left = (uint64_t)((now - start) *
fa9e4066f08beec538e775443c5be79dd423fcabahrens (1 - fraction_done) / fraction_done / 60);
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek minutes_taken = (uint64_t)((now - start) / 60);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek (void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek "%lluh%um to go\n"),
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek scrub_type, (u_longlong_t)(minutes_taken / 60),
18ce54df8809e9f672d0ed1a53e99669df0a6df0ek (uint_t)(minutes_taken % 60), 100 * fraction_done,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrocktypedef struct spare_cbdata {
99653d4ee642c6528e88224f12409a5f23060994eschrock uint64_t cb_guid;
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_handle_t *cb_zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock} spare_cbdata_t;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic boolean_t
99653d4ee642c6528e88224f12409a5f23060994eschrockfind_vdev(nvlist_t *nv, uint64_t search)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock uint64_t guid;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t **child;
99653d4ee642c6528e88224f12409a5f23060994eschrock uint_t c, children;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
99653d4ee642c6528e88224f12409a5f23060994eschrock search == guid)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
99653d4ee642c6528e88224f12409a5f23060994eschrock &child, &children) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++)
99653d4ee642c6528e88224f12409a5f23060994eschrock if (find_vdev(child[c], search))
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_FALSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic int
99653d4ee642c6528e88224f12409a5f23060994eschrockfind_spare(zpool_handle_t *zhp, void *data)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock spare_cbdata_t *cbp = data;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *config, *nvroot;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock config = zpool_get_config(zhp, NULL);
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
99653d4ee642c6528e88224f12409a5f23060994eschrock &nvroot) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (find_vdev(nvroot, cbp->cb_guid)) {
99653d4ee642c6528e88224f12409a5f23060994eschrock cbp->cb_zhp = zhp;
99653d4ee642c6528e88224f12409a5f23060994eschrock return (1);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out configuration state as requested by status_callback.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockprint_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *vs;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char rbuf[6], wbuf[6], cbuf[6], repaired[7];
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock char *vname;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint64_t notpresent;
99653d4ee642c6528e88224f12409a5f23060994eschrock spare_cbdata_t cb;
990b4856d0eaada6f8140335733a1b1771ed2746lling char *state;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint64_t **)&vs, &c) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens children = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (isspare) {
99653d4ee642c6528e88224f12409a5f23060994eschrock /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
99653d4ee642c6528e88224f12409a5f23060994eschrock * online drives.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (vs->vs_aux == VDEV_AUX_SPARED)
99653d4ee642c6528e88224f12409a5f23060994eschrock state = "INUSE";
99653d4ee642c6528e88224f12409a5f23060994eschrock else if (vs->vs_state == VDEV_STATE_HEALTHY)
99653d4ee642c6528e88224f12409a5f23060994eschrock state = "AVAIL";
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
99653d4ee642c6528e88224f12409a5f23060994eschrock name, state);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (!isspare) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &notpresent) == 0) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char *path;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
0917b783fd655a0c943e0b8fb848db2301774947eschrock (void) printf(" was %s", path);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (vs->vs_aux != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (vs->vs_aux) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_OPEN_FAILED:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("cannot open"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_BAD_GUID_SUM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("missing device"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_NO_REPLICAS:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("insufficient replicas"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case VDEV_AUX_VERSION_NEWER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("newer version"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock case VDEV_AUX_SPARED:
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
99653d4ee642c6528e88224f12409a5f23060994eschrock &cb.cb_guid) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (strcmp(zpool_get_name(cb.cb_zhp),
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_get_name(zhp)) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext("currently in "
99653d4ee642c6528e88224f12409a5f23060994eschrock "use"));
99653d4ee642c6528e88224f12409a5f23060994eschrock else
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext("in use by "
99653d4ee642c6528e88224f12409a5f23060994eschrock "pool '%s'"),
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_get_name(cb.cb_zhp));
99653d4ee642c6528e88224f12409a5f23060994eschrock zpool_close(cb.cb_zhp);
99653d4ee642c6528e88224f12409a5f23060994eschrock } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext("currently in use"));
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock break;
99653d4ee642c6528e88224f12409a5f23060994eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case VDEV_AUX_ERR_EXCEEDED:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("too many errors"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek case VDEV_AUX_IO_FAILURE:
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek (void) printf(gettext("experienced I/O failures"));
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek break;
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("corrupted data"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (vs->vs_scrub_repaired != 0 && children == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Report bytes resilvered/repaired on leaf devices.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" %s %s"), repaired,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
fa9e4066f08beec538e775443c5be79dd423fcabahrens "resilvered" : "repaired");
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock for (c = 0; c < children; c++) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin uint64_t is_log = B_FALSE;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin &is_log);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if ((is_log && !print_logs) || (!is_log && print_logs))
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin continue;
99653d4ee642c6528e88224f12409a5f23060994eschrock vname = zpool_vdev_name(g_zfs, zhp, child[c]);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock print_status_config(zhp, vname, child[c],
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin namewidth, depth + 2, isspare, B_FALSE);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock free(vname);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockstatic void
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockprint_error_log(zpool_handle_t *zhp)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
75519f380eac71fe6d10b26e736f01567d6c13c9ek nvlist_t *nverrlist = NULL;
55434c770c89aa1b84474f2559a106803511aba0ek nvpair_t *elem;
55434c770c89aa1b84474f2559a106803511aba0ek char *pathname;
55434c770c89aa1b84474f2559a106803511aba0ek size_t len = MAXPATHLEN * 2;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
55434c770c89aa1b84474f2559a106803511aba0ek if (zpool_get_errlog(zhp, &nverrlist) != 0) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf("errors: List of errors unavailable "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "(insufficient privileges)\n");
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
55434c770c89aa1b84474f2559a106803511aba0ek (void) printf("errors: Permanent errors have been "
55434c770c89aa1b84474f2559a106803511aba0ek "detected in the following files:\n\n");
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
55434c770c89aa1b84474f2559a106803511aba0ek pathname = safe_malloc(len);
55434c770c89aa1b84474f2559a106803511aba0ek elem = NULL;
55434c770c89aa1b84474f2559a106803511aba0ek while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_t *nv;
55434c770c89aa1b84474f2559a106803511aba0ek uint64_t dsobj, obj;
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek verify(nvpair_value_nvlist(elem, &nv) == 0);
55434c770c89aa1b84474f2559a106803511aba0ek verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
55434c770c89aa1b84474f2559a106803511aba0ek &dsobj) == 0);
55434c770c89aa1b84474f2559a106803511aba0ek verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
55434c770c89aa1b84474f2559a106803511aba0ek &obj) == 0);
55434c770c89aa1b84474f2559a106803511aba0ek zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
55434c770c89aa1b84474f2559a106803511aba0ek (void) printf("%7s %s\n", "", pathname);
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek free(pathname);
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nverrlist);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic void
99653d4ee642c6528e88224f12409a5f23060994eschrockprint_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
99653d4ee642c6528e88224f12409a5f23060994eschrock int namewidth)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock uint_t i;
99653d4ee642c6528e88224f12409a5f23060994eschrock char *name;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nspares == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext("\tspares\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock for (i = 0; i < nspares; i++) {
99653d4ee642c6528e88224f12409a5f23060994eschrock name = zpool_vdev_name(g_zfs, zhp, spares[i]);
99653d4ee642c6528e88224f12409a5f23060994eschrock print_status_config(zhp, name, spares[i],
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin namewidth, 2, B_TRUE, B_FALSE);
99653d4ee642c6528e88224f12409a5f23060994eschrock free(name);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanstatic void
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanprint_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan int namewidth)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan{
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan uint_t i;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan char *name;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nl2cache == 0)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf(gettext("\tcache\n"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (i = 0; i < nl2cache; i++) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan name = zpool_vdev_name(g_zfs, zhp, l2cache[i]);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan print_status_config(zhp, name, l2cache[i],
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan namewidth, 2, B_FALSE, B_FALSE);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan free(name);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan}
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Display a summary of pool status. Displays a summary such as:
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * pool: tank
fa9e4066f08beec538e775443c5be79dd423fcabahrens * status: DEGRADED
fa9e4066f08beec538e775443c5be79dd423fcabahrens * reason: One or more devices ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens * see: http://www.sun.com/msg/ZFS-xxxx-01
fa9e4066f08beec538e775443c5be79dd423fcabahrens * config:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * mirror DEGRADED
fa9e4066f08beec538e775443c5be79dd423fcabahrens * c1t0d0 OK
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * c2t0d0 UNAVAIL
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When given the '-v' option, we print out the complete config. If the '-e'
fa9e4066f08beec538e775443c5be79dd423fcabahrens * option is specified, then we print out error rate information as well.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatus_callback(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens status_cbdata_t *cbp = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *config, *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *msgid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int reason;
46657f8d750bdb71753495ce2919170f126b8e34mmusante const char *health;
46657f8d750bdb71753495ce2919170f126b8e34mmusante uint_t c;
46657f8d750bdb71753495ce2919170f126b8e34mmusante vdev_stat_t *vs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock config = zpool_get_config(zhp, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens reason = zpool_get_status(zhp, &msgid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cbp->cb_count++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we were given 'zpool status -x', only report those pools with
fa9e4066f08beec538e775443c5be79dd423fcabahrens * problems.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (!cbp->cb_allpools) {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) printf(gettext("pool '%s' is healthy\n"),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zpool_get_name(zhp));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (cbp->cb_first)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock cbp->cb_first = B_FALSE;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cbp->cb_first)
99653d4ee642c6528e88224f12409a5f23060994eschrock cbp->cb_first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
46657f8d750bdb71753495ce2919170f126b8e34mmusante verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
46657f8d750bdb71753495ce2919170f126b8e34mmusante &nvroot) == 0);
46657f8d750bdb71753495ce2919170f126b8e34mmusante verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
46657f8d750bdb71753495ce2919170f126b8e34mmusante (uint64_t **)&vs, &c) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" state: %s\n"), health);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (reason) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_MISSING_DEV_R:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices could not "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "be opened. Sufficient replicas exist for\n\tthe pool to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "continue functioning in a degraded state.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Attach the missing device and "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "online it using 'zpool online'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_MISSING_DEV_NR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices could not "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "be opened. There are insufficient\n\treplicas for the "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "pool to continue functioning.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Attach the missing device and "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "online it using 'zpool online'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_LABEL_R:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices could not "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "be used because the label is missing or\n\tinvalid. "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Sufficient replicas exist for the pool to continue\n\t"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "functioning in a degraded state.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Replace the device using "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'zpool replace'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_LABEL_NR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices could not "
b1b8ab34de515a5e83206da22c3d7e563241b021lling "be used because the label is missing \n\tor invalid. "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "There are insufficient replicas for the pool to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "continue\n\tfunctioning.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Destroy and re-create the pool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "from a backup source.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_FAILING_DEV:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices has "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "experienced an unrecoverable error. An\n\tattempt was "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "made to correct the error. Applications are "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "unaffected.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Determine if the device needs "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "to be replaced, and clear the errors\n\tusing "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "'zpool clear' or replace the device with 'zpool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "replace'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_OFFLINE_DEV:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices has "
d7d4af51b4d115490d97f0b89993fdbaaf441c94mmusante "been taken offline by the administrator.\n\tSufficient "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "replicas exist for the pool to continue functioning in "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "a\n\tdegraded state.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Online the device using "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'zpool online' or replace the device with\n\t'zpool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "replace'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_RESILVERING:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices is "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "currently being resilvered. The pool will\n\tcontinue "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "to function, possibly in a degraded state.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: Wait for the resilver to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "complete.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ZPOOL_STATUS_CORRUPT_DATA:
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("status: One or more devices has "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "experienced an error resulting in data\n\tcorruption. "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "Applications may be affected.\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("action: Restore the file in question "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "if possible. Otherwise restore the\n\tentire pool from "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "backup.\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ZPOOL_STATUS_CORRUPT_POOL:
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("status: The pool metadata is corrupted "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "and the pool cannot be opened.\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("action: Destroy and re-create the pool "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "from a backup source.\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_VERSION_OLDER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("status: The pool is formatted using an "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "older on-disk format. The pool can\n\tstill be used, but "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "some features are unavailable.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("action: Upgrade the pool using 'zpool "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "upgrade'. Once this is done, the\n\tpool will no longer "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "be accessible on older software versions.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case ZPOOL_STATUS_VERSION_NEWER:
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("status: The pool has been upgraded to a "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "newer, incompatible on-disk version.\n\tThe pool cannot "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "be accessed on this system.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("action: Access the pool from a system "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "running more recent software, or\n\trestore the pool from "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "backup.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case ZPOOL_STATUS_FAULTED_DEV_R:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("status: One or more devices are "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "faulted in response to persistent errors.\n\tSufficient "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "replicas exist for the pool to continue functioning "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "in a\n\tdegraded state.\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("action: Replace the faulted device, "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "or use 'zpool clear' to mark the device\n\trepaired.\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case ZPOOL_STATUS_FAULTED_DEV_NR:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("status: One or more devices are "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "faulted in response to persistent errors. There are "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "insufficient replicas for the pool to\n\tcontinue "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "functioning.\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) printf(gettext("action: Destroy and re-create the pool "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "from a backup source. Manually marking the device\n"
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "\trepaired using 'zpool clear' may allow some data "
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock "to be recovered.\n"));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock break;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek case ZPOOL_STATUS_IO_FAILURE_WAIT:
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek case ZPOOL_STATUS_IO_FAILURE_CONTINUE:
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek (void) printf(gettext("status: One or more devices are "
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek "faultd in response to IO failures.\n"));
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek (void) printf(gettext("action: Make sure the affected devices "
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek "are connected, then run 'zpool clear'.\n"));
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek break;
32b87932f3ef0887d873b7f6d2d1943799b2afc0ek
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The remaining errors can't actually be generated, yet.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens assert(reason == ZPOOL_STATUS_OK);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (msgid != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens msgid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (config != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int namewidth;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint64_t nerr;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan nvlist_t **spares, **l2cache;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan uint_t nspares, nl2cache;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" scrub: "));
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_scrub_status(nvroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock namewidth = max_width(zhp, nvroot, 0, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (namewidth < 10)
fa9e4066f08beec538e775443c5be79dd423fcabahrens namewidth = 10;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("config:\n\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "NAME", "STATE", "READ", "WRITE", "CKSUM");
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock print_status_config(zhp, zpool_get_name(zhp), nvroot,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin namewidth, 0, B_FALSE, B_FALSE);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (num_logs(nvroot) > 0)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin print_status_config(zhp, "logs", nvroot, namewidth, 0,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin B_FALSE, B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &l2cache, &nl2cache) == 0)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan print_l2cache(zhp, l2cache, nl2cache, namewidth);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock &spares, &nspares) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock print_spares(zhp, spares, nspares, namewidth);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &nerr) == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_t *nverrlist = NULL;
55434c770c89aa1b84474f2559a106803511aba0ek
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * If the approximate error count is small, get a
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * precise count by fetching the entire log and
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * uniquifying the results.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
75519f380eac71fe6d10b26e736f01567d6c13c9ek if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
55434c770c89aa1b84474f2559a106803511aba0ek zpool_get_errlog(zhp, &nverrlist) == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek nvpair_t *elem;
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek elem = NULL;
55434c770c89aa1b84474f2559a106803511aba0ek nerr = 0;
55434c770c89aa1b84474f2559a106803511aba0ek while ((elem = nvlist_next_nvpair(nverrlist,
55434c770c89aa1b84474f2559a106803511aba0ek elem)) != NULL) {
55434c770c89aa1b84474f2559a106803511aba0ek nerr++;
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nverrlist);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf("\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nerr == 0)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) printf(gettext("errors: No known data "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "errors\n"));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock else if (!cbp->cb_verbose)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) printf(gettext("errors: %llu data "
5ad820458efd0fdb914baff9c1447c22b819fa23nd "errors, use '-v' for a list\n"),
5ad820458efd0fdb914baff9c1447c22b819fa23nd (u_longlong_t)nerr);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock else
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock print_error_log(zhp);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("config: The configuration cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "determined.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool status [-vx] [pool] ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -v Display complete error logs
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -x Display only pools with potential problems
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Describes the health status of all pools or some subset.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_status(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens status_cbdata_t cb = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "vx")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'v':
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_verbose = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'x':
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_explain = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (argc == 0)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock cb.cb_allpools = B_TRUE;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock
b1b8ab34de515a5e83206da22c3d7e563241b021lling ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0 && cb.cb_count == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("no pools available\n"));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) printf(gettext("all pools are healthy\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrocktypedef struct upgrade_cbdata {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int cb_all;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int cb_first;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int cb_newer;
06eeb2ad640ce72d394ac521094bed7681044408ek int cb_argc;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t cb_version;
06eeb2ad640ce72d394ac521094bed7681044408ek char **cb_argv;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock} upgrade_cbdata_t;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockstatic int
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockupgrade_cb(zpool_handle_t *zhp, void *arg)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock{
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock upgrade_cbdata_t *cbp = arg;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock nvlist_t *config;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock uint64_t version;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int ret = 0;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock config = zpool_get_config(zhp, NULL);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock &version) == 0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
e7437265dc2a4920c197ed4337665539d358b22cahrens if (!cbp->cb_newer && version < SPA_VERSION) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (!cbp->cb_all) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (cbp->cb_first) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("The following pools are "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "out of date, and can be upgraded. After "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "being\nupgraded, these pools will no "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "longer be accessible by older software "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "versions.\n\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("VER POOL\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("--- ------------\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock cbp->cb_first = B_FALSE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
5ad820458efd0fdb914baff9c1447c22b819fa23nd (void) printf("%2llu %s\n", (u_longlong_t)version,
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock zpool_get_name(zhp));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock cbp->cb_first = B_FALSE;
990b4856d0eaada6f8140335733a1b1771ed2746lling ret = zpool_upgrade(zhp, cbp->cb_version);
06eeb2ad640ce72d394ac521094bed7681044408ek if (!ret) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("Successfully upgraded "
990b4856d0eaada6f8140335733a1b1771ed2746lling "'%s'\n\n"), zpool_get_name(zhp));
06eeb2ad640ce72d394ac521094bed7681044408ek }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
e7437265dc2a4920c197ed4337665539d358b22cahrens } else if (cbp->cb_newer && version > SPA_VERSION) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock assert(!cbp->cb_all);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (cbp->cb_first) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("The following pools are "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "formatted using a newer software version and\n"
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "cannot be accessed on the current system.\n\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("VER POOL\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("--- ------------\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock cbp->cb_first = B_FALSE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
5ad820458efd0fdb914baff9c1447c22b819fa23nd (void) printf("%2llu %s\n", (u_longlong_t)version,
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock zpool_get_name(zhp));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock zpool_close(zhp);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (ret);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock/* ARGSUSED */
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockstatic int
06eeb2ad640ce72d394ac521094bed7681044408ekupgrade_one(zpool_handle_t *zhp, void *data)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock{
990b4856d0eaada6f8140335733a1b1771ed2746lling upgrade_cbdata_t *cbp = data;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t cur_version;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int ret;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (strcmp("log", zpool_get_name(zhp)) == 0) {
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) printf(gettext("'log' is now a reserved word\n"
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "Pool 'log' must be renamed using export and import"
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin " to upgrade.\n"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin return (1);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
e6c728e129b367a26c1972c43cc89654eb585941brendan if (cur_version > cbp->cb_version) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("Pool '%s' is already formatted "
e6c728e129b367a26c1972c43cc89654eb585941brendan "using more current version '%llu'.\n"),
e6c728e129b367a26c1972c43cc89654eb585941brendan zpool_get_name(zhp), cur_version);
e6c728e129b367a26c1972c43cc89654eb585941brendan return (0);
e6c728e129b367a26c1972c43cc89654eb585941brendan }
e6c728e129b367a26c1972c43cc89654eb585941brendan if (cur_version == cbp->cb_version) {
e6c728e129b367a26c1972c43cc89654eb585941brendan (void) printf(gettext("Pool '%s' is already formatted "
e6c728e129b367a26c1972c43cc89654eb585941brendan "using the current version.\n"), zpool_get_name(zhp));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
990b4856d0eaada6f8140335733a1b1771ed2746lling ret = zpool_upgrade(zhp, cbp->cb_version);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if (!ret) {
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm (void) printf(gettext("Successfully upgraded '%s' "
990b4856d0eaada6f8140335733a1b1771ed2746lling "from version %llu to version %llu\n\n"),
990b4856d0eaada6f8140335733a1b1771ed2746lling zpool_get_name(zhp), (u_longlong_t)cur_version,
990b4856d0eaada6f8140335733a1b1771ed2746lling (u_longlong_t)cbp->cb_version);
06eeb2ad640ce72d394ac521094bed7681044408ek }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (ret != 0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock/*
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * zpool upgrade
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * zpool upgrade -v
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool upgrade [-V version] <-a | pool ...>
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock *
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * With no arguments, display downrev'd ZFS pool available for upgrade.
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * Individual pools can be upgraded by specifying the pool, and '-a' will
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * upgrade all pools.
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock */
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockint
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockzpool_do_upgrade(int argc, char **argv)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock{
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int c;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock upgrade_cbdata_t cb = { 0 };
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int ret = 0;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock boolean_t showversions = B_FALSE;
990b4856d0eaada6f8140335733a1b1771ed2746lling char *end;
990b4856d0eaada6f8140335733a1b1771ed2746lling
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock /* check options */
990b4856d0eaada6f8140335733a1b1771ed2746lling while ((c = getopt(argc, argv, "avV:")) != -1) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock switch (c) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case 'a':
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_all = B_TRUE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case 'v':
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock showversions = B_TRUE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case 'V':
990b4856d0eaada6f8140335733a1b1771ed2746lling cb.cb_version = strtoll(optarg, &end, 10);
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling if (*end != '\0' || cb.cb_version > SPA_VERSION ||
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling cb.cb_version < SPA_VERSION_1) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) fprintf(stderr,
990b4856d0eaada6f8140335733a1b1771ed2746lling gettext("invalid version '%s'\n"), optarg);
990b4856d0eaada6f8140335733a1b1771ed2746lling usage(B_FALSE);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock case '?':
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) fprintf(stderr, gettext("invalid option '%c'\n"),
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock optopt);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
06eeb2ad640ce72d394ac521094bed7681044408ek cb.cb_argc = argc;
06eeb2ad640ce72d394ac521094bed7681044408ek cb.cb_argv = argv;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock argc -= optind;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock argv += optind;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling if (cb.cb_version == 0) {
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling cb.cb_version = SPA_VERSION;
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling } else if (!cb.cb_all && argc == 0) {
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling (void) fprintf(stderr, gettext("-V option is "
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling "incompatible with other arguments\n"));
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling usage(B_FALSE);
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling }
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (showversions) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (cb.cb_all || argc != 0) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) fprintf(stderr, gettext("-v option is "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "incompatible with other arguments\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock } else if (cb.cb_all) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (argc != 0) {
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling (void) fprintf(stderr, gettext("-a option should not "
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling "be used along with a pool name\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
e7437265dc2a4920c197ed4337665539d358b22cahrens (void) printf(gettext("This system is currently running "
e7437265dc2a4920c197ed4337665539d358b22cahrens "ZFS pool version %llu.\n\n"), SPA_VERSION);
99653d4ee642c6528e88224f12409a5f23060994eschrock cb.cb_first = B_TRUE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (showversions) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("The following versions are "
d7d4af51b4d115490d97f0b89993fdbaaf441c94mmusante "supported:\n\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("VER DESCRIPTION\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf("--- -----------------------------------------"
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "---------------\n");
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext(" 1 Initial ZFS version\n"));
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm (void) printf(gettext(" 2 Ditto blocks "
44cd46cadd9aab751dae6a4023c1cb5bf316d274billm "(replicated metadata)\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) printf(gettext(" 3 Hot spares and double parity "
99653d4ee642c6528e88224f12409a5f23060994eschrock "RAID-Z\n"));
d7306b64c847d897abb9ece8624fca9cf28d358fek (void) printf(gettext(" 4 zpool history\n"));
c9431fa1e59a88c2f0abf611f25b97af964449e5ahl (void) printf(gettext(" 5 Compression using the gzip "
c9431fa1e59a88c2f0abf611f25b97af964449e5ahl "algorithm\n"));
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) printf(gettext(" 6 bootfs pool property\n"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) printf(gettext(" 7 Separate intent log devices\n"));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf(gettext(" 8 Delegated administration\n"));
8eed72d43abf6184b757f3eb9228c3c4979aca10ck (void) printf(gettext(" 9 refquota and refreservation "
a9799022bd90b13722204e80112efaa5bf573099ck "properties\n"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) printf(gettext(" 10 Cache devices\n"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin (void) printf(gettext("For more information on a particular "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "version, including supported releases, see:\n\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf("http://www.opensolaris.org/os/community/zfs/"
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "version/N\n\n");
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("Where 'N' is the version number.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock } else if (argc == 0) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock int notfound;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = zpool_iter(g_zfs, upgrade_cb, &cb);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock notfound = cb.cb_first;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (!cb.cb_all && ret == 0) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (!cb.cb_first)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf("\n");
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock cb.cb_first = B_TRUE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock cb.cb_newer = B_TRUE;
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = zpool_iter(g_zfs, upgrade_cb, &cb);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (!cb.cb_first) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock notfound = B_FALSE;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf("\n");
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (ret == 0) {
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock if (notfound)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("All pools are formatted "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "using this version.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock else if (!cb.cb_all)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) printf(gettext("Use 'zpool upgrade -v' "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "for a list of available versions and "
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock "their associated\nfeatures.\n"));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock } else {
b1b8ab34de515a5e83206da22c3d7e563241b021lling ret = for_each_pool(argc, argv, B_FALSE, NULL,
b1b8ab34de515a5e83206da22c3d7e563241b021lling upgrade_one, &cb);
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek return (ret);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarkstypedef struct hist_cbdata {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks boolean_t first;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks int longfmt;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks int internal;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks} hist_cbdata_t;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarkschar *hist_event_table[LOG_END] = {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "invalid event",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool create",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev add",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool remove",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool destroy",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool export",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool import",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev attach",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev replace",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev detach",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev online",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev offline",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "vdev upgrade",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool clear",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool scrub",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "pool property set",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "create",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "clone",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "destroy",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "destroy_begin_sync",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "inherit",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "property set",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "quota set",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "permission update",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "permission remove",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "permission who remove",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "promote",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "receive",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "rename",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "reservation set",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "replay_inc_sync",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "replay_full_sync",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "rollback",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "snapshot",
e7437265dc2a4920c197ed4337665539d358b22cahrens "filesystem version upgrade",
a9799022bd90b13722204e80112efaa5bf573099ck "refquota set",
a9799022bd90b13722204e80112efaa5bf573099ck "refreservation set",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks};
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
06eeb2ad640ce72d394ac521094bed7681044408ek/*
06eeb2ad640ce72d394ac521094bed7681044408ek * Print out the command history for a specific pool.
06eeb2ad640ce72d394ac521094bed7681044408ek */
06eeb2ad640ce72d394ac521094bed7681044408ekstatic int
06eeb2ad640ce72d394ac521094bed7681044408ekget_history_one(zpool_handle_t *zhp, void *data)
06eeb2ad640ce72d394ac521094bed7681044408ek{
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_t *nvhis;
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_t **records;
06eeb2ad640ce72d394ac521094bed7681044408ek uint_t numrecords;
06eeb2ad640ce72d394ac521094bed7681044408ek char *cmdstr;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks char *pathstr;
06eeb2ad640ce72d394ac521094bed7681044408ek uint64_t dst_time;
06eeb2ad640ce72d394ac521094bed7681044408ek time_t tsec;
06eeb2ad640ce72d394ac521094bed7681044408ek struct tm t;
06eeb2ad640ce72d394ac521094bed7681044408ek char tbuf[30];
06eeb2ad640ce72d394ac521094bed7681044408ek int ret, i;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks uint64_t who;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks struct passwd *pwd;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks char *hostname;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks char *zonename;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks char internalstr[MAXPATHLEN];
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks hist_cbdata_t *cb = (hist_cbdata_t *)data;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks uint64_t txg;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks uint64_t ievent;
06eeb2ad640ce72d394ac521094bed7681044408ek
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks cb->first = B_FALSE;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek (void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek return (ret);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
06eeb2ad640ce72d394ac521094bed7681044408ek &records, &numrecords) == 0);
06eeb2ad640ce72d394ac521094bed7681044408ek for (i = 0; i < numrecords; i++) {
06eeb2ad640ce72d394ac521094bed7681044408ek if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks &dst_time) != 0)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks /* is it an internal event or a standard event? */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks &cmdstr) != 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (cb->internal == 0)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (nvlist_lookup_uint64(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_INT_EVENT, &ievent) != 0)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks verify(nvlist_lookup_uint64(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_TXG, &txg) == 0);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks verify(nvlist_lookup_string(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_INT_STR, &pathstr) == 0);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (ievent > LOG_END)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) snprintf(internalstr,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks sizeof (internalstr),
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks "[internal %s txg:%lld] %s",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks hist_event_table[ievent], txg,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks pathstr);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks cmdstr = internalstr;
06eeb2ad640ce72d394ac521094bed7681044408ek }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks tsec = dst_time;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) localtime_r(&tsec, &t);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("%s %s", tbuf, cmdstr);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (!cb->longfmt) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("\n");
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf(" [");
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (nvlist_lookup_uint64(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_WHO, &who) == 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks pwd = getpwuid((uid_t)who);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (pwd)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("user %s on",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks pwd->pw_name);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks else
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("user %d on",
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (int)who);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks } else {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf(gettext("no info]\n"));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks continue;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (nvlist_lookup_string(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_HOST, &hostname) == 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf(" %s", hostname);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (nvlist_lookup_string(records[i],
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ZPOOL_HIST_ZONE, &zonename) == 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf(":%s", zonename);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("]");
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) printf("\n");
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek (void) printf("\n");
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_free(nvhis);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek return (ret);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek/*
06eeb2ad640ce72d394ac521094bed7681044408ek * zpool history <pool>
06eeb2ad640ce72d394ac521094bed7681044408ek *
06eeb2ad640ce72d394ac521094bed7681044408ek * Displays the history of commands that modified pools.
06eeb2ad640ce72d394ac521094bed7681044408ek */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
06eeb2ad640ce72d394ac521094bed7681044408ekint
06eeb2ad640ce72d394ac521094bed7681044408ekzpool_do_history(int argc, char **argv)
06eeb2ad640ce72d394ac521094bed7681044408ek{
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks hist_cbdata_t cbdata = { 0 };
06eeb2ad640ce72d394ac521094bed7681044408ek int ret;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks int c;
06eeb2ad640ce72d394ac521094bed7681044408ek
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks cbdata.first = B_TRUE;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks /* check options */
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks while ((c = getopt(argc, argv, "li")) != -1) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks switch (c) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case 'l':
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks cbdata.longfmt = 1;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case 'i':
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks cbdata.internal = 1;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks break;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks case '?':
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (void) fprintf(stderr, gettext("invalid option '%c'\n"),
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks optopt);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks usage(B_FALSE);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks }
06eeb2ad640ce72d394ac521094bed7681044408ek argc -= optind;
06eeb2ad640ce72d394ac521094bed7681044408ek argv += optind;
06eeb2ad640ce72d394ac521094bed7681044408ek
b1b8ab34de515a5e83206da22c3d7e563241b021lling ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks &cbdata);
06eeb2ad640ce72d394ac521094bed7681044408ek
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (argc == 0 && cbdata.first == B_TRUE) {
06eeb2ad640ce72d394ac521094bed7681044408ek (void) printf(gettext("no pools available\n"));
06eeb2ad640ce72d394ac521094bed7681044408ek return (0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock }
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (ret);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
b1b8ab34de515a5e83206da22c3d7e563241b021llingstatic int
b1b8ab34de515a5e83206da22c3d7e563241b021llingget_callback(zpool_handle_t *zhp, void *data)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
b1b8ab34de515a5e83206da22c3d7e563241b021lling char value[MAXNAMELEN];
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_source_t srctype;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_list_t *pl;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Skip the special fake placeholder. This will also skip
990b4856d0eaada6f8140335733a1b1771ed2746lling * over the name property when 'all' is specified.
b1b8ab34de515a5e83206da22c3d7e563241b021lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (pl->pl_prop == ZPOOL_PROP_NAME &&
b1b8ab34de515a5e83206da22c3d7e563241b021lling pl == cbp->cb_proplist)
b1b8ab34de515a5e83206da22c3d7e563241b021lling continue;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (zpool_get_prop(zhp, pl->pl_prop,
b1b8ab34de515a5e83206da22c3d7e563241b021lling value, sizeof (value), &srctype) != 0)
b1b8ab34de515a5e83206da22c3d7e563241b021lling continue;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_print_one_property(zpool_get_name(zhp), cbp,
b1b8ab34de515a5e83206da22c3d7e563241b021lling zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (0);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021llingint
b1b8ab34de515a5e83206da22c3d7e563241b021llingzpool_do_get(int argc, char **argv)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_get_cbdata_t cb = { 0 };
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_list_t fake_name = { 0 };
b1b8ab34de515a5e83206da22c3d7e563241b021lling int ret;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (argc < 3)
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_first = B_TRUE;
990b4856d0eaada6f8140335733a1b1771ed2746lling cb.cb_sources = ZPROP_SRC_ALL;
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_columns[0] = GET_COL_NAME;
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_columns[1] = GET_COL_PROPERTY;
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_columns[2] = GET_COL_VALUE;
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_columns[3] = GET_COL_SOURCE;
990b4856d0eaada6f8140335733a1b1771ed2746lling cb.cb_type = ZFS_TYPE_POOL;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
990b4856d0eaada6f8140335733a1b1771ed2746lling ZFS_TYPE_POOL) != 0)
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (cb.cb_proplist != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling fake_name.pl_prop = ZPOOL_PROP_NAME;
b1b8ab34de515a5e83206da22c3d7e563241b021lling fake_name.pl_width = strlen(gettext("NAME"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling fake_name.pl_next = cb.cb_proplist;
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_proplist = &fake_name;
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
b1b8ab34de515a5e83206da22c3d7e563241b021lling get_callback, &cb);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (cb.cb_proplist == &fake_name)
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_free_list(fake_name.pl_next);
b1b8ab34de515a5e83206da22c3d7e563241b021lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_free_list(cb.cb_proplist);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (ret);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021llingtypedef struct set_cbdata {
b1b8ab34de515a5e83206da22c3d7e563241b021lling char *cb_propname;
b1b8ab34de515a5e83206da22c3d7e563241b021lling char *cb_value;
b1b8ab34de515a5e83206da22c3d7e563241b021lling boolean_t cb_any_successful;
b1b8ab34de515a5e83206da22c3d7e563241b021lling} set_cbdata_t;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021llingint
b1b8ab34de515a5e83206da22c3d7e563241b021llingset_callback(zpool_handle_t *zhp, void *data)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
b1b8ab34de515a5e83206da22c3d7e563241b021lling int error;
b1b8ab34de515a5e83206da22c3d7e563241b021lling set_cbdata_t *cb = (set_cbdata_t *)data;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (!error)
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb->cb_any_successful = B_TRUE;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (error);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021llingint
b1b8ab34de515a5e83206da22c3d7e563241b021llingzpool_do_set(int argc, char **argv)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
b1b8ab34de515a5e83206da22c3d7e563241b021lling set_cbdata_t cb = { 0 };
b1b8ab34de515a5e83206da22c3d7e563241b021lling int error;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (argc > 1 && argv[1][0] == '-') {
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(stderr, gettext("invalid option '%c'\n"),
b1b8ab34de515a5e83206da22c3d7e563241b021lling argv[1][1]);
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (argc < 2) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(stderr, gettext("missing property=value "
b1b8ab34de515a5e83206da22c3d7e563241b021lling "argument\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (argc < 3) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(stderr, gettext("missing pool name\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (argc > 3) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(stderr, gettext("too many pool names\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_propname = argv[1];
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_value = strchr(cb.cb_propname, '=');
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (cb.cb_value == NULL) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) fprintf(stderr, gettext("missing value in "
b1b8ab34de515a5e83206da22c3d7e563241b021lling "property=value argument\n"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling usage(B_FALSE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling *(cb.cb_value) = '\0';
b1b8ab34de515a5e83206da22c3d7e563241b021lling cb.cb_value++;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
b1b8ab34de515a5e83206da22c3d7e563241b021lling set_callback, &cb);
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (error);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021llingstatic int
b1b8ab34de515a5e83206da22c3d7e563241b021llingfind_command_idx(char *command, int *idx)
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
b1b8ab34de515a5e83206da22c3d7e563241b021lling int i;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling for (i = 0; i < NCOMMAND; i++) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (command_table[i].name == NULL)
b1b8ab34de515a5e83206da22c3d7e563241b021lling continue;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (strcmp(command, command_table[i].name) == 0) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling *idx = i;
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (0);
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (1);
b1b8ab34de515a5e83206da22c3d7e563241b021lling}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensmain(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *cmdname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) setlocale(LC_ALL, "");
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) textdomain(TEXT_DOMAIN);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((g_zfs = libzfs_init()) == NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) fprintf(stderr, gettext("internal error: failed to "
203a47d89d37e993340060207ea2299ade638d68nd "initialize ZFS library\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (1);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_print_on_error(g_zfs, B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens opterr = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure the user has specified some command.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing command\n"));
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cmdname = argv[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Special case '-?'
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (strcmp(cmdname, "-?") == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek zpool_set_history_str("zpool", argc, argv, history_str);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek verify(zpool_stage_history(g_zfs, history_str) == 0);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Run the appropriate command.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (find_command_idx(cmdname, &i) == 0) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling current_command = &command_table[i];
b1b8ab34de515a5e83206da22c3d7e563241b021lling ret = command_table[i].func(argc - 1, argv + 1);
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens } else if (strchr(cmdname, '=')) {
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens verify(find_command_idx("set", &i) == 0);
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens current_command = &command_table[i];
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens ret = command_table[i].func(argc, argv);
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens } else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens /*
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * 'freeze' is a vile debugging abomination, so we treat
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * it as such.
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char buf[16384];
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock int fd = open(ZFS_DEV, O_RDWR);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strcpy((void *)buf, argv[2]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("unrecognized "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "command '%s'\n"), cmdname);
99653d4ee642c6528e88224f12409a5f23060994eschrock usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_fini(g_zfs);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The 'ZFS_ABORT' environment variable causes us to dump core on exit
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for the purposes of running ::findleaks.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (getenv("ZFS_ABORT") != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("dumping core by request\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens abort();
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}