1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright (c) 2012 by Delphix. All rights reserved.
  26  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  27  */
  28 
  29 #include <ctype.h>
  30 #include <errno.h>
  31 #include <devid.h>
  32 #include <fcntl.h>
  33 #include <libintl.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <unistd.h>
  38 #include <libgen.h>
  39 #include <sys/efi_partition.h>
  40 #include <sys/vtoc.h>
  41 #include <sys/zfs_ioctl.h>
  42 #include <dlfcn.h>
  43 
  44 #include "zfs_namecheck.h"
  45 #include "zfs_prop.h"
  46 #include "libzfs_impl.h"
  47 #include "zfs_comutil.h"
  48 #include "zfeature_common.h"
  49 
  50 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
  51 
  52 #define DISK_ROOT       "/dev/dsk"
  53 #define RDISK_ROOT      "/dev/rdsk"
  54 #define BACKUP_SLICE    "s2"
  55 
  56 typedef struct prop_flags {
  57         int create:1;   /* Validate property on creation */
  58         int import:1;   /* Validate property on import */
  59 } prop_flags_t;
  60 
  61 /*
  62  * ====================================================================
  63  *   zpool property functions
  64  * ====================================================================
  65  */
  66 
  67 static int
  68 zpool_get_all_props(zpool_handle_t *zhp)
  69 {
  70         zfs_cmd_t zc = { 0 };
  71         libzfs_handle_t *hdl = zhp->zpool_hdl;
  72 
  73         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
  74 
  75         if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
  76                 return (-1);
  77 
  78         while (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
  79                 if (errno == ENOMEM) {
  80                         if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
  81                                 zcmd_free_nvlists(&zc);
  82                                 return (-1);
  83                         }
  84                 } else {
  85                         zcmd_free_nvlists(&zc);
  86                         return (-1);
  87                 }
  88         }
  89 
  90         if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
  91                 zcmd_free_nvlists(&zc);
  92                 return (-1);
  93         }
  94 
  95         zcmd_free_nvlists(&zc);
  96 
  97         return (0);
  98 }
  99 
 100 static int
 101 zpool_props_refresh(zpool_handle_t *zhp)
 102 {
 103         nvlist_t *old_props;
 104 
 105         old_props = zhp->zpool_props;
 106 
 107         if (zpool_get_all_props(zhp) != 0)
 108                 return (-1);
 109 
 110         nvlist_free(old_props);
 111         return (0);
 112 }
 113 
 114 static char *
 115 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
 116     zprop_source_t *src)
 117 {
 118         nvlist_t *nv, *nvl;
 119         uint64_t ival;
 120         char *value;
 121         zprop_source_t source;
 122 
 123         nvl = zhp->zpool_props;
 124         if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
 125                 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &ival) == 0);
 126                 source = ival;
 127                 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
 128         } else {
 129                 source = ZPROP_SRC_DEFAULT;
 130                 if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
 131                         value = "-";
 132         }
 133 
 134         if (src)
 135                 *src = source;
 136 
 137         return (value);
 138 }
 139 
 140 uint64_t
 141 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
 142 {
 143         nvlist_t *nv, *nvl;
 144         uint64_t value;
 145         zprop_source_t source;
 146 
 147         if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
 148                 /*
 149                  * zpool_get_all_props() has most likely failed because
 150                  * the pool is faulted, but if all we need is the top level
 151                  * vdev's guid then get it from the zhp config nvlist.
 152                  */
 153                 if ((prop == ZPOOL_PROP_GUID) &&
 154                     (nvlist_lookup_nvlist(zhp->zpool_config,
 155                     ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
 156                     (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
 157                     == 0)) {
 158                         return (value);
 159                 }
 160                 return (zpool_prop_default_numeric(prop));
 161         }
 162 
 163         nvl = zhp->zpool_props;
 164         if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
 165                 verify(nvlist_lookup_uint64(nv, ZPROP_SOURCE, &value) == 0);
 166                 source = value;
 167                 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
 168         } else {
 169                 source = ZPROP_SRC_DEFAULT;
 170                 value = zpool_prop_default_numeric(prop);
 171         }
 172 
 173         if (src)
 174                 *src = source;
 175 
 176         return (value);
 177 }
 178 
 179 /*
 180  * Map VDEV STATE to printed strings.
 181  */
 182 char *
 183 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
 184 {
 185         switch (state) {
 186         case VDEV_STATE_CLOSED:
 187         case VDEV_STATE_OFFLINE:
 188                 return (gettext("OFFLINE"));
 189         case VDEV_STATE_REMOVED:
 190                 return (gettext("REMOVED"));
 191         case VDEV_STATE_CANT_OPEN:
 192                 if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
 193                         return (gettext("FAULTED"));
 194                 else if (aux == VDEV_AUX_SPLIT_POOL)
 195                         return (gettext("SPLIT"));
 196                 else
 197                         return (gettext("UNAVAIL"));
 198         case VDEV_STATE_FAULTED:
 199                 return (gettext("FAULTED"));
 200         case VDEV_STATE_DEGRADED:
 201                 return (gettext("DEGRADED"));
 202         case VDEV_STATE_HEALTHY:
 203                 return (gettext("ONLINE"));
 204         }
 205 
 206         return (gettext("UNKNOWN"));
 207 }
 208 
 209 /*
 210  * Get a zpool property value for 'prop' and return the value in
 211  * a pre-allocated buffer.
 212  */
 213 int
 214 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
 215     zprop_source_t *srctype)
 216 {
 217         uint64_t intval;
 218         const char *strval;
 219         zprop_source_t src = ZPROP_SRC_NONE;
 220         nvlist_t *nvroot;
 221         vdev_stat_t *vs;
 222         uint_t vsc;
 223 
 224         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
 225                 switch (prop) {
 226                 case ZPOOL_PROP_NAME:
 227                         (void) strlcpy(buf, zpool_get_name(zhp), len);
 228                         break;
 229 
 230                 case ZPOOL_PROP_HEALTH:
 231                         (void) strlcpy(buf, "FAULTED", len);
 232                         break;
 233 
 234                 case ZPOOL_PROP_GUID:
 235                         intval = zpool_get_prop_int(zhp, prop, &src);
 236                         (void) snprintf(buf, len, "%llu", intval);
 237                         break;
 238 
 239                 case ZPOOL_PROP_ALTROOT:
 240                 case ZPOOL_PROP_CACHEFILE:
 241                 case ZPOOL_PROP_COMMENT:
 242                         if (zhp->zpool_props != NULL ||
 243                             zpool_get_all_props(zhp) == 0) {
 244                                 (void) strlcpy(buf,
 245                                     zpool_get_prop_string(zhp, prop, &src),
 246                                     len);
 247                                 if (srctype != NULL)
 248                                         *srctype = src;
 249                                 return (0);
 250                         }
 251                         /* FALLTHROUGH */
 252                 default:
 253                         (void) strlcpy(buf, "-", len);
 254                         break;
 255                 }
 256 
 257                 if (srctype != NULL)
 258                         *srctype = src;
 259                 return (0);
 260         }
 261 
 262         if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
 263             prop != ZPOOL_PROP_NAME)
 264                 return (-1);
 265 
 266         switch (zpool_prop_get_type(prop)) {
 267         case PROP_TYPE_STRING:
 268                 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
 269                     len);
 270                 break;
 271 
 272         case PROP_TYPE_NUMBER:
 273                 intval = zpool_get_prop_int(zhp, prop, &src);
 274 
 275                 switch (prop) {
 276                 case ZPOOL_PROP_SIZE:
 277                 case ZPOOL_PROP_ALLOCATED:
 278                 case ZPOOL_PROP_FREE:
 279                 case ZPOOL_PROP_FREEING:
 280                 case ZPOOL_PROP_EXPANDSZ:
 281                         (void) zfs_nicenum(intval, buf, len);
 282                         break;
 283 
 284                 case ZPOOL_PROP_CAPACITY:
 285                         (void) snprintf(buf, len, "%llu%%",
 286                             (u_longlong_t)intval);
 287                         break;
 288 
 289                 case ZPOOL_PROP_DEDUPRATIO:
 290                         (void) snprintf(buf, len, "%llu.%02llux",
 291                             (u_longlong_t)(intval / 100),
 292                             (u_longlong_t)(intval % 100));
 293                         break;
 294 
 295                 case ZPOOL_PROP_HEALTH:
 296                         verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
 297                             ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
 298                         verify(nvlist_lookup_uint64_array(nvroot,
 299                             ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
 300                             == 0);
 301 
 302                         (void) strlcpy(buf, zpool_state_to_name(intval,
 303                             vs->vs_aux), len);
 304                         break;
 305                 case ZPOOL_PROP_VERSION:
 306                         if (intval >= SPA_VERSION_FEATURES) {
 307                                 (void) snprintf(buf, len, "-");
 308                                 break;
 309                         }
 310                         /* FALLTHROUGH */
 311                 default:
 312                         (void) snprintf(buf, len, "%llu", intval);
 313                 }
 314                 break;
 315 
 316         case PROP_TYPE_INDEX:
 317                 intval = zpool_get_prop_int(zhp, prop, &src);
 318                 if (zpool_prop_index_to_string(prop, intval, &strval)
 319                     != 0)
 320                         return (-1);
 321                 (void) strlcpy(buf, strval, len);
 322                 break;
 323 
 324         default:
 325                 abort();
 326         }
 327 
 328         if (srctype)
 329                 *srctype = src;
 330 
 331         return (0);
 332 }
 333 
 334 /*
 335  * Check if the bootfs name has the same pool name as it is set to.
 336  * Assuming bootfs is a valid dataset name.
 337  */
 338 static boolean_t
 339 bootfs_name_valid(const char *pool, char *bootfs)
 340 {
 341         int len = strlen(pool);
 342 
 343         if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
 344                 return (B_FALSE);
 345 
 346         if (strncmp(pool, bootfs, len) == 0 &&
 347             (bootfs[len] == '/' || bootfs[len] == '\0'))
 348                 return (B_TRUE);
 349 
 350         return (B_FALSE);
 351 }
 352 
 353 /*
 354  * Inspect the configuration to determine if any of the devices contain
 355  * an EFI label.
 356  */
 357 static boolean_t
 358 pool_uses_efi(nvlist_t *config)
 359 {
 360         nvlist_t **child;
 361         uint_t c, children;
 362 
 363         if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
 364             &child, &children) != 0)
 365                 return (read_efi_label(config, NULL) >= 0);
 366 
 367         for (c = 0; c < children; c++) {
 368                 if (pool_uses_efi(child[c]))
 369                         return (B_TRUE);
 370         }
 371         return (B_FALSE);
 372 }
 373 
 374 boolean_t
 375 zpool_is_bootable(zpool_handle_t *zhp)
 376 {
 377         char bootfs[ZPOOL_MAXNAMELEN];
 378 
 379         return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
 380             sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
 381             sizeof (bootfs)) != 0);
 382 }
 383 
 384 
 385 /*
 386  * Given an nvlist of zpool properties to be set, validate that they are
 387  * correct, and parse any numeric properties (index, boolean, etc) if they are
 388  * specified as strings.
 389  */
 390 static nvlist_t *
 391 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
 392     nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
 393 {
 394         nvpair_t *elem;
 395         nvlist_t *retprops;
 396         zpool_prop_t prop;
 397         char *strval;
 398         uint64_t intval;
 399         char *slash, *check;
 400         struct stat64 statbuf;
 401         zpool_handle_t *zhp;
 402         nvlist_t *nvroot;
 403 
 404         if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
 405                 (void) no_memory(hdl);
 406                 return (NULL);
 407         }
 408 
 409         elem = NULL;
 410         while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
 411                 const char *propname = nvpair_name(elem);
 412 
 413                 prop = zpool_name_to_prop(propname);
 414                 if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
 415                         int err;
 416                         zfeature_info_t *feature;
 417                         char *fname = strchr(propname, '@') + 1;
 418 
 419                         err = zfeature_lookup_name(fname, &feature);
 420                         if (err != 0) {
 421                                 ASSERT3U(err, ==, ENOENT);
 422                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 423                                     "invalid feature '%s'"), fname);
 424                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 425                                 goto error;
 426                         }
 427 
 428                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
 429                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 430                                     "'%s' must be a string"), propname);
 431                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 432                                 goto error;
 433                         }
 434 
 435                         (void) nvpair_value_string(elem, &strval);
 436                         if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
 437                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 438                                     "property '%s' can only be set to "
 439                                     "'enabled'"), propname);
 440                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 441                                 goto error;
 442                         }
 443 
 444                         if (nvlist_add_uint64(retprops, propname, 0) != 0) {
 445                                 (void) no_memory(hdl);
 446                                 goto error;
 447                         }
 448                         continue;
 449                 }
 450 
 451                 /*
 452                  * Make sure this property is valid and applies to this type.
 453                  */
 454                 if (prop == ZPROP_INVAL) {
 455                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 456                             "invalid property '%s'"), propname);
 457                         (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 458                         goto error;
 459                 }
 460 
 461                 if (zpool_prop_readonly(prop)) {
 462                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
 463                             "is readonly"), propname);
 464                         (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
 465                         goto error;
 466                 }
 467 
 468                 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
 469                     &strval, &intval, errbuf) != 0)
 470                         goto error;
 471 
 472                 /*
 473                  * Perform additional checking for specific properties.
 474                  */
 475                 switch (prop) {
 476                 case ZPOOL_PROP_VERSION:
 477                         if (intval < version ||
 478                             !SPA_VERSION_IS_SUPPORTED(intval)) {
 479                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 480                                     "property '%s' number %d is invalid."),
 481                                     propname, intval);
 482                                 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
 483                                 goto error;
 484                         }
 485                         break;
 486 
 487                 case ZPOOL_PROP_BOOTFS:
 488                         if (flags.create || flags.import) {
 489                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 490                                     "property '%s' cannot be set at creation "
 491                                     "or import time"), propname);
 492                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 493                                 goto error;
 494                         }
 495 
 496                         if (version < SPA_VERSION_BOOTFS) {
 497                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 498                                     "pool must be upgraded to support "
 499                                     "'%s' property"), propname);
 500                                 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
 501                                 goto error;
 502                         }
 503 
 504                         /*
 505                          * bootfs property value has to be a dataset name and
 506                          * the dataset has to be in the same pool as it sets to.
 507                          */
 508                         if (strval[0] != '\0' && !bootfs_name_valid(poolname,
 509                             strval)) {
 510                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
 511                                     "is an invalid name"), strval);
 512                                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
 513                                 goto error;
 514                         }
 515 
 516                         if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
 517                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 518                                     "could not open pool '%s'"), poolname);
 519                                 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
 520                                 goto error;
 521                         }
 522                         verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
 523                             ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
 524 
 525                         /*
 526                          * bootfs property cannot be set on a disk which has
 527                          * been EFI labeled.
 528                          */
 529                         if (pool_uses_efi(nvroot)) {
 530                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 531                                     "property '%s' not supported on "
 532                                     "EFI labeled devices"), propname);
 533                                 (void) zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf);
 534                                 zpool_close(zhp);
 535                                 goto error;
 536                         }
 537                         zpool_close(zhp);
 538                         break;
 539 
 540                 case ZPOOL_PROP_ALTROOT:
 541                         if (!flags.create && !flags.import) {
 542                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 543                                     "property '%s' can only be set during pool "
 544                                     "creation or import"), propname);
 545                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 546                                 goto error;
 547                         }
 548 
 549                         if (strval[0] != '/') {
 550                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 551                                     "bad alternate root '%s'"), strval);
 552                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
 553                                 goto error;
 554                         }
 555                         break;
 556 
 557                 case ZPOOL_PROP_CACHEFILE:
 558                         if (strval[0] == '\0')
 559                                 break;
 560 
 561                         if (strcmp(strval, "none") == 0)
 562                                 break;
 563 
 564                         if (strval[0] != '/') {
 565                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 566                                     "property '%s' must be empty, an "
 567                                     "absolute path, or 'none'"), propname);
 568                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
 569                                 goto error;
 570                         }
 571 
 572                         slash = strrchr(strval, '/');
 573 
 574                         if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
 575                             strcmp(slash, "/..") == 0) {
 576                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 577                                     "'%s' is not a valid file"), strval);
 578                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
 579                                 goto error;
 580                         }
 581 
 582                         *slash = '\0';
 583 
 584                         if (strval[0] != '\0' &&
 585                             (stat64(strval, &statbuf) != 0 ||
 586                             !S_ISDIR(statbuf.st_mode))) {
 587                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 588                                     "'%s' is not a valid directory"),
 589                                     strval);
 590                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
 591                                 goto error;
 592                         }
 593 
 594                         *slash = '/';
 595                         break;
 596 
 597                 case ZPOOL_PROP_COMMENT:
 598                         for (check = strval; *check != '\0'; check++) {
 599                                 if (!isprint(*check)) {
 600                                         zfs_error_aux(hdl,
 601                                             dgettext(TEXT_DOMAIN,
 602                                             "comment may only have printable "
 603                                             "characters"));
 604                                         (void) zfs_error(hdl, EZFS_BADPROP,
 605                                             errbuf);
 606                                         goto error;
 607                                 }
 608                         }
 609                         if (strlen(strval) > ZPROP_MAX_COMMENT) {
 610                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 611                                     "comment must not exceed %d characters"),
 612                                     ZPROP_MAX_COMMENT);
 613                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 614                                 goto error;
 615                         }
 616                         break;
 617                 case ZPOOL_PROP_READONLY:
 618                         if (!flags.import) {
 619                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 620                                     "property '%s' can only be set at "
 621                                     "import time"), propname);
 622                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
 623                                 goto error;
 624                         }
 625                         break;
 626                 }
 627         }
 628 
 629         return (retprops);
 630 error:
 631         nvlist_free(retprops);
 632         return (NULL);
 633 }
 634 
 635 /*
 636  * Set zpool property : propname=propval.
 637  */
 638 int
 639 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
 640 {
 641         zfs_cmd_t zc = { 0 };
 642         int ret = -1;
 643         char errbuf[1024];
 644         nvlist_t *nvl = NULL;
 645         nvlist_t *realprops;
 646         uint64_t version;
 647         prop_flags_t flags = { 0 };
 648 
 649         (void) snprintf(errbuf, sizeof (errbuf),
 650             dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
 651             zhp->zpool_name);
 652 
 653         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
 654                 return (no_memory(zhp->zpool_hdl));
 655 
 656         if (nvlist_add_string(nvl, propname, propval) != 0) {
 657                 nvlist_free(nvl);
 658                 return (no_memory(zhp->zpool_hdl));
 659         }
 660 
 661         version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
 662         if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
 663             zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
 664                 nvlist_free(nvl);
 665                 return (-1);
 666         }
 667 
 668         nvlist_free(nvl);
 669         nvl = realprops;
 670 
 671         /*
 672          * Execute the corresponding ioctl() to set this property.
 673          */
 674         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
 675 
 676         if (zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl) != 0) {
 677                 nvlist_free(nvl);
 678                 return (-1);
 679         }
 680 
 681         ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
 682 
 683         zcmd_free_nvlists(&zc);
 684         nvlist_free(nvl);
 685 
 686         if (ret)
 687                 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
 688         else
 689                 (void) zpool_props_refresh(zhp);
 690 
 691         return (ret);
 692 }
 693 
 694 int
 695 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
 696 {
 697         libzfs_handle_t *hdl = zhp->zpool_hdl;
 698         zprop_list_t *entry;
 699         char buf[ZFS_MAXPROPLEN];
 700         nvlist_t *features = NULL;
 701         zprop_list_t **last;
 702         boolean_t firstexpand = (NULL == *plp);
 703 
 704         if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
 705                 return (-1);
 706 
 707         last = plp;
 708         while (*last != NULL)
 709                 last = &(*last)->pl_next;
 710 
 711         if ((*plp)->pl_all)
 712                 features = zpool_get_features(zhp);
 713 
 714         if ((*plp)->pl_all && firstexpand) {
 715                 for (int i = 0; i < SPA_FEATURES; i++) {
 716                         zprop_list_t *entry = zfs_alloc(hdl,
 717                             sizeof (zprop_list_t));
 718                         entry->pl_prop = ZPROP_INVAL;
 719                         entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
 720                             spa_feature_table[i].fi_uname);
 721                         entry->pl_width = strlen(entry->pl_user_prop);
 722                         entry->pl_all = B_TRUE;
 723 
 724                         *last = entry;
 725                         last = &entry->pl_next;
 726                 }
 727         }
 728 
 729         /* add any unsupported features */
 730         for (nvpair_t *nvp = nvlist_next_nvpair(features, NULL);
 731             nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
 732                 char *propname;
 733                 boolean_t found;
 734                 zprop_list_t *entry;
 735 
 736                 if (zfeature_is_supported(nvpair_name(nvp)))
 737                         continue;
 738 
 739                 propname = zfs_asprintf(hdl, "unsupported@%s",
 740                     nvpair_name(nvp));
 741 
 742                 /*
 743                  * Before adding the property to the list make sure that no
 744                  * other pool already added the same property.
 745                  */
 746                 found = B_FALSE;
 747                 entry = *plp;
 748                 while (entry != NULL) {
 749                         if (entry->pl_user_prop != NULL &&
 750                             strcmp(propname, entry->pl_user_prop) == 0) {
 751                                 found = B_TRUE;
 752                                 break;
 753                         }
 754                         entry = entry->pl_next;
 755                 }
 756                 if (found) {
 757                         free(propname);
 758                         continue;
 759                 }
 760 
 761                 entry = zfs_alloc(hdl, sizeof (zprop_list_t));
 762                 entry->pl_prop = ZPROP_INVAL;
 763                 entry->pl_user_prop = propname;
 764                 entry->pl_width = strlen(entry->pl_user_prop);
 765                 entry->pl_all = B_TRUE;
 766 
 767                 *last = entry;
 768                 last = &entry->pl_next;
 769         }
 770 
 771         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
 772 
 773                 if (entry->pl_fixed)
 774                         continue;
 775 
 776                 if (entry->pl_prop != ZPROP_INVAL &&
 777                     zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
 778                     NULL) == 0) {
 779                         if (strlen(buf) > entry->pl_width)
 780                                 entry->pl_width = strlen(buf);
 781                 }
 782         }
 783 
 784         return (0);
 785 }
 786 
 787 /*
 788  * Get the state for the given feature on the given ZFS pool.
 789  */
 790 int
 791 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
 792     size_t len)
 793 {
 794         uint64_t refcount;
 795         boolean_t found = B_FALSE;
 796         nvlist_t *features = zpool_get_features(zhp);
 797         boolean_t supported;
 798         const char *feature = strchr(propname, '@') + 1;
 799 
 800         supported = zpool_prop_feature(propname);
 801         ASSERT(supported || zfs_prop_unsupported(propname));
 802 
 803         /*
 804          * Convert from feature name to feature guid. This conversion is
 805          * unecessary for unsupported@... properties because they already
 806          * use guids.
 807          */
 808         if (supported) {
 809                 int ret;
 810                 zfeature_info_t *fi;
 811 
 812                 ret = zfeature_lookup_name(feature, &fi);
 813                 if (ret != 0) {
 814                         (void) strlcpy(buf, "-", len);
 815                         return (ENOTSUP);
 816                 }
 817                 feature = fi->fi_guid;
 818         }
 819 
 820         if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
 821                 found = B_TRUE;
 822 
 823         if (supported) {
 824                 if (!found) {
 825                         (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
 826                 } else  {
 827                         if (refcount == 0)
 828                                 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
 829                         else
 830                                 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
 831                 }
 832         } else {
 833                 if (found) {
 834                         if (refcount == 0) {
 835                                 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
 836                         } else {
 837                                 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
 838                         }
 839                 } else {
 840                         (void) strlcpy(buf, "-", len);
 841                         return (ENOTSUP);
 842                 }
 843         }
 844 
 845         return (0);
 846 }
 847 
 848 /*
 849  * Don't start the slice at the default block of 34; many storage
 850  * devices will use a stripe width of 128k, so start there instead.
 851  */
 852 #define NEW_START_BLOCK 256
 853 
 854 /*
 855  * Validate the given pool name, optionally putting an extended error message in
 856  * 'buf'.
 857  */
 858 boolean_t
 859 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
 860 {
 861         namecheck_err_t why;
 862         char what;
 863         int ret;
 864 
 865         ret = pool_namecheck(pool, &why, &what);
 866 
 867         /*
 868          * The rules for reserved pool names were extended at a later point.
 869          * But we need to support users with existing pools that may now be
 870          * invalid.  So we only check for this expanded set of names during a
 871          * create (or import), and only in userland.
 872          */
 873         if (ret == 0 && !isopen &&
 874             (strncmp(pool, "mirror", 6) == 0 ||
 875             strncmp(pool, "raidz", 5) == 0 ||
 876             strncmp(pool, "spare", 5) == 0 ||
 877             strcmp(pool, "log") == 0)) {
 878                 if (hdl != NULL)
 879                         zfs_error_aux(hdl,
 880                             dgettext(TEXT_DOMAIN, "name is reserved"));
 881                 return (B_FALSE);
 882         }
 883 
 884 
 885         if (ret != 0) {
 886                 if (hdl != NULL) {
 887                         switch (why) {
 888                         case NAME_ERR_TOOLONG:
 889                                 zfs_error_aux(hdl,
 890                                     dgettext(TEXT_DOMAIN, "name is too long"));
 891                                 break;
 892 
 893                         case NAME_ERR_INVALCHAR:
 894                                 zfs_error_aux(hdl,
 895                                     dgettext(TEXT_DOMAIN, "invalid character "
 896                                     "'%c' in pool name"), what);
 897                                 break;
 898 
 899                         case NAME_ERR_NOLETTER:
 900                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 901                                     "name must begin with a letter"));
 902                                 break;
 903 
 904                         case NAME_ERR_RESERVED:
 905                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 906                                     "name is reserved"));
 907                                 break;
 908 
 909                         case NAME_ERR_DISKLIKE:
 910                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 911                                     "pool name is reserved"));
 912                                 break;
 913 
 914                         case NAME_ERR_LEADING_SLASH:
 915                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 916                                     "leading slash in name"));
 917                                 break;
 918 
 919                         case NAME_ERR_EMPTY_COMPONENT:
 920                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 921                                     "empty component in name"));
 922                                 break;
 923 
 924                         case NAME_ERR_TRAILING_SLASH:
 925                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 926                                     "trailing slash in name"));
 927                                 break;
 928 
 929                         case NAME_ERR_MULTIPLE_AT:
 930                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 931                                     "multiple '@' delimiters in name"));
 932                                 break;
 933 
 934                         }
 935                 }
 936                 return (B_FALSE);
 937         }
 938 
 939         return (B_TRUE);
 940 }
 941 
 942 /*
 943  * Open a handle to the given pool, even if the pool is currently in the FAULTED
 944  * state.
 945  */
 946 zpool_handle_t *
 947 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
 948 {
 949         zpool_handle_t *zhp;
 950         boolean_t missing;
 951 
 952         /*
 953          * Make sure the pool name is valid.
 954          */
 955         if (!zpool_name_valid(hdl, B_TRUE, pool)) {
 956                 (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
 957                     dgettext(TEXT_DOMAIN, "cannot open '%s'"),
 958                     pool);
 959                 return (NULL);
 960         }
 961 
 962         if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
 963                 return (NULL);
 964 
 965         zhp->zpool_hdl = hdl;
 966         (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
 967 
 968         if (zpool_refresh_stats(zhp, &missing) != 0) {
 969                 zpool_close(zhp);
 970                 return (NULL);
 971         }
 972 
 973         if (missing) {
 974                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
 975                 (void) zfs_error_fmt(hdl, EZFS_NOENT,
 976                     dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
 977                 zpool_close(zhp);
 978                 return (NULL);
 979         }
 980 
 981         return (zhp);
 982 }
 983 
 984 /*
 985  * Like the above, but silent on error.  Used when iterating over pools (because
 986  * the configuration cache may be out of date).
 987  */
 988 int
 989 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
 990 {
 991         zpool_handle_t *zhp;
 992         boolean_t missing;
 993 
 994         if ((zhp = zfs_alloc(hdl, sizeof (zpool_handle_t))) == NULL)
 995                 return (-1);
 996 
 997         zhp->zpool_hdl = hdl;
 998         (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
 999 
1000         if (zpool_refresh_stats(zhp, &missing) != 0) {
1001                 zpool_close(zhp);
1002                 return (-1);
1003         }
1004 
1005         if (missing) {
1006                 zpool_close(zhp);
1007                 *ret = NULL;
1008                 return (0);
1009         }
1010 
1011         *ret = zhp;
1012         return (0);
1013 }
1014 
1015 /*
1016  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
1017  * state.
1018  */
1019 zpool_handle_t *
1020 zpool_open(libzfs_handle_t *hdl, const char *pool)
1021 {
1022         zpool_handle_t *zhp;
1023 
1024         if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
1025                 return (NULL);
1026 
1027         if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
1028                 (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
1029                     dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
1030                 zpool_close(zhp);
1031                 return (NULL);
1032         }
1033 
1034         return (zhp);
1035 }
1036 
1037 /*
1038  * Close the handle.  Simply frees the memory associated with the handle.
1039  */
1040 void
1041 zpool_close(zpool_handle_t *zhp)
1042 {
1043         if (zhp->zpool_config)
1044                 nvlist_free(zhp->zpool_config);
1045         if (zhp->zpool_old_config)
1046                 nvlist_free(zhp->zpool_old_config);
1047         if (zhp->zpool_props)
1048                 nvlist_free(zhp->zpool_props);
1049         free(zhp);
1050 }
1051 
1052 /*
1053  * Return the name of the pool.
1054  */
1055 const char *
1056 zpool_get_name(zpool_handle_t *zhp)
1057 {
1058         return (zhp->zpool_name);
1059 }
1060 
1061 
1062 /*
1063  * Return the state of the pool (ACTIVE or UNAVAILABLE)
1064  */
1065 int
1066 zpool_get_state(zpool_handle_t *zhp)
1067 {
1068         return (zhp->zpool_state);
1069 }
1070 
1071 /*
1072  * Create the named pool, using the provided vdev list.  It is assumed
1073  * that the consumer has already validated the contents of the nvlist, so we
1074  * don't have to worry about error semantics.
1075  */
1076 int
1077 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
1078     nvlist_t *props, nvlist_t *fsprops)
1079 {
1080         zfs_cmd_t zc = { 0 };
1081         nvlist_t *zc_fsprops = NULL;
1082         nvlist_t *zc_props = NULL;
1083         char msg[1024];
1084         int ret = -1;
1085 
1086         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1087             "cannot create '%s'"), pool);
1088 
1089         if (!zpool_name_valid(hdl, B_FALSE, pool))
1090                 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
1091 
1092         if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
1093                 return (-1);
1094 
1095         if (props) {
1096                 prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
1097 
1098                 if ((zc_props = zpool_valid_proplist(hdl, pool, props,
1099                     SPA_VERSION_1, flags, msg)) == NULL) {
1100                         goto create_failed;
1101                 }
1102         }
1103 
1104         if (fsprops) {
1105                 uint64_t zoned;
1106                 char *zonestr;
1107 
1108                 zoned = ((nvlist_lookup_string(fsprops,
1109                     zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
1110                     strcmp(zonestr, "on") == 0);
1111 
1112                 if ((zc_fsprops = zfs_valid_proplist(hdl,
1113                     ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
1114                         goto create_failed;
1115                 }
1116                 if (!zc_props &&
1117                     (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
1118                         goto create_failed;
1119                 }
1120                 if (nvlist_add_nvlist(zc_props,
1121                     ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
1122                         goto create_failed;
1123                 }
1124         }
1125 
1126         if (zc_props && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
1127                 goto create_failed;
1128 
1129         (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
1130 
1131         if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
1132 
1133                 zcmd_free_nvlists(&zc);
1134                 nvlist_free(zc_props);
1135                 nvlist_free(zc_fsprops);
1136 
1137                 switch (errno) {
1138                 case EBUSY:
1139                         /*
1140                          * This can happen if the user has specified the same
1141                          * device multiple times.  We can't reliably detect this
1142                          * until we try to add it and see we already have a
1143                          * label.
1144                          */
1145                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1146                             "one or more vdevs refer to the same device"));
1147                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1148 
1149                 case EOVERFLOW:
1150                         /*
1151                          * This occurs when one of the devices is below
1152                          * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1153                          * device was the problem device since there's no
1154                          * reliable way to determine device size from userland.
1155                          */
1156                         {
1157                                 char buf[64];
1158 
1159                                 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
1160 
1161                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1162                                     "one or more devices is less than the "
1163                                     "minimum size (%s)"), buf);
1164                         }
1165                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1166 
1167                 case ENOSPC:
1168                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1169                             "one or more devices is out of space"));
1170                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1171 
1172                 case ENOTBLK:
1173                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1174                             "cache device must be a disk or disk slice"));
1175                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1176 
1177                 default:
1178                         return (zpool_standard_error(hdl, errno, msg));
1179                 }
1180         }
1181 
1182 create_failed:
1183         zcmd_free_nvlists(&zc);
1184         nvlist_free(zc_props);
1185         nvlist_free(zc_fsprops);
1186         return (ret);
1187 }
1188 
1189 /*
1190  * Destroy the given pool.  It is up to the caller to ensure that there are no
1191  * datasets left in the pool.
1192  */
1193 int
1194 zpool_destroy(zpool_handle_t *zhp, const char *log_str)
1195 {
1196         zfs_cmd_t zc = { 0 };
1197         zfs_handle_t *zfp = NULL;
1198         libzfs_handle_t *hdl = zhp->zpool_hdl;
1199         char msg[1024];
1200 
1201         if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1202             (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
1203                 return (-1);
1204 
1205         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1206         zc.zc_history = (uint64_t)(uintptr_t)log_str;
1207 
1208         if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1209                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1210                     "cannot destroy '%s'"), zhp->zpool_name);
1211 
1212                 if (errno == EROFS) {
1213                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1214                             "one or more devices is read only"));
1215                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1216                 } else {
1217                         (void) zpool_standard_error(hdl, errno, msg);
1218                 }
1219 
1220                 if (zfp)
1221                         zfs_close(zfp);
1222                 return (-1);
1223         }
1224 
1225         if (zfp) {
1226                 remove_mountpoint(zfp);
1227                 zfs_close(zfp);
1228         }
1229 
1230         return (0);
1231 }
1232 
1233 /*
1234  * Add the given vdevs to the pool.  The caller must have already performed the
1235  * necessary verification to ensure that the vdev specification is well-formed.
1236  */
1237 int
1238 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
1239 {
1240         zfs_cmd_t zc = { 0 };
1241         int ret;
1242         libzfs_handle_t *hdl = zhp->zpool_hdl;
1243         char msg[1024];
1244         nvlist_t **spares, **l2cache;
1245         uint_t nspares, nl2cache;
1246 
1247         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1248             "cannot add to '%s'"), zhp->zpool_name);
1249 
1250         if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1251             SPA_VERSION_SPARES &&
1252             nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1253             &spares, &nspares) == 0) {
1254                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1255                     "upgraded to add hot spares"));
1256                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1257         }
1258 
1259         if (zpool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
1260             ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
1261                 uint64_t s;
1262 
1263                 for (s = 0; s < nspares; s++) {
1264                         char *path;
1265 
1266                         if (nvlist_lookup_string(spares[s], ZPOOL_CONFIG_PATH,
1267                             &path) == 0 && pool_uses_efi(spares[s])) {
1268                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1269                                     "device '%s' contains an EFI label and "
1270                                     "cannot be used on root pools."),
1271                                     zpool_vdev_name(hdl, NULL, spares[s],
1272                                     B_FALSE));
1273                                 return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
1274                         }
1275                 }
1276         }
1277 
1278         if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1279             SPA_VERSION_L2CACHE &&
1280             nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
1281             &l2cache, &nl2cache) == 0) {
1282                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1283                     "upgraded to add cache devices"));
1284                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1285         }
1286 
1287         if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
1288                 return (-1);
1289         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1290 
1291         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
1292                 switch (errno) {
1293                 case EBUSY:
1294                         /*
1295                          * This can happen if the user has specified the same
1296                          * device multiple times.  We can't reliably detect this
1297                          * until we try to add it and see we already have a
1298                          * label.
1299                          */
1300                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1301                             "one or more vdevs refer to the same device"));
1302                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1303                         break;
1304 
1305                 case EOVERFLOW:
1306                         /*
1307                          * This occurrs when one of the devices is below
1308                          * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1309                          * device was the problem device since there's no
1310                          * reliable way to determine device size from userland.
1311                          */
1312                         {
1313                                 char buf[64];
1314 
1315                                 zfs_nicenum(SPA_MINDEVSIZE, buf, sizeof (buf));
1316 
1317                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1318                                     "device is less than the minimum "
1319                                     "size (%s)"), buf);
1320                         }
1321                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1322                         break;
1323 
1324                 case ENOTSUP:
1325                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1326                             "pool must be upgraded to add these vdevs"));
1327                         (void) zfs_error(hdl, EZFS_BADVERSION, msg);
1328                         break;
1329 
1330                 case EDOM:
1331                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1332                             "root pool can not have multiple vdevs"
1333                             " or separate logs"));
1334                         (void) zfs_error(hdl, EZFS_POOL_NOTSUP, msg);
1335                         break;
1336 
1337                 case ENOTBLK:
1338                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1339                             "cache device must be a disk or disk slice"));
1340                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1341                         break;
1342 
1343                 default:
1344                         (void) zpool_standard_error(hdl, errno, msg);
1345                 }
1346 
1347                 ret = -1;
1348         } else {
1349                 ret = 0;
1350         }
1351 
1352         zcmd_free_nvlists(&zc);
1353 
1354         return (ret);
1355 }
1356 
1357 /*
1358  * Exports the pool from the system.  The caller must ensure that there are no
1359  * mounted datasets in the pool.
1360  */
1361 static int
1362 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
1363     const char *log_str)
1364 {
1365         zfs_cmd_t zc = { 0 };
1366         char msg[1024];
1367 
1368         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1369             "cannot export '%s'"), zhp->zpool_name);
1370 
1371         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1372         zc.zc_cookie = force;
1373         zc.zc_guid = hardforce;
1374         zc.zc_history = (uint64_t)(uintptr_t)log_str;
1375 
1376         if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
1377                 switch (errno) {
1378                 case EXDEV:
1379                         zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
1380                             "use '-f' to override the following errors:\n"
1381                             "'%s' has an active shared spare which could be"
1382                             " used by other pools once '%s' is exported."),
1383                             zhp->zpool_name, zhp->zpool_name);
1384                         return (zfs_error(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
1385                             msg));
1386                 default:
1387                         return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
1388                             msg));
1389                 }
1390         }
1391 
1392         return (0);
1393 }
1394 
1395 int
1396 zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
1397 {
1398         return (zpool_export_common(zhp, force, B_FALSE, log_str));
1399 }
1400 
1401 int
1402 zpool_export_force(zpool_handle_t *zhp, const char *log_str)
1403 {
1404         return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
1405 }
1406 
1407 static void
1408 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1409     nvlist_t *config)
1410 {
1411         nvlist_t *nv = NULL;
1412         uint64_t rewindto;
1413         int64_t loss = -1;
1414         struct tm t;
1415         char timestr[128];
1416 
1417         if (!hdl->libzfs_printerr || config == NULL)
1418                 return;
1419 
1420         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1421             nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
1422                 return;
1423         }
1424 
1425         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1426                 return;
1427         (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1428 
1429         if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1430             strftime(timestr, 128, 0, &t) != 0) {
1431                 if (dryrun) {
1432                         (void) printf(dgettext(TEXT_DOMAIN,
1433                             "Would be able to return %s "
1434                             "to its state as of %s.\n"),
1435                             name, timestr);
1436                 } else {
1437                         (void) printf(dgettext(TEXT_DOMAIN,
1438                             "Pool %s returned to its state as of %s.\n"),
1439                             name, timestr);
1440                 }
1441                 if (loss > 120) {
1442                         (void) printf(dgettext(TEXT_DOMAIN,
1443                             "%s approximately %lld "),
1444                             dryrun ? "Would discard" : "Discarded",
1445                             (loss + 30) / 60);
1446                         (void) printf(dgettext(TEXT_DOMAIN,
1447                             "minutes of transactions.\n"));
1448                 } else if (loss > 0) {
1449                         (void) printf(dgettext(TEXT_DOMAIN,
1450                             "%s approximately %lld "),
1451                             dryrun ? "Would discard" : "Discarded", loss);
1452                         (void) printf(dgettext(TEXT_DOMAIN,
1453                             "seconds of transactions.\n"));
1454                 }
1455         }
1456 }
1457 
1458 void
1459 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1460     nvlist_t *config)
1461 {
1462         nvlist_t *nv = NULL;
1463         int64_t loss = -1;
1464         uint64_t edata = UINT64_MAX;
1465         uint64_t rewindto;
1466         struct tm t;
1467         char timestr[128];
1468 
1469         if (!hdl->libzfs_printerr)
1470                 return;
1471 
1472         if (reason >= 0)
1473                 (void) printf(dgettext(TEXT_DOMAIN, "action: "));
1474         else
1475                 (void) printf(dgettext(TEXT_DOMAIN, "\t"));
1476 
1477         /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1478         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1479             nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
1480             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1481                 goto no_info;
1482 
1483         (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1484         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1485             &edata);
1486 
1487         (void) printf(dgettext(TEXT_DOMAIN,
1488             "Recovery is possible, but will result in some data loss.\n"));
1489 
1490         if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1491             strftime(timestr, 128, 0, &t) != 0) {
1492                 (void) printf(dgettext(TEXT_DOMAIN,
1493                     "\tReturning the pool to its state as of %s\n"
1494                     "\tshould correct the problem.  "),
1495                     timestr);
1496         } else {
1497                 (void) printf(dgettext(TEXT_DOMAIN,
1498                     "\tReverting the pool to an earlier state "
1499                     "should correct the problem.\n\t"));
1500         }
1501 
1502         if (loss > 120) {
1503                 (void) printf(dgettext(TEXT_DOMAIN,
1504                     "Approximately %lld minutes of data\n"
1505                     "\tmust be discarded, irreversibly.  "), (loss + 30) / 60);
1506         } else if (loss > 0) {
1507                 (void) printf(dgettext(TEXT_DOMAIN,
1508                     "Approximately %lld seconds of data\n"
1509                     "\tmust be discarded, irreversibly.  "), loss);
1510         }
1511         if (edata != 0 && edata != UINT64_MAX) {
1512                 if (edata == 1) {
1513                         (void) printf(dgettext(TEXT_DOMAIN,
1514                             "After rewind, at least\n"
1515                             "\tone persistent user-data error will remain.  "));
1516                 } else {
1517                         (void) printf(dgettext(TEXT_DOMAIN,
1518                             "After rewind, several\n"
1519                             "\tpersistent user-data errors will remain.  "));
1520                 }
1521         }
1522         (void) printf(dgettext(TEXT_DOMAIN,
1523             "Recovery can be attempted\n\tby executing 'zpool %s -F %s'.  "),
1524             reason >= 0 ? "clear" : "import", name);
1525 
1526         (void) printf(dgettext(TEXT_DOMAIN,
1527             "A scrub of the pool\n"
1528             "\tis strongly recommended after recovery.\n"));
1529         return;
1530 
1531 no_info:
1532         (void) printf(dgettext(TEXT_DOMAIN,
1533             "Destroy and re-create the pool from\n\ta backup source.\n"));
1534 }
1535 
1536 /*
1537  * zpool_import() is a contracted interface. Should be kept the same
1538  * if possible.
1539  *
1540  * Applications should use zpool_import_props() to import a pool with
1541  * new properties value to be set.
1542  */
1543 int
1544 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1545     char *altroot)
1546 {
1547         nvlist_t *props = NULL;
1548         int ret;
1549 
1550         if (altroot != NULL) {
1551                 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
1552                         return (zfs_error_fmt(hdl, EZFS_NOMEM,
1553                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1554                             newname));
1555                 }
1556 
1557                 if (nvlist_add_string(props,
1558                     zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
1559                     nvlist_add_string(props,
1560                     zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
1561                         nvlist_free(props);
1562                         return (zfs_error_fmt(hdl, EZFS_NOMEM,
1563                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1564                             newname));
1565                 }
1566         }
1567 
1568         ret = zpool_import_props(hdl, config, newname, props,
1569             ZFS_IMPORT_NORMAL);
1570         if (props)
1571                 nvlist_free(props);
1572         return (ret);
1573 }
1574 
1575 static void
1576 print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
1577     int indent)
1578 {
1579         nvlist_t **child;
1580         uint_t c, children;
1581         char *vname;
1582         uint64_t is_log = 0;
1583 
1584         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
1585             &is_log);
1586 
1587         if (name != NULL)
1588                 (void) printf("\t%*s%s%s\n", indent, "", name,
1589                     is_log ? " [log]" : "");
1590 
1591         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1592             &child, &children) != 0)
1593                 return;
1594 
1595         for (c = 0; c < children; c++) {
1596                 vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
1597                 print_vdev_tree(hdl, vname, child[c], indent + 2);
1598                 free(vname);
1599         }
1600 }
1601 
1602 void
1603 zpool_print_unsup_feat(nvlist_t *config)
1604 {
1605         nvlist_t *nvinfo, *unsup_feat;
1606 
1607         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) ==
1608             0);
1609         verify(nvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT,
1610             &unsup_feat) == 0);
1611 
1612         for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); nvp != NULL;
1613             nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
1614                 char *desc;
1615 
1616                 verify(nvpair_type(nvp) == DATA_TYPE_STRING);
1617                 verify(nvpair_value_string(nvp, &desc) == 0);
1618 
1619                 if (strlen(desc) > 0)
1620                         (void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
1621                 else
1622                         (void) printf("\t%s\n", nvpair_name(nvp));
1623         }
1624 }
1625 
1626 /*
1627  * Import the given pool using the known configuration and a list of
1628  * properties to be set. The configuration should have come from
1629  * zpool_find_import(). The 'newname' parameters control whether the pool
1630  * is imported with a different name.
1631  */
1632 int
1633 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1634     nvlist_t *props, int flags)
1635 {
1636         zfs_cmd_t zc = { 0 };
1637         zpool_rewind_policy_t policy;
1638         nvlist_t *nv = NULL;
1639         nvlist_t *nvinfo = NULL;
1640         nvlist_t *missing = NULL;
1641         char *thename;
1642         char *origname;
1643         int ret;
1644         int error = 0;
1645         char errbuf[1024];
1646 
1647         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
1648             &origname) == 0);
1649 
1650         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1651             "cannot import pool '%s'"), origname);
1652 
1653         if (newname != NULL) {
1654                 if (!zpool_name_valid(hdl, B_FALSE, newname))
1655                         return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1656                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1657                             newname));
1658                 thename = (char *)newname;
1659         } else {
1660                 thename = origname;
1661         }
1662 
1663         if (props) {
1664                 uint64_t version;
1665                 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
1666 
1667                 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
1668                     &version) == 0);
1669 
1670                 if ((props = zpool_valid_proplist(hdl, origname,
1671                     props, version, flags, errbuf)) == NULL) {
1672                         return (-1);
1673                 } else if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
1674                         nvlist_free(props);
1675                         return (-1);
1676                 }
1677         }
1678 
1679         (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
1680 
1681         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
1682             &zc.zc_guid) == 0);
1683 
1684         if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0) {
1685                 nvlist_free(props);
1686                 return (-1);
1687         }
1688         if (zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2) != 0) {
1689                 nvlist_free(props);
1690                 return (-1);
1691         }
1692 
1693         zc.zc_cookie = flags;
1694         while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
1695             errno == ENOMEM) {
1696                 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
1697                         zcmd_free_nvlists(&zc);
1698                         return (-1);
1699                 }
1700         }
1701         if (ret != 0)
1702                 error = errno;
1703 
1704         (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
1705         zpool_get_rewind_policy(config, &policy);
1706 
1707         if (error) {
1708                 char desc[1024];
1709 
1710                 /*
1711                  * Dry-run failed, but we print out what success
1712                  * looks like if we found a best txg
1713                  */
1714                 if (policy.zrp_request & ZPOOL_TRY_REWIND) {
1715                         zpool_rewind_exclaim(hdl, newname ? origname : thename,
1716                             B_TRUE, nv);
1717                         nvlist_free(nv);
1718                         return (-1);
1719                 }
1720 
1721                 if (newname == NULL)
1722                         (void) snprintf(desc, sizeof (desc),
1723                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1724                             thename);
1725                 else
1726                         (void) snprintf(desc, sizeof (desc),
1727                             dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
1728                             origname, thename);
1729 
1730                 switch (error) {
1731                 case ENOTSUP:
1732                         if (nv != NULL && nvlist_lookup_nvlist(nv,
1733                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1734                             nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
1735                                 (void) printf(dgettext(TEXT_DOMAIN, "This "
1736                                     "pool uses the following feature(s) not "
1737                                     "supported by this system:\n"));
1738                                 zpool_print_unsup_feat(nv);
1739                                 if (nvlist_exists(nvinfo,
1740                                     ZPOOL_CONFIG_CAN_RDONLY)) {
1741                                         (void) printf(dgettext(TEXT_DOMAIN,
1742                                             "All unsupported features are only "
1743                                             "required for writing to the pool."
1744                                             "\nThe pool can be imported using "
1745                                             "'-o readonly=on'.\n"));
1746                                 }
1747                         }
1748                         /*
1749                          * Unsupported version.
1750                          */
1751                         (void) zfs_error(hdl, EZFS_BADVERSION, desc);
1752                         break;
1753 
1754                 case EINVAL:
1755                         (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
1756                         break;
1757 
1758                 case EROFS:
1759                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1760                             "one or more devices is read only"));
1761                         (void) zfs_error(hdl, EZFS_BADDEV, desc);
1762                         break;
1763 
1764                 case ENXIO:
1765                         if (nv && nvlist_lookup_nvlist(nv,
1766                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1767                             nvlist_lookup_nvlist(nvinfo,
1768                             ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
1769                                 (void) printf(dgettext(TEXT_DOMAIN,
1770                                     "The devices below are missing, use "
1771                                     "'-m' to import the pool anyway:\n"));
1772                                 print_vdev_tree(hdl, NULL, missing, 2);
1773                                 (void) printf("\n");
1774                         }
1775                         (void) zpool_standard_error(hdl, error, desc);
1776                         break;
1777 
1778                 case EEXIST:
1779                         (void) zpool_standard_error(hdl, error, desc);
1780                         break;
1781 
1782                 default:
1783                         (void) zpool_standard_error(hdl, error, desc);
1784                         zpool_explain_recover(hdl,
1785                             newname ? origname : thename, -error, nv);
1786                         break;
1787                 }
1788 
1789                 nvlist_free(nv);
1790                 ret = -1;
1791         } else {
1792                 zpool_handle_t *zhp;
1793 
1794                 /*
1795                  * This should never fail, but play it safe anyway.
1796                  */
1797                 if (zpool_open_silent(hdl, thename, &zhp) != 0)
1798                         ret = -1;
1799                 else if (zhp != NULL)
1800                         zpool_close(zhp);
1801                 if (policy.zrp_request &
1802                     (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
1803                         zpool_rewind_exclaim(hdl, newname ? origname : thename,
1804                             ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0), nv);
1805                 }
1806                 nvlist_free(nv);
1807                 return (0);
1808         }
1809 
1810         zcmd_free_nvlists(&zc);
1811         nvlist_free(props);
1812 
1813         return (ret);
1814 }
1815 
1816 /*
1817  * Scan the pool.
1818  */
1819 int
1820 zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
1821 {
1822         zfs_cmd_t zc = { 0 };
1823         char msg[1024];
1824         libzfs_handle_t *hdl = zhp->zpool_hdl;
1825 
1826         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1827         zc.zc_cookie = func;
1828 
1829         if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
1830             (errno == ENOENT && func != POOL_SCAN_NONE))
1831                 return (0);
1832 
1833         if (func == POOL_SCAN_SCRUB) {
1834                 (void) snprintf(msg, sizeof (msg),
1835                     dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
1836         } else if (func == POOL_SCAN_NONE) {
1837                 (void) snprintf(msg, sizeof (msg),
1838                     dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
1839                     zc.zc_name);
1840         } else {
1841                 assert(!"unexpected result");
1842         }
1843 
1844         if (errno == EBUSY) {
1845                 nvlist_t *nvroot;
1846                 pool_scan_stat_t *ps = NULL;
1847                 uint_t psc;
1848 
1849                 verify(nvlist_lookup_nvlist(zhp->zpool_config,
1850                     ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1851                 (void) nvlist_lookup_uint64_array(nvroot,
1852                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
1853                 if (ps && ps->pss_func == POOL_SCAN_SCRUB)
1854                         return (zfs_error(hdl, EZFS_SCRUBBING, msg));
1855                 else
1856                         return (zfs_error(hdl, EZFS_RESILVERING, msg));
1857         } else if (errno == ENOENT) {
1858                 return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
1859         } else {
1860                 return (zpool_standard_error(hdl, errno, msg));
1861         }
1862 }
1863 
1864 /*
1865  * This provides a very minimal check whether a given string is likely a
1866  * c#t#d# style string.  Users of this are expected to do their own
1867  * verification of the s# part.
1868  */
1869 #define CTD_CHECK(str)  (str && str[0] == 'c' && isdigit(str[1]))
1870 
1871 /*
1872  * More elaborate version for ones which may start with "/dev/dsk/"
1873  * and the like.
1874  */
1875 static int
1876 ctd_check_path(char *str) {
1877         /*
1878          * If it starts with a slash, check the last component.
1879          */
1880         if (str && str[0] == '/') {
1881                 char *tmp = strrchr(str, '/');
1882 
1883                 /*
1884                  * If it ends in "/old", check the second-to-last
1885                  * component of the string instead.
1886                  */
1887                 if (tmp != str && strcmp(tmp, "/old") == 0) {
1888                         for (tmp--; *tmp != '/'; tmp--)
1889                                 ;
1890                 }
1891                 str = tmp + 1;
1892         }
1893         return (CTD_CHECK(str));
1894 }
1895 
1896 /*
1897  * Find a vdev that matches the search criteria specified. We use the
1898  * the nvpair name to determine how we should look for the device.
1899  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
1900  * spare; but FALSE if its an INUSE spare.
1901  */
1902 static nvlist_t *
1903 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
1904     boolean_t *l2cache, boolean_t *log)
1905 {
1906         uint_t c, children;
1907         nvlist_t **child;
1908         nvlist_t *ret;
1909         uint64_t is_log;
1910         char *srchkey;
1911         nvpair_t *pair = nvlist_next_nvpair(search, NULL);
1912 
1913         /* Nothing to look for */
1914         if (search == NULL || pair == NULL)
1915                 return (NULL);
1916 
1917         /* Obtain the key we will use to search */
1918         srchkey = nvpair_name(pair);
1919 
1920         switch (nvpair_type(pair)) {
1921         case DATA_TYPE_UINT64:
1922                 if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
1923                         uint64_t srchval, theguid;
1924 
1925                         verify(nvpair_value_uint64(pair, &srchval) == 0);
1926                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
1927                             &theguid) == 0);
1928                         if (theguid == srchval)
1929                                 return (nv);
1930                 }
1931                 break;
1932 
1933         case DATA_TYPE_STRING: {
1934                 char *srchval, *val;
1935 
1936                 verify(nvpair_value_string(pair, &srchval) == 0);
1937                 if (nvlist_lookup_string(nv, srchkey, &val) != 0)
1938                         break;
1939 
1940                 /*
1941                  * Search for the requested value. Special cases:
1942                  *
1943                  * - ZPOOL_CONFIG_PATH for whole disk entries.  These end in
1944                  *   "s0" or "s0/old".  The "s0" part is hidden from the user,
1945                  *   but included in the string, so this matches around it.
1946                  * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
1947                  *
1948                  * Otherwise, all other searches are simple string compares.
1949                  */
1950                 if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0 &&
1951                     ctd_check_path(val)) {
1952                         uint64_t wholedisk = 0;
1953 
1954                         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
1955                             &wholedisk);
1956                         if (wholedisk) {
1957                                 int slen = strlen(srchval);
1958                                 int vlen = strlen(val);
1959 
1960                                 if (slen != vlen - 2)
1961                                         break;
1962 
1963                                 /*
1964                                  * make_leaf_vdev() should only set
1965                                  * wholedisk for ZPOOL_CONFIG_PATHs which
1966                                  * will include "/dev/dsk/", giving plenty of
1967                                  * room for the indices used next.
1968                                  */
1969                                 ASSERT(vlen >= 6);
1970 
1971                                 /*
1972                                  * strings identical except trailing "s0"
1973                                  */
1974                                 if (strcmp(&val[vlen - 2], "s0") == 0 &&
1975                                     strncmp(srchval, val, slen) == 0)
1976                                         return (nv);
1977 
1978                                 /*
1979                                  * strings identical except trailing "s0/old"
1980                                  */
1981                                 if (strcmp(&val[vlen - 6], "s0/old") == 0 &&
1982                                     strcmp(&srchval[slen - 4], "/old") == 0 &&
1983                                     strncmp(srchval, val, slen - 4) == 0)
1984                                         return (nv);
1985 
1986                                 break;
1987                         }
1988                 } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
1989                         char *type, *idx, *end, *p;
1990                         uint64_t id, vdev_id;
1991 
1992                         /*
1993                          * Determine our vdev type, keeping in mind
1994                          * that the srchval is composed of a type and
1995                          * vdev id pair (i.e. mirror-4).
1996                          */
1997                         if ((type = strdup(srchval)) == NULL)
1998                                 return (NULL);
1999 
2000                         if ((p = strrchr(type, '-')) == NULL) {
2001                                 free(type);
2002                                 break;
2003                         }
2004                         idx = p + 1;
2005                         *p = '\0';
2006 
2007                         /*
2008                          * If the types don't match then keep looking.
2009                          */
2010                         if (strncmp(val, type, strlen(val)) != 0) {
2011                                 free(type);
2012                                 break;
2013                         }
2014 
2015                         verify(strncmp(type, VDEV_TYPE_RAIDZ,
2016                             strlen(VDEV_TYPE_RAIDZ)) == 0 ||
2017                             strncmp(type, VDEV_TYPE_MIRROR,
2018                             strlen(VDEV_TYPE_MIRROR)) == 0);
2019                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
2020                             &id) == 0);
2021 
2022                         errno = 0;
2023                         vdev_id = strtoull(idx, &end, 10);
2024 
2025                         free(type);
2026                         if (errno != 0)
2027                                 return (NULL);
2028 
2029                         /*
2030                          * Now verify that we have the correct vdev id.
2031                          */
2032                         if (vdev_id == id)
2033                                 return (nv);
2034                 }
2035 
2036                 /*
2037                  * Common case
2038                  */
2039                 if (strcmp(srchval, val) == 0)
2040                         return (nv);
2041                 break;
2042         }
2043 
2044         default:
2045                 break;
2046         }
2047 
2048         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2049             &child, &children) != 0)
2050                 return (NULL);
2051 
2052         for (c = 0; c < children; c++) {
2053                 if ((ret = vdev_to_nvlist_iter(child[c], search,
2054                     avail_spare, l2cache, NULL)) != NULL) {
2055                         /*
2056                          * The 'is_log' value is only set for the toplevel
2057                          * vdev, not the leaf vdevs.  So we always lookup the
2058                          * log device from the root of the vdev tree (where
2059                          * 'log' is non-NULL).
2060                          */
2061                         if (log != NULL &&
2062                             nvlist_lookup_uint64(child[c],
2063                             ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
2064                             is_log) {
2065                                 *log = B_TRUE;
2066                         }
2067                         return (ret);
2068                 }
2069         }
2070 
2071         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
2072             &child, &children) == 0) {
2073                 for (c = 0; c < children; c++) {
2074                         if ((ret = vdev_to_nvlist_iter(child[c], search,
2075                             avail_spare, l2cache, NULL)) != NULL) {
2076                                 *avail_spare = B_TRUE;
2077                                 return (ret);
2078                         }
2079                 }
2080         }
2081 
2082         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2083             &child, &children) == 0) {
2084                 for (c = 0; c < children; c++) {
2085                         if ((ret = vdev_to_nvlist_iter(child[c], search,
2086                             avail_spare, l2cache, NULL)) != NULL) {
2087                                 *l2cache = B_TRUE;
2088                                 return (ret);
2089                         }
2090                 }
2091         }
2092 
2093         return (NULL);
2094 }
2095 
2096 /*
2097  * Given a physical path (minus the "/devices" prefix), find the
2098  * associated vdev.
2099  */
2100 nvlist_t *
2101 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
2102     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
2103 {
2104         nvlist_t *search, *nvroot, *ret;
2105 
2106         verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2107         verify(nvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath) == 0);
2108 
2109         verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
2110             &nvroot) == 0);
2111 
2112         *avail_spare = B_FALSE;
2113         *l2cache = B_FALSE;
2114         if (log != NULL)
2115                 *log = B_FALSE;
2116         ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
2117         nvlist_free(search);
2118 
2119         return (ret);
2120 }
2121 
2122 /*
2123  * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
2124  */
2125 boolean_t
2126 zpool_vdev_is_interior(const char *name)
2127 {
2128         if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
2129             strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
2130                 return (B_TRUE);
2131         return (B_FALSE);
2132 }
2133 
2134 nvlist_t *
2135 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
2136     boolean_t *l2cache, boolean_t *log)
2137 {
2138         char buf[MAXPATHLEN];
2139         char *end;
2140         nvlist_t *nvroot, *search, *ret;
2141         uint64_t guid;
2142 
2143         verify(nvlist_alloc(&search, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2144 
2145         guid = strtoull(path, &end, 10);
2146         if (guid != 0 && *end == '\0') {
2147                 verify(nvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid) == 0);
2148         } else if (zpool_vdev_is_interior(path)) {
2149                 verify(nvlist_add_string(search, ZPOOL_CONFIG_TYPE, path) == 0);
2150         } else if (path[0] != '/') {
2151                 (void) snprintf(buf, sizeof (buf), "%s%s", "/dev/dsk/", path);
2152                 verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, buf) == 0);
2153         } else {
2154                 verify(nvlist_add_string(search, ZPOOL_CONFIG_PATH, path) == 0);
2155         }
2156 
2157         verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
2158             &nvroot) == 0);
2159 
2160         *avail_spare = B_FALSE;
2161         *l2cache = B_FALSE;
2162         if (log != NULL)
2163                 *log = B_FALSE;
2164         ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
2165         nvlist_free(search);
2166 
2167         return (ret);
2168 }
2169 
2170 static int
2171 vdev_online(nvlist_t *nv)
2172 {
2173         uint64_t ival;
2174 
2175         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
2176             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
2177             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
2178                 return (0);
2179 
2180         return (1);
2181 }
2182 
2183 /*
2184  * Helper function for zpool_get_physpaths().
2185  */
2186 static int
2187 vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
2188     size_t *bytes_written)
2189 {
2190         size_t bytes_left, pos, rsz;
2191         char *tmppath;
2192         const char *format;
2193 
2194         if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
2195             &tmppath) != 0)
2196                 return (EZFS_NODEVICE);
2197 
2198         pos = *bytes_written;
2199         bytes_left = physpath_size - pos;
2200         format = (pos == 0) ? "%s" : " %s";
2201 
2202         rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
2203         *bytes_written += rsz;
2204 
2205         if (rsz >= bytes_left) {
2206                 /* if physpath was not copied properly, clear it */
2207                 if (bytes_left != 0) {
2208                         physpath[pos] = 0;
2209                 }
2210                 return (EZFS_NOSPC);
2211         }
2212         return (0);
2213 }
2214 
2215 static int
2216 vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
2217     size_t *rsz, boolean_t is_spare)
2218 {
2219         char *type;
2220         int ret;
2221 
2222         if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
2223                 return (EZFS_INVALCONFIG);
2224 
2225         if (strcmp(type, VDEV_TYPE_DISK) == 0) {
2226                 /*
2227                  * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
2228                  * For a spare vdev, we only want to boot from the active
2229                  * spare device.
2230                  */
2231                 if (is_spare) {
2232                         uint64_t spare = 0;
2233                         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
2234                             &spare);
2235                         if (!spare)
2236                                 return (EZFS_INVALCONFIG);
2237                 }
2238 
2239                 if (vdev_online(nv)) {
2240                         if ((ret = vdev_get_one_physpath(nv, physpath,
2241                             phypath_size, rsz)) != 0)
2242                                 return (ret);
2243                 }
2244         } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
2245             strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
2246             (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
2247                 nvlist_t **child;
2248                 uint_t count;
2249                 int i, ret;
2250 
2251                 if (nvlist_lookup_nvlist_array(nv,
2252                     ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
2253                         return (EZFS_INVALCONFIG);
2254 
2255                 for (i = 0; i < count; i++) {
2256                         ret = vdev_get_physpaths(child[i], physpath,
2257                             phypath_size, rsz, is_spare);
2258                         if (ret == EZFS_NOSPC)
2259                                 return (ret);
2260                 }
2261         }
2262 
2263         return (EZFS_POOL_INVALARG);
2264 }
2265 
2266 /*
2267  * Get phys_path for a root pool config.
2268  * Return 0 on success; non-zero on failure.
2269  */
2270 static int
2271 zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
2272 {
2273         size_t rsz;
2274         nvlist_t *vdev_root;
2275         nvlist_t **child;
2276         uint_t count;
2277         char *type;
2278 
2279         rsz = 0;
2280 
2281         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
2282             &vdev_root) != 0)
2283                 return (EZFS_INVALCONFIG);
2284 
2285         if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
2286             nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
2287             &child, &count) != 0)
2288                 return (EZFS_INVALCONFIG);
2289 
2290         /*
2291          * root pool can not have EFI labeled disks and can only have
2292          * a single top-level vdev.
2293          */
2294         if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1 ||
2295             pool_uses_efi(vdev_root))
2296                 return (EZFS_POOL_INVALARG);
2297 
2298         (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
2299             B_FALSE);
2300 
2301         /* No online devices */
2302         if (rsz == 0)
2303                 return (EZFS_NODEVICE);
2304 
2305         return (0);
2306 }
2307 
2308 /*
2309  * Get phys_path for a root pool
2310  * Return 0 on success; non-zero on failure.
2311  */
2312 int
2313 zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
2314 {
2315         return (zpool_get_config_physpath(zhp->zpool_config, physpath,
2316             phypath_size));
2317 }
2318 
2319 /*
2320  * If the device has being dynamically expanded then we need to relabel
2321  * the disk to use the new unallocated space.
2322  */
2323 static int
2324 zpool_relabel_disk(libzfs_handle_t *hdl, const char *name)
2325 {
2326         char path[MAXPATHLEN];
2327         char errbuf[1024];
2328         int fd, error;
2329         int (*_efi_use_whole_disk)(int);
2330 
2331         if ((_efi_use_whole_disk = (int (*)(int))dlsym(RTLD_DEFAULT,
2332             "efi_use_whole_disk")) == NULL)
2333                 return (-1);
2334 
2335         (void) snprintf(path, sizeof (path), "%s/%s", RDISK_ROOT, name);
2336 
2337         if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
2338                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
2339                     "relabel '%s': unable to open device"), name);
2340                 return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
2341         }
2342 
2343         /*
2344          * It's possible that we might encounter an error if the device
2345          * does not have any unallocated space left. If so, we simply
2346          * ignore that error and continue on.
2347          */
2348         error = _efi_use_whole_disk(fd);
2349         (void) close(fd);
2350         if (error && error != VT_ENOSPC) {
2351                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "cannot "
2352                     "relabel '%s': unable to read disk capacity"), name);
2353                 return (zfs_error(hdl, EZFS_NOCAP, errbuf));
2354         }
2355         return (0);
2356 }
2357 
2358 /*
2359  * Bring the specified vdev online.   The 'flags' parameter is a set of the
2360  * ZFS_ONLINE_* flags.
2361  */
2362 int
2363 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
2364     vdev_state_t *newstate)
2365 {
2366         zfs_cmd_t zc = { 0 };
2367         char msg[1024];
2368         nvlist_t *tgt;
2369         boolean_t avail_spare, l2cache, islog;
2370         libzfs_handle_t *hdl = zhp->zpool_hdl;
2371 
2372         if (flags & ZFS_ONLINE_EXPAND) {
2373                 (void) snprintf(msg, sizeof (msg),
2374                     dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
2375         } else {
2376                 (void) snprintf(msg, sizeof (msg),
2377                     dgettext(TEXT_DOMAIN, "cannot online %s"), path);
2378         }
2379 
2380         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2381         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2382             &islog)) == NULL)
2383                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2384 
2385         verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2386 
2387         if (avail_spare)
2388                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2389 
2390         if (flags & ZFS_ONLINE_EXPAND ||
2391             zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
2392                 char *pathname = NULL;
2393                 uint64_t wholedisk = 0;
2394 
2395                 (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
2396                     &wholedisk);
2397                 verify(nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH,
2398                     &pathname) == 0);
2399 
2400                 /*
2401                  * XXX - L2ARC 1.0 devices can't support expansion.
2402                  */
2403                 if (l2cache) {
2404                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2405                             "cannot expand cache devices"));
2406                         return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
2407                 }
2408 
2409                 if (wholedisk) {
2410                         pathname += strlen(DISK_ROOT) + 1;
2411                         (void) zpool_relabel_disk(hdl, pathname);
2412                 }
2413         }
2414 
2415         zc.zc_cookie = VDEV_STATE_ONLINE;
2416         zc.zc_obj = flags;
2417 
2418         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
2419                 if (errno == EINVAL) {
2420                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
2421                             "from this pool into a new one.  Use '%s' "
2422                             "instead"), "zpool detach");
2423                         return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, msg));
2424                 }
2425                 return (zpool_standard_error(hdl, errno, msg));
2426         }
2427 
2428         *newstate = zc.zc_cookie;
2429         return (0);
2430 }
2431 
2432 /*
2433  * Take the specified vdev offline
2434  */
2435 int
2436 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
2437 {
2438         zfs_cmd_t zc = { 0 };
2439         char msg[1024];
2440         nvlist_t *tgt;
2441         boolean_t avail_spare, l2cache;
2442         libzfs_handle_t *hdl = zhp->zpool_hdl;
2443 
2444         (void) snprintf(msg, sizeof (msg),
2445             dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
2446 
2447         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2448         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2449             NULL)) == NULL)
2450                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2451 
2452         verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2453 
2454         if (avail_spare)
2455                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2456 
2457         zc.zc_cookie = VDEV_STATE_OFFLINE;
2458         zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
2459 
2460         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2461                 return (0);
2462 
2463         switch (errno) {
2464         case EBUSY:
2465 
2466                 /*
2467                  * There are no other replicas of this device.
2468                  */
2469                 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2470 
2471         case EEXIST:
2472                 /*
2473                  * The log device has unplayed logs
2474                  */
2475                 return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
2476 
2477         default:
2478                 return (zpool_standard_error(hdl, errno, msg));
2479         }
2480 }
2481 
2482 /*
2483  * Mark the given vdev faulted.
2484  */
2485 int
2486 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2487 {
2488         zfs_cmd_t zc = { 0 };
2489         char msg[1024];
2490         libzfs_handle_t *hdl = zhp->zpool_hdl;
2491 
2492         (void) snprintf(msg, sizeof (msg),
2493             dgettext(TEXT_DOMAIN, "cannot fault %llu"), guid);
2494 
2495         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2496         zc.zc_guid = guid;
2497         zc.zc_cookie = VDEV_STATE_FAULTED;
2498         zc.zc_obj = aux;
2499 
2500         if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2501                 return (0);
2502 
2503         switch (errno) {
2504         case EBUSY:
2505 
2506                 /*
2507                  * There are no other replicas of this device.
2508                  */
2509                 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
2510 
2511         default:
2512                 return (zpool_standard_error(hdl, errno, msg));
2513         }
2514 
2515 }
2516 
2517 /*
2518  * Mark the given vdev degraded.
2519  */
2520 int
2521 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
2522 {
2523         zfs_cmd_t zc = { 0 };
2524         char msg[1024];
2525         libzfs_handle_t *hdl = zhp->zpool_hdl;
2526 
2527         (void) snprintf(msg, sizeof (msg),
2528             dgettext(TEXT_DOMAIN, "cannot degrade %llu"), guid);
2529 
2530         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2531         zc.zc_guid = guid;
2532         zc.zc_cookie = VDEV_STATE_DEGRADED;
2533         zc.zc_obj = aux;
2534 
2535         if (ioctl(hdl->libzfs_fd, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
2536                 return (0);
2537 
2538         return (zpool_standard_error(hdl, errno, msg));
2539 }
2540 
2541 /*
2542  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
2543  * a hot spare.
2544  */
2545 static boolean_t
2546 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
2547 {
2548         nvlist_t **child;
2549         uint_t c, children;
2550         char *type;
2551 
2552         if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
2553             &children) == 0) {
2554                 verify(nvlist_lookup_string(search, ZPOOL_CONFIG_TYPE,
2555                     &type) == 0);
2556 
2557                 if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
2558                     children == 2 && child[which] == tgt)
2559                         return (B_TRUE);
2560 
2561                 for (c = 0; c < children; c++)
2562                         if (is_replacing_spare(child[c], tgt, which))
2563                                 return (B_TRUE);
2564         }
2565 
2566         return (B_FALSE);
2567 }
2568 
2569 /*
2570  * Attach new_disk (fully described by nvroot) to old_disk.
2571  * If 'replacing' is specified, the new disk will replace the old one.
2572  */
2573 int
2574 zpool_vdev_attach(zpool_handle_t *zhp,
2575     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
2576 {
2577         zfs_cmd_t zc = { 0 };
2578         char msg[1024];
2579         int ret;
2580         nvlist_t *tgt;
2581         boolean_t avail_spare, l2cache, islog;
2582         uint64_t val;
2583         char *newname;
2584         nvlist_t **child;
2585         uint_t children;
2586         nvlist_t *config_root;
2587         libzfs_handle_t *hdl = zhp->zpool_hdl;
2588         boolean_t rootpool = zpool_is_bootable(zhp);
2589 
2590         if (replacing)
2591                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2592                     "cannot replace %s with %s"), old_disk, new_disk);
2593         else
2594                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2595                     "cannot attach %s to %s"), new_disk, old_disk);
2596 
2597         /*
2598          * If this is a root pool, make sure that we're not attaching an
2599          * EFI labeled device.
2600          */
2601         if (rootpool && pool_uses_efi(nvroot)) {
2602                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2603                     "EFI labeled devices are not supported on root pools."));
2604                 return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
2605         }
2606 
2607         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2608         if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
2609             &islog)) == 0)
2610                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2611 
2612         if (avail_spare)
2613                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2614 
2615         if (l2cache)
2616                 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2617 
2618         verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2619         zc.zc_cookie = replacing;
2620 
2621         if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
2622             &child, &children) != 0 || children != 1) {
2623                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2624                     "new device must be a single disk"));
2625                 return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
2626         }
2627 
2628         verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
2629             ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
2630 
2631         if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
2632                 return (-1);
2633 
2634         /*
2635          * If the target is a hot spare that has been swapped in, we can only
2636          * replace it with another hot spare.
2637          */
2638         if (replacing &&
2639             nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
2640             (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
2641             NULL) == NULL || !avail_spare) &&
2642             is_replacing_spare(config_root, tgt, 1)) {
2643                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2644                     "can only be replaced by another hot spare"));
2645                 free(newname);
2646                 return (zfs_error(hdl, EZFS_BADTARGET, msg));
2647         }
2648 
2649         free(newname);
2650 
2651         if (zcmd_write_conf_nvlist(hdl, &zc, nvroot) != 0)
2652                 return (-1);
2653 
2654         ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
2655 
2656         zcmd_free_nvlists(&zc);
2657 
2658         if (ret == 0) {
2659                 if (rootpool) {
2660                         /*
2661                          * XXX need a better way to prevent user from
2662                          * booting up a half-baked vdev.
2663                          */
2664                         (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Make "
2665                             "sure to wait until resilver is done "
2666                             "before rebooting.\n"));
2667                 }
2668                 return (0);
2669         }
2670 
2671         switch (errno) {
2672         case ENOTSUP:
2673                 /*
2674                  * Can't attach to or replace this type of vdev.
2675                  */
2676                 if (replacing) {
2677                         uint64_t version = zpool_get_prop_int(zhp,
2678                             ZPOOL_PROP_VERSION, NULL);
2679 
2680                         if (islog)
2681                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2682                                     "cannot replace a log with a spare"));
2683                         else if (version >= SPA_VERSION_MULTI_REPLACE)
2684                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2685                                     "already in replacing/spare config; wait "
2686                                     "for completion or use 'zpool detach'"));
2687                         else
2688                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2689                                     "cannot replace a replacing device"));
2690                 } else {
2691                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2692                             "can only attach to mirrors and top-level "
2693                             "disks"));
2694                 }
2695                 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
2696                 break;
2697 
2698         case EINVAL:
2699                 /*
2700                  * The new device must be a single disk.
2701                  */
2702                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2703                     "new device must be a single disk"));
2704                 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
2705                 break;
2706 
2707         case EBUSY:
2708                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy"),
2709                     new_disk);
2710                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2711                 break;
2712 
2713         case EOVERFLOW:
2714                 /*
2715                  * The new device is too small.
2716                  */
2717                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2718                     "device is too small"));
2719                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2720                 break;
2721 
2722         case EDOM:
2723                 /*
2724                  * The new device has a different alignment requirement.
2725                  */
2726                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2727                     "devices have different sector alignment"));
2728                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
2729                 break;
2730 
2731         case ENAMETOOLONG:
2732                 /*
2733                  * The resulting top-level vdev spec won't fit in the label.
2734                  */
2735                 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
2736                 break;
2737 
2738         default:
2739                 (void) zpool_standard_error(hdl, errno, msg);
2740         }
2741 
2742         return (-1);
2743 }
2744 
2745 /*
2746  * Detach the specified device.
2747  */
2748 int
2749 zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
2750 {
2751         zfs_cmd_t zc = { 0 };
2752         char msg[1024];
2753         nvlist_t *tgt;
2754         boolean_t avail_spare, l2cache;
2755         libzfs_handle_t *hdl = zhp->zpool_hdl;
2756 
2757         (void) snprintf(msg, sizeof (msg),
2758             dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
2759 
2760         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2761         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
2762             NULL)) == 0)
2763                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
2764 
2765         if (avail_spare)
2766                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
2767 
2768         if (l2cache)
2769                 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
2770 
2771         verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
2772 
2773         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
2774                 return (0);
2775 
2776         switch (errno) {
2777 
2778         case ENOTSUP:
2779                 /*
2780                  * Can't detach from this type of vdev.
2781                  */
2782                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
2783                     "applicable to mirror and replacing vdevs"));
2784                 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
2785                 break;
2786 
2787         case EBUSY:
2788                 /*
2789                  * There are no other replicas of this device.
2790                  */
2791                 (void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
2792                 break;
2793 
2794         default:
2795                 (void) zpool_standard_error(hdl, errno, msg);
2796         }
2797 
2798         return (-1);
2799 }
2800 
2801 /*
2802  * Find a mirror vdev in the source nvlist.
2803  *
2804  * The mchild array contains a list of disks in one of the top-level mirrors
2805  * of the source pool.  The schild array contains a list of disks that the
2806  * user specified on the command line.  We loop over the mchild array to
2807  * see if any entry in the schild array matches.
2808  *
2809  * If a disk in the mchild array is found in the schild array, we return
2810  * the index of that entry.  Otherwise we return -1.
2811  */
2812 static int
2813 find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
2814     nvlist_t **schild, uint_t schildren)
2815 {
2816         uint_t mc;
2817 
2818         for (mc = 0; mc < mchildren; mc++) {
2819                 uint_t sc;
2820                 char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
2821                     mchild[mc], B_FALSE);
2822 
2823                 for (sc = 0; sc < schildren; sc++) {
2824                         char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
2825                             schild[sc], B_FALSE);
2826                         boolean_t result = (strcmp(mpath, spath) == 0);
2827 
2828                         free(spath);
2829                         if (result) {
2830                                 free(mpath);
2831                                 return (mc);
2832                         }
2833                 }
2834 
2835                 free(mpath);
2836         }
2837 
2838         return (-1);
2839 }
2840 
2841 /*
2842  * Split a mirror pool.  If newroot points to null, then a new nvlist
2843  * is generated and it is the responsibility of the caller to free it.
2844  */
2845 int
2846 zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
2847     nvlist_t *props, splitflags_t flags)
2848 {
2849         zfs_cmd_t zc = { 0 };
2850         char msg[1024];
2851         nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
2852         nvlist_t **varray = NULL, *zc_props = NULL;
2853         uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
2854         libzfs_handle_t *hdl = zhp->zpool_hdl;
2855         uint64_t vers;
2856         boolean_t freelist = B_FALSE, memory_err = B_TRUE;
2857         int retval = 0;
2858 
2859         (void) snprintf(msg, sizeof (msg),
2860             dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
2861 
2862         if (!zpool_name_valid(hdl, B_FALSE, newname))
2863                 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
2864 
2865         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
2866                 (void) fprintf(stderr, gettext("Internal error: unable to "
2867                     "retrieve pool configuration\n"));
2868                 return (-1);
2869         }
2870 
2871         verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree)
2872             == 0);
2873         verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &vers) == 0);
2874 
2875         if (props) {
2876                 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
2877                 if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
2878                     props, vers, flags, msg)) == NULL)
2879                         return (-1);
2880         }
2881 
2882         if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
2883             &children) != 0) {
2884                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2885                     "Source pool is missing vdev tree"));
2886                 if (zc_props)
2887                         nvlist_free(zc_props);
2888                 return (-1);
2889         }
2890 
2891         varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
2892         vcount = 0;
2893 
2894         if (*newroot == NULL ||
2895             nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
2896             &newchild, &newchildren) != 0)
2897                 newchildren = 0;
2898 
2899         for (c = 0; c < children; c++) {
2900                 uint64_t is_log = B_FALSE, is_hole = B_FALSE;
2901                 char *type;
2902                 nvlist_t **mchild, *vdev;
2903                 uint_t mchildren;
2904                 int entry;
2905 
2906                 /*
2907                  * Unlike cache & spares, slogs are stored in the
2908                  * ZPOOL_CONFIG_CHILDREN array.  We filter them out here.
2909                  */
2910                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
2911                     &is_log);
2912                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
2913                     &is_hole);
2914                 if (is_log || is_hole) {
2915                         /*
2916                          * Create a hole vdev and put it in the config.
2917                          */
2918                         if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
2919                                 goto out;
2920                         if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
2921                             VDEV_TYPE_HOLE) != 0)
2922                                 goto out;
2923                         if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
2924                             1) != 0)
2925                                 goto out;
2926                         if (lastlog == 0)
2927                                 lastlog = vcount;
2928                         varray[vcount++] = vdev;
2929                         continue;
2930                 }
2931                 lastlog = 0;
2932                 verify(nvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE, &type)
2933                     == 0);
2934                 if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
2935                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2936                             "Source pool must be composed only of mirrors\n"));
2937                         retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
2938                         goto out;
2939                 }
2940 
2941                 verify(nvlist_lookup_nvlist_array(child[c],
2942                     ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
2943 
2944                 /* find or add an entry for this top-level vdev */
2945                 if (newchildren > 0 &&
2946                     (entry = find_vdev_entry(zhp, mchild, mchildren,
2947                     newchild, newchildren)) >= 0) {
2948                         /* We found a disk that the user specified. */
2949                         vdev = mchild[entry];
2950                         ++found;
2951                 } else {
2952                         /* User didn't specify a disk for this vdev. */
2953                         vdev = mchild[mchildren - 1];
2954                 }
2955 
2956                 if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
2957                         goto out;
2958         }
2959 
2960         /* did we find every disk the user specified? */
2961         if (found != newchildren) {
2962                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
2963                     "include at most one disk from each mirror"));
2964                 retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
2965                 goto out;
2966         }
2967 
2968         /* Prepare the nvlist for populating. */
2969         if (*newroot == NULL) {
2970                 if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
2971                         goto out;
2972                 freelist = B_TRUE;
2973                 if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
2974                     VDEV_TYPE_ROOT) != 0)
2975                         goto out;
2976         } else {
2977                 verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
2978         }
2979 
2980         /* Add all the children we found */
2981         if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN, varray,
2982             lastlog == 0 ? vcount : lastlog) != 0)
2983                 goto out;
2984 
2985         /*
2986          * If we're just doing a dry run, exit now with success.
2987          */
2988         if (flags.dryrun) {
2989                 memory_err = B_FALSE;
2990                 freelist = B_FALSE;
2991                 goto out;
2992         }
2993 
2994         /* now build up the config list & call the ioctl */
2995         if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
2996                 goto out;
2997 
2998         if (nvlist_add_nvlist(newconfig,
2999             ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
3000             nvlist_add_string(newconfig,
3001             ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
3002             nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
3003                 goto out;
3004 
3005         /*
3006          * The new pool is automatically part of the namespace unless we
3007          * explicitly export it.
3008          */
3009         if (!flags.import)
3010                 zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
3011         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3012         (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
3013         if (zcmd_write_conf_nvlist(hdl, &zc, newconfig) != 0)
3014                 goto out;
3015         if (zc_props != NULL && zcmd_write_src_nvlist(hdl, &zc, zc_props) != 0)
3016                 goto out;
3017 
3018         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
3019                 retval = zpool_standard_error(hdl, errno, msg);
3020                 goto out;
3021         }
3022 
3023         freelist = B_FALSE;
3024         memory_err = B_FALSE;
3025 
3026 out:
3027         if (varray != NULL) {
3028                 int v;
3029 
3030                 for (v = 0; v < vcount; v++)
3031                         nvlist_free(varray[v]);
3032                 free(varray);
3033         }
3034         zcmd_free_nvlists(&zc);
3035         if (zc_props)
3036                 nvlist_free(zc_props);
3037         if (newconfig)
3038                 nvlist_free(newconfig);
3039         if (freelist) {
3040                 nvlist_free(*newroot);
3041                 *newroot = NULL;
3042         }
3043 
3044         if (retval != 0)
3045                 return (retval);
3046 
3047         if (memory_err)
3048                 return (no_memory(hdl));
3049 
3050         return (0);
3051 }
3052 
3053 /*
3054  * Remove the given device.  Currently, this is supported only for hot spares
3055  * and level 2 cache devices.
3056  */
3057 int
3058 zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
3059 {
3060         zfs_cmd_t zc = { 0 };
3061         char msg[1024];
3062         nvlist_t *tgt;
3063         boolean_t avail_spare, l2cache, islog;
3064         libzfs_handle_t *hdl = zhp->zpool_hdl;
3065         uint64_t version;
3066 
3067         (void) snprintf(msg, sizeof (msg),
3068             dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
3069 
3070         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3071         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3072             &islog)) == 0)
3073                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3074         /*
3075          * XXX - this should just go away.
3076          */
3077         if (!avail_spare && !l2cache && !islog) {
3078                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3079                     "only inactive hot spares, cache, top-level, "
3080                     "or log devices can be removed"));
3081                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3082         }
3083 
3084         version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3085         if (islog && version < SPA_VERSION_HOLES) {
3086                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3087                     "pool must be upgrade to support log removal"));
3088                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
3089         }
3090 
3091         verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &zc.zc_guid) == 0);
3092 
3093         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
3094                 return (0);
3095 
3096         return (zpool_standard_error(hdl, errno, msg));
3097 }
3098 
3099 /*
3100  * Clear the errors for the pool, or the particular device if specified.
3101  */
3102 int
3103 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
3104 {
3105         zfs_cmd_t zc = { 0 };
3106         char msg[1024];
3107         nvlist_t *tgt;
3108         zpool_rewind_policy_t policy;
3109         boolean_t avail_spare, l2cache;
3110         libzfs_handle_t *hdl = zhp->zpool_hdl;
3111         nvlist_t *nvi = NULL;
3112         int error;
3113 
3114         if (path)
3115                 (void) snprintf(msg, sizeof (msg),
3116                     dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
3117                     path);
3118         else
3119                 (void) snprintf(msg, sizeof (msg),
3120                     dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
3121                     zhp->zpool_name);
3122 
3123         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3124         if (path) {
3125                 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
3126                     &l2cache, NULL)) == 0)
3127                         return (zfs_error(hdl, EZFS_NODEVICE, msg));
3128 
3129                 /*
3130                  * Don't allow error clearing for hot spares.  Do allow
3131                  * error clearing for l2cache devices.
3132                  */
3133                 if (avail_spare)
3134                         return (zfs_error(hdl, EZFS_ISSPARE, msg));
3135 
3136                 verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
3137                     &zc.zc_guid) == 0);
3138         }
3139 
3140         zpool_get_rewind_policy(rewindnvl, &policy);
3141         zc.zc_cookie = policy.zrp_request;
3142 
3143         if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2) != 0)
3144                 return (-1);
3145 
3146         if (zcmd_write_src_nvlist(hdl, &zc, rewindnvl) != 0)
3147                 return (-1);
3148 
3149         while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
3150             errno == ENOMEM) {
3151                 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
3152                         zcmd_free_nvlists(&zc);
3153                         return (-1);
3154                 }
3155         }
3156 
3157         if (!error || ((policy.zrp_request & ZPOOL_TRY_REWIND) &&
3158             errno != EPERM && errno != EACCES)) {
3159                 if (policy.zrp_request &
3160                     (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
3161                         (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
3162                         zpool_rewind_exclaim(hdl, zc.zc_name,
3163                             ((policy.zrp_request & ZPOOL_TRY_REWIND) != 0),
3164                             nvi);
3165                         nvlist_free(nvi);
3166                 }
3167                 zcmd_free_nvlists(&zc);
3168                 return (0);
3169         }
3170 
3171         zcmd_free_nvlists(&zc);
3172         return (zpool_standard_error(hdl, errno, msg));
3173 }
3174 
3175 /*
3176  * Similar to zpool_clear(), but takes a GUID (used by fmd).
3177  */
3178 int
3179 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
3180 {
3181         zfs_cmd_t zc = { 0 };
3182         char msg[1024];
3183         libzfs_handle_t *hdl = zhp->zpool_hdl;
3184 
3185         (void) snprintf(msg, sizeof (msg),
3186             dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
3187             guid);
3188 
3189         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3190         zc.zc_guid = guid;
3191         zc.zc_cookie = ZPOOL_NO_REWIND;
3192 
3193         if (ioctl(hdl->libzfs_fd, ZFS_IOC_CLEAR, &zc) == 0)
3194                 return (0);
3195 
3196         return (zpool_standard_error(hdl, errno, msg));
3197 }
3198 
3199 /*
3200  * Change the GUID for a pool.
3201  */
3202 int
3203 zpool_reguid(zpool_handle_t *zhp)
3204 {
3205         char msg[1024];
3206         libzfs_handle_t *hdl = zhp->zpool_hdl;
3207         zfs_cmd_t zc = { 0 };
3208 
3209         (void) snprintf(msg, sizeof (msg),
3210             dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
3211 
3212         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3213         if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
3214                 return (0);
3215 
3216         return (zpool_standard_error(hdl, errno, msg));
3217 }
3218 
3219 /*
3220  * Reopen the pool.
3221  */
3222 int
3223 zpool_reopen(zpool_handle_t *zhp)
3224 {
3225         zfs_cmd_t zc = { 0 };
3226         char msg[1024];
3227         libzfs_handle_t *hdl = zhp->zpool_hdl;
3228 
3229         (void) snprintf(msg, sizeof (msg),
3230             dgettext(TEXT_DOMAIN, "cannot reopen '%s'"),
3231             zhp->zpool_name);
3232 
3233         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3234         if (zfs_ioctl(hdl, ZFS_IOC_POOL_REOPEN, &zc) == 0)
3235                 return (0);
3236         return (zpool_standard_error(hdl, errno, msg));
3237 }
3238 
3239 /*
3240  * Convert from a devid string to a path.
3241  */
3242 static char *
3243 devid_to_path(char *devid_str)
3244 {
3245         ddi_devid_t devid;
3246         char *minor;
3247         char *path;
3248         devid_nmlist_t *list = NULL;
3249         int ret;
3250 
3251         if (devid_str_decode(devid_str, &devid, &minor) != 0)
3252                 return (NULL);
3253 
3254         ret = devid_deviceid_to_nmlist("/dev", devid, minor, &list);
3255 
3256         devid_str_free(minor);
3257         devid_free(devid);
3258 
3259         if (ret != 0)
3260                 return (NULL);
3261 
3262         if ((path = strdup(list[0].devname)) == NULL)
3263                 return (NULL);
3264 
3265         devid_free_nmlist(list);
3266 
3267         return (path);
3268 }
3269 
3270 /*
3271  * Convert from a path to a devid string.
3272  */
3273 static char *
3274 path_to_devid(const char *path)
3275 {
3276         int fd;
3277         ddi_devid_t devid;
3278         char *minor, *ret;
3279 
3280         if ((fd = open(path, O_RDONLY)) < 0)
3281                 return (NULL);
3282 
3283         minor = NULL;
3284         ret = NULL;
3285         if (devid_get(fd, &devid) == 0) {
3286                 if (devid_get_minor_name(fd, &minor) == 0)
3287                         ret = devid_str_encode(devid, minor);
3288                 if (minor != NULL)
3289                         devid_str_free(minor);
3290                 devid_free(devid);
3291         }
3292         (void) close(fd);
3293 
3294         return (ret);
3295 }
3296 
3297 /*
3298  * Issue the necessary ioctl() to update the stored path value for the vdev.  We
3299  * ignore any failure here, since a common case is for an unprivileged user to
3300  * type 'zpool status', and we'll display the correct information anyway.
3301  */
3302 static void
3303 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
3304 {
3305         zfs_cmd_t zc = { 0 };
3306 
3307         (void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3308         (void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
3309         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
3310             &zc.zc_guid) == 0);
3311 
3312         (void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
3313 }
3314 
3315 /*
3316  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
3317  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
3318  * We also check if this is a whole disk, in which case we strip off the
3319  * trailing 's0' slice name.
3320  *
3321  * This routine is also responsible for identifying when disks have been
3322  * reconfigured in a new location.  The kernel will have opened the device by
3323  * devid, but the path will still refer to the old location.  To catch this, we
3324  * first do a path -> devid translation (which is fast for the common case).  If
3325  * the devid matches, we're done.  If not, we do a reverse devid -> path
3326  * translation and issue the appropriate ioctl() to update the path of the vdev.
3327  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
3328  * of these checks.
3329  */
3330 char *
3331 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
3332     boolean_t verbose)
3333 {
3334         char *path, *devid;
3335         uint64_t value;
3336         char buf[64];
3337         vdev_stat_t *vs;
3338         uint_t vsc;
3339 
3340         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
3341             &value) == 0) {
3342                 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
3343                     &value) == 0);
3344                 (void) snprintf(buf, sizeof (buf), "%llu",
3345                     (u_longlong_t)value);
3346                 path = buf;
3347         } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
3348 
3349                 /*
3350                  * If the device is dead (faulted, offline, etc) then don't
3351                  * bother opening it.  Otherwise we may be forcing the user to
3352                  * open a misbehaving device, which can have undesirable
3353                  * effects.
3354                  */
3355                 if ((nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
3356                     (uint64_t **)&vs, &vsc) != 0 ||
3357                     vs->vs_state >= VDEV_STATE_DEGRADED) &&
3358                     zhp != NULL &&
3359                     nvlist_lookup_string(nv, ZPOOL_CONFIG_DEVID, &devid) == 0) {
3360                         /*
3361                          * Determine if the current path is correct.
3362                          */
3363                         char *newdevid = path_to_devid(path);
3364 
3365                         if (newdevid == NULL ||
3366                             strcmp(devid, newdevid) != 0) {
3367                                 char *newpath;
3368 
3369                                 if ((newpath = devid_to_path(devid)) != NULL) {
3370                                         /*
3371                                          * Update the path appropriately.
3372                                          */
3373                                         set_path(zhp, nv, newpath);
3374                                         if (nvlist_add_string(nv,
3375                                             ZPOOL_CONFIG_PATH, newpath) == 0)
3376                                                 verify(nvlist_lookup_string(nv,
3377                                                     ZPOOL_CONFIG_PATH,
3378                                                     &path) == 0);
3379                                         free(newpath);
3380                                 }
3381                         }
3382 
3383                         if (newdevid)
3384                                 devid_str_free(newdevid);
3385                 }
3386 
3387                 if (strncmp(path, "/dev/dsk/", 9) == 0)
3388                         path += 9;
3389 
3390                 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
3391                     &value) == 0 && value) {
3392                         int pathlen = strlen(path);
3393                         char *tmp = zfs_strdup(hdl, path);
3394 
3395                         /*
3396                          * If it starts with c#, and ends with "s0", chop
3397                          * the "s0" off, or if it ends with "s0/old", remove
3398                          * the "s0" from the middle.
3399                          */
3400                         if (CTD_CHECK(tmp)) {
3401                                 if (strcmp(&tmp[pathlen - 2], "s0") == 0) {
3402                                         tmp[pathlen - 2] = '\0';
3403                                 } else if (pathlen > 6 &&
3404                                     strcmp(&tmp[pathlen - 6], "s0/old") == 0) {
3405                                         (void) strcpy(&tmp[pathlen - 6],
3406                                             "/old");
3407                                 }
3408                         }
3409                         return (tmp);
3410                 }
3411         } else {
3412                 verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
3413 
3414                 /*
3415                  * If it's a raidz device, we need to stick in the parity level.
3416                  */
3417                 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
3418                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY,
3419                             &value) == 0);
3420                         (void) snprintf(buf, sizeof (buf), "%s%llu", path,
3421                             (u_longlong_t)value);
3422                         path = buf;
3423                 }
3424 
3425                 /*
3426                  * We identify each top-level vdev by using a <type-id>
3427                  * naming convention.
3428                  */
3429                 if (verbose) {
3430                         uint64_t id;
3431 
3432                         verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
3433                             &id) == 0);
3434                         (void) snprintf(buf, sizeof (buf), "%s-%llu", path,
3435                             (u_longlong_t)id);
3436                         path = buf;
3437                 }
3438         }
3439 
3440         return (zfs_strdup(hdl, path));
3441 }
3442 
3443 static int
3444 zbookmark_compare(const void *a, const void *b)
3445 {
3446         return (memcmp(a, b, sizeof (zbookmark_t)));
3447 }
3448 
3449 /*
3450  * Retrieve the persistent error log, uniquify the members, and return to the
3451  * caller.
3452  */
3453 int
3454 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
3455 {
3456         zfs_cmd_t zc = { 0 };
3457         uint64_t count;
3458         zbookmark_t *zb = NULL;
3459         int i;
3460 
3461         /*
3462          * Retrieve the raw error list from the kernel.  If the number of errors
3463          * has increased, allocate more space and continue until we get the
3464          * entire list.
3465          */
3466         verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
3467             &count) == 0);
3468         if (count == 0)
3469                 return (0);
3470         if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
3471             count * sizeof (zbookmark_t))) == (uintptr_t)NULL)
3472                 return (-1);
3473         zc.zc_nvlist_dst_size = count;
3474         (void) strcpy(zc.zc_name, zhp->zpool_name);
3475         for (;;) {
3476                 if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
3477                     &zc) != 0) {
3478                         free((void *)(uintptr_t)zc.zc_nvlist_dst);
3479                         if (errno == ENOMEM) {
3480                                 count = zc.zc_nvlist_dst_size;
3481                                 if ((zc.zc_nvlist_dst = (uintptr_t)
3482                                     zfs_alloc(zhp->zpool_hdl, count *
3483                                     sizeof (zbookmark_t))) == (uintptr_t)NULL)
3484                                         return (-1);
3485                         } else {
3486                                 return (-1);
3487                         }
3488                 } else {
3489                         break;
3490                 }
3491         }
3492 
3493         /*
3494          * Sort the resulting bookmarks.  This is a little confusing due to the
3495          * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
3496          * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
3497          * _not_ copied as part of the process.  So we point the start of our
3498          * array appropriate and decrement the total number of elements.
3499          */
3500         zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
3501             zc.zc_nvlist_dst_size;
3502         count -= zc.zc_nvlist_dst_size;
3503 
3504         qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
3505 
3506         verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
3507 
3508         /*
3509          * Fill in the nverrlistp with nvlist's of dataset and object numbers.
3510          */
3511         for (i = 0; i < count; i++) {
3512                 nvlist_t *nv;
3513 
3514                 /* ignoring zb_blkid and zb_level for now */
3515                 if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
3516                     zb[i-1].zb_object == zb[i].zb_object)
3517                         continue;
3518 
3519                 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
3520                         goto nomem;
3521                 if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
3522                     zb[i].zb_objset) != 0) {
3523                         nvlist_free(nv);
3524                         goto nomem;
3525                 }
3526                 if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
3527                     zb[i].zb_object) != 0) {
3528                         nvlist_free(nv);
3529                         goto nomem;
3530                 }
3531                 if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
3532                         nvlist_free(nv);
3533                         goto nomem;
3534                 }
3535                 nvlist_free(nv);
3536         }
3537 
3538         free((void *)(uintptr_t)zc.zc_nvlist_dst);
3539         return (0);
3540 
3541 nomem:
3542         free((void *)(uintptr_t)zc.zc_nvlist_dst);
3543         return (no_memory(zhp->zpool_hdl));
3544 }
3545 
3546 /*
3547  * Upgrade a ZFS pool to the latest on-disk version.
3548  */
3549 int
3550 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
3551 {
3552         zfs_cmd_t zc = { 0 };
3553         libzfs_handle_t *hdl = zhp->zpool_hdl;
3554 
3555         (void) strcpy(zc.zc_name, zhp->zpool_name);
3556         zc.zc_cookie = new_version;
3557 
3558         if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
3559                 return (zpool_standard_error_fmt(hdl, errno,
3560                     dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
3561                     zhp->zpool_name));
3562         return (0);
3563 }
3564 
3565 void
3566 zfs_save_arguments(int argc, char **argv, char *string, int len)
3567 {
3568         (void) strlcpy(string, basename(argv[0]), len);
3569         for (int i = 1; i < argc; i++) {
3570                 (void) strlcat(string, " ", len);
3571                 (void) strlcat(string, argv[i], len);
3572         }
3573 }
3574 
3575 int
3576 zpool_log_history(libzfs_handle_t *hdl, const char *message)
3577 {
3578         zfs_cmd_t zc = { 0 };
3579         nvlist_t *args;
3580         int err;
3581 
3582         args = fnvlist_alloc();
3583         fnvlist_add_string(args, "message", message);
3584         err = zcmd_write_src_nvlist(hdl, &zc, args);
3585         if (err == 0)
3586                 err = ioctl(hdl->libzfs_fd, ZFS_IOC_LOG_HISTORY, &zc);
3587         nvlist_free(args);
3588         zcmd_free_nvlists(&zc);
3589         return (err);
3590 }
3591 
3592 /*
3593  * Perform ioctl to get some command history of a pool.
3594  *
3595  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
3596  * logical offset of the history buffer to start reading from.
3597  *
3598  * Upon return, 'off' is the next logical offset to read from and
3599  * 'len' is the actual amount of bytes read into 'buf'.
3600  */
3601 static int
3602 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
3603 {
3604         zfs_cmd_t zc = { 0 };
3605         libzfs_handle_t *hdl = zhp->zpool_hdl;
3606 
3607         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3608 
3609         zc.zc_history = (uint64_t)(uintptr_t)buf;
3610         zc.zc_history_len = *len;
3611         zc.zc_history_offset = *off;
3612 
3613         if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
3614                 switch (errno) {
3615                 case EPERM:
3616                         return (zfs_error_fmt(hdl, EZFS_PERM,
3617                             dgettext(TEXT_DOMAIN,
3618                             "cannot show history for pool '%s'"),
3619                             zhp->zpool_name));
3620                 case ENOENT:
3621                         return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
3622                             dgettext(TEXT_DOMAIN, "cannot get history for pool "
3623                             "'%s'"), zhp->zpool_name));
3624                 case ENOTSUP:
3625                         return (zfs_error_fmt(hdl, EZFS_BADVERSION,
3626                             dgettext(TEXT_DOMAIN, "cannot get history for pool "
3627                             "'%s', pool must be upgraded"), zhp->zpool_name));
3628                 default:
3629                         return (zpool_standard_error_fmt(hdl, errno,
3630                             dgettext(TEXT_DOMAIN,
3631                             "cannot get history for '%s'"), zhp->zpool_name));
3632                 }
3633         }
3634 
3635         *len = zc.zc_history_len;
3636         *off = zc.zc_history_offset;
3637 
3638         return (0);
3639 }
3640 
3641 /*
3642  * Process the buffer of nvlists, unpacking and storing each nvlist record
3643  * into 'records'.  'leftover' is set to the number of bytes that weren't
3644  * processed as there wasn't a complete record.
3645  */
3646 int
3647 zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
3648     nvlist_t ***records, uint_t *numrecords)
3649 {
3650         uint64_t reclen;
3651         nvlist_t *nv;
3652         int i;
3653 
3654         while (bytes_read > sizeof (reclen)) {
3655 
3656                 /* get length of packed record (stored as little endian) */
3657                 for (i = 0, reclen = 0; i < sizeof (reclen); i++)
3658                         reclen += (uint64_t)(((uchar_t *)buf)[i]) << (8*i);
3659 
3660                 if (bytes_read < sizeof (reclen) + reclen)
3661                         break;
3662 
3663                 /* unpack record */
3664                 if (nvlist_unpack(buf + sizeof (reclen), reclen, &nv, 0) != 0)
3665                         return (ENOMEM);
3666                 bytes_read -= sizeof (reclen) + reclen;
3667                 buf += sizeof (reclen) + reclen;
3668 
3669                 /* add record to nvlist array */
3670                 (*numrecords)++;
3671                 if (ISP2(*numrecords + 1)) {
3672                         *records = realloc(*records,
3673                             *numrecords * 2 * sizeof (nvlist_t *));
3674                 }
3675                 (*records)[*numrecords - 1] = nv;
3676         }
3677 
3678         *leftover = bytes_read;
3679         return (0);
3680 }
3681 
3682 #define HIS_BUF_LEN     (128*1024)
3683 
3684 /*
3685  * Retrieve the command history of a pool.
3686  */
3687 int
3688 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
3689 {
3690         char buf[HIS_BUF_LEN];
3691         uint64_t off = 0;
3692         nvlist_t **records = NULL;
3693         uint_t numrecords = 0;
3694         int err, i;
3695 
3696         do {
3697                 uint64_t bytes_read = sizeof (buf);
3698                 uint64_t leftover;
3699 
3700                 if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
3701                         break;
3702 
3703                 /* if nothing else was read in, we're at EOF, just return */
3704                 if (!bytes_read)
3705                         break;
3706 
3707                 if ((err = zpool_history_unpack(buf, bytes_read,
3708                     &leftover, &records, &numrecords)) != 0)
3709                         break;
3710                 off -= leftover;
3711 
3712                 /* CONSTCOND */
3713         } while (1);
3714 
3715         if (!err) {
3716                 verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
3717                 verify(nvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
3718                     records, numrecords) == 0);
3719         }
3720         for (i = 0; i < numrecords; i++)
3721                 nvlist_free(records[i]);
3722         free(records);
3723 
3724         return (err);
3725 }
3726 
3727 void
3728 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
3729     char *pathname, size_t len)
3730 {
3731         zfs_cmd_t zc = { 0 };
3732         boolean_t mounted = B_FALSE;
3733         char *mntpnt = NULL;
3734         char dsname[MAXNAMELEN];
3735 
3736         if (dsobj == 0) {
3737                 /* special case for the MOS */
3738                 (void) snprintf(pathname, len, "<metadata>:<0x%llx>", obj);
3739                 return;
3740         }
3741 
3742         /* get the dataset's name */
3743         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3744         zc.zc_obj = dsobj;
3745         if (ioctl(zhp->zpool_hdl->libzfs_fd,
3746             ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
3747                 /* just write out a path of two object numbers */
3748                 (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
3749                     dsobj, obj);
3750                 return;
3751         }
3752         (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
3753 
3754         /* find out if the dataset is mounted */
3755         mounted = is_mounted(zhp->zpool_hdl, dsname, &mntpnt);
3756 
3757         /* get the corrupted object's path */
3758         (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
3759         zc.zc_obj = obj;
3760         if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJ_TO_PATH,
3761             &zc) == 0) {
3762                 if (mounted) {
3763                         (void) snprintf(pathname, len, "%s%s", mntpnt,
3764                             zc.zc_value);
3765                 } else {
3766                         (void) snprintf(pathname, len, "%s:%s",
3767                             dsname, zc.zc_value);
3768                 }
3769         } else {
3770                 (void) snprintf(pathname, len, "%s:<0x%llx>", dsname, obj);
3771         }
3772         free(mntpnt);
3773 }
3774 
3775 /*
3776  * Read the EFI label from the config, if a label does not exist then
3777  * pass back the error to the caller. If the caller has passed a non-NULL
3778  * diskaddr argument then we set it to the starting address of the EFI
3779  * partition.
3780  */
3781 static int
3782 read_efi_label(nvlist_t *config, diskaddr_t *sb)
3783 {
3784         char *path;
3785         int fd;
3786         char diskname[MAXPATHLEN];
3787         int err = -1;
3788 
3789         if (nvlist_lookup_string(config, ZPOOL_CONFIG_PATH, &path) != 0)
3790                 return (err);
3791 
3792         (void) snprintf(diskname, sizeof (diskname), "%s%s", RDISK_ROOT,
3793             strrchr(path, '/'));
3794         if ((fd = open(diskname, O_RDONLY|O_NDELAY)) >= 0) {
3795                 struct dk_gpt *vtoc;
3796 
3797                 if ((err = efi_alloc_and_read(fd, &vtoc)) >= 0) {
3798                         if (sb != NULL)
3799                                 *sb = vtoc->efi_parts[0].p_start;
3800                         efi_free(vtoc);
3801                 }
3802                 (void) close(fd);
3803         }
3804         return (err);
3805 }
3806 
3807 /*
3808  * determine where a partition starts on a disk in the current
3809  * configuration
3810  */
3811 static diskaddr_t
3812 find_start_block(nvlist_t *config)
3813 {
3814         nvlist_t **child;
3815         uint_t c, children;
3816         diskaddr_t sb = MAXOFFSET_T;
3817         uint64_t wholedisk;
3818 
3819         if (nvlist_lookup_nvlist_array(config,
3820             ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) {
3821                 if (nvlist_lookup_uint64(config,
3822                     ZPOOL_CONFIG_WHOLE_DISK,
3823                     &wholedisk) != 0 || !wholedisk) {
3824                         return (MAXOFFSET_T);
3825                 }
3826                 if (read_efi_label(config, &sb) < 0)
3827                         sb = MAXOFFSET_T;
3828                 return (sb);
3829         }
3830 
3831         for (c = 0; c < children; c++) {
3832                 sb = find_start_block(child[c]);
3833                 if (sb != MAXOFFSET_T) {
3834                         return (sb);
3835                 }
3836         }
3837         return (MAXOFFSET_T);
3838 }
3839 
3840 /*
3841  * Label an individual disk.  The name provided is the short name,
3842  * stripped of any leading /dev path.
3843  */
3844 int
3845 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
3846 {
3847         char path[MAXPATHLEN];
3848         struct dk_gpt *vtoc;
3849         int fd;
3850         size_t resv = EFI_MIN_RESV_SIZE;
3851         uint64_t slice_size;
3852         diskaddr_t start_block;
3853         char errbuf[1024];
3854 
3855         /* prepare an error message just in case */
3856         (void) snprintf(errbuf, sizeof (errbuf),
3857             dgettext(TEXT_DOMAIN, "cannot label '%s'"), name);
3858 
3859         if (zhp) {
3860                 nvlist_t *nvroot;
3861 
3862                 if (zpool_is_bootable(zhp)) {
3863                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3864                             "EFI labeled devices are not supported on root "
3865                             "pools."));
3866                         return (zfs_error(hdl, EZFS_POOL_NOTSUP, errbuf));
3867                 }
3868 
3869                 verify(nvlist_lookup_nvlist(zhp->zpool_config,
3870                     ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
3871 
3872                 if (zhp->zpool_start_block == 0)
3873                         start_block = find_start_block(nvroot);
3874                 else
3875                         start_block = zhp->zpool_start_block;
3876                 zhp->zpool_start_block = start_block;
3877         } else {
3878                 /* new pool */
3879                 start_block = NEW_START_BLOCK;
3880         }
3881 
3882         (void) snprintf(path, sizeof (path), "%s/%s%s", RDISK_ROOT, name,
3883             BACKUP_SLICE);
3884 
3885         if ((fd = open(path, O_RDWR | O_NDELAY)) < 0) {
3886                 /*
3887                  * This shouldn't happen.  We've long since verified that this
3888                  * is a valid device.
3889                  */
3890                 zfs_error_aux(hdl,
3891                     dgettext(TEXT_DOMAIN, "unable to open device"));
3892                 return (zfs_error(hdl, EZFS_OPENFAILED, errbuf));
3893         }
3894 
3895         if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
3896                 /*
3897                  * The only way this can fail is if we run out of memory, or we
3898                  * were unable to read the disk's capacity
3899                  */
3900                 if (errno == ENOMEM)
3901                         (void) no_memory(hdl);
3902 
3903                 (void) close(fd);
3904                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3905                     "unable to read disk capacity"), name);
3906 
3907                 return (zfs_error(hdl, EZFS_NOCAP, errbuf));
3908         }
3909 
3910         slice_size = vtoc->efi_last_u_lba + 1;
3911         slice_size -= EFI_MIN_RESV_SIZE;
3912         if (start_block == MAXOFFSET_T)
3913                 start_block = NEW_START_BLOCK;
3914         slice_size -= start_block;
3915 
3916         vtoc->efi_parts[0].p_start = start_block;
3917         vtoc->efi_parts[0].p_size = slice_size;
3918 
3919         /*
3920          * Why we use V_USR: V_BACKUP confuses users, and is considered
3921          * disposable by some EFI utilities (since EFI doesn't have a backup
3922          * slice).  V_UNASSIGNED is supposed to be used only for zero size
3923          * partitions, and efi_write() will fail if we use it.  V_ROOT, V_BOOT,
3924          * etc. were all pretty specific.  V_USR is as close to reality as we
3925          * can get, in the absence of V_OTHER.
3926          */
3927         vtoc->efi_parts[0].p_tag = V_USR;
3928         (void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
3929 
3930         vtoc->efi_parts[8].p_start = slice_size + start_block;
3931         vtoc->efi_parts[8].p_size = resv;
3932         vtoc->efi_parts[8].p_tag = V_RESERVED;
3933 
3934         if (efi_write(fd, vtoc) != 0) {
3935                 /*
3936                  * Some block drivers (like pcata) may not support EFI
3937                  * GPT labels.  Print out a helpful error message dir-
3938                  * ecting the user to manually label the disk and give
3939                  * a specific slice.
3940                  */
3941                 (void) close(fd);
3942                 efi_free(vtoc);
3943 
3944                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3945                     "try using fdisk(1M) and then provide a specific slice"));
3946                 return (zfs_error(hdl, EZFS_LABELFAILED, errbuf));
3947         }
3948 
3949         (void) close(fd);
3950         efi_free(vtoc);
3951         return (0);
3952 }
3953 
3954 static boolean_t
3955 supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf)
3956 {
3957         char *type;
3958         nvlist_t **child;
3959         uint_t children, c;
3960 
3961         verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0);
3962         if (strcmp(type, VDEV_TYPE_FILE) == 0 ||
3963             strcmp(type, VDEV_TYPE_HOLE) == 0 ||
3964             strcmp(type, VDEV_TYPE_MISSING) == 0) {
3965                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3966                     "vdev type '%s' is not supported"), type);
3967                 (void) zfs_error(hdl, EZFS_VDEVNOTSUP, errbuf);
3968                 return (B_FALSE);
3969         }
3970         if (nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN,
3971             &child, &children) == 0) {
3972                 for (c = 0; c < children; c++) {
3973                         if (!supported_dump_vdev_type(hdl, child[c], errbuf))
3974                                 return (B_FALSE);
3975                 }
3976         }
3977         return (B_TRUE);
3978 }
3979 
3980 /*
3981  * Check if this zvol is allowable for use as a dump device; zero if
3982  * it is, > 0 if it isn't, < 0 if it isn't a zvol.
3983  *
3984  * Allowable storage configurations include mirrors, all raidz variants, and
3985  * pools with log, cache, and spare devices.  Pools which are backed by files or
3986  * have missing/hole vdevs are not suitable.
3987  */
3988 int
3989 zvol_check_dump_config(char *arg)
3990 {
3991         zpool_handle_t *zhp = NULL;
3992         nvlist_t *config, *nvroot;
3993         char *p, *volname;
3994         nvlist_t **top;
3995         uint_t toplevels;
3996         libzfs_handle_t *hdl;
3997         char errbuf[1024];
3998         char poolname[ZPOOL_MAXNAMELEN];
3999         int pathlen = strlen(ZVOL_FULL_DEV_DIR);
4000         int ret = 1;
4001 
4002         if (strncmp(arg, ZVOL_FULL_DEV_DIR, pathlen)) {
4003                 return (-1);
4004         }
4005 
4006         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4007             "dump is not supported on device '%s'"), arg);
4008 
4009         if ((hdl = libzfs_init()) == NULL)
4010                 return (1);
4011         libzfs_print_on_error(hdl, B_TRUE);
4012 
4013         volname = arg + pathlen;
4014 
4015         /* check the configuration of the pool */
4016         if ((p = strchr(volname, '/')) == NULL) {
4017                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4018                     "malformed dataset name"));
4019                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
4020                 return (1);
4021         } else if (p - volname >= ZFS_MAXNAMELEN) {
4022                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4023                     "dataset name is too long"));
4024                 (void) zfs_error(hdl, EZFS_NAMETOOLONG, errbuf);
4025                 return (1);
4026         } else {
4027                 (void) strncpy(poolname, volname, p - volname);
4028                 poolname[p - volname] = '\0';
4029         }
4030 
4031         if ((zhp = zpool_open(hdl, poolname)) == NULL) {
4032                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4033                     "could not open pool '%s'"), poolname);
4034                 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
4035                 goto out;
4036         }
4037         config = zpool_get_config(zhp, NULL);
4038         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
4039             &nvroot) != 0) {
4040                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4041                     "could not obtain vdev configuration for  '%s'"), poolname);
4042                 (void) zfs_error(hdl, EZFS_INVALCONFIG, errbuf);
4043                 goto out;
4044         }
4045 
4046         verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
4047             &top, &toplevels) == 0);
4048 
4049         if (!supported_dump_vdev_type(hdl, top[0], errbuf)) {
4050                 goto out;
4051         }
4052         ret = 0;
4053 
4054 out:
4055         if (zhp)
4056                 zpool_close(zhp);
4057         libzfs_fini(hdl);
4058         return (ret);
4059 }