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