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