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