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