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