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