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