libzfs_pool.c revision 069f55e237020c4a4907b235fc38fafc6442ce94
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
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 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
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 * CDDL HEADER END
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "invalid event",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool create",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool remove",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool destroy",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool export",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool import",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev attach",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev replace",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev detach",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev online",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev offline",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "vdev upgrade",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool clear",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool scrub",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool property set",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "destroy_begin_sync",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "property set",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "permission update",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "permission remove",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "permission who remove",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "reservation set",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "replay_inc_sync",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "replay_full_sync",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "filesystem version upgrade",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "refquota set",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "refreservation set",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "pool scrub done",
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "user release",
15e6edf145a9c2bb0e0272cf8debe823bb97529bgwstatic int read_efi_label(nvlist_t *config, diskaddr_t *sb);
990b4856d0eaada6f8140335733a1b1771ed2746lling * ====================================================================
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool property functions
990b4856d0eaada6f8140335733a1b1771ed2746lling * ====================================================================
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746llingstatic char *
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
b87f3af36bb994656da117319f5129ddfd05ed21perrin if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
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.
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
990b4856d0eaada6f8140335733a1b1771ed2746lling * Map VDEV STATE to printed strings.
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
b87f3af36bb994656da117319f5129ddfd05ed21perrin if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
990b4856d0eaada6f8140335733a1b1771ed2746lling * Get a zpool property value for 'prop' and return the value in
990b4856d0eaada6f8140335733a1b1771ed2746lling * a pre-allocated buffer.
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
990b4856d0eaada6f8140335733a1b1771ed2746lling const char *strval;
379c004d1f26b343f034bba8a350290691d00d38Eric Schrock /* FALLTHROUGH */
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
990b4856d0eaada6f8140335733a1b1771ed2746lling * Check if the bootfs name has the same pool name as it is set to.
990b4856d0eaada6f8140335733a1b1771ed2746lling * Assuming bootfs is a valid dataset name.
fe3e2633be44d2f5361a7bba26abeb80fcc04fbcEric Taylor if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * Inspect the configuration to determine if any of the devices contain
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * an EFI label.
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw for (c = 0; c < children; c++) {
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson sizeof (bootfs)) != 0);
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.
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimhzpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
990b4856d0eaada6f8140335733a1b1771ed2746lling nvlist_t *props, uint64_t version, boolean_t create_or_import, char *errbuf)
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling * Make sure this property is valid and applies to this type.
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
990b4856d0eaada6f8140335733a1b1771ed2746lling * Perform additional checking for specific properties.
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' number %d is invalid."),
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' cannot be set at creation "
990b4856d0eaada6f8140335733a1b1771ed2746lling "pool must be upgraded to support "
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.
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * bootfs property cannot be set on a disk which has
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw * been EFI labeled.
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw "property '%s' not supported on "
990b4856d0eaada6f8140335733a1b1771ed2746lling "property '%s' can only be set during pool "
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "property '%s' must be empty, an "
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock "'%s' is not a valid directory"),
990b4856d0eaada6f8140335733a1b1771ed2746lling * Set zpool property : propname=propval.
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
990b4856d0eaada6f8140335733a1b1771ed2746lling dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
990b4856d0eaada6f8140335733a1b1771ed2746lling version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
990b4856d0eaada6f8140335733a1b1771ed2746lling zhp->zpool_name, nvl, version, B_FALSE, errbuf)) == NULL) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling * Execute the corresponding ioctl() to set this property.
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
990b4856d0eaada6f8140335733a1b1771ed2746lling if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling for (entry = *plp; entry != NULL; entry = entry->pl_next) {
990b4856d0eaada6f8140335733a1b1771ed2746lling zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
990b4856d0eaada6f8140335733a1b1771ed2746lling return (0);
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.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Validate the given pool name, optionally putting an extended error message in
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
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 if (ret != 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock "name must begin with a letter"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "name is reserved"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "pool name is reserved"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd "leading slash in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd "empty component in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd "trailing slash in name"));
5ad820458efd0fdb914baff9c1447c22b819fa23nd "multiple '@' delimiters in name"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Open a handle to the given pool, even if the pool is currently in the FAULTED
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Make sure the pool name is valid.
99653d4ee642c6528e88224f12409a5f23060994eschrock if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
990b4856d0eaada6f8140335733a1b1771ed2746lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Like the above, but silent on error. Used when iterating over pools (because
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the configuration cache may be out of date).
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrockzpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (-1);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (0);
94de1d4cf6ec0a3bf040dcc4b8df107c4ed36b51eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
99653d4ee642c6528e88224f12409a5f23060994eschrock dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Close the handle. Simply frees the memory associated with the handle.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return the name of the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Return the state of the pool (ACTIVE or UNAVAILABLE)
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.
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
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
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more vdevs refer to the same device"));
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.
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is less than the "
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is out of space"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "cache device must be a disk or disk slice"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If this is an alternate root pool, then we automatically set the
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * mountpoint of the root dataset to be '/'.
990b4856d0eaada6f8140335733a1b1771ed2746lling if (nvlist_lookup_string(props, zpool_prop_to_name(ZPOOL_PROP_ALTROOT),
990b4856d0eaada6f8140335733a1b1771ed2746lling verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_DATASET)) != NULL);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock "/") == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Destroy the given pool. It is up to the caller to ensure that there are no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * datasets left in the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more devices is read only"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
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.
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
99653d4ee642c6528e88224f12409a5f23060994eschrock "upgraded to add hot spares"));
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson for (s = 0; s < nspares; s++) {
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson "device '%s' contains an EFI label and "
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson "cannot be used on root pools."),
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "upgraded to add cache devices"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
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
99653d4ee642c6528e88224f12409a5f23060994eschrock "one or more vdevs refer to the same device"));
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.
99653d4ee642c6528e88224f12409a5f23060994eschrock "device is less than the minimum "
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "pool must be upgraded to add these vdevs"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "root pool can not have multiple vdevs"
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin " or separate logs"));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan "cache device must be a disk or disk slice"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Exports the pool from the system. The caller must ensure that there are no
fa9e4066f08beec538e775443c5be79dd423fcabahrens * mounted datasets in the pool.
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilsonzpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce)
89a89ebfd7c3b4056afe2c03e959e22824df777dlling (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
89a89ebfd7c3b4056afe2c03e959e22824df777dlling if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
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 return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilsonzpool_export(zpool_handle_t *zhp, boolean_t force)
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson return (zpool_export_common(zhp, force, B_FALSE));
394ab0cbe9de0b3be5bf232d9224a9d050999ae5George Wilson return (zpool_export_common(zhp, B_TRUE, B_TRUE));
990b4856d0eaada6f8140335733a1b1771ed2746lling * zpool_import() is a contracted interface. Should be kept the same
990b4856d0eaada6f8140335733a1b1771ed2746lling * if possible.
990b4856d0eaada6f8140335733a1b1771ed2746lling * Applications should use zpool_import_props() to import a pool with
990b4856d0eaada6f8140335733a1b1771ed2746lling * new properties value to be set.
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
352d8027a91dfc2f3c5bdda788b82548169bf512George Wilson zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
352d8027a91dfc2f3c5bdda788b82548169bf512George Wilson zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
c5904d138f3bdf0762dbf452a43d5a5c387ea6a8eschrock ret = zpool_import_props(hdl, config, newname, props, B_FALSE);
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.
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
990b4856d0eaada6f8140335733a1b1771ed2746lling verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
351420b34707afeafa8d5c3e0c77b7bcffb1edc0lling } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
990b4856d0eaada6f8140335733a1b1771ed2746lling return (-1);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
fa9e4066f08beec538e775443c5be79dd423fcabahrens verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Unsupported version.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This should never fail, but play it safe anyway.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Scrub the pool.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_scrub(zpool_handle_t *zhp, pool_scrub_type_t type)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SCRUB, &zc) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
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.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonvdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson nvpair_t *pair = nvlist_next_nvpair(search, NULL);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /* Nothing to look for */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /* Obtain the key we will use to search */
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvpair_value_uint64(pair, &srchval) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * If the device has never been present since
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * import, the only reliable way to match the
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * vdev is by GUID.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvpair_value_string(pair, &srchval) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (nvlist_lookup_string(nv, srchkey, &val) != 0)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Search for the requested value. We special case the search
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * for ZPOOL_CONFIG_PATH when it's a wholedisk and when
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Otherwise, all other searches are simple string compares.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 && val) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * For whole disks, the internal path has 's0',
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * but the path passed in by the user doesn't.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
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 * If the types don't match then keep looking.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Now verify that we have the correct vdev id.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Common case
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
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).
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan for (c = 0; c < children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((ret = vdev_to_nvlist_iter(child[c], search,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Given a physical path (minus the "/devices" prefix), find the
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * associated vdev.
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 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 verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
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)
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendanzpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
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)
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * Helper function for zpool_get_physpaths().
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Lingvdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* if physpath was not copied properly, clear it */
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Lingvdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
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 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling for (i = 0; i < count; i++) {
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Get phys_path for a root pool config.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 0 on success; non-zero on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorezpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
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 * root pool can not have EFI labeled disks and can only have
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * a single top-level vdev.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore /* No online devices */
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Get phys_path for a root pool
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore * Return 0 on success; non-zero on failure.
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moorezpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
753a6d457b330b1b29b2d3eefcd0831116ce950dSherry Moore return (zpool_get_config_physpath(zhp->zpool_config, physpath,
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 Wilsonzpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
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 * 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 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "relabel '%s': unable to read disk capacity"), name);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Bring the specified vdev online. The 'flags' parameter is a set of the
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * ZFS_ONLINE_* flags.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson dgettext(TEXT_DOMAIN, "cannot online %s"), path);
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,
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * XXX - L2ARC 1.0 devices can't support expansion.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson "cannot expand cache devices"));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) zpool_relabel_disk(zhp->zpool_hdl, pathname);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Take the specified vdev offline
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
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,
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * There are no other replicas of this device.
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson * The log device has unplayed logs
e6ca193ded880d478cc39e34ef82d4be36e4445dGeorge Wilson return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Mark the given vdev faulted.
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrockzpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There are no other replicas of this device.
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Mark the given vdev degraded.
069f55e237020c4a4907b235fc38fafc6442ce94Eric Schrockzpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
99653d4ee642c6528e88224f12409a5f23060994eschrock * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
99653d4ee642c6528e88224f12409a5f23060994eschrock * a hot spare.
99653d4ee642c6528e88224f12409a5f23060994eschrockis_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
99653d4ee642c6528e88224f12409a5f23060994eschrock for (c = 0; c < children; c++)
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 const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson * If this is a root pool, make sure that we're not attaching an
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson * EFI labeled device.
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson "EFI labeled devices are not supported on root pools."));
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
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,
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
99653d4ee642c6528e88224f12409a5f23060994eschrock "new device must be a single disk"));
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
0430f8daa551890e0788d3fd28aef3be44cf8730eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock * If the target is a hot spare that has been swapped in, we can only
99653d4ee642c6528e88224f12409a5f23060994eschrock * replace it with another hot spare.
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
ee0eb9f2d12b8a03b5a193cd667735c1962e0c7bEric Schrock (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
99653d4ee642c6528e88224f12409a5f23060994eschrock "can only be replaced by another hot spare"));
99653d4ee642c6528e88224f12409a5f23060994eschrock * If we are attempting to replace a spare, it canot be applied to an
99653d4ee642c6528e88224f12409a5f23060994eschrock * already spared device.
99653d4ee642c6528e88224f12409a5f23060994eschrock nvlist_lookup_string(child[0], ZPOOL_CONFIG_PATH, &path) == 0 &&
99653d4ee642c6528e88224f12409a5f23060994eschrock "device has already been replaced with a spare"));
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_VDEV_ATTACH, &zc);
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson * XXX - This should be removed once we can
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson * automatically install the bootblocks on the
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson * newly attached disk.
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please "
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson "be sure to invoke %s to make '%s' bootable.\n"),
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * XXX need a better way to prevent user from
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling * booting up a half-baked vdev.
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling "sure to wait until resilver is done "
21ecdf64e1e200cd74cadf771fc7ddc3d0062080Lin Ling "before rebooting.\n"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Can't attach to or replace this type of vdev.
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "cannot replace a log with a spare"));
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin "cannot replace a replacing device"));
99653d4ee642c6528e88224f12409a5f23060994eschrock "can only attach to mirrors and top-level "
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device must be a single disk.
99653d4ee642c6528e88224f12409a5f23060994eschrock "new device must be a single disk"));
99653d4ee642c6528e88224f12409a5f23060994eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device is too small.
99653d4ee642c6528e88224f12409a5f23060994eschrock "device is too small"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The new device has a different alignment requirement.
99653d4ee642c6528e88224f12409a5f23060994eschrock "devices have different sector alignment"));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The resulting top-level vdev spec won't fit in the label.
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Detach the specified device.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszpool_vdev_detach(zpool_handle_t *zhp, const char *path)
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,
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Can't detach from this type of vdev.
99653d4ee642c6528e88224f12409a5f23060994eschrock "applicable to mirror and replacing vdevs"));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) zfs_error(zhp->zpool_hdl, EZFS_BADTARGET, msg);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There are no other replicas of this device.
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Remove the given device. Currently, this is supported only for hot spares
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * and level 2 cache devices.
99653d4ee642c6528e88224f12409a5f23060994eschrockzpool_vdev_remove(zpool_handle_t *zhp, const char *path)
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 * XXX - this should just go away.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "only inactive hot spares, cache, top-level, "
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "or log devices can be removed"));
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson "pool must be upgrade to support log removal"));
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson return (zfs_error(hdl, EZFS_BADVERSION, msg));
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Clear the errors for the pool, or the particular device if specified.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * Don't allow error clearing for hot spares. Do allow
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan * error clearing for l2cache devices.
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
99653d4ee642c6528e88224f12409a5f23060994eschrock return (0);
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock * Similar to zpool_clear(), but takes a GUID (used by fmd).
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrockzpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
3d7072f8bd27709dba14f6fe336f149d25d9e207eschrock return (0);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Convert from a devid string to a path.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockstatic char *
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (devid_str_decode(devid_str, &devid, &minor) != 0)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Convert from a path to a devid string.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockstatic char *
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.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrockset_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
99653d4ee642c6528e88224f12409a5f23060994eschrock (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
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 * 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.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilsonzpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
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 if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Determine if the current path is correct.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock * Update the path appropriately.
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
c67d9675bbc8392fe45f3a7dfbda1ad4daa1eb07eschrock verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock * If it's a raidz device, we need to stick in the parity level.
99653d4ee642c6528e88224f12409a5f23060994eschrock verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * We identify each top-level vdev by using a <type-id>
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * naming convention.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson (void) snprintf(buf, sizeof (buf), "%s-%llu", path,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockzbookmark_compare(const void *a, const void *b)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Retrieve the persistent error log, uniquify the members, and return to the
55434c770c89aa1b84474f2559a106803511aba0ekzpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
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 verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
75519f380eac71fe6d10b26e736f01567d6c13c9ek return (0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
99653d4ee642c6528e88224f12409a5f23060994eschrock if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
99653d4ee642c6528e88224f12409a5f23060994eschrock return (-1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (-1);
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.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
55434c770c89aa1b84474f2559a106803511aba0ek * Fill in the nverrlistp with nvlist's of dataset and object numbers.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock for (i = 0; i < count; i++) {
c0a81264b59ba24de8701436570c3aae5689dc89ek /* ignoring zb_blkid and zb_level for now */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock * Upgrade a ZFS pool to the latest on-disk version.
990b4856d0eaada6f8140335733a1b1771ed2746llingzpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock return (0);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ekzpool_set_history_str(const char *subcommand, int argc, char **argv,
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek (void) strlcpy(history_str, subcommand, HIS_MAX_RECORD_LEN);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek (void) strlcat(history_str, argv[i], HIS_MAX_RECORD_LEN);
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek * Stage command history for logging.
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ekzpool_stage_history(libzfs_handle_t *hdl, const char *history_str)
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek return (0);
06eeb2ad640ce72d394ac521094bed7681044408ek * Perform ioctl to get some command history of a pool.
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 * Upon return, 'off' is the next logical offset to read from and
06eeb2ad640ce72d394ac521094bed7681044408ek * 'len' is the actual amount of bytes read into 'buf'.
06eeb2ad640ce72d394ac521094bed7681044408ekget_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
06eeb2ad640ce72d394ac521094bed7681044408ek (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
06eeb2ad640ce72d394ac521094bed7681044408ek if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
06eeb2ad640ce72d394ac521094bed7681044408ek switch (errno) {
06eeb2ad640ce72d394ac521094bed7681044408ek "cannot show history for pool '%s'"),
06eeb2ad640ce72d394ac521094bed7681044408ek return (0);
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.
06eeb2ad640ce72d394ac521094bed7681044408ekzpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
06eeb2ad640ce72d394ac521094bed7681044408ek /* get length of packed record (stored as little endian) */
06eeb2ad640ce72d394ac521094bed7681044408ek /* unpack record */
06eeb2ad640ce72d394ac521094bed7681044408ek if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek /* add record to nvlist array */
06eeb2ad640ce72d394ac521094bed7681044408ek return (0);
06eeb2ad640ce72d394ac521094bed7681044408ek * Retrieve the command history of a pool.
06eeb2ad640ce72d394ac521094bed7681044408ek if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
06eeb2ad640ce72d394ac521094bed7681044408ek /* if nothing else was read in, we're at EOF, just return */
06eeb2ad640ce72d394ac521094bed7681044408ek /* CONSTCOND */
06eeb2ad640ce72d394ac521094bed7681044408ek } while (1);
06eeb2ad640ce72d394ac521094bed7681044408ek verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
06eeb2ad640ce72d394ac521094bed7681044408ek for (i = 0; i < numrecords; i++)
55434c770c89aa1b84474f2559a106803511aba0ekzpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
55434c770c89aa1b84474f2559a106803511aba0ek if (dsobj == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek /* special case for the MOS */
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
55434c770c89aa1b84474f2559a106803511aba0ek /* get the dataset's name */
55434c770c89aa1b84474f2559a106803511aba0ek (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
55434c770c89aa1b84474f2559a106803511aba0ek /* just write out a path of two object numbers */
55434c770c89aa1b84474f2559a106803511aba0ek /* find out if the dataset is mounted */
55434c770c89aa1b84474f2559a106803511aba0ek /* get the corrupted object's path */
55434c770c89aa1b84474f2559a106803511aba0ek if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
55434c770c89aa1b84474f2559a106803511aba0ek &zc) == 0) {
55434c770c89aa1b84474f2559a106803511aba0ek (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
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 if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
15e6edf145a9c2bb0e0272cf8debe823bb97529bgw (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * determine where a partition starts on a disk in the current
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * configuration
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor for (c = 0; c < children; c++) {
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * Label an individual disk. The name provided is the short name,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * stripped of any leading /dev path.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylorzpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante /* prepare an error message just in case */
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson "EFI labeled devices are not supported on root "
b5b76fec872120fb1395471edcf51f378acd7e83George Wilson return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor /* new pool */
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor (void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * This shouldn't happen. We've long since verified that this
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor * is a valid device.
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
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 * 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 vtoc->efi_parts[8].p_start = slice_size + start_block;
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.
c6ef114f2f708797a9cba68e8c08f42a03f094bbmmusante "try using fdisk(1M) and then provide a specific slice"));
8488aeb5df27784d479c16cde06a9e25cd9a1152taylor return (0);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gwsupported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw for (c = 0; c < children; c++) {
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * check if this zvol is allowable for use as a dump device; zero if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * it is, > 0 if it isn't, < 0 if it isn't a zvol
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (-1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw /* check the configuration of the pool */
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "malformed dataset name"));
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "dataset name is too long"));
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw return (1);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw "could not obtain vdev configuration for '%s'"), poolname);