zpool_main.c revision 8eed72d43abf6184b757f3eb9228c3c4979aca10
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Common Development and Distribution License (the "License").
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 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 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Copyright 2007 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>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <pwd.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <zone.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/fs/zfs.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/stat.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libzfs.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "zpool_util.h"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_create(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_destroy(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_add(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic 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 **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic 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
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_upgrade(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_history(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_get(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zpool_do_set(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * These libumem hooks provide a reasonable set of defaults for the allocator's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * debugging facilities.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrens_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
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef enum {
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_ADD,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_ATTACH,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_CLEAR,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_CREATE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_DESTROY,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_DETACH,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_EXPORT,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_HISTORY,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_IMPORT,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_IOSTAT,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_LIST,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_OFFLINE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_ONLINE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_REPLACE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_REMOVE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_SCRUB,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_STATUS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_UPGRADE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_GET,
fa9e4066f08beec538e775443c5be79dd423fcabahrens HELP_SET
fa9e4066f08beec538e775443c5be79dd423fcabahrens} zpool_help_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct zpool_command {
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *name;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int (*func)(int, char **);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_help_t usage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} zpool_command_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Master command table. Each ZFS command has a name, associated function, and
fa9e4066f08beec538e775443c5be79dd423fcabahrens * usage message. The usage messages need to be internationalized, so we have
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to have a function to return the usage message based on a command index.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * These commands are organized according to how they are displayed in the usage
fa9e4066f08beec538e775443c5be79dd423fcabahrens * message. An empty command (one with a NULL name) indicates an empty line in
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the generic usage message.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic zpool_command_t command_table[] = {
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "create", zpool_do_create, HELP_CREATE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "destroy", zpool_do_destroy, HELP_DESTROY },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "add", zpool_do_add, HELP_ADD },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "remove", zpool_do_remove, HELP_REMOVE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "list", zpool_do_list, HELP_LIST },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "iostat", zpool_do_iostat, HELP_IOSTAT },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "status", zpool_do_status, HELP_STATUS },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "online", zpool_do_online, HELP_ONLINE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "offline", zpool_do_offline, HELP_OFFLINE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "clear", zpool_do_clear, HELP_CLEAR },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "attach", zpool_do_attach, HELP_ATTACH },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "detach", zpool_do_detach, HELP_DETACH },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "replace", zpool_do_replace, HELP_REPLACE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "scrub", zpool_do_scrub, HELP_SCRUB },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "import", zpool_do_import, HELP_IMPORT },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "export", zpool_do_export, HELP_EXPORT },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "upgrade", zpool_do_upgrade, HELP_UPGRADE },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { NULL },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "history", zpool_do_history, HELP_HISTORY },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "get", zpool_do_get, HELP_GET },
fa9e4066f08beec538e775443c5be79dd423fcabahrens { "set", zpool_do_set, HELP_SET },
fa9e4066f08beec538e775443c5be79dd423fcabahrens};
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define NCOMMAND (sizeof (command_table) / sizeof (command_table[0]))
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_command_t *current_command;
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char history_str[HIS_MAX_RECORD_LEN];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic const char *
fa9e4066f08beec538e775443c5be79dd423fcabahrensget_usage(zpool_help_t idx) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (idx) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_ADD:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tadd [-fn] <pool> <vdev> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_ATTACH:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tattach [-f] <pool> <device> "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "<new-device>\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_CLEAR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tclear <pool> [device]\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_CREATE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tcreate [-fn] [-o property=value] ... \n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_DESTROY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tdestroy [-f] <pool>\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_DETACH:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tdetach <pool> <device>\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_EXPORT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\texport [-f] <pool> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_HISTORY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\thistory [-il] [<pool>] ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_IMPORT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\timport [-d dir] [-D]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\timport [-o mntopts] [-o property=value] ... \n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t [-d dir | -c cachefile] [-D] [-f] [-R root] -a\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\timport [-o mntopts] [-o property=value] ... \n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t [-d dir | -c cachefile] [-D] [-f] [-R root] "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "<pool | id> [newpool]\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_IOSTAT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tiostat [-v] [pool] ... [interval "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "[count]]\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_LIST:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tlist [-H] [-o property[,...]] "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "[pool] ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_OFFLINE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\toffline [-t] <pool> <device> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_ONLINE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tonline <pool> <device> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_REPLACE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\treplace [-f] <pool> <device> "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "[new-device]\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_REMOVE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tremove <pool> <device>\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_SCRUB:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tscrub [-s] <pool> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_STATUS:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tstatus [-vx] [pool] ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_UPGRADE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tupgrade\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\tupgrade -v\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\tupgrade [-V version] <-a | pool ...>\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_GET:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tget <\"all\" | property[,...]> "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "<pool> ...\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HELP_SET:
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (gettext("\tset <property=value> <pool> \n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens abort();
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* NOTREACHED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Callback routine that will print out a pool property value.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_prop_cb(int prop, void *cb)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens FILE *fp = cb;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "\t%-13s ", zpool_prop_to_name(prop));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_prop_readonly(prop))
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, " NO ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, " YES ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_prop_values(prop) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "-\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "%s\n", zpool_prop_values(prop));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ZPROP_CONT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensusage(boolean_t requested)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock 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
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock for (i = 0; i < NCOMMAND; i++) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (command_table[i].name == NULL)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock (void) fprintf(fp, "\n");
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock else
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock (void) fprintf(fp, "%s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens get_usage(command_table[i].usage));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, gettext("usage:\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "%s", get_usage(current_command->usage));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (current_command != NULL &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((strcmp(current_command->name, "set") == 0) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens (strcmp(current_command->name, "get") == 0) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens (strcmp(current_command->name, "list") == 0))) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("\nthe following properties are supported:\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(fp, "\n\t%-13s %s %s\n\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens "PROPERTY", "EDIT", "VALUES");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Iterate over all properties */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) zprop_iter(print_prop_cb, fp, B_FALSE, B_TRUE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZFS_TYPE_POOL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See comments at end of main().
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (getenv("ZFS_ABORT") != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("dumping core by request\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens abort();
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens exit(requested ? 0 : 2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t print_logs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t is_log = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &is_log);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((is_log && !print_logs) || (!is_log && print_logs))
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens vname = zpool_vdev_name(g_zfs, zhp, child[c]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, vname, child[c], indent + 2,
fa9e4066f08beec538e775443c5be79dd423fcabahrens B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(vname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add a property pair (name, string-value) into a property nvlist.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensadd_prop_list(const char *propname, char *propval, nvlist_t **props)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *strval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *proplist;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_prop_t prop;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*props == NULL &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_alloc(props, NV_UNIQUE_NAME, 0) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("internal error: out of memory\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens proplist = *props;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("property '%s' is "
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock "not a valid pool property\n"), propname);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Use normalized property name for nvlist operations */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_string(proplist, zpool_prop_to_name(prop),
fa9e4066f08beec538e775443c5be79dd423fcabahrens &strval) == 0 && prop != ZPOOL_PROP_CACHEFILE) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("property '%s' "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "specified multiple times\n"), propname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_add_string(proplist, zpool_prop_to_name(prop),
fa9e4066f08beec538e775443c5be79dd423fcabahrens propval) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("internal "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "error: out of memory\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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{
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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':
fa9e4066f08beec538e775443c5be79dd423fcabahrens force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'n':
fa9e4066f08beec538e775443c5be79dd423fcabahrens dryrun = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing vdev specification\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* print original main pool and new tree */
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Do the same for the logs */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (num_logs(poolnvroot) > 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (num_logs(nvroot) > 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = (zpool_add(zhp, nvroot) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(nvroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool remove <pool> <vdev>
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Removes the given vdev from the pool. Currently, this only supports removing
fa9e4066f08beec538e775443c5be79dd423fcabahrens * spares from the pool. Eventually, we'll want to support removing leaf vdevs
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (as an alias for 'detach') as well as toplevel vdevs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_remove(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* get pool name and check number of arguments */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name argument\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing device\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = (zpool_vdev_remove(zhp, argv[1]) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool create [-fn] [-o property=value] ... [-R root] [-m mountpoint]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * <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>'
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -o Set property=value.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 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{
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t dryrun = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *nvroot = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *altroot = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *mountpoint = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *props = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *propval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, ":fnR:m:o:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'n':
fa9e4066f08beec538e775443c5be79dd423fcabahrens dryrun = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'R':
fa9e4066f08beec538e775443c5be79dd423fcabahrens altroot = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(zpool_prop_to_name(
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_PROP_ALTROOT), optarg, &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_string(props,
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
fa9e4066f08beec538e775443c5be79dd423fcabahrens &propval) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(zpool_prop_to_name(
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_PROP_CACHEFILE), "none", &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'm':
fa9e4066f08beec538e775443c5be79dd423fcabahrens mountpoint = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'o':
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((propval = strchr(optarg, '=')) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'=' for -o option\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens *propval = '\0';
fa9e4066f08beec538e775443c5be79dd423fcabahrens propval++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(optarg, propval, &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto badusage;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing vdev specification\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* pass off to get_vdev_spec for bulk processing */
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvroot = make_root_vdev(NULL, force, !force, B_FALSE, argc - 1,
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv + 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvroot == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* make_root_vdev() allows 0 toplevel children if there are spares */
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (children == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid vdev "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "specification: at least one toplevel vdev must be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "specified\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (altroot != NULL && altroot[0] != '/') {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid alternate root '%s': "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "must be an absolute path\n"), altroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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];
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct stat64 statbuf;
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);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (stat64(buf, &statbuf) == 0 &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens statbuf.st_nlink != 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (mountpoint == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("default "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "mountpoint '%s' exists and is not "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "empty\n"), buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("mountpoint "
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock "'%s' exists and is not empty\n"), buf);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock (void) fprintf(stderr, gettext("use '-m' "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "option to provide a different default\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (num_logs(nvroot) > 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Hand off to libzfs.
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_create(g_zfs, poolname, nvroot, props) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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,
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_prop_to_name(
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZFS_PROP_MOUNTPOINT),
fa9e4066f08beec538e775443c5be79dd423fcabahrens mountpoint) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zfs_mount(pool, NULL, 0) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = zfs_shareall(pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_close(pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("pool name may have "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "been omitted\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenserrout:
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(nvroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrensbadusage:
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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{
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock boolean_t force = B_FALSE;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock int c;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock char *pool;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock int ret;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "f")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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 *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 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{
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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':
fa9e4066f08beec538e775443c5be79dd423fcabahrens force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < argc; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open_canfail(g_zfs, argv[i])) == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_disable_datasets(zhp, force) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
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
fa9e4066f08beec538e775443c5be79dd423fcabahrensmax_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((ret = max_width(zhp, child[c], depth + 2,
fa9e4066f08beec538e775443c5be79dd423fcabahrens max)) > max)
fa9e4066f08beec538e775443c5be79dd423fcabahrens max = ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((ret = max_width(zhp, child[c], depth + 2,
fa9e4066f08beec538e775443c5be79dd423fcabahrens max)) > max)
fa9e4066f08beec538e775443c5be79dd423fcabahrens max = ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (max);
cbcb6089bf49be7bed77b8c9c1727b26f2e9c913lling}
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
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t print_logs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t **child;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint_t c, children;
fa9e4066f08beec538e775443c5be79dd423fcabahrens vdev_stat_t *vs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_VERSION_NEWER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("newer version"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case VDEV_AUX_ERR_EXCEEDED:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("too many errors"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t is_log = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &is_log);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((is_log && !print_logs) || (!is_log && print_logs))
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens vname = zpool_vdev_name(g_zfs, NULL, child[c]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_import_config(vname, child[c],
fa9e4066f08beec538e775443c5be79dd423fcabahrens namewidth, depth + 2, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(vname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &child, &children) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\tspares\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens vname = zpool_vdev_name(g_zfs, NULL, child[c]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t %s\n", vname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(vname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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);
fa9e4066f08beec538e775443c5be79dd423fcabahrens health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens reason = zpool_import_status(config, &msgid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" pool: %s\n"), name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" id: %llu\n"), (u_longlong_t)guid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" state: %s"), health);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool_state == POOL_STATE_DESTROYED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext(" (DESTROYED)"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (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
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_OFFLINE_DEV:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "are offlined.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_CORRUPT_POOL:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: The pool metadata is "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "corrupted.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_VERSION_OLDER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: The pool is formatted using an "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "older on-disk version.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_VERSION_NEWER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: The pool is formatted using an "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "incompatible version.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_HOSTID_MISMATCH:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: The pool was last accessed by "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "another system.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_FAULTED_DEV_R:
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_FAULTED_DEV_NR:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("status: One or more devices are "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "faulted.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (vs->vs_state == VDEV_STATE_HEALTHY) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (reason == ZPOOL_STATUS_VERSION_OLDER)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool can be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported using its name or numeric identifier, "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "though\n\tsome features will not be available "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "without an explicit 'zpool upgrade'.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool can be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported using its name or numeric "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "identifier and\n\tthe '-f' flag.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool can be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported using its name or numeric "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "identifier.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens } 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 "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "tolerance of the pool may be compromised if imported.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (reason) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ZPOOL_STATUS_VERSION_NEWER:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported. Access the pool on a system running "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "newer\n\tsoftware, or recreate the pool from "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "backup.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
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("action: The pool cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported. Attach the missing\n\tdevices and try "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "again.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("action: The pool cannot be "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "imported due to damaged devices or data.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the state is "closed" or "can't open", and the aux state
fa9e4066f08beec538e775443c5be79dd423fcabahrens * is "corrupt data":
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (((vs->vs_state == VDEV_STATE_CLOSED) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens (vs->vs_state == VDEV_STATE_CANT_OPEN)) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (vs->vs_aux == VDEV_AUX_CORRUPT_DATA)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool_state == POOL_STATE_DESTROYED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\tThe pool was destroyed, "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "but can be imported using the '-Df' flags.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (pool_state != POOL_STATE_EXPORTED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\tThe pool may be active on "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "on another system, but can be imported using\n\t"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "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
fa9e4066f08beec538e775443c5be79dd423fcabahrens namewidth = max_width(NULL, nvroot, 0, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (namewidth < 10)
fa9e4066f08beec538e775443c5be79dd423fcabahrens namewidth = 10;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_import_config(name, nvroot, namewidth, 0, B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (num_logs(nvroot) > 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\tlogs\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_import_config(name, nvroot, namewidth, 0, B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("\n\tAdditional devices are known to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "be part of this pool, though their\n\texact "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "configuration cannot be determined.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Perform the import for the given configuration. This passes the heavy
fa9e4066f08beec538e775443c5be79dd423fcabahrens * lifting off to zpool_import_props(), and then mounts the datasets contained
fa9e4066f08beec538e775443c5be79dd423fcabahrens * within the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensdo_import(nvlist_t *config, const char *newname, const char *mntopts,
fa9e4066f08beec538e775443c5be79dd423fcabahrens int force, nvlist_t *props)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *name;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock uint64_t state;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock uint64_t version;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock verify(nvlist_lookup_uint64(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_VERSION, &version) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (version > SPA_VERSION) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot import '%s': pool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "is formatted using a newer ZFS version\n"), name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (state != POOL_STATE_EXPORTED && !force) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t hostid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &hostid) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((unsigned long)hostid != gethostid()) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *hostname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t timestamp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens time_t t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config,
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_CONFIG_TIMESTAMP, &timestamp) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens t = timestamp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot import "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%s': pool may be in use from other "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "system, it was last accessed by %s "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "(hostid: 0x%lx) on %s"), name, hostname,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (unsigned long)hostid,
fa9e4066f08beec538e775443c5be79dd423fcabahrens asctime(localtime(&t)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("use '-f' to "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "import anyway\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot import '%s': "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "pool may be in use from other system\n"), name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("use '-f' to import "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "anyway\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_import_props(g_zfs, config, newname, props) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newname != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens name = (char *)newname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify((zhp = zpool_open(g_zfs, name)) != NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_enable_datasets(zhp, mntopts, 0) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (error);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock * zpool import [-d dir] [-D]
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * [-d dir | -c cachefile] [-f] -a
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock * import [-o mntopts] [-o prop=value] ... [-R root] [-D]
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock * [-d dir | -c cachefile] [-f] <pool | id> [newpool]
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -c Read pool information from a cachefile instead of searching
fa9e4066f08beec538e775443c5be79dd423fcabahrens * devices.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock *
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * -d Scan in a specific directory, other than /dev/dsk. More than
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * one directory can be specified using multiple '-d' options.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock *
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * -D Scan for previously destroyed pools or import all or only
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * specified destroyed pools.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock *
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * -R Temporarily import the pool, with all mountpoints relative to
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * the given root. The pool will remain exported when the machine
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * is rebooted.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock *
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * -f Force import, even if it appears that the pool is active.
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock *
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock * -a Import all pools found.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -o Set property=value and/or temporary mount options (without '=').
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
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;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock int nsearch = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock int err;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *pools = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t do_all = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t do_destroyed = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *mntopts = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t do_force = B_FALSE;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock nvpair_t *elem;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *config;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock uint64_t searchguid;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock char *searchname;
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock char *propval;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *found_config;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *props = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t first;
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t pool_state;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *cachefile = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, ":afc:d:Do:p:R:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'a':
fa9e4066f08beec538e775443c5be79dd423fcabahrens do_all = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'c':
fa9e4066f08beec538e775443c5be79dd423fcabahrens cachefile = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'd':
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (searchdirs == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs = safe_malloc(sizeof (char *));
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **tmp = safe_malloc((nsearch + 1) *
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens bcopy(searchdirs, tmp, nsearch *
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (char *));
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(searchdirs);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock searchdirs = tmp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchdirs[nsearch++] = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'D':
fa9e4066f08beec538e775443c5be79dd423fcabahrens do_destroyed = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens do_force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'o':
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((propval = strchr(optarg, '=')) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens *propval = '\0';
fa9e4066f08beec538e775443c5be79dd423fcabahrens propval++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(optarg, propval, &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens mntopts = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'R':
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(zpool_prop_to_name(
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_PROP_ALTROOT), optarg, &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvlist_lookup_string(props,
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
fa9e4066f08beec538e775443c5be79dd423fcabahrens &propval) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (add_prop_list(zpool_prop_to_name(
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZPOOL_PROP_CACHEFILE), "none", &props))
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto error;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cachefile && nsearch != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("-c is incompatible with -d\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cachefile)
fa9e4066f08beec538e775443c5be79dd423fcabahrens pools = zpool_find_import_cached(g_zfs, cachefile);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens pools = zpool_find_import(g_zfs, nsearch, searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pools == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(searchdirs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We now have a list of all available pools in the given directories.
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.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -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 else
fa9e4066f08beec538e775443c5be79dd423fcabahrens searchname = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens found_config = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens elem = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvpair_value_nvlist(elem, &config) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &pool_state) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (first)
fa9e4066f08beec538e775443c5be79dd423fcabahrens first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (!do_all)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock if (do_all)
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock err |= do_import(config, NULL, mntopts,
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock do_force, props);
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock else
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock show_import(config);
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock } else if (searchname != NULL) {
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens err |= do_import(found_config, argc == 1 ? NULL :
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv[1], mntopts, do_force, props);
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
fa9e4066f08beec538e775443c5be79dd423fcabahrenserror:
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(pools);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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 */
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrockstatic 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
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < children; c++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens vname = zpool_vdev_name(g_zfs, zhp, newchild[c]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens newchild[c], cb, depth + 2);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(vname);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrensrefresh_iostat(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens iostat_cbdata_t *cb = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t missing;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the pool has disappeared, remove it from the list and continue.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_refresh_stats(zhp, &missing) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (missing)
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool_list_remove(cb->cb_list, zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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
fa9e4066f08beec538e775443c5be79dd423fcabahrens newconfig = zpool_get_config(zhp, &oldconfig);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cb->cb_iteration == 1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldconfig = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(newconfig, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &newnvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (oldconfig == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens oldnvroot = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_nvlist(oldconfig, ZPOOL_CONFIG_VDEV_TREE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &oldnvroot) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Print out the statistics for the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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':
fa9e4066f08beec538e775443c5be79dd423fcabahrens verbose = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Ignore the last parameter
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens interval = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Construct the list of all interesting pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((list = pool_list_get(argc, argv, NULL, &ret)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool_list_count(list) == 0 && argc != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool_list_free(list);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pool_list_count(list) == 0 && interval == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Refresh all statistics. This is done as an explicit step
fa9e4066f08beec538e775443c5be79dd423fcabahrens * before calculating the maximum name width, so that any
fa9e4066f08beec538e775443c5be79dd423fcabahrens * configuration changes are properly accounted for.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) pool_list_iter(list, B_FALSE, refresh_iostat, &cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (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
fa9e4066f08beec538e775443c5be79dd423fcabahrens (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
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Flush the output so that redirection to a file isn't buffered
fa9e4066f08beec538e775443c5be79dd423fcabahrens * indefinitely.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fflush(stdout);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
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 {
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t cb_scripted;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t cb_first;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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 */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_header(zprop_list_t *pl)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *header;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t right_justify;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; pl != NULL; pl = pl->pl_next) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pl->pl_prop == ZPROP_INVAL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens continue;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!first)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens header = zpool_prop_column_name(pl->pl_prop);
fa9e4066f08beec538e775443c5be79dd423fcabahrens right_justify = zpool_prop_align_right(pl->pl_prop);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pl->pl_next == NULL && !right_justify)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%s", header);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (right_justify)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%*s", pl->pl_width, header);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%-*s", pl->pl_width, header);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a pool and a list of properties, print out all the properties according
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to the described layout.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void
fa9e4066f08beec538e775443c5be79dd423fcabahrensprint_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char property[ZPOOL_MAXPROPLEN];
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *propstr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t right_justify;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int width;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (; pl != NULL; pl = pl->pl_next) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!first) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (scripted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\t");
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(" ");
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens right_justify = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pl->pl_prop != ZPROP_INVAL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_get_prop(zhp, pl->pl_prop, property,
fa9e4066f08beec538e775443c5be79dd423fcabahrens sizeof (property), NULL) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens propstr = "-";
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens propstr = property;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens right_justify = zpool_prop_align_right(pl->pl_prop);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens propstr = "-";
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens width = pl->pl_width;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If this is being called in scripted mode, or if this is the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * last column and it is left-justified, don't include a width
fa9e4066f08beec538e775443c5be79dd423fcabahrens * format specifier.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (scripted || (pl->pl_next == NULL && !right_justify))
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%s", propstr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (right_justify)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%*s", width, propstr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%-*s", width, propstr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Generic callback function to list a pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenslist_callback(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens list_cbdata_t *cbp = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cbp->cb_first) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!cbp->cb_scripted)
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_header(cbp->cb_proplist);
fa9e4066f08beec538e775443c5be79dd423fcabahrens cbp->cb_first = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool list [-H] [-o prop[,prop]*] [pool] ...
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -H Scripted mode. Don't display headers, and separate properties
fa9e4066f08beec538e775443c5be79dd423fcabahrens * by a single tab.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -o List of properties to display. Defaults to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * "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 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens static char default_props[] =
fa9e4066f08beec538e775443c5be79dd423fcabahrens "name,size,used,available,capacity,health,altroot";
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *props = default_props;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, ":Ho:")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'H':
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_scripted = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'o':
fa9e4066f08beec538e775443c5be79dd423fcabahrens props = optarg;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ':':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing argument for "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' option\n"), optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens argc -= optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv += optind;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cb.cb_first = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
fa9e4066f08beec538e775443c5be79dd423fcabahrens list_callback, &cb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zprop_free_list(cb.cb_proplist);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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{
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t force = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_t *nvroot;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname, *old_disk, *new_disk;
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':
fa9e4066f08beec538e775443c5be79dd423fcabahrens force = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <device> specification\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock old_disk = argv[1];
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 3) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!replacing) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <new_device> specification\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock }
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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvroot = make_root_vdev(zhp, force, B_FALSE, replacing, argc, argv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (nvroot == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens nvlist_free(nvroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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)
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock{
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (zpool_do_attach_or_replace(argc, argv, B_TRUE));
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock/*
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock * 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
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrockzpool_do_detach(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int c;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *poolname, *path;
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':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr,
fa9e4066f08beec538e775443c5be79dd423fcabahrens gettext("missing <device> specification\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens path = argv[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = zpool_vdev_detach(zhp, path);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing device name\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 1; i < argc; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_vdev_online(zhp, argv[i], 0, &newstate) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newstate != VDEV_STATE_HEALTHY) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("warning: device '%s' "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "onlined, but remains in faulted state\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens argv[i]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newstate == VDEV_STATE_FAULTED)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("use 'zpool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "clear' to restore a faulted "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "device\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf(gettext("use 'zpool "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "replace' to replace devices "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "that are no longer present\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool offline [-ft] <pool> <device> ...
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock *
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * -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;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens boolean_t istmp = B_FALSE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* check options */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((c = getopt(argc, argv, "ft")) != -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (c) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 't':
fa9e4066f08beec538e775443c5be79dd423fcabahrens istmp = B_TRUE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens case 'f':
fa9e4066f08beec538e775443c5be79dd423fcabahrens case '?':
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("invalid option '%c'\n"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens optopt);
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing device name\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens poolname = argv[0];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 1; i < argc; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_vdev_offline(zhp, argv[i], istmp) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zpool clear <pool> [device]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Clear all errors associated with a pool or a particular device.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_do_clear(int argc, char **argv)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *pool, *device;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc < 2) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("missing pool name\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc > 3) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("too many arguments\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens usage(B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens pool = argv[1];
fa9e4066f08beec538e775443c5be79dd423fcabahrens device = argc == 3 ? argv[2] : NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((zhp = zpool_open(g_zfs, pool)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_clear(zhp, device) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct scrub_cbdata {
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int cb_argc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **cb_argv;
fa9e4066f08beec538e775443c5be79dd423fcabahrens} scrub_cbdata_t;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrensscrub_callback(zpool_handle_t *zhp, void *data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens scrub_cbdata_t *cb = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int err;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Ignore faulted pools.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "currently unavailable\n"), zpool_get_name(zhp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens err = zpool_scrub(zhp, cb->cb_type);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens 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
cb.cb_type = POOL_SCRUB_EVERYTHING;
/* check options */
while ((c = getopt(argc, argv, "s")) != -1) {
switch (c) {
case 's':
cb.cb_type = POOL_SCRUB_NONE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
cb.cb_argc = argc;
cb.cb_argv = argv;
argc -= optind;
argv += optind;
if (argc < 1) {
(void) fprintf(stderr, gettext("missing pool name argument\n"));
usage(B_FALSE);
}
return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
}
typedef struct status_cbdata {
int cb_count;
boolean_t cb_allpools;
boolean_t cb_verbose;
boolean_t cb_explain;
boolean_t cb_first;
} status_cbdata_t;
/*
* Print out detailed scrub status.
*/
void
print_scrub_status(nvlist_t *nvroot)
{
vdev_stat_t *vs;
uint_t vsc;
time_t start, end, now;
double fraction_done;
uint64_t examined, total, minutes_left;
char *scrub_type;
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &vsc) == 0);
/*
* If there's never been a scrub, there's not much to say.
*/
if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
(void) printf(gettext("none requested\n"));
return;
}
scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
"resilver" : "scrub";
start = vs->vs_scrub_start;
end = vs->vs_scrub_end;
now = time(NULL);
examined = vs->vs_scrub_examined;
total = vs->vs_alloc;
if (end != 0) {
(void) printf(gettext("%s %s with %llu errors on %s"),
scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
(u_longlong_t)vs->vs_scrub_errors, ctime(&end));
return;
}
if (examined == 0)
examined = 1;
if (examined > total)
total = examined;
fraction_done = (double)examined / total;
minutes_left = (uint64_t)((now - start) *
(1 - fraction_done) / fraction_done / 60);
(void) printf(gettext("%s in progress, %.2f%% done, %lluh%um to go\n"),
scrub_type, 100 * fraction_done,
(u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
}
typedef struct spare_cbdata {
uint64_t cb_guid;
zpool_handle_t *cb_zhp;
} spare_cbdata_t;
static boolean_t
find_vdev(nvlist_t *nv, uint64_t search)
{
uint64_t guid;
nvlist_t **child;
uint_t c, children;
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0 &&
search == guid)
return (B_TRUE);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) == 0) {
for (c = 0; c < children; c++)
if (find_vdev(child[c], search))
return (B_TRUE);
}
return (B_FALSE);
}
static int
find_spare(zpool_handle_t *zhp, void *data)
{
spare_cbdata_t *cbp = data;
nvlist_t *config, *nvroot;
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
if (find_vdev(nvroot, cbp->cb_guid)) {
cbp->cb_zhp = zhp;
return (1);
}
zpool_close(zhp);
return (0);
}
/*
* Print out configuration state as requested by status_callback.
*/
void
print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
int namewidth, int depth, boolean_t isspare, boolean_t print_logs)
{
nvlist_t **child;
uint_t c, children;
vdev_stat_t *vs;
char rbuf[6], wbuf[6], cbuf[6], repaired[7];
char *vname;
uint64_t notpresent;
spare_cbdata_t cb;
char *state;
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) == 0);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0)
children = 0;
state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
if (isspare) {
/*
* For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
* online drives.
*/
if (vs->vs_aux == VDEV_AUX_SPARED)
state = "INUSE";
else if (vs->vs_state == VDEV_STATE_HEALTHY)
state = "AVAIL";
}
(void) printf("\t%*s%-*s %-8s", depth, "", namewidth - depth,
name, state);
if (!isspare) {
zfs_nicenum(vs->vs_read_errors, rbuf, sizeof (rbuf));
zfs_nicenum(vs->vs_write_errors, wbuf, sizeof (wbuf));
zfs_nicenum(vs->vs_checksum_errors, cbuf, sizeof (cbuf));
(void) printf(" %5s %5s %5s", rbuf, wbuf, cbuf);
}
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
&notpresent) == 0) {
char *path;
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0);
(void) printf(" was %s", path);
} else if (vs->vs_aux != 0) {
(void) printf(" ");
switch (vs->vs_aux) {
case VDEV_AUX_OPEN_FAILED:
(void) printf(gettext("cannot open"));
break;
case VDEV_AUX_BAD_GUID_SUM:
(void) printf(gettext("missing device"));
break;
case VDEV_AUX_NO_REPLICAS:
(void) printf(gettext("insufficient replicas"));
break;
case VDEV_AUX_VERSION_NEWER:
(void) printf(gettext("newer version"));
break;
case VDEV_AUX_SPARED:
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
&cb.cb_guid) == 0);
if (zpool_iter(g_zfs, find_spare, &cb) == 1) {
if (strcmp(zpool_get_name(cb.cb_zhp),
zpool_get_name(zhp)) == 0)
(void) printf(gettext("currently in "
"use"));
else
(void) printf(gettext("in use by "
"pool '%s'"),
zpool_get_name(cb.cb_zhp));
zpool_close(cb.cb_zhp);
} else {
(void) printf(gettext("currently in use"));
}
break;
case VDEV_AUX_ERR_EXCEEDED:
(void) printf(gettext("too many errors"));
break;
default:
(void) printf(gettext("corrupted data"));
break;
}
} else if (vs->vs_scrub_repaired != 0 && children == 0) {
/*
* Report bytes resilvered/repaired on leaf devices.
*/
zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
(void) printf(gettext(" %s %s"), repaired,
(vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
"resilvered" : "repaired");
}
(void) printf("\n");
for (c = 0; c < children; c++) {
uint64_t is_log = B_FALSE;
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
if ((is_log && !print_logs) || (!is_log && print_logs))
continue;
vname = zpool_vdev_name(g_zfs, zhp, child[c]);
print_status_config(zhp, vname, child[c],
namewidth, depth + 2, isspare, B_FALSE);
free(vname);
}
}
static void
print_error_log(zpool_handle_t *zhp)
{
nvlist_t *nverrlist = NULL;
nvpair_t *elem;
char *pathname;
size_t len = MAXPATHLEN * 2;
if (zpool_get_errlog(zhp, &nverrlist) != 0) {
(void) printf("errors: List of errors unavailable "
"(insufficient privileges)\n");
return;
}
(void) printf("errors: Permanent errors have been "
"detected in the following files:\n\n");
pathname = safe_malloc(len);
elem = NULL;
while ((elem = nvlist_next_nvpair(nverrlist, elem)) != NULL) {
nvlist_t *nv;
uint64_t dsobj, obj;
verify(nvpair_value_nvlist(elem, &nv) == 0);
verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_DATASET,
&dsobj) == 0);
verify(nvlist_lookup_uint64(nv, ZPOOL_ERR_OBJECT,
&obj) == 0);
zpool_obj_to_path(zhp, dsobj, obj, pathname, len);
(void) printf("%7s %s\n", "", pathname);
}
free(pathname);
nvlist_free(nverrlist);
}
static void
print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
int namewidth)
{
uint_t i;
char *name;
if (nspares == 0)
return;
(void) printf(gettext("\tspares\n"));
for (i = 0; i < nspares; i++) {
name = zpool_vdev_name(g_zfs, zhp, spares[i]);
print_status_config(zhp, name, spares[i],
namewidth, 2, B_TRUE, B_FALSE);
free(name);
}
}
/*
* Display a summary of pool status. Displays a summary such as:
*
* pool: tank
* status: DEGRADED
* reason: One or more devices ...
* see: http://www.sun.com/msg/ZFS-xxxx-01
* config:
* mirror DEGRADED
* c1t0d0 OK
* c2t0d0 UNAVAIL
*
* When given the '-v' option, we print out the complete config. If the '-e'
* option is specified, then we print out error rate information as well.
*/
int
status_callback(zpool_handle_t *zhp, void *data)
{
status_cbdata_t *cbp = data;
nvlist_t *config, *nvroot;
char *msgid;
int reason;
const char *health;
uint_t c;
vdev_stat_t *vs;
config = zpool_get_config(zhp, NULL);
reason = zpool_get_status(zhp, &msgid);
cbp->cb_count++;
/*
* If we were given 'zpool status -x', only report those pools with
* problems.
*/
if (reason == ZPOOL_STATUS_OK && cbp->cb_explain) {
if (!cbp->cb_allpools) {
(void) printf(gettext("pool '%s' is healthy\n"),
zpool_get_name(zhp));
if (cbp->cb_first)
cbp->cb_first = B_FALSE;
}
return (0);
}
if (cbp->cb_first)
cbp->cb_first = B_FALSE;
else
(void) printf("\n");
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) == 0);
health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
(void) printf(gettext(" pool: %s\n"), zpool_get_name(zhp));
(void) printf(gettext(" state: %s\n"), health);
switch (reason) {
case ZPOOL_STATUS_MISSING_DEV_R:
(void) printf(gettext("status: One or more devices could not "
"be opened. Sufficient replicas exist for\n\tthe pool to "
"continue functioning in a degraded state.\n"));
(void) printf(gettext("action: Attach the missing device and "
"online it using 'zpool online'.\n"));
break;
case ZPOOL_STATUS_MISSING_DEV_NR:
(void) printf(gettext("status: One or more devices could not "
"be opened. There are insufficient\n\treplicas for the "
"pool to continue functioning.\n"));
(void) printf(gettext("action: Attach the missing device and "
"online it using 'zpool online'.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_R:
(void) printf(gettext("status: One or more devices could not "
"be used because the label is missing or\n\tinvalid. "
"Sufficient replicas exist for the pool to continue\n\t"
"functioning in a degraded state.\n"));
(void) printf(gettext("action: Replace the device using "
"'zpool replace'.\n"));
break;
case ZPOOL_STATUS_CORRUPT_LABEL_NR:
(void) printf(gettext("status: One or more devices could not "
"be used because the label is missing \n\tor invalid. "
"There are insufficient replicas for the pool to "
"continue\n\tfunctioning.\n"));
(void) printf(gettext("action: Destroy and re-create the pool "
"from a backup source.\n"));
break;
case ZPOOL_STATUS_FAILING_DEV:
(void) printf(gettext("status: One or more devices has "
"experienced an unrecoverable error. An\n\tattempt was "
"made to correct the error. Applications are "
"unaffected.\n"));
(void) printf(gettext("action: Determine if the device needs "
"to be replaced, and clear the errors\n\tusing "
"'zpool clear' or replace the device with 'zpool "
"replace'.\n"));
break;
case ZPOOL_STATUS_OFFLINE_DEV:
(void) printf(gettext("status: One or more devices has "
"been taken offline by the administrator.\n\tSufficient "
"replicas exist for the pool to continue functioning in "
"a\n\tdegraded state.\n"));
(void) printf(gettext("action: Online the device using "
"'zpool online' or replace the device with\n\t'zpool "
"replace'.\n"));
break;
case ZPOOL_STATUS_RESILVERING:
(void) printf(gettext("status: One or more devices is "
"currently being resilvered. The pool will\n\tcontinue "
"to function, possibly in a degraded state.\n"));
(void) printf(gettext("action: Wait for the resilver to "
"complete.\n"));
break;
case ZPOOL_STATUS_CORRUPT_DATA:
(void) printf(gettext("status: One or more devices has "
"experienced an error resulting in data\n\tcorruption. "
"Applications may be affected.\n"));
(void) printf(gettext("action: Restore the file in question "
"if possible. Otherwise restore the\n\tentire pool from "
"backup.\n"));
break;
case ZPOOL_STATUS_CORRUPT_POOL:
(void) printf(gettext("status: The pool metadata is corrupted "
"and the pool cannot be opened.\n"));
(void) printf(gettext("action: Destroy and re-create the pool "
"from a backup source.\n"));
break;
case ZPOOL_STATUS_VERSION_OLDER:
(void) printf(gettext("status: The pool is formatted using an "
"older on-disk format. The pool can\n\tstill be used, but "
"some features are unavailable.\n"));
(void) printf(gettext("action: Upgrade the pool using 'zpool "
"upgrade'. Once this is done, the\n\tpool will no longer "
"be accessible on older software versions.\n"));
break;
case ZPOOL_STATUS_VERSION_NEWER:
(void) printf(gettext("status: The pool has been upgraded to a "
"newer, incompatible on-disk version.\n\tThe pool cannot "
"be accessed on this system.\n"));
(void) printf(gettext("action: Access the pool from a system "
"running more recent software, or\n\trestore the pool from "
"backup.\n"));
break;
case ZPOOL_STATUS_FAULTED_DEV_R:
(void) printf(gettext("status: One or more devices are "
"faulted in response to persistent errors.\n\tSufficient "
"replicas exist for the pool to continue functioning "
"in a\n\tdegraded state.\n"));
(void) printf(gettext("action: Replace the faulted device, "
"or use 'zpool clear' to mark the device\n\trepaired.\n"));
break;
case ZPOOL_STATUS_FAULTED_DEV_NR:
(void) printf(gettext("status: One or more devices are "
"faulted in response to persistent errors. There are "
"insufficient replicas for the pool to\n\tcontinue "
"functioning.\n"));
(void) printf(gettext("action: Destroy and re-create the pool "
"from a backup source. Manually marking the device\n"
"\trepaired using 'zpool clear' may allow some data "
"to be recovered.\n"));
break;
default:
/*
* The remaining errors can't actually be generated, yet.
*/
assert(reason == ZPOOL_STATUS_OK);
}
if (msgid != NULL)
(void) printf(gettext(" see: http://www.sun.com/msg/%s\n"),
msgid);
if (config != NULL) {
int namewidth;
uint64_t nerr;
nvlist_t **spares;
uint_t nspares;
(void) printf(gettext(" scrub: "));
print_scrub_status(nvroot);
namewidth = max_width(zhp, nvroot, 0, 0);
if (namewidth < 10)
namewidth = 10;
(void) printf(gettext("config:\n\n"));
(void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
"NAME", "STATE", "READ", "WRITE", "CKSUM");
print_status_config(zhp, zpool_get_name(zhp), nvroot,
namewidth, 0, B_FALSE, B_FALSE);
if (num_logs(nvroot) > 0)
print_status_config(zhp, "logs", nvroot, namewidth, 0,
B_FALSE, B_TRUE);
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
&spares, &nspares) == 0)
print_spares(zhp, spares, nspares, namewidth);
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
&nerr) == 0) {
nvlist_t *nverrlist = NULL;
/*
* If the approximate error count is small, get a
* precise count by fetching the entire log and
* uniquifying the results.
*/
if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
zpool_get_errlog(zhp, &nverrlist) == 0) {
nvpair_t *elem;
elem = NULL;
nerr = 0;
while ((elem = nvlist_next_nvpair(nverrlist,
elem)) != NULL) {
nerr++;
}
}
nvlist_free(nverrlist);
(void) printf("\n");
if (nerr == 0)
(void) printf(gettext("errors: No known data "
"errors\n"));
else if (!cbp->cb_verbose)
(void) printf(gettext("errors: %llu data "
"errors, use '-v' for a list\n"),
(u_longlong_t)nerr);
else
print_error_log(zhp);
}
} else {
(void) printf(gettext("config: The configuration cannot be "
"determined.\n"));
}
return (0);
}
/*
* zpool status [-vx] [pool] ...
*
* -v Display complete error logs
* -x Display only pools with potential problems
*
* Describes the health status of all pools or some subset.
*/
int
zpool_do_status(int argc, char **argv)
{
int c;
int ret;
status_cbdata_t cb = { 0 };
/* check options */
while ((c = getopt(argc, argv, "vx")) != -1) {
switch (c) {
case 'v':
cb.cb_verbose = B_TRUE;
break;
case 'x':
cb.cb_explain = B_TRUE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
argc -= optind;
argv += optind;
cb.cb_first = B_TRUE;
if (argc == 0)
cb.cb_allpools = B_TRUE;
ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
if (argc == 0 && cb.cb_count == 0)
(void) printf(gettext("no pools available\n"));
else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
(void) printf(gettext("all pools are healthy\n"));
return (ret);
}
typedef struct upgrade_cbdata {
int cb_all;
int cb_first;
int cb_newer;
int cb_argc;
uint64_t cb_version;
char **cb_argv;
} upgrade_cbdata_t;
static int
upgrade_cb(zpool_handle_t *zhp, void *arg)
{
upgrade_cbdata_t *cbp = arg;
nvlist_t *config;
uint64_t version;
int ret = 0;
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
if (!cbp->cb_newer && version < SPA_VERSION) {
if (!cbp->cb_all) {
if (cbp->cb_first) {
(void) printf(gettext("The following pools are "
"out of date, and can be upgraded. After "
"being\nupgraded, these pools will no "
"longer be accessible by older software "
"versions.\n\n"));
(void) printf(gettext("VER POOL\n"));
(void) printf(gettext("--- ------------\n"));
cbp->cb_first = B_FALSE;
}
(void) printf("%2llu %s\n", (u_longlong_t)version,
zpool_get_name(zhp));
} else {
cbp->cb_first = B_FALSE;
ret = zpool_upgrade(zhp, cbp->cb_version);
if (!ret) {
(void) printf(gettext("Successfully upgraded "
"'%s'\n\n"), zpool_get_name(zhp));
}
}
} else if (cbp->cb_newer && version > SPA_VERSION) {
assert(!cbp->cb_all);
if (cbp->cb_first) {
(void) printf(gettext("The following pools are "
"formatted using a newer software version and\n"
"cannot be accessed on the current system.\n\n"));
(void) printf(gettext("VER POOL\n"));
(void) printf(gettext("--- ------------\n"));
cbp->cb_first = B_FALSE;
}
(void) printf("%2llu %s\n", (u_longlong_t)version,
zpool_get_name(zhp));
}
zpool_close(zhp);
return (ret);
}
/* ARGSUSED */
static int
upgrade_one(zpool_handle_t *zhp, void *data)
{
upgrade_cbdata_t *cbp = data;
uint64_t cur_version;
int ret;
if (strcmp("log", zpool_get_name(zhp)) == 0) {
(void) printf(gettext("'log' is now a reserved word\n"
"Pool 'log' must be renamed using export and import"
" to upgrade.\n"));
return (1);
}
cur_version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
if (cur_version >= cbp->cb_version) {
(void) printf(gettext("Pool '%s' is already formatted "
"using more current version '%d'.\n"), zpool_get_name(zhp),
cur_version);
return (0);
}
ret = zpool_upgrade(zhp, cbp->cb_version);
if (!ret) {
(void) printf(gettext("Successfully upgraded '%s' "
"from version %llu to version %llu\n\n"),
zpool_get_name(zhp), (u_longlong_t)cur_version,
(u_longlong_t)cbp->cb_version);
}
return (ret != 0);
}
/*
* zpool upgrade
* zpool upgrade -v
* zpool upgrade [-V version] <-a | pool ...>
*
* With no arguments, display downrev'd ZFS pool available for upgrade.
* Individual pools can be upgraded by specifying the pool, and '-a' will
* upgrade all pools.
*/
int
zpool_do_upgrade(int argc, char **argv)
{
int c;
upgrade_cbdata_t cb = { 0 };
int ret = 0;
boolean_t showversions = B_FALSE;
char *end;
/* check options */
while ((c = getopt(argc, argv, "avV:")) != -1) {
switch (c) {
case 'a':
cb.cb_all = B_TRUE;
break;
case 'v':
showversions = B_TRUE;
break;
case 'V':
cb.cb_version = strtoll(optarg, &end, 10);
if (*end != '\0' || cb.cb_version > SPA_VERSION ||
cb.cb_version < SPA_VERSION_1) {
(void) fprintf(stderr,
gettext("invalid version '%s'\n"), optarg);
usage(B_FALSE);
}
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
cb.cb_argc = argc;
cb.cb_argv = argv;
argc -= optind;
argv += optind;
if (cb.cb_version == 0) {
cb.cb_version = SPA_VERSION;
} else if (!cb.cb_all && argc == 0) {
(void) fprintf(stderr, gettext("-V option is "
"incompatible with other arguments\n"));
usage(B_FALSE);
}
if (showversions) {
if (cb.cb_all || argc != 0) {
(void) fprintf(stderr, gettext("-v option is "
"incompatible with other arguments\n"));
usage(B_FALSE);
}
} else if (cb.cb_all) {
if (argc != 0) {
(void) fprintf(stderr, gettext("-a option should not "
"be used along with a pool name\n"));
usage(B_FALSE);
}
}
(void) printf(gettext("This system is currently running "
"ZFS pool version %llu.\n\n"), SPA_VERSION);
cb.cb_first = B_TRUE;
if (showversions) {
(void) printf(gettext("The following versions are "
"supported:\n\n"));
(void) printf(gettext("VER DESCRIPTION\n"));
(void) printf("--- -----------------------------------------"
"---------------\n");
(void) printf(gettext(" 1 Initial ZFS version\n"));
(void) printf(gettext(" 2 Ditto blocks "
"(replicated metadata)\n"));
(void) printf(gettext(" 3 Hot spares and double parity "
"RAID-Z\n"));
(void) printf(gettext(" 4 zpool history\n"));
(void) printf(gettext(" 5 Compression using the gzip "
"algorithm\n"));
(void) printf(gettext(" 6 bootfs pool property\n"));
(void) printf(gettext(" 7 Separate intent log devices\n"));
(void) printf(gettext(" 8 Delegated administration\n"));
(void) printf(gettext(" 9 refquota and refreservation "
"properties\n"));
(void) printf(gettext("For more information on a particular "
"version, including supported releases, see:\n\n"));
(void) printf("http://www.opensolaris.org/os/community/zfs/"
"version/N\n\n");
(void) printf(gettext("Where 'N' is the version number.\n"));
} else if (argc == 0) {
int notfound;
ret = zpool_iter(g_zfs, upgrade_cb, &cb);
notfound = cb.cb_first;
if (!cb.cb_all && ret == 0) {
if (!cb.cb_first)
(void) printf("\n");
cb.cb_first = B_TRUE;
cb.cb_newer = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_cb, &cb);
if (!cb.cb_first) {
notfound = B_FALSE;
(void) printf("\n");
}
}
if (ret == 0) {
if (notfound)
(void) printf(gettext("All pools are formatted "
"using this version.\n"));
else if (!cb.cb_all)
(void) printf(gettext("Use 'zpool upgrade -v' "
"for a list of available versions and "
"their associated\nfeatures.\n"));
}
} else {
ret = for_each_pool(argc, argv, B_FALSE, NULL,
upgrade_one, &cb);
}
return (ret);
}
typedef struct hist_cbdata {
boolean_t first;
int longfmt;
int internal;
} hist_cbdata_t;
char *hist_event_table[LOG_END] = {
"invalid event",
"pool create",
"vdev add",
"pool remove",
"pool destroy",
"pool export",
"pool import",
"vdev attach",
"vdev replace",
"vdev detach",
"vdev online",
"vdev offline",
"vdev upgrade",
"pool clear",
"pool scrub",
"pool property set",
"create",
"clone",
"destroy",
"destroy_begin_sync",
"inherit",
"property set",
"quota set",
"permission update",
"permission remove",
"permission who remove",
"promote",
"receive",
"rename",
"reservation set",
"replay_inc_sync",
"replay_full_sync",
"rollback",
"snapshot",
"filesystem version upgrade",
"refquota set",
"refreservation set",
};
/*
* Print out the command history for a specific pool.
*/
static int
get_history_one(zpool_handle_t *zhp, void *data)
{
nvlist_t *nvhis;
nvlist_t **records;
uint_t numrecords;
char *cmdstr;
char *pathstr;
uint64_t dst_time;
time_t tsec;
struct tm t;
char tbuf[30];
int ret, i;
uint64_t who;
struct passwd *pwd;
char *hostname;
char *zonename;
char internalstr[MAXPATHLEN];
hist_cbdata_t *cb = (hist_cbdata_t *)data;
uint64_t txg;
uint64_t ievent;
cb->first = B_FALSE;
(void) printf(gettext("History for '%s':\n"), zpool_get_name(zhp));
if ((ret = zpool_get_history(zhp, &nvhis)) != 0)
return (ret);
verify(nvlist_lookup_nvlist_array(nvhis, ZPOOL_HIST_RECORD,
&records, &numrecords) == 0);
for (i = 0; i < numrecords; i++) {
if (nvlist_lookup_uint64(records[i], ZPOOL_HIST_TIME,
&dst_time) != 0)
continue;
/* is it an internal event or a standard event? */
if (nvlist_lookup_string(records[i], ZPOOL_HIST_CMD,
&cmdstr) != 0) {
if (cb->internal == 0)
continue;
if (nvlist_lookup_uint64(records[i],
ZPOOL_HIST_INT_EVENT, &ievent) != 0)
continue;
verify(nvlist_lookup_uint64(records[i],
ZPOOL_HIST_TXG, &txg) == 0);
verify(nvlist_lookup_string(records[i],
ZPOOL_HIST_INT_STR, &pathstr) == 0);
if (ievent > LOG_END)
continue;
(void) snprintf(internalstr,
sizeof (internalstr),
"[internal %s txg:%lld] %s",
hist_event_table[ievent], txg,
pathstr);
cmdstr = internalstr;
}
tsec = dst_time;
(void) localtime_r(&tsec, &t);
(void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t);
(void) printf("%s %s", tbuf, cmdstr);
if (!cb->longfmt) {
(void) printf("\n");
continue;
}
(void) printf(" [");
if (nvlist_lookup_uint64(records[i],
ZPOOL_HIST_WHO, &who) == 0) {
pwd = getpwuid((uid_t)who);
if (pwd)
(void) printf("user %s on",
pwd->pw_name);
else
(void) printf("user %d on",
(int)who);
} else {
(void) printf(gettext("no info]\n"));
continue;
}
if (nvlist_lookup_string(records[i],
ZPOOL_HIST_HOST, &hostname) == 0) {
(void) printf(" %s", hostname);
}
if (nvlist_lookup_string(records[i],
ZPOOL_HIST_ZONE, &zonename) == 0) {
(void) printf(":%s", zonename);
}
(void) printf("]");
(void) printf("\n");
}
(void) printf("\n");
nvlist_free(nvhis);
return (ret);
}
/*
* zpool history <pool>
*
* Displays the history of commands that modified pools.
*/
int
zpool_do_history(int argc, char **argv)
{
hist_cbdata_t cbdata = { 0 };
int ret;
int c;
cbdata.first = B_TRUE;
/* check options */
while ((c = getopt(argc, argv, "li")) != -1) {
switch (c) {
case 'l':
cbdata.longfmt = 1;
break;
case 'i':
cbdata.internal = 1;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
usage(B_FALSE);
}
}
argc -= optind;
argv += optind;
ret = for_each_pool(argc, argv, B_FALSE, NULL, get_history_one,
&cbdata);
if (argc == 0 && cbdata.first == B_TRUE) {
(void) printf(gettext("no pools available\n"));
return (0);
}
return (ret);
}
static int
get_callback(zpool_handle_t *zhp, void *data)
{
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
char value[MAXNAMELEN];
zprop_source_t srctype;
zprop_list_t *pl;
for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
/*
* Skip the special fake placeholder. This will also skip
* over the name property when 'all' is specified.
*/
if (pl->pl_prop == ZPOOL_PROP_NAME &&
pl == cbp->cb_proplist)
continue;
if (zpool_get_prop(zhp, pl->pl_prop,
value, sizeof (value), &srctype) != 0)
continue;
zprop_print_one_property(zpool_get_name(zhp), cbp,
zpool_prop_to_name(pl->pl_prop), value, srctype, NULL);
}
return (0);
}
int
zpool_do_get(int argc, char **argv)
{
zprop_get_cbdata_t cb = { 0 };
zprop_list_t fake_name = { 0 };
int ret;
if (argc < 3)
usage(B_FALSE);
cb.cb_first = B_TRUE;
cb.cb_sources = ZPROP_SRC_ALL;
cb.cb_columns[0] = GET_COL_NAME;
cb.cb_columns[1] = GET_COL_PROPERTY;
cb.cb_columns[2] = GET_COL_VALUE;
cb.cb_columns[3] = GET_COL_SOURCE;
cb.cb_type = ZFS_TYPE_POOL;
if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
ZFS_TYPE_POOL) != 0)
usage(B_FALSE);
if (cb.cb_proplist != NULL) {
fake_name.pl_prop = ZPOOL_PROP_NAME;
fake_name.pl_width = strlen(gettext("NAME"));
fake_name.pl_next = cb.cb_proplist;
cb.cb_proplist = &fake_name;
}
ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
get_callback, &cb);
if (cb.cb_proplist == &fake_name)
zprop_free_list(fake_name.pl_next);
else
zprop_free_list(cb.cb_proplist);
return (ret);
}
typedef struct set_cbdata {
char *cb_propname;
char *cb_value;
boolean_t cb_any_successful;
} set_cbdata_t;
int
set_callback(zpool_handle_t *zhp, void *data)
{
int error;
set_cbdata_t *cb = (set_cbdata_t *)data;
error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
if (!error)
cb->cb_any_successful = B_TRUE;
return (error);
}
int
zpool_do_set(int argc, char **argv)
{
set_cbdata_t cb = { 0 };
int error;
if (argc > 1 && argv[1][0] == '-') {
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
argv[1][1]);
usage(B_FALSE);
}
if (argc < 2) {
(void) fprintf(stderr, gettext("missing property=value "
"argument\n"));
usage(B_FALSE);
}
if (argc < 3) {
(void) fprintf(stderr, gettext("missing pool name\n"));
usage(B_FALSE);
}
if (argc > 3) {
(void) fprintf(stderr, gettext("too many pool names\n"));
usage(B_FALSE);
}
cb.cb_propname = argv[1];
cb.cb_value = strchr(cb.cb_propname, '=');
if (cb.cb_value == NULL) {
(void) fprintf(stderr, gettext("missing value in "
"property=value argument\n"));
usage(B_FALSE);
}
*(cb.cb_value) = '\0';
cb.cb_value++;
error = for_each_pool(argc - 2, argv + 2, B_TRUE, NULL,
set_callback, &cb);
return (error);
}
static int
find_command_idx(char *command, int *idx)
{
int i;
for (i = 0; i < NCOMMAND; i++) {
if (command_table[i].name == NULL)
continue;
if (strcmp(command, command_table[i].name) == 0) {
*idx = i;
return (0);
}
}
return (1);
}
int
main(int argc, char **argv)
{
int ret;
int i;
char *cmdname;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
if ((g_zfs = libzfs_init()) == NULL) {
(void) fprintf(stderr, gettext("internal error: failed to "
"initialize ZFS library\n"));
return (1);
}
libzfs_print_on_error(g_zfs, B_TRUE);
opterr = 0;
/*
* Make sure the user has specified some command.
*/
if (argc < 2) {
(void) fprintf(stderr, gettext("missing command\n"));
usage(B_FALSE);
}
cmdname = argv[1];
/*
* Special case '-?'
*/
if (strcmp(cmdname, "-?") == 0)
usage(B_TRUE);
zpool_set_history_str("zpool", argc, argv, history_str);
verify(zpool_stage_history(g_zfs, history_str) == 0);
/*
* Run the appropriate command.
*/
if (find_command_idx(cmdname, &i) == 0) {
current_command = &command_table[i];
ret = command_table[i].func(argc - 1, argv + 1);
} else if (strchr(cmdname, '=')) {
verify(find_command_idx("set", &i) == 0);
current_command = &command_table[i];
ret = command_table[i].func(argc, argv);
} else if (strcmp(cmdname, "freeze") == 0 && argc == 3) {
/*
* 'freeze' is a vile debugging abomination, so we treat
* it as such.
*/
char buf[16384];
int fd = open(ZFS_DEV, O_RDWR);
(void) strcpy((void *)buf, argv[2]);
return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
} else {
(void) fprintf(stderr, gettext("unrecognized "
"command '%s'\n"), cmdname);
usage(B_FALSE);
}
libzfs_fini(g_zfs);
/*
* The 'ZFS_ABORT' environment variable causes us to dump core on exit
* for the purposes of running ::findleaks.
*/
if (getenv("ZFS_ABORT") != NULL) {
(void) printf("dumping core by request\n");
abort();
}
return (ret);
}