fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * Common Development and Distribution License (the "License").
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
9a686fbc186e8e2a64e9a5094d44c7d6fa0ea167Paul Dagnelie * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * Copyright (c) 2013, Joyent, Inc. All rights reserved.
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews * Copyright 2016 Nexenta Systems, Inc.
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <ctype.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <devid.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <fcntl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <libintl.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdio.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdlib.h>
f3861e1a2ceec23a5b699c24d814b7775a9e0b52ahl#include <strings.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <unistd.h>
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens#include <libgen.h>
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor#include <sys/efi_partition.h>
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor#include <sys/vtoc.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/zfs_ioctl.h>
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson#include <dlfcn.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "zfs_namecheck.h"
b1b8ab34de515a5e83206da22c3d7e563241b021lling#include "zfs_prop.h"
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "libzfs_impl.h"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley#include "zfs_comutil.h"
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden#include "zfeature_common.h"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
15e6edf145a9c2bb0e0272cf8debe823bb97529bgwstatic int read_efi_label(nvlist_t *config, diskaddr_t *sb);
990b4856d0eaada6f8140335733a1b1771ed2746lling
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson#define BACKUP_SLICE "s2"
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilsontypedef struct prop_flags {
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson int create:1; /* Validate property on creation */
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson int import:1; /* Validate property on import */
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson} prop_flags_t;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * ====================================================================
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool property functions
990b4856d0eaada6f8140335733a1b1771ed2746lling * ====================================================================
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic int
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_all_props(zpool_handle_t *zhp)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_cmd_t zc = { 0 };
990b4856d0eaada6f8140335733a1b1771ed2746lling libzfs_handle_t *hdl = zhp->zpool_hdl;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (errno == ENOMEM) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zcmd_free_nvlists(&zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling zcmd_free_nvlists(&zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zcmd_free_nvlists(&zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling zcmd_free_nvlists(&zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic int
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_props_refresh(zpool_handle_t *zhp)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *old_props;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling old_props = zhp->zpool_props;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_get_all_props(zhp) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(old_props);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic char *
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_source_t *src)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *nv, *nvl;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t ival;
990b4856d0eaada6f8140335733a1b1771ed2746lling char *value;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_source_t source;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling nvl = zhp->zpool_props;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling source = ival;
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling source = ZPROP_SRC_DEFAULT;
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
990b4856d0eaada6f8140335733a1b1771ed2746lling value = "-";
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (src)
990b4856d0eaada6f8140335733a1b1771ed2746lling *src = source;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (value);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746llinguint64_t
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *nv, *nvl;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t value;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_source_t source;
990b4856d0eaada6f8140335733a1b1771ed2746lling
b87f3af36bb994656da117319f5129ddfd05ed21perrin if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
b87f3af36bb994656da117319f5129ddfd05ed21perrin /*
b87f3af36bb994656da117319f5129ddfd05ed21perrin * zpool_get_all_props() has most likely failed because
b87f3af36bb994656da117319f5129ddfd05ed21perrin * the pool is faulted, but if all we need is the top level
b87f3af36bb994656da117319f5129ddfd05ed21perrin * vdev's guid then get it from the zhp config nvlist.
b87f3af36bb994656da117319f5129ddfd05ed21perrin */
b87f3af36bb994656da117319f5129ddfd05ed21perrin if ((prop == ZPOOL_PROP_GUID) &&
b87f3af36bb994656da117319f5129ddfd05ed21perrin (nvlist_lookup_nvlist(zhp->zpool_config,
b87f3af36bb994656da117319f5129ddfd05ed21perrin ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
b87f3af36bb994656da117319f5129ddfd05ed21perrin (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
b87f3af36bb994656da117319f5129ddfd05ed21perrin == 0)) {
b87f3af36bb994656da117319f5129ddfd05ed21perrin return (value);
b87f3af36bb994656da117319f5129ddfd05ed21perrin }
990b4856d0eaada6f8140335733a1b1771ed2746lling return (zpool_prop_default_numeric(prop));
b87f3af36bb994656da117319f5129ddfd05ed21perrin }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling nvl = zhp->zpool_props;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling source = value;
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling } else {
990b4856d0eaada6f8140335733a1b1771ed2746lling source = ZPROP_SRC_DEFAULT;
990b4856d0eaada6f8140335733a1b1771ed2746lling value = zpool_prop_default_numeric(prop);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (src)
990b4856d0eaada6f8140335733a1b1771ed2746lling *src = source;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (value);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Map VDEV STATE to printed strings.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrewsconst char *
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling switch (state) {
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_CLOSED:
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_OFFLINE:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("OFFLINE"));
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_REMOVED:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("REMOVED"));
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_CANT_OPEN:
b87f3af36bb994656da117319f5129ddfd05ed21perrin if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("FAULTED"));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante else if (aux == VDEV_AUX_SPLIT_POOL)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (gettext("SPLIT"));
990b4856d0eaada6f8140335733a1b1771ed2746lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("UNAVAIL"));
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_FAULTED:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("FAULTED"));
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_DEGRADED:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("DEGRADED"));
990b4856d0eaada6f8140335733a1b1771ed2746lling case VDEV_STATE_HEALTHY:
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("ONLINE"));
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov default:
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov break;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (gettext("UNKNOWN"));
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews/*
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews * Map POOL STATE to printed strings.
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews */
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrewsconst char *
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrewszpool_pool_state_to_name(pool_state_t state)
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews{
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews switch (state) {
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_ACTIVE:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("ACTIVE"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_EXPORTED:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("EXPORTED"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_DESTROYED:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("DESTROYED"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_SPARE:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("SPARE"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_L2CACHE:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("L2CACHE"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_UNINITIALIZED:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("UNINITIALIZED"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_UNAVAIL:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("UNAVAIL"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews case POOL_STATE_POTENTIALLY_ACTIVE:
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("POTENTIALLY_ACTIVE"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews }
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews return (gettext("UNKNOWN"));
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews}
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Get a zpool property value for 'prop' and return the value in
990b4856d0eaada6f8140335733a1b1771ed2746lling * a pre-allocated buffer.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingint
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko zprop_source_t *srctype, boolean_t literal)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t intval;
990b4856d0eaada6f8140335733a1b1771ed2746lling const char *strval;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_source_t src = ZPROP_SRC_NONE;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *nvroot;
990b4856d0eaada6f8140335733a1b1771ed2746lling vdev_stat_t *vs;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint_t vsc;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock switch (prop) {
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock case ZPOOL_PROP_NAME:
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, zpool_get_name(zhp), len);
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock break;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock case ZPOOL_PROP_HEALTH:
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, "FAULTED", len);
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock break;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock case ZPOOL_PROP_GUID:
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock intval = zpool_get_prop_int(zhp, prop, &src);
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock (void) snprintf(buf, len, "%llu", intval);
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock break;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock case ZPOOL_PROP_ALTROOT:
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock case ZPOOL_PROP_CACHEFILE:
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald case ZPOOL_PROP_COMMENT:
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock if (zhp->zpool_props != NULL ||
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock zpool_get_all_props(zhp) == 0) {
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock (void) strlcpy(buf,
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock zpool_get_prop_string(zhp, prop, &src),
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock len);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko break;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock }
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock /* FALLTHROUGH */
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock default:
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, "-", len);
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock break;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock }
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock if (srctype != NULL)
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock *srctype = src;
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
990b4856d0eaada6f8140335733a1b1771ed2746lling prop != ZPOOL_PROP_NAME)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling switch (zpool_prop_get_type(prop)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling case PROP_TYPE_STRING:
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
990b4856d0eaada6f8140335733a1b1771ed2746lling len);
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling case PROP_TYPE_NUMBER:
990b4856d0eaada6f8140335733a1b1771ed2746lling intval = zpool_get_prop_int(zhp, prop, &src);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling switch (prop) {
990b4856d0eaada6f8140335733a1b1771ed2746lling case ZPOOL_PROP_SIZE:
485bbbf5450c6645352388d798251c1a89ef4c9cGeorge Wilson case ZPOOL_PROP_ALLOCATED:
485bbbf5450c6645352388d798251c1a89ef4c9cGeorge Wilson case ZPOOL_PROP_FREE:
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden case ZPOOL_PROP_FREEING:
7fd05ac4dec0c343d2f68f310d3718b715ecfbafMatthew Ahrens case ZPOOL_PROP_LEAKED:
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko if (literal) {
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (void) snprintf(buf, len, "%llu",
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (u_longlong_t)intval);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko } else {
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (void) zfs_nicenum(intval, buf, len);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko }
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson case ZPOOL_PROP_EXPANDSZ:
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson if (intval == 0) {
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson (void) strlcpy(buf, "-", len);
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson } else if (literal) {
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson (void) snprintf(buf, len, "%llu",
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson (u_longlong_t)intval);
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson } else {
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson (void) zfs_nicenum(intval, buf, len);
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson }
7a09f97bc0d52b763c580864e78a665b15be37f8George Wilson break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case ZPOOL_PROP_CAPACITY:
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko if (literal) {
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (void) snprintf(buf, len, "%llu",
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (u_longlong_t)intval);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko } else {
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (void) snprintf(buf, len, "%llu%%",
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko (u_longlong_t)intval);
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko }
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson case ZPOOL_PROP_FRAGMENTATION:
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson if (intval == UINT64_MAX) {
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson (void) strlcpy(buf, "-", len);
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson } else {
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson (void) snprintf(buf, len, "%llu%%",
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson (u_longlong_t)intval);
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson }
2e4c998613148111f2fc5371085331ffb39122ffGeorge Wilson break;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick case ZPOOL_PROP_DEDUPRATIO:
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) snprintf(buf, len, "%llu.%02llux",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (u_longlong_t)(intval / 100),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (u_longlong_t)(intval % 100));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick break;
990b4856d0eaada6f8140335733a1b1771ed2746lling case ZPOOL_PROP_HEALTH:
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
990b4856d0eaada6f8140335733a1b1771ed2746lling ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64_array(nvroot,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, zpool_state_to_name(intval,
990b4856d0eaada6f8140335733a1b1771ed2746lling vs->vs_aux), len);
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden case ZPOOL_PROP_VERSION:
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (intval >= SPA_VERSION_FEATURES) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) snprintf(buf, len, "-");
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden break;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /* FALLTHROUGH */
990b4856d0eaada6f8140335733a1b1771ed2746lling default:
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) snprintf(buf, len, "%llu", intval);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling case PROP_TYPE_INDEX:
990b4856d0eaada6f8140335733a1b1771ed2746lling intval = zpool_get_prop_int(zhp, prop, &src);
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_prop_index_to_string(prop, intval, &strval)
990b4856d0eaada6f8140335733a1b1771ed2746lling != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, strval, len);
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling default:
990b4856d0eaada6f8140335733a1b1771ed2746lling abort();
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (srctype)
990b4856d0eaada6f8140335733a1b1771ed2746lling *srctype = src;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Check if the bootfs name has the same pool name as it is set to.
990b4856d0eaada6f8140335733a1b1771ed2746lling * Assuming bootfs is a valid dataset name.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic boolean_t
990b4856d0eaada6f8140335733a1b1771ed2746llingbootfs_name_valid(const char *pool, char *bootfs)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling int len = strlen(pool);
990b4856d0eaada6f8140335733a1b1771ed2746lling
fe3e2633be44d2f5361a7bba26abeb80fcc04fbcEric Taylor if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
990b4856d0eaada6f8140335733a1b1771ed2746lling return (B_FALSE);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (strncmp(pool, bootfs, len) == 0 &&
990b4856d0eaada6f8140335733a1b1771ed2746lling (bootfs[len] == '/' || bootfs[len] == '\0'))
990b4856d0eaada6f8140335733a1b1771ed2746lling return (B_TRUE);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (B_FALSE);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
4263d13f00c9691fa14620eff82abef795be0693George Wilsonboolean_t
4263d13f00c9691fa14620eff82abef795be0693George Wilsonzpool_is_bootable(zpool_handle_t *zhp)
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson{
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char bootfs[ZFS_MAX_DATASET_NAME_LEN];
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-",
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson sizeof (bootfs)) != 0);
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson}
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Given an nvlist of zpool properties to be set, validate that they are
990b4856d0eaada6f8140335733a1b1771ed2746lling * correct, and parse any numeric properties (index, boolean, etc) if they are
990b4856d0eaada6f8140335733a1b1771ed2746lling * specified as strings.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic nvlist_t *
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhzpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling nvpair_t *elem;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *retprops;
990b4856d0eaada6f8140335733a1b1771ed2746lling zpool_prop_t prop;
990b4856d0eaada6f8140335733a1b1771ed2746lling char *strval;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t intval;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald char *slash, *check;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock struct stat64 statbuf;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw zpool_handle_t *zhp;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) no_memory(hdl);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (NULL);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling elem = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling const char *propname = nvpair_name(elem);
990b4856d0eaada6f8140335733a1b1771ed2746lling
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden prop = zpool_name_to_prop(propname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden int err;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden char *fname = strchr(propname, '@') + 1;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens err = zfeature_lookup_name(fname, NULL);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (err != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ASSERT3U(err, ==, ENOENT);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "invalid feature '%s'"), fname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto error;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nvpair_type(elem) != DATA_TYPE_STRING) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "'%s' must be a string"), propname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto error;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) nvpair_value_string(elem, &strval);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "property '%s' can only be set to "
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "'enabled'"), propname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto error;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nvlist_add_uint64(retprops, propname, 0) != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) no_memory(hdl);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden goto error;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden continue;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Make sure this property is valid and applies to this type.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (prop == ZPROP_INVAL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "invalid property '%s'"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zpool_prop_readonly(prop)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
990b4856d0eaada6f8140335733a1b1771ed2746lling "is readonly"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
990b4856d0eaada6f8140335733a1b1771ed2746lling &strval, &intval, errbuf) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Perform additional checking for specific properties.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling switch (prop) {
990b4856d0eaada6f8140335733a1b1771ed2746lling case ZPOOL_PROP_VERSION:
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (intval < version ||
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden !SPA_VERSION_IS_SUPPORTED(intval)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' number %d is invalid."),
990b4856d0eaada6f8140335733a1b1771ed2746lling propname, intval);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling case ZPOOL_PROP_BOOTFS:
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson if (flags.create || flags.import) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' cannot be set at creation "
990b4856d0eaada6f8140335733a1b1771ed2746lling "or import time"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (version < SPA_VERSION_BOOTFS) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "pool must be upgraded to support "
990b4856d0eaada6f8140335733a1b1771ed2746lling "'%s' property"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * bootfs property value has to be a dataset name and
990b4856d0eaada6f8140335733a1b1771ed2746lling * the dataset has to be in the same pool as it sets to.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (strval[0] != '\0' && !bootfs_name_valid(poolname,
990b4856d0eaada6f8140335733a1b1771ed2746lling strval)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
990b4856d0eaada6f8140335733a1b1771ed2746lling "is an invalid name"), strval);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw "could not open pool '%s'"), poolname);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw goto error;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw }
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw zpool_close(zhp);
990b4856d0eaada6f8140335733a1b1771ed2746lling break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock case ZPOOL_PROP_ALTROOT:
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson if (!flags.create && !flags.import) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' can only be set during pool "
990b4856d0eaada6f8140335733a1b1771ed2746lling "creation or import"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (strval[0] != '/') {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "bad alternate root '%s'"), strval);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock case ZPOOL_PROP_CACHEFILE:
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (strval[0] == '\0')
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (strcmp(strval, "none") == 0)
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (strval[0] != '/') {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "property '%s' must be empty, an "
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "absolute path, or 'none'"), propname);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling goto error;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock slash = strrchr(strval, '/');
990b4856d0eaada6f8140335733a1b1771ed2746lling
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock strcmp(slash, "/..") == 0) {
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "'%s' is not a valid file"), strval);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock goto error;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock }
990b4856d0eaada6f8140335733a1b1771ed2746lling
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock *slash = '\0';
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock
2c32020f848d8e5619a1f441a92f0ee4aca1b297eschrock if (strval[0] != '\0' &&
2c32020f848d8e5619a1f441a92f0ee4aca1b297eschrock (stat64(strval, &statbuf) != 0 ||
2c32020f848d8e5619a1f441a92f0ee4aca1b297eschrock !S_ISDIR(statbuf.st_mode))) {
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "'%s' is not a valid directory"),
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock strval);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock goto error;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock }
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock *slash = '/';
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock break;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald case ZPOOL_PROP_COMMENT:
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald for (check = strval; *check != '\0'; check++) {
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald if (!isprint(*check)) {
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald zfs_error_aux(hdl,
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald dgettext(TEXT_DOMAIN,
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald "comment may only have printable "
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald "characters"));
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald (void) zfs_error(hdl, EZFS_BADPROP,
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald errbuf);
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald goto error;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald }
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald }
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald if (strlen(strval) > ZPROP_MAX_COMMENT) {
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald "comment must not exceed %d characters"),
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald ZPROP_MAX_COMMENT);
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald goto error;
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald }
8704186e373c9ed74daa395ff3f7fd745396df9eDan McDonald break;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson case ZPOOL_PROP_READONLY:
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson if (!flags.import) {
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson "property '%s' can only be set at "
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson "import time"), propname);
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson goto error;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson }
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson break;
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov default:
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov "property '%s'(%d) not defined"), propname, prop);
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov break;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (retprops);
990b4856d0eaada6f8140335733a1b1771ed2746llingerror:
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(retprops);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (NULL);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Set zpool property : propname=propval.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingint
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_cmd_t zc = { 0 };
990b4856d0eaada6f8140335733a1b1771ed2746lling int ret = -1;
990b4856d0eaada6f8140335733a1b1771ed2746lling char errbuf[1024];
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *nvl = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *realprops;
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t version;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson prop_flags_t flags = { 0 };
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) snprintf(errbuf, sizeof (errbuf),
990b4856d0eaada6f8140335733a1b1771ed2746lling dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
990b4856d0eaada6f8140335733a1b1771ed2746lling zhp->zpool_name);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (no_memory(zhp->zpool_hdl));
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_add_string(nvl, propname, propval) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(nvl);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (no_memory(zhp->zpool_hdl));
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(nvl);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(nvl);
990b4856d0eaada6f8140335733a1b1771ed2746lling nvl = realprops;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Execute the corresponding ioctl() to set this property.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(nvl);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling zcmd_free_nvlists(&zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(nvl);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (ret)
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746lling else
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zpool_props_refresh(zhp);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (ret);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746llingint
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling libzfs_handle_t *hdl = zhp->zpool_hdl;
990b4856d0eaada6f8140335733a1b1771ed2746lling zprop_list_t *entry;
990b4856d0eaada6f8140335733a1b1771ed2746lling char buf[ZFS_MAXPROPLEN];
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_t *features = NULL;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zprop_list_t **last;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden boolean_t firstexpand = (NULL == *plp);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden last = plp;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden while (*last != NULL)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden last = &(*last)->pl_next;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if ((*plp)->pl_all)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden features = zpool_get_features(zhp);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if ((*plp)->pl_all && firstexpand) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden for (int i = 0; i < SPA_FEATURES; i++) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zprop_list_t *entry = zfs_alloc(hdl,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden sizeof (zprop_list_t));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_prop = ZPROP_INVAL;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden spa_feature_table[i].fi_uname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_width = strlen(entry->pl_user_prop);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_all = B_TRUE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden *last = entry;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden last = &entry->pl_next;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /* add any unsupported features */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden for (nvpair_t *nvp = nvlist_next_nvpair(features, NULL);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden char *propname;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden boolean_t found;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zprop_list_t *entry;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (zfeature_is_supported(nvpair_name(nvp)))
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden continue;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden propname = zfs_asprintf(hdl, "unsupported@%s",
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvpair_name(nvp));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /*
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * Before adding the property to the list make sure that no
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * other pool already added the same property.
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden found = B_FALSE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry = *plp;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden while (entry != NULL) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (entry->pl_user_prop != NULL &&
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden strcmp(propname, entry->pl_user_prop) == 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden found = B_TRUE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden break;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry = entry->pl_next;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (found) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden free(propname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden continue;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry = zfs_alloc(hdl, sizeof (zprop_list_t));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_prop = ZPROP_INVAL;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_user_prop = propname;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_width = strlen(entry->pl_user_prop);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden entry->pl_all = B_TRUE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden *last = entry;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden last = &entry->pl_next;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
990b4856d0eaada6f8140335733a1b1771ed2746lling for (entry = *plp; entry != NULL; entry = entry->pl_next) {
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (entry->pl_fixed)
990b4856d0eaada6f8140335733a1b1771ed2746lling continue;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (entry->pl_prop != ZPROP_INVAL &&
990b4856d0eaada6f8140335733a1b1771ed2746lling zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
c58b352673e88983cd2b8a388a8c7625f35e2f18Adam Stevko NULL, B_FALSE) == 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (strlen(buf) > entry->pl_width)
990b4856d0eaada6f8140335733a1b1771ed2746lling entry->pl_width = strlen(buf);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden/*
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * Get the state for the given feature on the given ZFS pool.
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenint
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenzpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden size_t len)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden{
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden uint64_t refcount;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden boolean_t found = B_FALSE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_t *features = zpool_get_features(zhp);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden boolean_t supported;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden const char *feature = strchr(propname, '@') + 1;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden supported = zpool_prop_feature(propname);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ASSERT(supported || zfs_prop_unsupported(propname));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden /*
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * Convert from feature name to feature guid. This conversion is
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * unecessary for unsupported@... properties because they already
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden * use guids.
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden */
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (supported) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden int ret;
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens spa_feature_t fid;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens ret = zfeature_lookup_name(feature, &fid);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (ret != 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strlcpy(buf, "-", len);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden return (ENOTSUP);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
2acef22db7808606888f8f92715629ff3ba555b9Matthew Ahrens feature = spa_feature_table[fid].fi_guid;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden found = B_TRUE;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (supported) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (!found) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (refcount == 0)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden else
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (found) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (refcount == 0) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden } else {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) strlcpy(buf, "-", len);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden return (ENOTSUP);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden return (0);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden}
990b4856d0eaada6f8140335733a1b1771ed2746lling
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson/*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Don't start the slice at the default block of 34; many storage
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * devices will use a stripe width of 128k, so start there instead.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson#define NEW_START_BLOCK 256
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Validate the given pool name, optionally putting an extended error message in
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 'buf'.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwboolean_t
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens namecheck_err_t why;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char what;
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock int ret;
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock ret = pool_namecheck(pool, &why, &what);
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock /*
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock * The rules for reserved pool names were extended at a later point.
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock * But we need to support users with existing pools that may now be
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock * invalid. So we only check for this expanded set of names during a
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock * create (or import), and only in userland.
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock */
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock if (ret == 0 && !isopen &&
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock (strncmp(pool, "mirror", 6) == 0 ||
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock strncmp(pool, "raidz", 5) == 0 ||
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin strncmp(pool, "spare", 5) == 0 ||
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin strcmp(pool, "log") == 0)) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (hdl != NULL)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dgettext(TEXT_DOMAIN, "name is reserved"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_FALSE);
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock }
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b468a217b67dc26ce21da5d5a2ca09bb6249e4faeschrock if (ret != 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (hdl != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (why) {
b81d61a68b235e0529ebadc18e14d9d1dd52a258lling case NAME_ERR_TOOLONG:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl,
b81d61a68b235e0529ebadc18e14d9d1dd52a258lling dgettext(TEXT_DOMAIN, "name is too long"));
b81d61a68b235e0529ebadc18e14d9d1dd52a258lling break;
b81d61a68b235e0529ebadc18e14d9d1dd52a258lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens case NAME_ERR_INVALCHAR:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl,
fa9e4066f08beec538e775443c5be79dd423fcabahrens dgettext(TEXT_DOMAIN, "invalid character "
fa9e4066f08beec538e775443c5be79dd423fcabahrens "'%c' in pool name"), what);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case NAME_ERR_NOLETTER:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "name must begin with a letter"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case NAME_ERR_RESERVED:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "name is reserved"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case NAME_ERR_DISKLIKE:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "pool name is reserved"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
5ad820458efd0fdb914baff9c1447c22b819fa23nd
5ad820458efd0fdb914baff9c1447c22b819fa23nd case NAME_ERR_LEADING_SLASH:
5ad820458efd0fdb914baff9c1447c22b819fa23nd zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5ad820458efd0fdb914baff9c1447c22b819fa23nd "leading slash in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd break;
5ad820458efd0fdb914baff9c1447c22b819fa23nd
5ad820458efd0fdb914baff9c1447c22b819fa23nd case NAME_ERR_EMPTY_COMPONENT:
5ad820458efd0fdb914baff9c1447c22b819fa23nd zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5ad820458efd0fdb914baff9c1447c22b819fa23nd "empty component in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd break;
5ad820458efd0fdb914baff9c1447c22b819fa23nd
5ad820458efd0fdb914baff9c1447c22b819fa23nd case NAME_ERR_TRAILING_SLASH:
5ad820458efd0fdb914baff9c1447c22b819fa23nd zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5ad820458efd0fdb914baff9c1447c22b819fa23nd "trailing slash in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd break;
5ad820458efd0fdb914baff9c1447c22b819fa23nd
edb901aab9c738b5eb15aa55933e82b0f2f9d9a2Marcel Telka case NAME_ERR_MULTIPLE_DELIMITERS:
5ad820458efd0fdb914baff9c1447c22b819fa23nd zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
edb901aab9c738b5eb15aa55933e82b0f2f9d9a2Marcel Telka "multiple '@' and/or '#' delimiters in "
edb901aab9c738b5eb15aa55933e82b0f2f9d9a2Marcel Telka "name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd break;
5ad820458efd0fdb914baff9c1447c22b819fa23nd
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov default:
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov "(%d) not defined"), why);
88f61dee20b358671b1b643e9d1dbf220a1d69beIgor Kozhukhov break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_TRUE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Open a handle to the given pool, even if the pool is currently in the FAULTED
fa9e4066f08beec538e775443c5be79dd423fcabahrens * state.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_handle_t *
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock boolean_t missing;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure the pool name is valid.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (!zpool_name_valid(hdl, B_TRUE, pool)) {
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot open '%s'"),
99653d4ee642c6528e88224f12409a5f23060994eschrock pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zhp->zpool_hdl = hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (zpool_refresh_stats(zhp, &missing) != 0) {
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock zpool_close(zhp);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (NULL);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock }
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (missing) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling (void) zfs_error_fmt(hdl, EZFS_NOENT,
990b4856d0eaada6f8140335733a1b1771ed2746lling dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock zpool_close(zhp);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Like the above, but silent on error. Used when iterating over pools (because
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the configuration cache may be out of date).
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrockint
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrockzpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock boolean_t missing;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zhp->zpool_hdl = hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (zpool_refresh_stats(zhp, &missing) != 0) {
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock zpool_close(zhp);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if (missing) {
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock zpool_close(zhp);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock *ret = NULL;
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (0);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock }
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock *ret = zhp;
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
fa9e4066f08beec538e775443c5be79dd423fcabahrens * state.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_handle_t *
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_open(libzfs_handle_t *hdl, const char *pool)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Close the handle. Simply frees the memory associated with the handle.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_close(zpool_handle_t *zhp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(zhp->zpool_config);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(zhp->zpool_old_config);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(zhp->zpool_props);
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return the name of the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_get_name(zpool_handle_t *zhp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zhp->zpool_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return the state of the pool (ACTIVE or UNAVAILABLE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_get_state(zpool_handle_t *zhp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zhp->zpool_state);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create the named pool, using the provided vdev list. It is assumed
fa9e4066f08beec538e775443c5be79dd423fcabahrens * that the consumer has already validated the contents of the nvlist, so we
fa9e4066f08beec538e775443c5be79dd423fcabahrens * don't have to worry about error semantics.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_t *props, nvlist_t *fsprops)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_t *zc_fsprops = NULL;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_t *zc_props = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock char msg[1024];
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh int ret = -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "cannot create '%s'"), pool);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (!zpool_name_valid(hdl, B_FALSE, pool))
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (props) {
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((zc_props = zpool_valid_proplist(hdl, pool, props,
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson SPA_VERSION_1, flags, msg)) == NULL) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto create_failed;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
99653d4ee642c6528e88224f12409a5f23060994eschrock
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (fsprops) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh uint64_t zoned;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh char *zonestr;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh zoned = ((nvlist_lookup_string(fsprops,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh strcmp(zonestr, "on") == 0);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein fsprops, zoned, NULL, NULL, msg)) == NULL) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto create_failed;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (!zc_props &&
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto create_failed;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (nvlist_add_nvlist(zc_props,
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto create_failed;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh }
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh goto create_failed;
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zcmd_free_nvlists(&zc);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_free(zc_props);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_free(zc_fsprops);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock switch (errno) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EBUSY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This can happen if the user has specified the same
fa9e4066f08beec538e775443c5be79dd423fcabahrens * device multiple times. We can't reliably detect this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * until we try to add it and see we already have a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * label.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more vdevs refer to the same device"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_BADDEV, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein case ERANGE:
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein /*
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * This happens if the record size is smaller or larger
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * than the allowed size range, or not a power of 2.
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein *
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * NOTE: although zfs_valid_proplist is called earlier,
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * this case may have slipped through since the
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * pool does not exist yet and it is therefore
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * impossible to read properties e.g. max blocksize
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein * from the pool.
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein */
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein "record size invalid"));
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein return (zfs_error(hdl, EZFS_BADPROP, msg));
e9316f7696401f3e5e263a5939031cb8d5641a88Joe Stein
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EOVERFLOW:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * This occurs when one of the devices is below
fa9e4066f08beec538e775443c5be79dd423fcabahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which
fa9e4066f08beec538e775443c5be79dd423fcabahrens * device was the problem device since there's no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * reliable way to determine device size from userland.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char buf[64];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is less than the "
99653d4ee642c6528e88224f12409a5f23060994eschrock "minimum size (%s)"), buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_BADDEV, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case ENOSPC:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is out of space"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_BADDEV, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan case ENOTBLK:
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "cache device must be a disk or disk slice"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (zfs_error(hdl, EZFS_BADDEV, msg));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zpool_standard_error(hdl, errno, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhcreate_failed:
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling zcmd_free_nvlists(&zc);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_free(zc_props);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh nvlist_free(zc_fsprops);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Destroy the given pool. It is up to the caller to ensure that there are no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * datasets left in the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszpool_destroy(zpool_handle_t *zhp, const char *log_str)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_handle_t *zfp = NULL;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
99653d4ee642c6528e88224f12409a5f23060994eschrock char msg[1024];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zhp->zpool_state == POOL_STATE_ACTIVE &&
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens zc.zc_history = (uint64_t)(uintptr_t)log_str;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "cannot destroy '%s'"), zhp->zpool_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (errno == EROFS) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is read only"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
99653d4ee642c6528e88224f12409a5f23060994eschrock } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zpool_standard_error(hdl, errno, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zfp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_close(zfp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zfp) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens remove_mountpoint(zfp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_close(zfp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add the given vdevs to the pool. The caller must have already performed the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * necessary verification to ensure that the vdev specification is well-formed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zfs_cmd_t zc = { 0 };
99653d4ee642c6528e88224f12409a5f23060994eschrock int ret;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
99653d4ee642c6528e88224f12409a5f23060994eschrock char msg[1024];
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan nvlist_t **spares, **l2cache;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan uint_t nspares, nl2cache;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "cannot add to '%s'"), zhp->zpool_name);
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan SPA_VERSION_SPARES &&
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock &spares, &nspares) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
99653d4ee642c6528e88224f12409a5f23060994eschrock "upgraded to add hot spares"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_BADVERSION, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan SPA_VERSION_L2CACHE &&
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &l2cache, &nl2cache) == 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "upgraded to add cache devices"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (zfs_error(hdl, EZFS_BADVERSION, msg));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (errno) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EBUSY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This can happen if the user has specified the same
fa9e4066f08beec538e775443c5be79dd423fcabahrens * device multiple times. We can't reliably detect this
fa9e4066f08beec538e775443c5be79dd423fcabahrens * until we try to add it and see we already have a
fa9e4066f08beec538e775443c5be79dd423fcabahrens * label.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more vdevs refer to the same device"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case EOVERFLOW:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This occurrs when one of the devices is below
fa9e4066f08beec538e775443c5be79dd423fcabahrens * SPA_MINDEVSIZE. Unfortunately, we can't detect which
fa9e4066f08beec538e775443c5be79dd423fcabahrens * device was the problem device since there's no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * reliable way to determine device size from userland.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char buf[64];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "device is less than the minimum "
99653d4ee642c6528e88224f12409a5f23060994eschrock "size (%s)"), buf);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
99653d4ee642c6528e88224f12409a5f23060994eschrock break;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock case ENOTSUP:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "pool must be upgraded to add these vdevs"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADVERSION, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b1b8ab34de515a5e83206da22c3d7e563241b021lling case EDOM:
b1b8ab34de515a5e83206da22c3d7e563241b021lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "root pool can not have multiple vdevs"
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin " or separate logs"));
b1b8ab34de515a5e83206da22c3d7e563241b021lling (void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
b1b8ab34de515a5e83206da22c3d7e563241b021lling break;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan case ENOTBLK:
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "cache device must be a disk or disk slice"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan (void) zfs_error(hdl, EZFS_BADDEV, msg);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan break;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zpool_standard_error(hdl, errno, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = -1;
99653d4ee642c6528e88224f12409a5f23060994eschrock } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock ret = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zcmd_free_nvlists(&zc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Exports the pool from the system. The caller must ensure that there are no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * mounted datasets in the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrensstatic int
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens const char *log_str)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
89a89ebfd7c3b4056afe2c03e959e22824df777dlling char msg[1024];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
89a89ebfd7c3b4056afe2c03e959e22824df777dlling (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
89a89ebfd7c3b4056afe2c03e959e22824df777dlling "cannot export '%s'"), zhp->zpool_name);
89a89ebfd7c3b4056afe2c03e959e22824df777dlling
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
89a89ebfd7c3b4056afe2c03e959e22824df777dlling zc.zc_cookie = force;
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson zc.zc_guid = hardforce;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens zc.zc_history = (uint64_t)(uintptr_t)log_str;
89a89ebfd7c3b4056afe2c03e959e22824df777dlling
89a89ebfd7c3b4056afe2c03e959e22824df777dlling if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
89a89ebfd7c3b4056afe2c03e959e22824df777dlling switch (errno) {
89a89ebfd7c3b4056afe2c03e959e22824df777dlling case EXDEV:
89a89ebfd7c3b4056afe2c03e959e22824df777dlling zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
89a89ebfd7c3b4056afe2c03e959e22824df777dlling "use '-f' to override the following errors:\n"
89a89ebfd7c3b4056afe2c03e959e22824df777dlling "'%s' has an active shared spare which could be"
89a89ebfd7c3b4056afe2c03e959e22824df777dlling " used by other pools once '%s' is exported."),
89a89ebfd7c3b4056afe2c03e959e22824df777dlling zhp->zpool_name, zhp->zpool_name);
89a89ebfd7c3b4056afe2c03e959e22824df777dlling return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
89a89ebfd7c3b4056afe2c03e959e22824df777dlling msg));
89a89ebfd7c3b4056afe2c03e959e22824df777dlling default:
89a89ebfd7c3b4056afe2c03e959e22824df777dlling return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
89a89ebfd7c3b4056afe2c03e959e22824df777dlling msg));
89a89ebfd7c3b4056afe2c03e959e22824df777dlling }
89a89ebfd7c3b4056afe2c03e959e22824df777dlling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilsonint
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson{
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens return (zpool_export_common(zhp, force, B_FALSE, log_str));
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson}
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilsonint
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszpool_export_force(zpool_handle_t *zhp, const char *log_str)
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson{
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson}
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleystatic void
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleyzpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *config)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley{
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *nv = NULL;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley uint64_t rewindto;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley int64_t loss = -1;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley struct tm t;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley char timestr[128];
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (!hdl->libzfs_printerr || config == NULL)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson return;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (localtime_r((time_t *)&rewindto, &t) != NULL &&
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley strftime(timestr, 128, 0, &t) != 0) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (dryrun) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Would be able to return %s "
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "to its state as of %s.\n"),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley name, timestr);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley } else {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Pool %s returned to its state as of %s.\n"),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley name, timestr);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (loss > 120) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "%s approximately %lld "),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley dryrun ? "Would discard" : "Discarded",
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (loss + 30) / 60);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "minutes of transactions.\n"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley } else if (loss > 0) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "%s approximately %lld "),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley dryrun ? "Would discard" : "Discarded", loss);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "seconds of transactions.\n"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley}
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleyvoid
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleyzpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley nvlist_t *config)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley{
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *nv = NULL;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley int64_t loss = -1;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley uint64_t edata = UINT64_MAX;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley uint64_t rewindto;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley struct tm t;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley char timestr[128];
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (!hdl->libzfs_printerr)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (reason >= 0)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN, "action: "));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley else
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN, "\t"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley goto no_info;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley &edata);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Recovery is possible, but will result in some data loss.\n"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (localtime_r((time_t *)&rewindto, &t) != NULL &&
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley strftime(timestr, 128, 0, &t) != 0) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tReturning the pool to its state as of %s\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tshould correct the problem. "),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley timestr);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley } else {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tReverting the pool to an earlier state "
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "should correct the problem.\n\t"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (loss > 120) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Approximately %lld minutes of data\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tmust be discarded, irreversibly. "), (loss + 30) / 60);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley } else if (loss > 0) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Approximately %lld seconds of data\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tmust be discarded, irreversibly. "), loss);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (edata != 0 && edata != UINT64_MAX) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (edata == 1) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "After rewind, at least\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tone persistent user-data error will remain. "));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley } else {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "After rewind, several\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tpersistent user-data errors will remain. "));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
a33cae9802e94744efee12a7a77c89360645eae8Tim Haley "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
a33cae9802e94744efee12a7a77c89360645eae8Tim Haley reason >= 0 ? "clear" : "import", name);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "A scrub of the pool\n"
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "\tis strongly recommended after recovery.\n"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleyno_info:
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) printf(dgettext(TEXT_DOMAIN,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley "Destroy and re-create the pool from\n\ta backup source.\n"));
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley}
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool_import() is a contracted interface. Should be kept the same
990b4856d0eaada6f8140335733a1b1771ed2746lling * if possible.
990b4856d0eaada6f8140335733a1b1771ed2746lling *
990b4856d0eaada6f8140335733a1b1771ed2746lling * Applications should use zpool_import_props() to import a pool with
990b4856d0eaada6f8140335733a1b1771ed2746lling * new properties value to be set.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
990b4856d0eaada6f8140335733a1b1771ed2746lling char *altroot)
990b4856d0eaada6f8140335733a1b1771ed2746lling{
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *props = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling int ret;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (altroot != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (zfs_error_fmt(hdl, EZFS_NOMEM,
990b4856d0eaada6f8140335733a1b1771ed2746lling dgettext(TEXT_DOMAIN, "cannot import '%s'"),
990b4856d0eaada6f8140335733a1b1771ed2746lling newname));
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_add_string(props,
352d8027a91dfc2f3c5bdda788b82548169bf512George Wilson zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
352d8027a91dfc2f3c5bdda788b82548169bf512George Wilson nvlist_add_string(props,
352d8027a91dfc2f3c5bdda788b82548169bf512George Wilson zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_free(props);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (zfs_error_fmt(hdl, EZFS_NOMEM,
990b4856d0eaada6f8140335733a1b1771ed2746lling dgettext(TEXT_DOMAIN, "cannot import '%s'"),
990b4856d0eaada6f8140335733a1b1771ed2746lling newname));
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson ret = zpool_import_props(hdl, config, newname, props,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson ZFS_IMPORT_NORMAL);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(props);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (ret);
990b4856d0eaada6f8140335733a1b1771ed2746lling}
990b4856d0eaada6f8140335733a1b1771ed2746lling
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilsonstatic void
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilsonprint_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson int indent)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson{
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t **child;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson uint_t c, children;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson char *vname;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson uint64_t is_log = 0;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson &is_log);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (name != NULL)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) printf("\t%*s%s%s\n", indent, "", name,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson is_log ? " [log]" : "");
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson &child, &children) != 0)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson return;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson for (c = 0; c < children; c++) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson print_vdev_tree(hdl, vname, child[c], indent + 2);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson free(vname);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson}
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenvoid
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Sidenzpool_print_unsup_feat(nvlist_t *config)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden{
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_t *nvinfo, *unsup_feat;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) ==
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden 0);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden verify(nvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden &unsup_feat) == 0);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); nvp != NULL;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden char *desc;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden verify(nvpair_type(nvp) == DATA_TYPE_STRING);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden verify(nvpair_value_string(nvp, &desc) == 0);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (strlen(desc) > 0)
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden else
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) printf("\t%s\n", nvpair_name(nvp));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden}
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden
990b4856d0eaada6f8140335733a1b1771ed2746lling/*
990b4856d0eaada6f8140335733a1b1771ed2746lling * Import the given pool using the known configuration and a list of
990b4856d0eaada6f8140335733a1b1771ed2746lling * properties to be set. The configuration should have come from
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool_find_import(). The 'newname' parameters control whether the pool
990b4856d0eaada6f8140335733a1b1771ed2746lling * is imported with a different name.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746llingint
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *props, int flags)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zfs_cmd_t zc = { 0 };
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_rewind_policy_t policy;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *nv = NULL;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *nvinfo = NULL;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_t *missing = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *thename;
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *origname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson int error = 0;
990b4856d0eaada6f8140335733a1b1771ed2746lling char errbuf[1024];
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &origname) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling "cannot import pool '%s'"), origname);
990b4856d0eaada6f8140335733a1b1771ed2746lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newname != NULL) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (!zpool_name_valid(hdl, B_FALSE, newname))
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot import '%s'"),
99653d4ee642c6528e88224f12409a5f23060994eschrock newname));
fa9e4066f08beec538e775443c5be79dd423fcabahrens thename = (char *)newname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens thename = origname;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka if (props != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling uint64_t version;
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
fa9e4066f08beec538e775443c5be79dd423fcabahrens
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
990b4856d0eaada6f8140335733a1b1771ed2746lling &version) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((props = zpool_valid_proplist(hdl, origname,
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka props, version, flags, errbuf)) == NULL)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling nvlist_free(props);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling }
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka nvlist_free(props);
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka zcmd_free_nvlists(&zc);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling }
57f304cac4eb658f78f98cbdf8de4b9af05b87c9George Wilson if (zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2) != 0) {
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka zcmd_free_nvlists(&zc);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (-1);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson zc.zc_cookie = flags;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson errno == ENOMEM) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson zcmd_free_nvlists(&zc);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson return (-1);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (ret != 0)
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson error = errno;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka zcmd_free_nvlists(&zc);
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson zpool_get_rewind_policy(config, &policy);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (error) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens char desc[1024];
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley /*
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley * Dry-run failed, but we print out what success
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley * looks like if we found a best txg
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley */
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (policy.zrp_request & ZPOOL_TRY_REWIND) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_rewind_exclaim(hdl, newname ? origname : thename,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson B_TRUE, nv);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_free(nv);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (-1);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newname == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(desc, sizeof (desc),
fa9e4066f08beec538e775443c5be79dd423fcabahrens dgettext(TEXT_DOMAIN, "cannot import '%s'"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens thename);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(desc, sizeof (desc),
fa9e4066f08beec538e775443c5be79dd423fcabahrens dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens origname, thename);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson switch (error) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ENOTSUP:
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nv != NULL && nvlist_lookup_nvlist(nv,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) printf(dgettext(TEXT_DOMAIN, "This "
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "pool uses the following feature(s) not "
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "supported by this system:\n"));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden zpool_print_unsup_feat(nv);
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden if (nvlist_exists(nvinfo,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden ZPOOL_CONFIG_CAN_RDONLY)) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) printf(dgettext(TEXT_DOMAIN,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "All unsupported features are only "
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "required for writing to the pool."
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "\nThe pool can be imported using "
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden "'-o readonly=on'.\n"));
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Unsupported version.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADVERSION, desc);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
b5989ec7cd031c9bb066c68877fb5017e45f205beschrock case EINVAL:
b5989ec7cd031c9bb066c68877fb5017e45f205beschrock (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
b5989ec7cd031c9bb066c68877fb5017e45f205beschrock break;
b5989ec7cd031c9bb066c68877fb5017e45f205beschrock
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby case EROFS:
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby "one or more devices is read only"));
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby (void) zfs_error(hdl, EZFS_BADDEV, desc);
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby break;
54a91118eee5bfd63eb614a44e1b68f1571a99eaChris Kirby
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson case ENXIO:
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (nv && nvlist_lookup_nvlist(nv,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_lookup_nvlist(nvinfo,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) printf(dgettext(TEXT_DOMAIN,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson "The devices below are missing, use "
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson "'-m' to import the pool anyway:\n"));
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson print_vdev_tree(hdl, NULL, missing, 2);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) printf("\n");
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) zpool_standard_error(hdl, error, desc);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson break;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson case EEXIST:
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) zpool_standard_error(hdl, error, desc);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson break;
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie case ENAMETOOLONG:
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie "new name of at least one dataset is longer than "
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie "the maximum allowable length"));
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie (void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
c971037baa5d64dfecf6d87ed602fc3116ebec41Paul Dagnelie break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default:
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson (void) zpool_standard_error(hdl, error, desc);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_explain_recover(hdl,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson newname ? origname : thename, -error, nv);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_free(nv);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_handle_t *zhp;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This should never fail, but play it safe anyway.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor if (zpool_open_silent(hdl, thename, &zhp) != 0)
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock ret = -1;
681d9761e8516a7dc5ab6589e2dfe717777e1123Eric Taylor else if (zhp != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens zpool_close(zhp);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (policy.zrp_request &
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_rewind_exclaim(hdl, newname ? origname : thename,
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0), nv);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson nvlist_free(nv);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * Scan the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Lingzpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling zc.zc_cookie = func;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (errno == ENOENT && func != POOL_SCAN_NONE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (func == POOL_SCAN_SCRUB) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (void) snprintf(msg, sizeof (msg),
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling } else if (func == POOL_SCAN_NONE) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (void) snprintf(msg, sizeof (msg),
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling zc.zc_name);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling } else {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling assert(!"unexpected result");
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (errno == EBUSY) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling nvlist_t *nvroot;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling pool_scan_stat_t *ps = NULL;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling uint_t psc;
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling verify(nvlist_lookup_nvlist(zhp->zpool_config,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling (void) nvlist_lookup_uint64_array(nvroot,
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if (ps && ps->pss_func == POOL_SCAN_SCRUB)
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return (zfs_error(hdl, EZFS_SCRUBBING, msg));
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling else
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return (zfs_error(hdl, EZFS_RESILVERING, msg));
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling } else if (errno == ENOENT) {
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zpool_standard_error(hdl, errno, msg));
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres/*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * This provides a very minimal check whether a given string is likely a
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * c#t#d# style string. Users of this are expected to do their own
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * verification of the s# part.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres#define CTD_CHECK(str) (str && str[0] == 'c' && isdigit(str[1]))
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres/*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * More elaborate version for ones which may start with "/dev/dsk/"
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * and the like.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harresstatic int
9a686fbc186e8e2a64e9a5094d44c7d6fa0ea167Paul Dagneliectd_check_path(char *str)
9a686fbc186e8e2a64e9a5094d44c7d6fa0ea167Paul Dagnelie{
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * If it starts with a slash, check the last component.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (str && str[0] == '/') {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres char *tmp = strrchr(str, '/');
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * If it ends in "/old", check the second-to-last
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * component of the string instead.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (tmp != str && strcmp(tmp, "/old") == 0) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres for (tmp--; *tmp != '/'; tmp--)
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres ;
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres }
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres str = tmp + 1;
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres }
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres return (CTD_CHECK(str));
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres}
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
a43d325b828008a3ab54eed57fd7c00b6470172bek/*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Find a vdev that matches the search criteria specified. We use the
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * the nvpair name to determine how we should look for the device.
a43d325b828008a3ab54eed57fd7c00b6470172bek * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
a43d325b828008a3ab54eed57fd7c00b6470172bek * spare; but FALSE if its an INUSE spare.
a43d325b828008a3ab54eed57fd7c00b6470172bek */
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic nvlist_t *
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonvdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson boolean_t *l2cache, boolean_t *log)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint_t c, children;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock nvlist_t **child;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *ret;
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock uint64_t is_log;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson char *srchkey;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvpair_t *pair = nvlist_next_nvpair(search, NULL);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /* Nothing to look for */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (search == NULL || pair == NULL)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (NULL);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /* Obtain the key we will use to search */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson srchkey = nvpair_name(pair);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson switch (nvpair_type(pair)) {
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante case DATA_TYPE_UINT64:
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante uint64_t srchval, theguid;
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante verify(nvpair_value_uint64(pair, &srchval) == 0);
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante &theguid) == 0);
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (theguid == srchval)
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante return (nv);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson break;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson case DATA_TYPE_STRING: {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson char *srchval, *val;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvpair_value_string(pair, &srchval) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (nvlist_lookup_string(nv, srchkey, &val) != 0)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * Search for the requested value. Special cases:
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres *
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * - ZPOOL_CONFIG_PATH for whole disk entries. These end in
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * "s0" or "s0/old". The "s0" part is hidden from the user,
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * but included in the string, so this matches around it.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres *
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Otherwise, all other searches are simple string compares.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 &&
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres ctd_check_path(val)) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson uint64_t wholedisk = 0;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson &wholedisk);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (wholedisk) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres int slen = strlen(srchval);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres int vlen = strlen(val);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (slen != vlen - 2)
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres break;
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * make_leaf_vdev() should only set
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * wholedisk for ZPOOL_CONFIG_PATHs which
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * will include "/dev/dsk/", giving plenty of
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * room for the indices used next.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres ASSERT(vlen >= 6);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * strings identical except trailing "s0"
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (strcmp(&val[vlen - 2], "s0") == 0 &&
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres strncmp(srchval, val, slen) == 0)
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres return (nv);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * strings identical except trailing "s0/old"
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (strcmp(&val[vlen - 6], "s0/old") == 0 &&
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres strcmp(&srchval[slen - 4], "/old") == 0 &&
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres strncmp(srchval, val, slen - 4) == 0)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (nv);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson break;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson char *type, *idx, *end, *p;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson uint64_t id, vdev_id;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson /*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Determine our vdev type, keeping in mind
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * that the srchval is composed of a type and
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * vdev id pair (i.e. mirror-4).
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((type = strdup(srchval)) == NULL)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (NULL);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((p = strrchr(type, '-')) == NULL) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson free(type);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson break;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson idx = p + 1;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson *p = '\0';
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson /*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * If the types don't match then keep looking.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (strncmp(val, type, strlen(val)) != 0) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson free(type);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson break;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(strncmp(type, VDEV_TYPE_RAIDZ,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson strlen(VDEV_TYPE_RAIDZ)) == 0 ||
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson strncmp(type, VDEV_TYPE_MIRROR,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson strlen(VDEV_TYPE_MIRROR)) == 0);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson &id) == 0);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson errno = 0;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson vdev_id = strtoull(idx, &end, 10);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson free(type);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (errno != 0)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (NULL);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson /*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Now verify that we have the correct vdev id.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (vdev_id == id)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (nv);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Common case
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (strcmp(srchval, val) == 0)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (nv);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson break;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson default:
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &child, &children) != 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (NULL);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock avail_spare, l2cache, NULL)) != NULL) {
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock /*
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock * The 'is_log' value is only set for the toplevel
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock * vdev, not the leaf vdevs. So we always lookup the
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock * log device from the root of the vdev tree (where
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock * 'log' is non-NULL).
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock */
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if (log != NULL &&
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock nvlist_lookup_uint64(child[c],
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock is_log) {
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock *log = B_TRUE;
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (ret);
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock }
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock &child, &children) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock avail_spare, l2cache, NULL)) != NULL) {
a43d325b828008a3ab54eed57fd7c00b6470172bek *avail_spare = B_TRUE;
99653d4ee642c6528e88224f12409a5f23060994eschrock return (ret);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan &child, &children) == 0) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock avail_spare, l2cache, NULL)) != NULL) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan *l2cache = B_TRUE;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (ret);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan }
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
99653d4ee642c6528e88224f12409a5f23060994eschrock return (NULL);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson/*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Given a physical path (minus the "/devices" prefix), find the
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * associated vdev.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonnvlist_t *
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonzpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson{
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvlist_t *search, *nvroot, *ret;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson &nvroot) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson *avail_spare = B_FALSE;
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante *l2cache = B_FALSE;
daeb70e535f1925e743a5fbc4c6078dc8306a87fMark J Musante if (log != NULL)
daeb70e535f1925e743a5fbc4c6078dc8306a87fMark J Musante *log = B_FALSE;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvlist_free(search);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (ret);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson}
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson/*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilsonboolean_t
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilsonzpool_vdev_is_interior(const char *name)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson{
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (B_TRUE);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (B_FALSE);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson}
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
99653d4ee642c6528e88224f12409a5f23060994eschrocknvlist_t *
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanzpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock boolean_t *l2cache, boolean_t *log)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char buf[MAXPATHLEN];
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char *end;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvlist_t *nvroot, *search, *ret;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint64_t guid;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
0917b783fd655a0c943e0b8fb848db2301774947eschrock guid = strtoull(path, &end, 10);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (guid != 0 && *end == '\0') {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson } else if (zpool_vdev_is_interior(path)) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (path[0] != '/') {
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews (void) snprintf(buf, sizeof (buf), "%s/%s", ZFS_DISK_ROOT,
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews path);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &nvroot) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
a43d325b828008a3ab54eed57fd7c00b6470172bek *avail_spare = B_FALSE;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan *l2cache = B_FALSE;
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if (log != NULL)
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock *log = B_FALSE;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvlist_free(search);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (ret);
a43d325b828008a3ab54eed57fd7c00b6470172bek}
a43d325b828008a3ab54eed57fd7c00b6470172bek
193974072f41a843678abf5f61979c748687e66bSherry Moorestatic int
193974072f41a843678abf5f61979c748687e66bSherry Moorevdev_online(nvlist_t *nv)
193974072f41a843678abf5f61979c748687e66bSherry Moore{
193974072f41a843678abf5f61979c748687e66bSherry Moore uint64_t ival;
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
193974072f41a843678abf5f61979c748687e66bSherry Moore nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
193974072f41a843678abf5f61979c748687e66bSherry Moore nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
193974072f41a843678abf5f61979c748687e66bSherry Moore return (0);
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore return (1);
193974072f41a843678abf5f61979c748687e66bSherry Moore}
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore/*
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * Helper function for zpool_get_physpaths().
193974072f41a843678abf5f61979c748687e66bSherry Moore */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorestatic int
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Lingvdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore size_t *bytes_written)
193974072f41a843678abf5f61979c748687e66bSherry Moore{
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore size_t bytes_left, pos, rsz;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore char *tmppath;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore const char *format;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore &tmppath) != 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_NODEVICE);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore pos = *bytes_written;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore bytes_left = physpath_size - pos;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore format = (pos == 0) ? "%s" : " %s";
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore *bytes_written += rsz;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (rsz >= bytes_left) {
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* if physpath was not copied properly, clear it */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (bytes_left != 0) {
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore physpath[pos] = 0;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore }
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_NOSPC);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore }
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (0);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore}
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Lingstatic int
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Lingvdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling size_t *rsz, boolean_t is_spare)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling{
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling char *type;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling int ret;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (EZFS_INVALCONFIG);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (strcmp(type, VDEV_TYPE_DISK) == 0) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling /*
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * For a spare vdev, we only want to boot from the active
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * spare device.
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling */
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (is_spare) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling uint64_t spare = 0;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling &spare);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (!spare)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (EZFS_INVALCONFIG);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling }
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (vdev_online(nv)) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if ((ret = vdev_get_one_physpath(nv, physpath,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling phypath_size, rsz)) != 0)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (ret);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling }
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
d5f26ad8122c3762fb16413a17bfb497db86a782Toomas Soome strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling nvlist_t **child;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling uint_t count;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling int i, ret;
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (nvlist_lookup_nvlist_array(nv,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (EZFS_INVALCONFIG);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling for (i = 0; i < count; i++) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling ret = vdev_get_physpaths(child[i], physpath,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling phypath_size, rsz, is_spare);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (ret == EZFS_NOSPC)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (ret);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling }
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling }
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling return (EZFS_POOL_INVALARG);
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling}
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore/*
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Get phys_path for a root pool config.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 0 on success; non-zero on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorestatic int
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorezpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore{
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore size_t rsz;
193974072f41a843678abf5f61979c748687e66bSherry Moore nvlist_t *vdev_root;
193974072f41a843678abf5f61979c748687e66bSherry Moore nvlist_t **child;
193974072f41a843678abf5f61979c748687e66bSherry Moore uint_t count;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore char *type;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore rsz = 0;
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore &vdev_root) != 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_INVALCONFIG);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore &child, &count) != 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_INVALCONFIG);
193974072f41a843678abf5f61979c748687e66bSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore /*
1a902ef8628b0dffd6df5442354ab59bb8530962Hans Rosenfeld * root pool can only have a single top-level vdev.
193974072f41a843678abf5f61979c748687e66bSherry Moore */
1a902ef8628b0dffd6df5442354ab59bb8530962Hans Rosenfeld if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_POOL_INVALARG);
193974072f41a843678abf5f61979c748687e66bSherry Moore
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling B_FALSE);
193974072f41a843678abf5f61979c748687e66bSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* No online devices */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (rsz == 0)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (EZFS_NODEVICE);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
193974072f41a843678abf5f61979c748687e66bSherry Moore return (0);
193974072f41a843678abf5f61979c748687e66bSherry Moore}
193974072f41a843678abf5f61979c748687e66bSherry Moore
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore/*
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Get phys_path for a root pool
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 0 on success; non-zero on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Mooreint
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorezpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore{
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (zpool_get_config_physpath(zhp->zpool_config, physpath,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore phypath_size));
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore}
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson/*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * If the device has being dynamically expanded then we need to relabel
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * the disk to use the new unallocated space.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonstatic int
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonzpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson{
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson char path[MAXPATHLEN];
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson char errbuf[1024];
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson int fd, error;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson int (*_efi_use_whole_disk)(int);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "efi_use_whole_disk")) == NULL)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (-1);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews (void) snprintf(path, sizeof (path), "%s/%s", ZFS_RDISK_ROOT, name);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "relabel '%s': unable to open device"), name);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * It's possible that we might encounter an error if the device
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * does not have any unallocated space left. If so, we simply
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * ignore that error and continue on.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson error = _efi_use_whole_disk(fd);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) close(fd);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (error && error != VT_ENOSPC) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "relabel '%s': unable to read disk capacity"), name);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (zfs_error(hdl, EZFS_NOCAP, errbuf));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson}
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Bring the specified vdev online. The 'flags' parameter is a set of the
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * ZFS_ONLINE_* flags.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock vdev_state_t *newstate)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson boolean_t avail_spare, l2cache, islog;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (flags & ZFS_ONLINE_EXPAND) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) snprintf(msg, sizeof (msg),
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson } else {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) snprintf(msg, sizeof (msg),
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson dgettext(TEXT_DOMAIN, "cannot online %s"), path);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson &islog)) == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock if (avail_spare)
a43d325b828008a3ab54eed57fd7c00b6470172bek return (zfs_error(hdl, EZFS_ISSPARE, msg));
a43d325b828008a3ab54eed57fd7c00b6470172bek
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (flags & ZFS_ONLINE_EXPAND ||
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson char *pathname = NULL;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson uint64_t wholedisk = 0;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson &wholedisk);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson &pathname) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /*
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * XXX - L2ARC 1.0 devices can't support expansion.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (l2cache) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "cannot expand cache devices"));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (wholedisk) {
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews pathname += strlen(ZFS_DISK_ROOT) + 1;
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante (void) zpool_relabel_disk(hdl, pathname);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson }
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_cookie = VDEV_STATE_ONLINE;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_obj = flags;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (errno == EINVAL) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "from this pool into a new one. Use '%s' "
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "instead"), "zpool detach");
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, msg));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (zpool_standard_error(hdl, errno, msg));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock *newstate = zc.zc_cookie;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Take the specified vdev offline
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan boolean_t avail_spare, l2cache;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock NULL)) == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock if (avail_spare)
a43d325b828008a3ab54eed57fd7c00b6470172bek return (zfs_error(hdl, EZFS_ISSPARE, msg));
a43d325b828008a3ab54eed57fd7c00b6470172bek
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_cookie = VDEV_STATE_OFFLINE;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock switch (errno) {
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock case EBUSY:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock /*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * There are no other replicas of this device.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson case EEXIST:
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson /*
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * The log device has unplayed logs
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson */
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock default:
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (zpool_standard_error(hdl, errno, msg));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock}
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock/*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Mark the given vdev faulted.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockint
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrockzpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zfs_cmd_t zc = { 0 };
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock char msg[1024];
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) snprintf(msg, sizeof (msg),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_guid = guid;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_cookie = VDEV_STATE_FAULTED;
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock zc.zc_obj = aux;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (errno) {
99653d4ee642c6528e88224f12409a5f23060994eschrock case EBUSY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There are no other replicas of this device.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock default:
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zpool_standard_error(hdl, errno, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock}
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock/*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Mark the given vdev degraded.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockint
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrockzpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zfs_cmd_t zc = { 0 };
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock char msg[1024];
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) snprintf(msg, sizeof (msg),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_guid = guid;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_cookie = VDEV_STATE_DEGRADED;
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrock zc.zc_obj = aux;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (zpool_standard_error(hdl, errno, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock/*
99653d4ee642c6528e88224f12409a5f23060994eschrock * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
99653d4ee642c6528e88224f12409a5f23060994eschrock * a hot spare.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrockstatic boolean_t
99653d4ee642c6528e88224f12409a5f23060994eschrockis_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t **child;
99653d4ee642c6528e88224f12409a5f23060994eschrock uint_t c, children;
99653d4ee642c6528e88224f12409a5f23060994eschrock char *type;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
99653d4ee642c6528e88224f12409a5f23060994eschrock &children) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
99653d4ee642c6528e88224f12409a5f23060994eschrock &type) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
99653d4ee642c6528e88224f12409a5f23060994eschrock children == 2 && child[which] == tgt)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++)
99653d4ee642c6528e88224f12409a5f23060994eschrock if (is_replacing_spare(child[c], tgt, which))
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_TRUE);
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (B_FALSE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Attach new_disk (fully described by nvroot) to old_disk.
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin * If 'replacing' is specified, the new disk will replace the old one.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_vdev_attach(zpool_handle_t *zhp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens char msg[1024];
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock boolean_t avail_spare, l2cache, islog;
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock uint64_t val;
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante char *newname;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t **child;
99653d4ee642c6528e88224f12409a5f23060994eschrock uint_t children;
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *config_root;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
4263d13f00c9691fa14620eff82abef795be0693George Wilson boolean_t rootpool = zpool_is_bootable(zhp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (replacing)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "cannot replace %s with %s"), old_disk, new_disk);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock else
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "cannot attach %s to %s"), new_disk, old_disk);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock &islog)) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock
a43d325b828008a3ab54eed57fd7c00b6470172bek if (avail_spare)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_ISSPARE, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (l2cache)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens zc.zc_cookie = replacing;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
99653d4ee642c6528e88224f12409a5f23060994eschrock &child, &children) != 0 || children != 1) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "new device must be a single disk"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
99653d4ee642c6528e88224f12409a5f23060994eschrock ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock return (-1);
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * If the target is a hot spare that has been swapped in, we can only
99653d4ee642c6528e88224f12409a5f23060994eschrock * replace it with another hot spare.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (replacing &&
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock NULL) == NULL || !avail_spare) &&
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock is_replacing_spare(config_root, tgt, 1)) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "can only be replaced by another hot spare"));
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock free(newname);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_BADTARGET, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock free(newname);
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zcmd_free_nvlists(&zc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson if (ret == 0) {
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson if (rootpool) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling /*
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * XXX need a better way to prevent user from
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * booting up a half-baked vdev.
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling */
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling "sure to wait until resilver is done "
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling "before rebooting.\n"));
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (errno) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ENOTSUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Can't attach to or replace this type of vdev.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (replacing) {
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante uint64_t version = zpool_get_prop_int(zhp,
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante ZPOOL_PROP_VERSION, NULL);
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if (islog)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "cannot replace a log with a spare"));
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante else if (version >= SPA_VERSION_MULTI_REPLACE)
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante "already in replacing/spare config; wait "
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante "for completion or use 'zpool detach'"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin else
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "cannot replace a replacing device"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin } else {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "can only attach to mirrors and top-level "
99653d4ee642c6528e88224f12409a5f23060994eschrock "disks"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADTARGET, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EINVAL:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device must be a single disk.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "new device must be a single disk"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EBUSY:
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
99653d4ee642c6528e88224f12409a5f23060994eschrock new_disk);
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EOVERFLOW:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device is too small.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "device is too small"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EDOM:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device has a different alignment requirement.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "devices have different sector alignment"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_BADDEV, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ENAMETOOLONG:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The resulting top-level vdev spec won't fit in the label.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock default:
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zpool_standard_error(hdl, errno, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Detach the specified device.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_vdev_detach(zpool_handle_t *zhp, const char *path)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_cmd_t zc = { 0 };
fa9e4066f08beec538e775443c5be79dd423fcabahrens char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan boolean_t avail_spare, l2cache;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock NULL)) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
a43d325b828008a3ab54eed57fd7c00b6470172bek if (avail_spare)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_ISSPARE, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (l2cache)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens switch (errno) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case ENOTSUP:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Can't detach from this type of vdev.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
99653d4ee642c6528e88224f12409a5f23060994eschrock "applicable to mirror and replacing vdevs"));
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante (void) zfs_error(hdl, EZFS_BADTARGET, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock case EBUSY:
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There are no other replicas of this device.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock default:
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zpool_standard_error(hdl, errno, msg);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock}
99653d4ee642c6528e88224f12409a5f23060994eschrock
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante/*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * Find a mirror vdev in the source nvlist.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante *
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * The mchild array contains a list of disks in one of the top-level mirrors
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * of the source pool. The schild array contains a list of disks that the
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * user specified on the command line. We loop over the mchild array to
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * see if any entry in the schild array matches.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante *
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * If a disk in the mchild array is found in the schild array, we return
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * the index of that entry. Otherwise we return -1.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musantestatic int
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musantefind_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t **schild, uint_t schildren)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante{
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint_t mc;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (mc = 0; mc < mchildren; mc++) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint_t sc;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante mchild[mc], B_FALSE);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (sc = 0; sc < schildren; sc++) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante schild[sc], B_FALSE);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante boolean_t result = (strcmp(mpath, spath) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante free(spath);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (result) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante free(mpath);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (mc);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante free(mpath);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (-1);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante}
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante/*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * Split a mirror pool. If newroot points to null, then a new nvlist
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * is generated and it is the responsibility of the caller to free it.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musanteint
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musantezpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t *props, splitflags_t flags)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante{
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zfs_cmd_t zc = { 0 };
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante char msg[1024];
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t **varray = NULL, *zc_props = NULL;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante libzfs_handle_t *hdl = zhp->zpool_hdl;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint64_t vers;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante boolean_t freelist = B_FALSE, memory_err = B_TRUE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante int retval = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) snprintf(msg, sizeof (msg),
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (!zpool_name_valid(hdl, B_FALSE, newname))
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if ((config = zpool_get_config(zhp, NULL)) == NULL) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) fprintf(stderr, gettext("Internal error: unable to "
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "retrieve pool configuration\n"));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (-1);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &vers) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (props) {
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson props, vers, flags, msg)) == NULL)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (-1);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante &children) != 0) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "Source pool is missing vdev tree"));
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(zc_props);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (-1);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante vcount = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (*newroot == NULL ||
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante &newchild, &newchildren) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante newchildren = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (c = 0; c < children; c++) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint64_t is_log = B_FALSE, is_hole = B_FALSE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante char *type;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t **mchild, *vdev;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint_t mchildren;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante int entry;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * Unlike cache & spares, slogs are stored in the
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * ZPOOL_CONFIG_CHILDREN array. We filter them out here.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante &is_log);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante &is_hole);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (is_log || is_hole) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * Create a hole vdev and put it in the config.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VDEV_TYPE_HOLE) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante 1) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (lastlog == 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante lastlog = vcount;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante varray[vcount++] = vdev;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante continue;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante lastlog = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante verify(nvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE, &type)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "Source pool must be composed only of mirrors\n"));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante verify(nvlist_lookup_nvlist_array(child[c],
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* find or add an entry for this top-level vdev */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (newchildren > 0 &&
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (entry = find_vdev_entry(zhp, mchild, mchildren,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante newchild, newchildren)) >= 0) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* We found a disk that the user specified. */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante vdev = mchild[entry];
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ++found;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante } else {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* User didn't specify a disk for this vdev. */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante vdev = mchild[mchildren - 1];
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* did we find every disk the user specified? */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (found != newchildren) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante "include at most one disk from each mirror"));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* Prepare the nvlist for populating. */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (*newroot == NULL) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante freelist = B_TRUE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VDEV_TYPE_ROOT) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante } else {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* Add all the children we found */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, varray,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante lastlog == 0 ? vcount : lastlog) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * If we're just doing a dry run, exit now with success.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (flags.dryrun) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante memory_err = B_FALSE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante freelist = B_FALSE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* now build up the config list & call the ioctl */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (nvlist_add_nvlist(newconfig,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_add_string(newconfig,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /*
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * The new pool is automatically part of the namespace unless we
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * explicitly export it.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (!flags.import)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (zcmd_write_conf_nvlist(hdl, &zc, newconfig) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (zc_props != NULL && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante retval = zpool_standard_error(hdl, errno, msg);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante goto out;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante freelist = B_FALSE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante memory_err = B_FALSE;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musanteout:
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (varray != NULL) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante int v;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (v = 0; v < vcount; v++)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_free(varray[v]);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante free(varray);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante zcmd_free_nvlists(&zc);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(zc_props);
aab83bb83be7342f6cfccaed8d5fe0b2f404855dJosef 'Jeff' Sipek nvlist_free(newconfig);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (freelist) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_free(*newroot);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante *newroot = NULL;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante }
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (retval != 0)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (retval);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (memory_err)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (no_memory(hdl));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante return (0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante}
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante
99653d4ee642c6528e88224f12409a5f23060994eschrock/*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Remove the given device. Currently, this is supported only for hot spares
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * and level 2 cache devices.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrockint
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_vdev_remove(zpool_handle_t *zhp, const char *path)
99653d4ee642c6528e88224f12409a5f23060994eschrock{
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_cmd_t zc = { 0 };
99653d4ee642c6528e88224f12409a5f23060994eschrock char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson boolean_t avail_spare, l2cache, islog;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson uint64_t version;
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg),
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson &islog)) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson /*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * XXX - this should just go away.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (!avail_spare && !l2cache && !islog) {
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "only inactive hot spares, cache, top-level, "
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "or log devices can be removed"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock }
99653d4ee642c6528e88224f12409a5f23060994eschrock
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (islog && version < SPA_VERSION_HOLES) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "pool must be upgrade to support log removal"));
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (zfs_error(hdl, EZFS_BADVERSION, msg));
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zpool_standard_error(hdl, errno, msg));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock/*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Clear the errors for the pool, or the particular device if specified.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockint
468c413a79615e77179e8d98f22a7e513a8135bdTim Haleyzpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zfs_cmd_t zc = { 0 };
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char msg[1024];
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_t *tgt;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_rewind_policy_t policy;
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan boolean_t avail_spare, l2cache;
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley nvlist_t *nvi = NULL;
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson int error;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (path)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock path);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock else
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zhp->zpool_name);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
99653d4ee642c6528e88224f12409a5f23060994eschrock if (path) {
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock &l2cache, NULL)) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_NODEVICE, msg));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan /*
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Don't allow error clearing for hot spares. Do allow
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * error clearing for l2cache devices.
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan */
a43d325b828008a3ab54eed57fd7c00b6470172bek if (avail_spare)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_error(hdl, EZFS_ISSPARE, msg));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
99653d4ee642c6528e88224f12409a5f23060994eschrock &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_get_rewind_policy(rewindnvl, &policy);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zc.zc_cookie = policy.zrp_request;
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
57f304cac4eb658f78f98cbdf8de4b9af05b87c9George Wilson if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2) != 0)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (-1);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
cb04b8739c50e3e6d12e89b790fa7b8d0d899865Mark J Musante if (zcmd_write_src_nvlist(hdl, &zc, rewindnvl) != 0)
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley return (-1);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson errno == ENOMEM) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson zcmd_free_nvlists(&zc);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson return (-1);
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson }
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson if (!error || ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley errno != EPERM && errno != EACCES)) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley if (policy.zrp_request &
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zpool_rewind_exclaim(hdl, zc.zc_name,
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley nvi);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley nvlist_free(nvi);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zcmd_free_nvlists(&zc);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley }
99653d4ee642c6528e88224f12409a5f23060994eschrock
468c413a79615e77179e8d98f22a7e513a8135bdTim Haley zcmd_free_nvlists(&zc);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zpool_standard_error(hdl, errno, msg));
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock/*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Similar to zpool_clear(), but takes a GUID (used by fmd).
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockint
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock{
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zfs_cmd_t zc = { 0 };
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock char msg[1024];
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) snprintf(msg, sizeof (msg),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock guid);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zc.zc_guid = guid;
14f8ce414fea788600a888bbc0fa3ca49f2c1d2dVictor Latushkin zc.zc_cookie = ZPOOL_NO_REWIND;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (zpool_standard_error(hdl, errno, msg));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock}
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore/*
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore * Change the GUID for a pool.
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore */
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amoreint
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amorezpool_reguid(zpool_handle_t *zhp)
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore{
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore char msg[1024];
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore libzfs_handle_t *hdl = zhp->zpool_hdl;
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore zfs_cmd_t zc = { 0 };
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore (void) snprintf(msg, sizeof (msg),
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore return (0);
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore return (zpool_standard_error(hdl, errno, msg));
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore}
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore
4263d13f00c9691fa14620eff82abef795be0693George Wilson/*
4263d13f00c9691fa14620eff82abef795be0693George Wilson * Reopen the pool.
4263d13f00c9691fa14620eff82abef795be0693George Wilson */
4263d13f00c9691fa14620eff82abef795be0693George Wilsonint
4263d13f00c9691fa14620eff82abef795be0693George Wilsonzpool_reopen(zpool_handle_t *zhp)
4263d13f00c9691fa14620eff82abef795be0693George Wilson{
4263d13f00c9691fa14620eff82abef795be0693George Wilson zfs_cmd_t zc = { 0 };
4263d13f00c9691fa14620eff82abef795be0693George Wilson char msg[1024];
4263d13f00c9691fa14620eff82abef795be0693George Wilson libzfs_handle_t *hdl = zhp->zpool_hdl;
4263d13f00c9691fa14620eff82abef795be0693George Wilson
4263d13f00c9691fa14620eff82abef795be0693George Wilson (void) snprintf(msg, sizeof (msg),
4263d13f00c9691fa14620eff82abef795be0693George Wilson dgettext(TEXT_DOMAIN, "cannot reopen '%s'"),
4263d13f00c9691fa14620eff82abef795be0693George Wilson zhp->zpool_name);
4263d13f00c9691fa14620eff82abef795be0693George Wilson
4263d13f00c9691fa14620eff82abef795be0693George Wilson (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4263d13f00c9691fa14620eff82abef795be0693George Wilson if (zfs_ioctl(hdl, ZFS_IOC_POOL_REOPEN, &zc) == 0)
4263d13f00c9691fa14620eff82abef795be0693George Wilson return (0);
4263d13f00c9691fa14620eff82abef795be0693George Wilson return (zpool_standard_error(hdl, errno, msg));
4263d13f00c9691fa14620eff82abef795be0693George Wilson}
4263d13f00c9691fa14620eff82abef795be0693George Wilson
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock/*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Convert from a devid string to a path.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockstatic char *
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockdevid_to_path(char *devid_str)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock{
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ddi_devid_t devid;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *minor;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *path;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_nmlist_t *list = NULL;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock int ret;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (devid_str_decode(devid_str, &devid, &minor) != 0)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (NULL);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_str_free(minor);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_free(devid);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (ret != 0)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (NULL);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka /*
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka * In a case the strdup() fails, we will just return NULL below.
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka */
078266a5aafa880521ea55488ef3d676f35e908eMarcel Telka path = strdup(list[0].devname);
99653d4ee642c6528e88224f12409a5f23060994eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_free_nmlist(list);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (path);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock/*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Convert from a path to a devid string.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockstatic char *
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockpath_to_devid(const char *path)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock{
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock int fd;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ddi_devid_t devid;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *minor, *ret;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if ((fd = open(path, O_RDONLY)) < 0)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (NULL);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock minor = NULL;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ret = NULL;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (devid_get(fd, &devid) == 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (devid_get_minor_name(fd, &minor) == 0)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ret = devid_str_encode(devid, minor);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (minor != NULL)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_str_free(minor);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock devid_free(devid);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock (void) close(fd);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (ret);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock/*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Issue the necessary ioctl() to update the stored path value for the vdev. We
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * ignore any failure here, since a common case is for an unprivileged user to
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * type 'zpool status', and we'll display the correct information anyway.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockstatic void
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockset_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock{
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock zfs_cmd_t zc = { 0 };
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &zc.zc_guid) == 0);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock/*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Given a vdev, return the name to display in iostat. If the vdev has a path,
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * We also check if this is a whole disk, in which case we strip off the
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * trailing 's0' slice name.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock *
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * This routine is also responsible for identifying when disks have been
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * reconfigured in a new location. The kernel will have opened the device by
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * devid, but the path will still refer to the old location. To catch this, we
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * first do a path -> devid translation (which is fast for the common case). If
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * the devid matches, we're done. If not, we do a reverse devid -> path
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * translation and issue the appropriate ioctl() to update the path of the vdev.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * of these checks.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockchar *
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilsonzpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson boolean_t verbose)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock{
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *path, *devid;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint64_t value;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock char buf[64];
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock vdev_stat_t *vs;
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock uint_t vsc;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &value) == 0) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &value) == 0);
5ad820458efd0fdb914baff9c1447c22b819fa23nd (void) snprintf(buf, sizeof (buf), "%llu",
5ad820458efd0fdb914baff9c1447c22b819fa23nd (u_longlong_t)value);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock path = buf;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock /*
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * If the device is dead (faulted, offline, etc) then don't
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * bother opening it. Otherwise we may be forcing the user to
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * open a misbehaving device, which can have undesirable
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * effects.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock */
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (uint64_t **)&vs, &vsc) != 0 ||
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock vs->vs_state >= VDEV_STATE_DEGRADED) &&
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock zhp != NULL &&
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock /*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Determine if the current path is correct.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *newdevid = path_to_devid(path);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (newdevid == NULL ||
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock strcmp(devid, newdevid) != 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock char *newpath;
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if ((newpath = devid_to_path(devid)) != NULL) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock /*
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Update the path appropriately.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock */
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock set_path(zhp, nv, newpath);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_add_string(nv,
99653d4ee642c6528e88224f12409a5f23060994eschrock ZPOOL_CONFIG_PATH, newpath) == 0)
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_string(nv,
99653d4ee642c6528e88224f12409a5f23060994eschrock ZPOOL_CONFIG_PATH,
99653d4ee642c6528e88224f12409a5f23060994eschrock &path) == 0);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock free(newpath);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (newdevid)
99653d4ee642c6528e88224f12409a5f23060994eschrock devid_str_free(newdevid);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews if (strncmp(path, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0)
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews path += strlen(ZFS_DISK_ROOTD);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &value) == 0 && value) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres int pathlen = strlen(path);
99653d4ee642c6528e88224f12409a5f23060994eschrock char *tmp = zfs_strdup(hdl, path);
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres /*
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * If it starts with c#, and ends with "s0", chop
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * the "s0" off, or if it ends with "s0/old", remove
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres * the "s0" from the middle.
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres */
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (CTD_CHECK(tmp)) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres if (strcmp(&tmp[pathlen - 2], "s0") == 0) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres tmp[pathlen - 2] = '\0';
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres } else if (pathlen > 6 &&
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres strcmp(&tmp[pathlen - 6], "s0/old") == 0) {
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres (void) strcpy(&tmp[pathlen - 6],
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres "/old");
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres }
3fdda4994a108ded4ec1a2b544804f191a4ec83aJohn Harres }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock return (tmp);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock } else {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock /*
99653d4ee642c6528e88224f12409a5f23060994eschrock * If it's a raidz device, we need to stick in the parity level.
99653d4ee642c6528e88224f12409a5f23060994eschrock */
99653d4ee642c6528e88224f12409a5f23060994eschrock if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
99653d4ee642c6528e88224f12409a5f23060994eschrock &value) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(buf, sizeof (buf), "%s%llu", path,
5ad820458efd0fdb914baff9c1447c22b819fa23nd (u_longlong_t)value);
99653d4ee642c6528e88224f12409a5f23060994eschrock path = buf;
99653d4ee642c6528e88224f12409a5f23060994eschrock }
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson /*
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * We identify each top-level vdev by using a <type-id>
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * naming convention.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson */
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (verbose) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson uint64_t id;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson &id) == 0);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson (void) snprintf(buf, sizeof (buf), "%s-%llu", path,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson (u_longlong_t)id);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson path = buf;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock }
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock return (zfs_strdup(hdl, path));
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockstatic int
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagneliezbookmark_mem_compare(const void *a, const void *b)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens return (memcmp(a, b, sizeof (zbookmark_phys_t)));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock/*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Retrieve the persistent error log, uniquify the members, and return to the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * caller.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockint
55434c770c89aa1b84474f2559a106803511aba0ekzpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock{
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zfs_cmd_t zc = { 0 };
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock uint64_t count;
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens zbookmark_phys_t *zb = NULL;
55434c770c89aa1b84474f2559a106803511aba0ek int i;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Retrieve the raw error list from the kernel. If the number of errors
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * has increased, allocate more space and continue until we get the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * entire list.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock &count) == 0);
75519f380eac71fe6d10b26e736f01567d6c13c9ek if (count == 0)
75519f380eac71fe6d10b26e736f01567d6c13c9ek return (0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens count * sizeof (zbookmark_phys_t))) == (uintptr_t)NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zc.zc_nvlist_dst_size = count;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) strcpy(zc.zc_name, zhp->zpool_name);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock for (;;) {
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
99653d4ee642c6528e88224f12409a5f23060994eschrock &zc) != 0) {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock free((void *)(uintptr_t)zc.zc_nvlist_dst);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (errno == ENOMEM) {
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens void *dst;
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens
bf561db0030e7d3435bcc1e1f5889fac05a18814vb count = zc.zc_nvlist_dst_size;
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens dst = zfs_alloc(zhp->zpool_hdl, count *
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens sizeof (zbookmark_phys_t));
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens if (dst == NULL)
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens zc.zc_nvlist_dst = (uintptr_t)dst;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (-1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock break;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Sort the resulting bookmarks. This is a little confusing due to the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * implementation of ZFS_IOC_ERROR_LOG. The bookmarks are copied last
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * _not_ copied as part of the process. So we point the start of our
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * array appropriate and decrement the total number of elements.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
7802d7bf98dec568dadf72286893b1fe5abd8602Matthew Ahrens zb = ((zbookmark_phys_t *)(uintptr_t)zc.zc_nvlist_dst) +
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zc.zc_nvlist_dst_size;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock count -= zc.zc_nvlist_dst_size;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
55434c770c89aa1b84474f2559a106803511aba0ek verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /*
55434c770c89aa1b84474f2559a106803511aba0ek * Fill in the nverrlistp with nvlist's of dataset and object numbers.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock for (i = 0; i < count; i++) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock nvlist_t *nv;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
c0a81264b59ba24de8701436570c3aae5689dc89ek /* ignoring zb_blkid and zb_level for now */
c0a81264b59ba24de8701436570c3aae5689dc89ek if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
c0a81264b59ba24de8701436570c3aae5689dc89ek zb[i-1].zb_object == zb[i].zb_object)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock continue;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
55434c770c89aa1b84474f2559a106803511aba0ek if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
55434c770c89aa1b84474f2559a106803511aba0ek goto nomem;
55434c770c89aa1b84474f2559a106803511aba0ek if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
55434c770c89aa1b84474f2559a106803511aba0ek zb[i].zb_objset) != 0) {
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nv);
99653d4ee642c6528e88224f12409a5f23060994eschrock goto nomem;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
55434c770c89aa1b84474f2559a106803511aba0ek if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
55434c770c89aa1b84474f2559a106803511aba0ek zb[i].zb_object) != 0) {
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nv);
55434c770c89aa1b84474f2559a106803511aba0ek goto nomem;
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nv);
55434c770c89aa1b84474f2559a106803511aba0ek goto nomem;
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek nvlist_free(nv);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
3ccfa83cd9cddd1e34808ba18082c156758c5ec8ahrens free((void *)(uintptr_t)zc.zc_nvlist_dst);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrocknomem:
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock free((void *)(uintptr_t)zc.zc_nvlist_dst);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (no_memory(zhp->zpool_hdl));
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock/*
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * Upgrade a ZFS pool to the latest on-disk version.
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock */
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrockint
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock{
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock zfs_cmd_t zc = { 0 };
99653d4ee642c6528e88224f12409a5f23060994eschrock libzfs_handle_t *hdl = zhp->zpool_hdl;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock (void) strcpy(zc.zc_name, zhp->zpool_name);
990b4856d0eaada6f8140335733a1b1771ed2746lling zc.zc_cookie = new_version;
990b4856d0eaada6f8140335733a1b1771ed2746lling
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (zpool_standard_error_fmt(hdl, errno,
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
99653d4ee642c6528e88224f12409a5f23060994eschrock zhp->zpool_name));
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ekvoid
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszfs_save_arguments(int argc, char **argv, char *string, int len)
06eeb2ad640ce72d394ac521094bed7681044408ek{
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens (void) strlcpy(string, basename(argv[0]), len);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens for (int i = 1; i < argc; i++) {
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens (void) strlcat(string, " ", len);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens (void) strlcat(string, argv[i], len);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek }
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek}
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ekint
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrenszpool_log_history(libzfs_handle_t *hdl, const char *message)
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek{
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens zfs_cmd_t zc = { 0 };
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens nvlist_t *args;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens int err;
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens args = fnvlist_alloc();
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens fnvlist_add_string(args, "message", message);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens err = zcmd_write_src_nvlist(hdl, &zc, args);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens if (err == 0)
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens nvlist_free(args);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens zcmd_free_nvlists(&zc);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens return (err);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek/*
06eeb2ad640ce72d394ac521094bed7681044408ek * Perform ioctl to get some command history of a pool.
06eeb2ad640ce72d394ac521094bed7681044408ek *
06eeb2ad640ce72d394ac521094bed7681044408ek * 'buf' is the buffer to fill up to 'len' bytes. 'off' is the
06eeb2ad640ce72d394ac521094bed7681044408ek * logical offset of the history buffer to start reading from.
06eeb2ad640ce72d394ac521094bed7681044408ek *
06eeb2ad640ce72d394ac521094bed7681044408ek * Upon return, 'off' is the next logical offset to read from and
06eeb2ad640ce72d394ac521094bed7681044408ek * 'len' is the actual amount of bytes read into 'buf'.
06eeb2ad640ce72d394ac521094bed7681044408ek */
06eeb2ad640ce72d394ac521094bed7681044408ekstatic int
06eeb2ad640ce72d394ac521094bed7681044408ekget_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
06eeb2ad640ce72d394ac521094bed7681044408ek{
06eeb2ad640ce72d394ac521094bed7681044408ek zfs_cmd_t zc = { 0 };
06eeb2ad640ce72d394ac521094bed7681044408ek libzfs_handle_t *hdl = zhp->zpool_hdl;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek zc.zc_history = (uint64_t)(uintptr_t)buf;
06eeb2ad640ce72d394ac521094bed7681044408ek zc.zc_history_len = *len;
06eeb2ad640ce72d394ac521094bed7681044408ek zc.zc_history_offset = *off;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
06eeb2ad640ce72d394ac521094bed7681044408ek switch (errno) {
06eeb2ad640ce72d394ac521094bed7681044408ek case EPERM:
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (zfs_error_fmt(hdl, EZFS_PERM,
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling dgettext(TEXT_DOMAIN,
06eeb2ad640ce72d394ac521094bed7681044408ek "cannot show history for pool '%s'"),
06eeb2ad640ce72d394ac521094bed7681044408ek zhp->zpool_name));
06eeb2ad640ce72d394ac521094bed7681044408ek case ENOENT:
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
06eeb2ad640ce72d394ac521094bed7681044408ek dgettext(TEXT_DOMAIN, "cannot get history for pool "
06eeb2ad640ce72d394ac521094bed7681044408ek "'%s'"), zhp->zpool_name));
d7306b64c847d897abb9ece8624fca9cf28d358fek case ENOTSUP:
d7306b64c847d897abb9ece8624fca9cf28d358fek return (zfs_error_fmt(hdl, EZFS_BADVERSION,
d7306b64c847d897abb9ece8624fca9cf28d358fek dgettext(TEXT_DOMAIN, "cannot get history for pool "
d7306b64c847d897abb9ece8624fca9cf28d358fek "'%s', pool must be upgraded"), zhp->zpool_name));
06eeb2ad640ce72d394ac521094bed7681044408ek default:
ece3d9b3bacef51a5f34d993935eedbb7bb87059lling return (zpool_standard_error_fmt(hdl, errno,
06eeb2ad640ce72d394ac521094bed7681044408ek dgettext(TEXT_DOMAIN,
06eeb2ad640ce72d394ac521094bed7681044408ek "cannot get history for '%s'"), zhp->zpool_name));
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek *len = zc.zc_history_len;
06eeb2ad640ce72d394ac521094bed7681044408ek *off = zc.zc_history_offset;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek return (0);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek/*
06eeb2ad640ce72d394ac521094bed7681044408ek * Process the buffer of nvlists, unpacking and storing each nvlist record
06eeb2ad640ce72d394ac521094bed7681044408ek * into 'records'. 'leftover' is set to the number of bytes that weren't
06eeb2ad640ce72d394ac521094bed7681044408ek * processed as there wasn't a complete record.
06eeb2ad640ce72d394ac521094bed7681044408ek */
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilsonint
06eeb2ad640ce72d394ac521094bed7681044408ekzpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_t ***records, uint_t *numrecords)
06eeb2ad640ce72d394ac521094bed7681044408ek{
06eeb2ad640ce72d394ac521094bed7681044408ek uint64_t reclen;
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_t *nv;
06eeb2ad640ce72d394ac521094bed7681044408ek int i;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek while (bytes_read > sizeof (reclen)) {
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek /* get length of packed record (stored as little endian) */
06eeb2ad640ce72d394ac521094bed7681044408ek for (i = 0, reclen = 0; i < sizeof (reclen); i++)
06eeb2ad640ce72d394ac521094bed7681044408ek reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if (bytes_read < sizeof (reclen) + reclen)
06eeb2ad640ce72d394ac521094bed7681044408ek break;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek /* unpack record */
06eeb2ad640ce72d394ac521094bed7681044408ek if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek return (ENOMEM);
06eeb2ad640ce72d394ac521094bed7681044408ek bytes_read -= sizeof (reclen) + reclen;
06eeb2ad640ce72d394ac521094bed7681044408ek buf += sizeof (reclen) + reclen;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek /* add record to nvlist array */
06eeb2ad640ce72d394ac521094bed7681044408ek (*numrecords)++;
06eeb2ad640ce72d394ac521094bed7681044408ek if (ISP2(*numrecords + 1)) {
06eeb2ad640ce72d394ac521094bed7681044408ek *records = realloc(*records,
06eeb2ad640ce72d394ac521094bed7681044408ek *numrecords * 2 * sizeof (nvlist_t *));
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek (*records)[*numrecords - 1] = nv;
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek *leftover = bytes_read;
06eeb2ad640ce72d394ac521094bed7681044408ek return (0);
06eeb2ad640ce72d394ac521094bed7681044408ek}
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek/*
06eeb2ad640ce72d394ac521094bed7681044408ek * Retrieve the command history of a pool.
06eeb2ad640ce72d394ac521094bed7681044408ek */
06eeb2ad640ce72d394ac521094bed7681044408ekint
06eeb2ad640ce72d394ac521094bed7681044408ekzpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
06eeb2ad640ce72d394ac521094bed7681044408ek{
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens char *buf;
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens int buflen = 128 * 1024;
06eeb2ad640ce72d394ac521094bed7681044408ek uint64_t off = 0;
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_t **records = NULL;
06eeb2ad640ce72d394ac521094bed7681044408ek uint_t numrecords = 0;
06eeb2ad640ce72d394ac521094bed7681044408ek int err, i;
06eeb2ad640ce72d394ac521094bed7681044408ek
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens buf = malloc(buflen);
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens if (buf == NULL)
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens return (ENOMEM);
06eeb2ad640ce72d394ac521094bed7681044408ek do {
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens uint64_t bytes_read = buflen;
06eeb2ad640ce72d394ac521094bed7681044408ek uint64_t leftover;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek break;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek /* if nothing else was read in, we're at EOF, just return */
06eeb2ad640ce72d394ac521094bed7681044408ek if (!bytes_read)
06eeb2ad640ce72d394ac521094bed7681044408ek break;
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek if ((err = zpool_history_unpack(buf, bytes_read,
06eeb2ad640ce72d394ac521094bed7681044408ek &leftover, &records, &numrecords)) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek break;
06eeb2ad640ce72d394ac521094bed7681044408ek off -= leftover;
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens if (leftover == bytes_read) {
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens /*
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens * no progress made, because buffer is not big enough
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens * to hold this record; resize and retry.
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens */
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens buflen *= 2;
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens free(buf);
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens buf = malloc(buflen);
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens if (buf == NULL)
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens return (ENOMEM);
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens }
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek /* CONSTCOND */
06eeb2ad640ce72d394ac521094bed7681044408ek } while (1);
06eeb2ad640ce72d394ac521094bed7681044408ek
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens free(buf);
3339867a862f63acdad71abd574d5d79e18d8579Matthew Ahrens
06eeb2ad640ce72d394ac521094bed7681044408ek if (!err) {
06eeb2ad640ce72d394ac521094bed7681044408ek verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
06eeb2ad640ce72d394ac521094bed7681044408ek verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
06eeb2ad640ce72d394ac521094bed7681044408ek records, numrecords) == 0);
06eeb2ad640ce72d394ac521094bed7681044408ek }
06eeb2ad640ce72d394ac521094bed7681044408ek for (i = 0; i < numrecords; i++)
06eeb2ad640ce72d394ac521094bed7681044408ek nvlist_free(records[i]);
06eeb2ad640ce72d394ac521094bed7681044408ek free(records);
06eeb2ad640ce72d394ac521094bed7681044408ek
06eeb2ad640ce72d394ac521094bed7681044408ek return (err);
06eeb2ad640ce72d394ac521094bed7681044408ek}
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ekvoid
55434c770c89aa1b84474f2559a106803511aba0ekzpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
55434c770c89aa1b84474f2559a106803511aba0ek char *pathname, size_t len)
55434c770c89aa1b84474f2559a106803511aba0ek{
55434c770c89aa1b84474f2559a106803511aba0ek zfs_cmd_t zc = { 0 };
55434c770c89aa1b84474f2559a106803511aba0ek boolean_t mounted = B_FALSE;
55434c770c89aa1b84474f2559a106803511aba0ek char *mntpnt = NULL;
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char dsname[ZFS_MAX_DATASET_NAME_LEN];
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek if (dsobj == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek /* special case for the MOS */
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
55434c770c89aa1b84474f2559a106803511aba0ek return;
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek /* get the dataset's name */
55434c770c89aa1b84474f2559a106803511aba0ek (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
55434c770c89aa1b84474f2559a106803511aba0ek zc.zc_obj = dsobj;
55434c770c89aa1b84474f2559a106803511aba0ek if (ioctl(zhp->zpool_hdl->libzfs_fd,
55434c770c89aa1b84474f2559a106803511aba0ek ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
55434c770c89aa1b84474f2559a106803511aba0ek /* just write out a path of two object numbers */
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
55434c770c89aa1b84474f2559a106803511aba0ek dsobj, obj);
55434c770c89aa1b84474f2559a106803511aba0ek return;
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek /* find out if the dataset is mounted */
55434c770c89aa1b84474f2559a106803511aba0ek mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
55434c770c89aa1b84474f2559a106803511aba0ek
55434c770c89aa1b84474f2559a106803511aba0ek /* get the corrupted object's path */
55434c770c89aa1b84474f2559a106803511aba0ek (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
55434c770c89aa1b84474f2559a106803511aba0ek zc.zc_obj = obj;
55434c770c89aa1b84474f2559a106803511aba0ek if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
55434c770c89aa1b84474f2559a106803511aba0ek &zc) == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek if (mounted) {
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "%s%s", mntpnt,
55434c770c89aa1b84474f2559a106803511aba0ek zc.zc_value);
55434c770c89aa1b84474f2559a106803511aba0ek } else {
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "%s:%s",
55434c770c89aa1b84474f2559a106803511aba0ek dsname, zc.zc_value);
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek } else {
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
55434c770c89aa1b84474f2559a106803511aba0ek }
55434c770c89aa1b84474f2559a106803511aba0ek free(mntpnt);
55434c770c89aa1b84474f2559a106803511aba0ek}
b1b8ab34de515a5e83206da22c3d7e563241b021lling
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw/*
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * Read the EFI label from the config, if a label does not exist then
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * pass back the error to the caller. If the caller has passed a non-NULL
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * diskaddr argument then we set it to the starting address of the EFI
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * partition.
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw */
15e6edf145a9c2bb0e0272cf8debe823bb97529bgwstatic int
15e6edf145a9c2bb0e0272cf8debe823bb97529bgwread_efi_label(nvlist_t *config, diskaddr_t *sb)
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw{
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw char *path;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw int fd;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw char diskname[MAXPATHLEN];
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw int err = -1;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw return (err);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews (void) snprintf(diskname, sizeof (diskname), "%s%s", ZFS_RDISK_ROOT,
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw strrchr(path, '/'));
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw struct dk_gpt *vtoc;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if (sb != NULL)
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw *sb = vtoc->efi_parts[0].p_start;
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw efi_free(vtoc);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw }
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw (void) close(fd);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw }
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw return (err);
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw}
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor/*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * determine where a partition starts on a disk in the current
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * configuration
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylorstatic diskaddr_t
8488aeb5df27784d479c16cde06a9e25cd9a1152taylorfind_start_block(nvlist_t *config)
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor{
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor nvlist_t **child;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor uint_t c, children;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor diskaddr_t sb = MAXOFFSET_T;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor uint64_t wholedisk;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (nvlist_lookup_nvlist_array(config,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (nvlist_lookup_uint64(config,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor ZPOOL_CONFIG_WHOLE_DISK,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor &wholedisk) != 0 || !wholedisk) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (MAXOFFSET_T);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if (read_efi_label(config, &sb) < 0)
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw sb = MAXOFFSET_T;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (sb);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor for (c = 0; c < children; c++) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor sb = find_start_block(child[c]);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (sb != MAXOFFSET_T) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (sb);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (MAXOFFSET_T);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor}
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor/*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Label an individual disk. The name provided is the short name,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * stripped of any leading /dev path.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylorint
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrewszpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor{
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor char path[MAXPATHLEN];
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor struct dk_gpt *vtoc;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor int fd;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor size_t resv = EFI_MIN_RESV_SIZE;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor uint64_t slice_size;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor diskaddr_t start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor char errbuf[1024];
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante /* prepare an error message just in case */
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante (void) snprintf(errbuf, sizeof (errbuf),
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (zhp) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor nvlist_t *nvroot;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor verify(nvlist_lookup_nvlist(zhp->zpool_config,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (zhp->zpool_start_block == 0)
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor start_block = find_start_block(nvroot);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor else
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor start_block = zhp->zpool_start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor zhp->zpool_start_block = start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor } else {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /* new pool */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor start_block = NEW_START_BLOCK;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
6401734d545a04c18f68b448202f9d9a77216bb9Will Andrews (void) snprintf(path, sizeof (path), "%s/%s%s", ZFS_RDISK_ROOT, name,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor BACKUP_SLICE);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * This shouldn't happen. We've long since verified that this
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * is a valid device.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante zfs_error_aux(hdl,
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante dgettext(TEXT_DOMAIN, "unable to open device"));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * The only way this can fail is if we run out of memory, or we
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * were unable to read the disk's capacity
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (errno == ENOMEM)
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) no_memory(hdl);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) close(fd);
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante "unable to read disk capacity"), name);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (zfs_error(hdl, EZFS_NOCAP, errbuf));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor slice_size = vtoc->efi_last_u_lba + 1;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor slice_size -= EFI_MIN_RESV_SIZE;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (start_block == MAXOFFSET_T)
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor start_block = NEW_START_BLOCK;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor slice_size -= start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[0].p_start = start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[0].p_size = slice_size;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Why we use V_USR: V_BACKUP confuses users, and is considered
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * disposable by some EFI utilities (since EFI doesn't have a backup
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * slice). V_UNASSIGNED is supposed to be used only for zero size
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * partitions, and efi_write() will fail if we use it. V_ROOT, V_BOOT,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * etc. were all pretty specific. V_USR is as close to reality as we
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * can get, in the absence of V_OTHER.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[0].p_tag = V_USR;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[8].p_start = slice_size + start_block;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[8].p_size = resv;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor vtoc->efi_parts[8].p_tag = V_RESERVED;
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (efi_write(fd, vtoc) != 0) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /*
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Some block drivers (like pcata) may not support EFI
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * GPT labels. Print out a helpful error message dir-
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * ecting the user to manually label the disk and give
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * a specific slice.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) close(fd);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor efi_free(vtoc);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante "try using fdisk(1M) and then provide a specific slice"));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor }
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) close(fd);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor efi_free(vtoc);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (0);
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor}
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwstatic boolean_t
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwsupported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw{
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw char *type;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw nvlist_t **child;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw uint_t children, c;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski if (strcmp(type, VDEV_TYPE_FILE) == 0 ||
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson strcmp(type, VDEV_TYPE_HOLE) == 0 ||
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw strcmp(type, VDEV_TYPE_MISSING) == 0) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "vdev type '%s' is not supported"), type);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (B_FALSE);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw &child, &children) == 0) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw for (c = 0; c < children; c++) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (!supported_dump_vdev_type(hdl, child[c], errbuf))
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (B_FALSE);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (B_TRUE);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw}
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw/*
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * Check if this zvol is allowable for use as a dump device; zero if
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * it is, > 0 if it isn't, < 0 if it isn't a zvol.
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski *
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * Allowable storage configurations include mirrors, all raidz variants, and
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * pools with log, cache, and spare devices. Pools which are backed by files or
810e43b2eb0e320833671a403fdda51917e8b036Bill Pijewski * have missing/hole vdevs are not suitable.
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw */
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwint
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwzvol_check_dump_config(char *arg)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw{
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zpool_handle_t *zhp = NULL;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw nvlist_t *config, *nvroot;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw char *p, *volname;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw nvlist_t **top;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw uint_t toplevels;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw libzfs_handle_t *hdl;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw char errbuf[1024];
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char poolname[ZFS_MAX_DATASET_NAME_LEN];
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw int pathlen = strlen(ZVOL_FULL_DEV_DIR);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw int ret = 1;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (-1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "dump is not supported on device '%s'"), arg);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if ((hdl = libzfs_init()) == NULL)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw libzfs_print_on_error(hdl, B_TRUE);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw volname = arg + pathlen;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw /* check the configuration of the pool */
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if ((p = strchr(volname, '/')) == NULL) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "malformed dataset name"));
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens } else if (p - volname >= ZFS_MAX_DATASET_NAME_LEN) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "dataset name is too long"));
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw } else {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) strncpy(poolname, volname, p - volname);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw poolname[p - volname] = '\0';
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if ((zhp = zpool_open(hdl, poolname)) == NULL) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "could not open pool '%s'"), poolname);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw goto out;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw config = zpool_get_config(zhp, NULL);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw &nvroot) != 0) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "could not obtain vdev configuration for '%s'"), poolname);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw goto out;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw &top, &toplevels) == 0);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (!supported_dump_vdev_type(hdl, top[0], errbuf)) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw goto out;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw }
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ret = 0;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwout:
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (zhp)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zpool_close(zhp);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw libzfs_fini(hdl);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (ret);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw}