]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libzfs/libzfs_pool.c
libspl/include: remove unused/empty headers
[FreeBSD/FreeBSD.git] / lib / libzfs / libzfs_pool.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21
22 /*
23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
24  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25  * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
26  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27  * Copyright (c) 2018 Datto Inc.
28  * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
29  * Copyright (c) 2017, Intel Corporation.
30  * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>
31  * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
32  * Copyright (c) 2021, Klara Inc.
33  */
34
35 #include <errno.h>
36 #include <libintl.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <strings.h>
40 #include <unistd.h>
41 #include <libgen.h>
42 #include <zone.h>
43 #include <sys/stat.h>
44 #include <sys/efi_partition.h>
45 #include <sys/systeminfo.h>
46 #include <sys/zfs_ioctl.h>
47 #include <sys/zfs_sysfs.h>
48 #include <sys/vdev_disk.h>
49 #include <sys/types.h>
50 #include <dlfcn.h>
51 #include <libzutil.h>
52 #include <fcntl.h>
53
54 #include "zfs_namecheck.h"
55 #include "zfs_prop.h"
56 #include "libzfs_impl.h"
57 #include "zfs_comutil.h"
58 #include "zfeature_common.h"
59
60 static boolean_t zpool_vdev_is_interior(const char *name);
61
62 typedef struct prop_flags {
63         int create:1;   /* Validate property on creation */
64         int import:1;   /* Validate property on import */
65         int vdevprop:1; /* Validate property as a VDEV property */
66 } prop_flags_t;
67
68 /*
69  * ====================================================================
70  *   zpool property functions
71  * ====================================================================
72  */
73
74 static int
75 zpool_get_all_props(zpool_handle_t *zhp)
76 {
77         zfs_cmd_t zc = {"\0"};
78         libzfs_handle_t *hdl = zhp->zpool_hdl;
79
80         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
81
82         zcmd_alloc_dst_nvlist(hdl, &zc, 0);
83
84         while (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_PROPS, &zc) != 0) {
85                 if (errno == ENOMEM)
86                         zcmd_expand_dst_nvlist(hdl, &zc);
87                 else {
88                         zcmd_free_nvlists(&zc);
89                         return (-1);
90                 }
91         }
92
93         if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zpool_props) != 0) {
94                 zcmd_free_nvlists(&zc);
95                 return (-1);
96         }
97
98         zcmd_free_nvlists(&zc);
99
100         return (0);
101 }
102
103 int
104 zpool_props_refresh(zpool_handle_t *zhp)
105 {
106         nvlist_t *old_props;
107
108         old_props = zhp->zpool_props;
109
110         if (zpool_get_all_props(zhp) != 0)
111                 return (-1);
112
113         nvlist_free(old_props);
114         return (0);
115 }
116
117 static const char *
118 zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
119     zprop_source_t *src)
120 {
121         nvlist_t *nv, *nvl;
122         char *value;
123         zprop_source_t source;
124
125         nvl = zhp->zpool_props;
126         if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
127                 source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
128                 value = fnvlist_lookup_string(nv, ZPROP_VALUE);
129         } else {
130                 source = ZPROP_SRC_DEFAULT;
131                 if ((value = (char *)zpool_prop_default_string(prop)) == NULL)
132                         value = "-";
133         }
134
135         if (src)
136                 *src = source;
137
138         return (value);
139 }
140
141 uint64_t
142 zpool_get_prop_int(zpool_handle_t *zhp, zpool_prop_t prop, zprop_source_t *src)
143 {
144         nvlist_t *nv, *nvl;
145         uint64_t value;
146         zprop_source_t source;
147
148         if (zhp->zpool_props == NULL && zpool_get_all_props(zhp)) {
149                 /*
150                  * zpool_get_all_props() has most likely failed because
151                  * the pool is faulted, but if all we need is the top level
152                  * vdev's guid then get it from the zhp config nvlist.
153                  */
154                 if ((prop == ZPOOL_PROP_GUID) &&
155                     (nvlist_lookup_nvlist(zhp->zpool_config,
156                     ZPOOL_CONFIG_VDEV_TREE, &nv) == 0) &&
157                     (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value)
158                     == 0)) {
159                         return (value);
160                 }
161                 return (zpool_prop_default_numeric(prop));
162         }
163
164         nvl = zhp->zpool_props;
165         if (nvlist_lookup_nvlist(nvl, zpool_prop_to_name(prop), &nv) == 0) {
166                 source = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
167                 value = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
168         } else {
169                 source = ZPROP_SRC_DEFAULT;
170                 value = zpool_prop_default_numeric(prop);
171         }
172
173         if (src)
174                 *src = source;
175
176         return (value);
177 }
178
179 /*
180  * Map VDEV STATE to printed strings.
181  */
182 const char *
183 zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
184 {
185         switch (state) {
186         case VDEV_STATE_CLOSED:
187         case VDEV_STATE_OFFLINE:
188                 return (gettext("OFFLINE"));
189         case VDEV_STATE_REMOVED:
190                 return (gettext("REMOVED"));
191         case VDEV_STATE_CANT_OPEN:
192                 if (aux == VDEV_AUX_CORRUPT_DATA || aux == VDEV_AUX_BAD_LOG)
193                         return (gettext("FAULTED"));
194                 else if (aux == VDEV_AUX_SPLIT_POOL)
195                         return (gettext("SPLIT"));
196                 else
197                         return (gettext("UNAVAIL"));
198         case VDEV_STATE_FAULTED:
199                 return (gettext("FAULTED"));
200         case VDEV_STATE_DEGRADED:
201                 return (gettext("DEGRADED"));
202         case VDEV_STATE_HEALTHY:
203                 return (gettext("ONLINE"));
204
205         default:
206                 break;
207         }
208
209         return (gettext("UNKNOWN"));
210 }
211
212 /*
213  * Map POOL STATE to printed strings.
214  */
215 const char *
216 zpool_pool_state_to_name(pool_state_t state)
217 {
218         switch (state) {
219         default:
220                 break;
221         case POOL_STATE_ACTIVE:
222                 return (gettext("ACTIVE"));
223         case POOL_STATE_EXPORTED:
224                 return (gettext("EXPORTED"));
225         case POOL_STATE_DESTROYED:
226                 return (gettext("DESTROYED"));
227         case POOL_STATE_SPARE:
228                 return (gettext("SPARE"));
229         case POOL_STATE_L2CACHE:
230                 return (gettext("L2CACHE"));
231         case POOL_STATE_UNINITIALIZED:
232                 return (gettext("UNINITIALIZED"));
233         case POOL_STATE_UNAVAIL:
234                 return (gettext("UNAVAIL"));
235         case POOL_STATE_POTENTIALLY_ACTIVE:
236                 return (gettext("POTENTIALLY_ACTIVE"));
237         }
238
239         return (gettext("UNKNOWN"));
240 }
241
242 /*
243  * Given a pool handle, return the pool health string ("ONLINE", "DEGRADED",
244  * "SUSPENDED", etc).
245  */
246 const char *
247 zpool_get_state_str(zpool_handle_t *zhp)
248 {
249         zpool_errata_t errata;
250         zpool_status_t status;
251         const char *str;
252
253         status = zpool_get_status(zhp, NULL, &errata);
254
255         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
256                 str = gettext("FAULTED");
257         } else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
258             status == ZPOOL_STATUS_IO_FAILURE_MMP) {
259                 str = gettext("SUSPENDED");
260         } else {
261                 nvlist_t *nvroot = fnvlist_lookup_nvlist(
262                     zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE);
263                 uint_t vsc;
264                 vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
265                     nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc);
266                 str = zpool_state_to_name(vs->vs_state, vs->vs_aux);
267         }
268         return (str);
269 }
270
271 /*
272  * Get a zpool property value for 'prop' and return the value in
273  * a pre-allocated buffer.
274  */
275 int
276 zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
277     size_t len, zprop_source_t *srctype, boolean_t literal)
278 {
279         uint64_t intval;
280         const char *strval;
281         zprop_source_t src = ZPROP_SRC_NONE;
282
283         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
284                 switch (prop) {
285                 case ZPOOL_PROP_NAME:
286                         (void) strlcpy(buf, zpool_get_name(zhp), len);
287                         break;
288
289                 case ZPOOL_PROP_HEALTH:
290                         (void) strlcpy(buf, zpool_get_state_str(zhp), len);
291                         break;
292
293                 case ZPOOL_PROP_GUID:
294                         intval = zpool_get_prop_int(zhp, prop, &src);
295                         (void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
296                         break;
297
298                 case ZPOOL_PROP_ALTROOT:
299                 case ZPOOL_PROP_CACHEFILE:
300                 case ZPOOL_PROP_COMMENT:
301                 case ZPOOL_PROP_COMPATIBILITY:
302                         if (zhp->zpool_props != NULL ||
303                             zpool_get_all_props(zhp) == 0) {
304                                 (void) strlcpy(buf,
305                                     zpool_get_prop_string(zhp, prop, &src),
306                                     len);
307                                 break;
308                         }
309                         zfs_fallthrough;
310                 default:
311                         (void) strlcpy(buf, "-", len);
312                         break;
313                 }
314
315                 if (srctype != NULL)
316                         *srctype = src;
317                 return (0);
318         }
319
320         if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
321             prop != ZPOOL_PROP_NAME)
322                 return (-1);
323
324         switch (zpool_prop_get_type(prop)) {
325         case PROP_TYPE_STRING:
326                 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
327                     len);
328                 break;
329
330         case PROP_TYPE_NUMBER:
331                 intval = zpool_get_prop_int(zhp, prop, &src);
332
333                 switch (prop) {
334                 case ZPOOL_PROP_SIZE:
335                 case ZPOOL_PROP_ALLOCATED:
336                 case ZPOOL_PROP_FREE:
337                 case ZPOOL_PROP_FREEING:
338                 case ZPOOL_PROP_LEAKED:
339                 case ZPOOL_PROP_ASHIFT:
340                 case ZPOOL_PROP_MAXBLOCKSIZE:
341                 case ZPOOL_PROP_MAXDNODESIZE:
342                         if (literal)
343                                 (void) snprintf(buf, len, "%llu",
344                                     (u_longlong_t)intval);
345                         else
346                                 (void) zfs_nicenum(intval, buf, len);
347                         break;
348
349                 case ZPOOL_PROP_EXPANDSZ:
350                 case ZPOOL_PROP_CHECKPOINT:
351                         if (intval == 0) {
352                                 (void) strlcpy(buf, "-", len);
353                         } else if (literal) {
354                                 (void) snprintf(buf, len, "%llu",
355                                     (u_longlong_t)intval);
356                         } else {
357                                 (void) zfs_nicebytes(intval, buf, len);
358                         }
359                         break;
360
361                 case ZPOOL_PROP_CAPACITY:
362                         if (literal) {
363                                 (void) snprintf(buf, len, "%llu",
364                                     (u_longlong_t)intval);
365                         } else {
366                                 (void) snprintf(buf, len, "%llu%%",
367                                     (u_longlong_t)intval);
368                         }
369                         break;
370
371                 case ZPOOL_PROP_FRAGMENTATION:
372                         if (intval == UINT64_MAX) {
373                                 (void) strlcpy(buf, "-", len);
374                         } else if (literal) {
375                                 (void) snprintf(buf, len, "%llu",
376                                     (u_longlong_t)intval);
377                         } else {
378                                 (void) snprintf(buf, len, "%llu%%",
379                                     (u_longlong_t)intval);
380                         }
381                         break;
382
383                 case ZPOOL_PROP_DEDUPRATIO:
384                         if (literal)
385                                 (void) snprintf(buf, len, "%llu.%02llu",
386                                     (u_longlong_t)(intval / 100),
387                                     (u_longlong_t)(intval % 100));
388                         else
389                                 (void) snprintf(buf, len, "%llu.%02llux",
390                                     (u_longlong_t)(intval / 100),
391                                     (u_longlong_t)(intval % 100));
392                         break;
393
394                 case ZPOOL_PROP_HEALTH:
395                         (void) strlcpy(buf, zpool_get_state_str(zhp), len);
396                         break;
397                 case ZPOOL_PROP_VERSION:
398                         if (intval >= SPA_VERSION_FEATURES) {
399                                 (void) snprintf(buf, len, "-");
400                                 break;
401                         }
402                         zfs_fallthrough;
403                 default:
404                         (void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
405                 }
406                 break;
407
408         case PROP_TYPE_INDEX:
409                 intval = zpool_get_prop_int(zhp, prop, &src);
410                 if (zpool_prop_index_to_string(prop, intval, &strval)
411                     != 0)
412                         return (-1);
413                 (void) strlcpy(buf, strval, len);
414                 break;
415
416         default:
417                 abort();
418         }
419
420         if (srctype)
421                 *srctype = src;
422
423         return (0);
424 }
425
426 /*
427  * Check if the bootfs name has the same pool name as it is set to.
428  * Assuming bootfs is a valid dataset name.
429  */
430 static boolean_t
431 bootfs_name_valid(const char *pool, const char *bootfs)
432 {
433         int len = strlen(pool);
434         if (bootfs[0] == '\0')
435                 return (B_TRUE);
436
437         if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
438                 return (B_FALSE);
439
440         if (strncmp(pool, bootfs, len) == 0 &&
441             (bootfs[len] == '/' || bootfs[len] == '\0'))
442                 return (B_TRUE);
443
444         return (B_FALSE);
445 }
446
447 /*
448  * Given an nvlist of zpool properties to be set, validate that they are
449  * correct, and parse any numeric properties (index, boolean, etc) if they are
450  * specified as strings.
451  */
452 static nvlist_t *
453 zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
454     nvlist_t *props, uint64_t version, prop_flags_t flags, char *errbuf)
455 {
456         nvpair_t *elem;
457         nvlist_t *retprops;
458         zpool_prop_t prop;
459         char *strval;
460         uint64_t intval;
461         char *slash, *check;
462         struct stat64 statbuf;
463         zpool_handle_t *zhp;
464         char report[1024];
465
466         if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
467                 (void) no_memory(hdl);
468                 return (NULL);
469         }
470
471         elem = NULL;
472         while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
473                 const char *propname = nvpair_name(elem);
474
475                 if (flags.vdevprop && zpool_prop_vdev(propname)) {
476                         vdev_prop_t vprop = vdev_name_to_prop(propname);
477
478                         if (vdev_prop_readonly(vprop)) {
479                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
480                                     "is readonly"), propname);
481                                 (void) zfs_error(hdl, EZFS_PROPREADONLY,
482                                     errbuf);
483                                 goto error;
484                         }
485
486                         if (zprop_parse_value(hdl, elem, vprop, ZFS_TYPE_VDEV,
487                             retprops, &strval, &intval, errbuf) != 0)
488                                 goto error;
489
490                         continue;
491                 } else if (flags.vdevprop && vdev_prop_user(propname)) {
492                         if (nvlist_add_nvpair(retprops, elem) != 0) {
493                                 (void) no_memory(hdl);
494                                 goto error;
495                         }
496                         continue;
497                 } else if (flags.vdevprop) {
498                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
499                             "invalid property: '%s'"), propname);
500                         (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
501                         goto error;
502                 }
503
504                 prop = zpool_name_to_prop(propname);
505                 if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) {
506                         int err;
507                         char *fname = strchr(propname, '@') + 1;
508
509                         err = zfeature_lookup_name(fname, NULL);
510                         if (err != 0) {
511                                 ASSERT3U(err, ==, ENOENT);
512                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
513                                     "feature '%s' unsupported by kernel"),
514                                     fname);
515                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
516                                 goto error;
517                         }
518
519                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
520                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
521                                     "'%s' must be a string"), propname);
522                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
523                                 goto error;
524                         }
525
526                         (void) nvpair_value_string(elem, &strval);
527                         if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0 &&
528                             strcmp(strval, ZFS_FEATURE_DISABLED) != 0) {
529                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
530                                     "property '%s' can only be set to "
531                                     "'enabled' or 'disabled'"), propname);
532                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
533                                 goto error;
534                         }
535
536                         if (!flags.create &&
537                             strcmp(strval, ZFS_FEATURE_DISABLED) == 0) {
538                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
539                                     "property '%s' can only be set to "
540                                     "'disabled' at creation time"), propname);
541                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
542                                 goto error;
543                         }
544
545                         if (nvlist_add_uint64(retprops, propname, 0) != 0) {
546                                 (void) no_memory(hdl);
547                                 goto error;
548                         }
549                         continue;
550                 }
551
552                 /*
553                  * Make sure this property is valid and applies to this type.
554                  */
555                 if (prop == ZPOOL_PROP_INVAL) {
556                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
557                             "invalid property '%s'"), propname);
558                         (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
559                         goto error;
560                 }
561
562                 if (zpool_prop_readonly(prop)) {
563                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
564                             "is readonly"), propname);
565                         (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
566                         goto error;
567                 }
568
569                 if (!flags.create && zpool_prop_setonce(prop)) {
570                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
571                             "property '%s' can only be set at "
572                             "creation time"), propname);
573                         (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
574                         goto error;
575                 }
576
577                 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
578                     &strval, &intval, errbuf) != 0)
579                         goto error;
580
581                 /*
582                  * Perform additional checking for specific properties.
583                  */
584                 switch (prop) {
585                 case ZPOOL_PROP_VERSION:
586                         if (intval < version ||
587                             !SPA_VERSION_IS_SUPPORTED(intval)) {
588                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
589                                     "property '%s' number %llu is invalid."),
590                                     propname, (unsigned long long)intval);
591                                 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
592                                 goto error;
593                         }
594                         break;
595
596                 case ZPOOL_PROP_ASHIFT:
597                         if (intval != 0 &&
598                             (intval < ASHIFT_MIN || intval > ASHIFT_MAX)) {
599                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
600                                     "property '%s' number %llu is invalid, "
601                                     "only values between %" PRId32 " and %"
602                                     PRId32 " are allowed."),
603                                     propname, (unsigned long long)intval,
604                                     ASHIFT_MIN, ASHIFT_MAX);
605                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
606                                 goto error;
607                         }
608                         break;
609
610                 case ZPOOL_PROP_BOOTFS:
611                         if (flags.create || flags.import) {
612                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
613                                     "property '%s' cannot be set at creation "
614                                     "or import time"), propname);
615                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
616                                 goto error;
617                         }
618
619                         if (version < SPA_VERSION_BOOTFS) {
620                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
621                                     "pool must be upgraded to support "
622                                     "'%s' property"), propname);
623                                 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
624                                 goto error;
625                         }
626
627                         /*
628                          * bootfs property value has to be a dataset name and
629                          * the dataset has to be in the same pool as it sets to.
630                          */
631                         if (!bootfs_name_valid(poolname, strval)) {
632                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
633                                     "is an invalid name"), strval);
634                                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
635                                 goto error;
636                         }
637
638                         if ((zhp = zpool_open_canfail(hdl, poolname)) == NULL) {
639                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
640                                     "could not open pool '%s'"), poolname);
641                                 (void) zfs_error(hdl, EZFS_OPENFAILED, errbuf);
642                                 goto error;
643                         }
644                         zpool_close(zhp);
645                         break;
646
647                 case ZPOOL_PROP_ALTROOT:
648                         if (!flags.create && !flags.import) {
649                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
650                                     "property '%s' can only be set during pool "
651                                     "creation or import"), propname);
652                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
653                                 goto error;
654                         }
655
656                         if (strval[0] != '/') {
657                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
658                                     "bad alternate root '%s'"), strval);
659                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
660                                 goto error;
661                         }
662                         break;
663
664                 case ZPOOL_PROP_CACHEFILE:
665                         if (strval[0] == '\0')
666                                 break;
667
668                         if (strcmp(strval, "none") == 0)
669                                 break;
670
671                         if (strval[0] != '/') {
672                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
673                                     "property '%s' must be empty, an "
674                                     "absolute path, or 'none'"), propname);
675                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
676                                 goto error;
677                         }
678
679                         slash = strrchr(strval, '/');
680
681                         if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
682                             strcmp(slash, "/..") == 0) {
683                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
684                                     "'%s' is not a valid file"), strval);
685                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
686                                 goto error;
687                         }
688
689                         *slash = '\0';
690
691                         if (strval[0] != '\0' &&
692                             (stat64(strval, &statbuf) != 0 ||
693                             !S_ISDIR(statbuf.st_mode))) {
694                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
695                                     "'%s' is not a valid directory"),
696                                     strval);
697                                 (void) zfs_error(hdl, EZFS_BADPATH, errbuf);
698                                 goto error;
699                         }
700
701                         *slash = '/';
702                         break;
703
704                 case ZPOOL_PROP_COMPATIBILITY:
705                         switch (zpool_load_compat(strval, NULL, report, 1024)) {
706                         case ZPOOL_COMPATIBILITY_OK:
707                         case ZPOOL_COMPATIBILITY_WARNTOKEN:
708                                 break;
709                         case ZPOOL_COMPATIBILITY_BADFILE:
710                         case ZPOOL_COMPATIBILITY_BADTOKEN:
711                         case ZPOOL_COMPATIBILITY_NOFILES:
712                                 zfs_error_aux(hdl, "%s", report);
713                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
714                                 goto error;
715                         }
716                         break;
717
718                 case ZPOOL_PROP_COMMENT:
719                         for (check = strval; *check != '\0'; check++) {
720                                 if (!isprint(*check)) {
721                                         zfs_error_aux(hdl,
722                                             dgettext(TEXT_DOMAIN,
723                                             "comment may only have printable "
724                                             "characters"));
725                                         (void) zfs_error(hdl, EZFS_BADPROP,
726                                             errbuf);
727                                         goto error;
728                                 }
729                         }
730                         if (strlen(strval) > ZPROP_MAX_COMMENT) {
731                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
732                                     "comment must not exceed %d characters"),
733                                     ZPROP_MAX_COMMENT);
734                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
735                                 goto error;
736                         }
737                         break;
738                 case ZPOOL_PROP_READONLY:
739                         if (!flags.import) {
740                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
741                                     "property '%s' can only be set at "
742                                     "import time"), propname);
743                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
744                                 goto error;
745                         }
746                         break;
747                 case ZPOOL_PROP_MULTIHOST:
748                         if (get_system_hostid() == 0) {
749                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
750                                     "requires a non-zero system hostid"));
751                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
752                                 goto error;
753                         }
754                         break;
755                 case ZPOOL_PROP_DEDUPDITTO:
756                         printf("Note: property '%s' no longer has "
757                             "any effect\n", propname);
758                         break;
759
760                 default:
761                         break;
762                 }
763         }
764
765         return (retprops);
766 error:
767         nvlist_free(retprops);
768         return (NULL);
769 }
770
771 /*
772  * Set zpool property : propname=propval.
773  */
774 int
775 zpool_set_prop(zpool_handle_t *zhp, const char *propname, const char *propval)
776 {
777         zfs_cmd_t zc = {"\0"};
778         int ret = -1;
779         char errbuf[1024];
780         nvlist_t *nvl = NULL;
781         nvlist_t *realprops;
782         uint64_t version;
783         prop_flags_t flags = { 0 };
784
785         (void) snprintf(errbuf, sizeof (errbuf),
786             dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
787             zhp->zpool_name);
788
789         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
790                 return (no_memory(zhp->zpool_hdl));
791
792         if (nvlist_add_string(nvl, propname, propval) != 0) {
793                 nvlist_free(nvl);
794                 return (no_memory(zhp->zpool_hdl));
795         }
796
797         version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
798         if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
799             zhp->zpool_name, nvl, version, flags, errbuf)) == NULL) {
800                 nvlist_free(nvl);
801                 return (-1);
802         }
803
804         nvlist_free(nvl);
805         nvl = realprops;
806
807         /*
808          * Execute the corresponding ioctl() to set this property.
809          */
810         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
811
812         zcmd_write_src_nvlist(zhp->zpool_hdl, &zc, nvl);
813
814         ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
815
816         zcmd_free_nvlists(&zc);
817         nvlist_free(nvl);
818
819         if (ret)
820                 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
821         else
822                 (void) zpool_props_refresh(zhp);
823
824         return (ret);
825 }
826
827 int
828 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp,
829     zfs_type_t type, boolean_t literal)
830 {
831         libzfs_handle_t *hdl = zhp->zpool_hdl;
832         zprop_list_t *entry;
833         char buf[ZFS_MAXPROPLEN];
834         nvlist_t *features = NULL;
835         nvpair_t *nvp;
836         zprop_list_t **last;
837         boolean_t firstexpand = (NULL == *plp);
838         int i;
839
840         if (zprop_expand_list(hdl, plp, type) != 0)
841                 return (-1);
842
843         if (type == ZFS_TYPE_VDEV)
844                 return (0);
845
846         last = plp;
847         while (*last != NULL)
848                 last = &(*last)->pl_next;
849
850         if ((*plp)->pl_all)
851                 features = zpool_get_features(zhp);
852
853         if ((*plp)->pl_all && firstexpand) {
854                 for (i = 0; i < SPA_FEATURES; i++) {
855                         zprop_list_t *entry = zfs_alloc(hdl,
856                             sizeof (zprop_list_t));
857                         entry->pl_prop = ZPROP_INVAL;
858                         entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
859                             spa_feature_table[i].fi_uname);
860                         entry->pl_width = strlen(entry->pl_user_prop);
861                         entry->pl_all = B_TRUE;
862
863                         *last = entry;
864                         last = &entry->pl_next;
865                 }
866         }
867
868         /* add any unsupported features */
869         for (nvp = nvlist_next_nvpair(features, NULL);
870             nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
871                 char *propname;
872                 boolean_t found;
873                 zprop_list_t *entry;
874
875                 if (zfeature_is_supported(nvpair_name(nvp)))
876                         continue;
877
878                 propname = zfs_asprintf(hdl, "unsupported@%s",
879                     nvpair_name(nvp));
880
881                 /*
882                  * Before adding the property to the list make sure that no
883                  * other pool already added the same property.
884                  */
885                 found = B_FALSE;
886                 entry = *plp;
887                 while (entry != NULL) {
888                         if (entry->pl_user_prop != NULL &&
889                             strcmp(propname, entry->pl_user_prop) == 0) {
890                                 found = B_TRUE;
891                                 break;
892                         }
893                         entry = entry->pl_next;
894                 }
895                 if (found) {
896                         free(propname);
897                         continue;
898                 }
899
900                 entry = zfs_alloc(hdl, sizeof (zprop_list_t));
901                 entry->pl_prop = ZPROP_INVAL;
902                 entry->pl_user_prop = propname;
903                 entry->pl_width = strlen(entry->pl_user_prop);
904                 entry->pl_all = B_TRUE;
905
906                 *last = entry;
907                 last = &entry->pl_next;
908         }
909
910         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
911                 if (entry->pl_fixed && !literal)
912                         continue;
913
914                 if (entry->pl_prop != ZPROP_INVAL &&
915                     zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
916                     NULL, literal) == 0) {
917                         if (strlen(buf) > entry->pl_width)
918                                 entry->pl_width = strlen(buf);
919                 }
920         }
921
922         return (0);
923 }
924
925 int
926 vdev_expand_proplist(zpool_handle_t *zhp, const char *vdevname,
927     zprop_list_t **plp)
928 {
929         zprop_list_t *entry;
930         char buf[ZFS_MAXPROPLEN];
931         char *strval = NULL;
932         int err = 0;
933         nvpair_t *elem = NULL;
934         nvlist_t *vprops = NULL;
935         nvlist_t *propval = NULL;
936         const char *propname;
937         vdev_prop_t prop;
938         zprop_list_t **last;
939
940         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
941                 if (entry->pl_fixed)
942                         continue;
943
944                 if (zpool_get_vdev_prop(zhp, vdevname, entry->pl_prop,
945                     entry->pl_user_prop, buf, sizeof (buf), NULL,
946                     B_FALSE) == 0) {
947                         if (strlen(buf) > entry->pl_width)
948                                 entry->pl_width = strlen(buf);
949                 }
950                 if (entry->pl_prop == VDEV_PROP_NAME &&
951                     strlen(vdevname) > entry->pl_width)
952                         entry->pl_width = strlen(vdevname);
953         }
954
955         /* Handle the all properties case */
956         last = plp;
957         if (*last != NULL && (*last)->pl_all == B_TRUE) {
958                 while (*last != NULL)
959                         last = &(*last)->pl_next;
960
961                 err = zpool_get_all_vdev_props(zhp, vdevname, &vprops);
962                 if (err != 0)
963                         return (err);
964
965                 while ((elem = nvlist_next_nvpair(vprops, elem)) != NULL) {
966                         propname = nvpair_name(elem);
967
968                         /* Skip properties that are not user defined */
969                         if ((prop = vdev_name_to_prop(propname)) !=
970                             VDEV_PROP_USER)
971                                 continue;
972
973                         if (nvpair_value_nvlist(elem, &propval) != 0)
974                                 continue;
975
976                         strval = fnvlist_lookup_string(propval, ZPROP_VALUE);
977
978                         entry = zfs_alloc(zhp->zpool_hdl,
979                             sizeof (zprop_list_t));
980                         entry->pl_prop = prop;
981                         entry->pl_user_prop = zfs_strdup(zhp->zpool_hdl,
982                             propname);
983                         entry->pl_width = strlen(strval);
984                         entry->pl_all = B_TRUE;
985                         *last = entry;
986                         last = &entry->pl_next;
987                 }
988         }
989
990         return (0);
991 }
992
993 /*
994  * Get the state for the given feature on the given ZFS pool.
995  */
996 int
997 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
998     size_t len)
999 {
1000         uint64_t refcount;
1001         boolean_t found = B_FALSE;
1002         nvlist_t *features = zpool_get_features(zhp);
1003         boolean_t supported;
1004         const char *feature = strchr(propname, '@') + 1;
1005
1006         supported = zpool_prop_feature(propname);
1007         ASSERT(supported || zpool_prop_unsupported(propname));
1008
1009         /*
1010          * Convert from feature name to feature guid. This conversion is
1011          * unnecessary for unsupported@... properties because they already
1012          * use guids.
1013          */
1014         if (supported) {
1015                 int ret;
1016                 spa_feature_t fid;
1017
1018                 ret = zfeature_lookup_name(feature, &fid);
1019                 if (ret != 0) {
1020                         (void) strlcpy(buf, "-", len);
1021                         return (ENOTSUP);
1022                 }
1023                 feature = spa_feature_table[fid].fi_guid;
1024         }
1025
1026         if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
1027                 found = B_TRUE;
1028
1029         if (supported) {
1030                 if (!found) {
1031                         (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
1032                 } else  {
1033                         if (refcount == 0)
1034                                 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
1035                         else
1036                                 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
1037                 }
1038         } else {
1039                 if (found) {
1040                         if (refcount == 0) {
1041                                 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
1042                         } else {
1043                                 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
1044                         }
1045                 } else {
1046                         (void) strlcpy(buf, "-", len);
1047                         return (ENOTSUP);
1048                 }
1049         }
1050
1051         return (0);
1052 }
1053
1054 /*
1055  * Validate the given pool name, optionally putting an extended error message in
1056  * 'buf'.
1057  */
1058 boolean_t
1059 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
1060 {
1061         namecheck_err_t why;
1062         char what;
1063         int ret;
1064
1065         ret = pool_namecheck(pool, &why, &what);
1066
1067         /*
1068          * The rules for reserved pool names were extended at a later point.
1069          * But we need to support users with existing pools that may now be
1070          * invalid.  So we only check for this expanded set of names during a
1071          * create (or import), and only in userland.
1072          */
1073         if (ret == 0 && !isopen &&
1074             (strncmp(pool, "mirror", 6) == 0 ||
1075             strncmp(pool, "raidz", 5) == 0 ||
1076             strncmp(pool, "draid", 5) == 0 ||
1077             strncmp(pool, "spare", 5) == 0 ||
1078             strcmp(pool, "log") == 0)) {
1079                 if (hdl != NULL)
1080                         zfs_error_aux(hdl,
1081                             dgettext(TEXT_DOMAIN, "name is reserved"));
1082                 return (B_FALSE);
1083         }
1084
1085
1086         if (ret != 0) {
1087                 if (hdl != NULL) {
1088                         switch (why) {
1089                         case NAME_ERR_TOOLONG:
1090                                 zfs_error_aux(hdl,
1091                                     dgettext(TEXT_DOMAIN, "name is too long"));
1092                                 break;
1093
1094                         case NAME_ERR_INVALCHAR:
1095                                 zfs_error_aux(hdl,
1096                                     dgettext(TEXT_DOMAIN, "invalid character "
1097                                     "'%c' in pool name"), what);
1098                                 break;
1099
1100                         case NAME_ERR_NOLETTER:
1101                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1102                                     "name must begin with a letter"));
1103                                 break;
1104
1105                         case NAME_ERR_RESERVED:
1106                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1107                                     "name is reserved"));
1108                                 break;
1109
1110                         case NAME_ERR_DISKLIKE:
1111                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1112                                     "pool name is reserved"));
1113                                 break;
1114
1115                         case NAME_ERR_LEADING_SLASH:
1116                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1117                                     "leading slash in name"));
1118                                 break;
1119
1120                         case NAME_ERR_EMPTY_COMPONENT:
1121                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1122                                     "empty component in name"));
1123                                 break;
1124
1125                         case NAME_ERR_TRAILING_SLASH:
1126                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1127                                     "trailing slash in name"));
1128                                 break;
1129
1130                         case NAME_ERR_MULTIPLE_DELIMITERS:
1131                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1132                                     "multiple '@' and/or '#' delimiters in "
1133                                     "name"));
1134                                 break;
1135
1136                         case NAME_ERR_NO_AT:
1137                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1138                                     "permission set is missing '@'"));
1139                                 break;
1140
1141                         default:
1142                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1143                                     "(%d) not defined"), why);
1144                                 break;
1145                         }
1146                 }
1147                 return (B_FALSE);
1148         }
1149
1150         return (B_TRUE);
1151 }
1152
1153 /*
1154  * Open a handle to the given pool, even if the pool is currently in the FAULTED
1155  * state.
1156  */
1157 zpool_handle_t *
1158 zpool_open_canfail(libzfs_handle_t *hdl, const char *pool)
1159 {
1160         zpool_handle_t *zhp;
1161         boolean_t missing;
1162
1163         /*
1164          * Make sure the pool name is valid.
1165          */
1166         if (!zpool_name_valid(hdl, B_TRUE, pool)) {
1167                 (void) zfs_error_fmt(hdl, EZFS_INVALIDNAME,
1168                     dgettext(TEXT_DOMAIN, "cannot open '%s'"),
1169                     pool);
1170                 return (NULL);
1171         }
1172
1173         zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
1174
1175         zhp->zpool_hdl = hdl;
1176         (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
1177
1178         if (zpool_refresh_stats(zhp, &missing) != 0) {
1179                 zpool_close(zhp);
1180                 return (NULL);
1181         }
1182
1183         if (missing) {
1184                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "no such pool"));
1185                 (void) zfs_error_fmt(hdl, EZFS_NOENT,
1186                     dgettext(TEXT_DOMAIN, "cannot open '%s'"), pool);
1187                 zpool_close(zhp);
1188                 return (NULL);
1189         }
1190
1191         return (zhp);
1192 }
1193
1194 /*
1195  * Like the above, but silent on error.  Used when iterating over pools (because
1196  * the configuration cache may be out of date).
1197  */
1198 int
1199 zpool_open_silent(libzfs_handle_t *hdl, const char *pool, zpool_handle_t **ret)
1200 {
1201         zpool_handle_t *zhp;
1202         boolean_t missing;
1203
1204         zhp = zfs_alloc(hdl, sizeof (zpool_handle_t));
1205
1206         zhp->zpool_hdl = hdl;
1207         (void) strlcpy(zhp->zpool_name, pool, sizeof (zhp->zpool_name));
1208
1209         if (zpool_refresh_stats(zhp, &missing) != 0) {
1210                 zpool_close(zhp);
1211                 return (-1);
1212         }
1213
1214         if (missing) {
1215                 zpool_close(zhp);
1216                 *ret = NULL;
1217                 return (0);
1218         }
1219
1220         *ret = zhp;
1221         return (0);
1222 }
1223
1224 /*
1225  * Similar to zpool_open_canfail(), but refuses to open pools in the faulted
1226  * state.
1227  */
1228 zpool_handle_t *
1229 zpool_open(libzfs_handle_t *hdl, const char *pool)
1230 {
1231         zpool_handle_t *zhp;
1232
1233         if ((zhp = zpool_open_canfail(hdl, pool)) == NULL)
1234                 return (NULL);
1235
1236         if (zhp->zpool_state == POOL_STATE_UNAVAIL) {
1237                 (void) zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
1238                     dgettext(TEXT_DOMAIN, "cannot open '%s'"), zhp->zpool_name);
1239                 zpool_close(zhp);
1240                 return (NULL);
1241         }
1242
1243         return (zhp);
1244 }
1245
1246 /*
1247  * Close the handle.  Simply frees the memory associated with the handle.
1248  */
1249 void
1250 zpool_close(zpool_handle_t *zhp)
1251 {
1252         nvlist_free(zhp->zpool_config);
1253         nvlist_free(zhp->zpool_old_config);
1254         nvlist_free(zhp->zpool_props);
1255         free(zhp);
1256 }
1257
1258 /*
1259  * Return the name of the pool.
1260  */
1261 const char *
1262 zpool_get_name(zpool_handle_t *zhp)
1263 {
1264         return (zhp->zpool_name);
1265 }
1266
1267
1268 /*
1269  * Return the state of the pool (ACTIVE or UNAVAILABLE)
1270  */
1271 int
1272 zpool_get_state(zpool_handle_t *zhp)
1273 {
1274         return (zhp->zpool_state);
1275 }
1276
1277 /*
1278  * Check if vdev list contains a special vdev
1279  */
1280 static boolean_t
1281 zpool_has_special_vdev(nvlist_t *nvroot)
1282 {
1283         nvlist_t **child;
1284         uint_t children;
1285
1286         if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child,
1287             &children) == 0) {
1288                 for (uint_t c = 0; c < children; c++) {
1289                         char *bias;
1290
1291                         if (nvlist_lookup_string(child[c],
1292                             ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 &&
1293                             strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) {
1294                                 return (B_TRUE);
1295                         }
1296                 }
1297         }
1298         return (B_FALSE);
1299 }
1300
1301 /*
1302  * Check if vdev list contains a dRAID vdev
1303  */
1304 static boolean_t
1305 zpool_has_draid_vdev(nvlist_t *nvroot)
1306 {
1307         nvlist_t **child;
1308         uint_t children;
1309
1310         if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
1311             &child, &children) == 0) {
1312                 for (uint_t c = 0; c < children; c++) {
1313                         char *type;
1314
1315                         if (nvlist_lookup_string(child[c],
1316                             ZPOOL_CONFIG_TYPE, &type) == 0 &&
1317                             strcmp(type, VDEV_TYPE_DRAID) == 0) {
1318                                 return (B_TRUE);
1319                         }
1320                 }
1321         }
1322         return (B_FALSE);
1323 }
1324
1325 /*
1326  * Output a dRAID top-level vdev name in to the provided buffer.
1327  */
1328 static char *
1329 zpool_draid_name(char *name, int len, uint64_t data, uint64_t parity,
1330     uint64_t spares, uint64_t children)
1331 {
1332         snprintf(name, len, "%s%llu:%llud:%lluc:%llus",
1333             VDEV_TYPE_DRAID, (u_longlong_t)parity, (u_longlong_t)data,
1334             (u_longlong_t)children, (u_longlong_t)spares);
1335
1336         return (name);
1337 }
1338
1339 /*
1340  * Return B_TRUE if the provided name is a dRAID spare name.
1341  */
1342 boolean_t
1343 zpool_is_draid_spare(const char *name)
1344 {
1345         uint64_t spare_id, parity, vdev_id;
1346
1347         if (sscanf(name, VDEV_TYPE_DRAID "%llu-%llu-%llu",
1348             (u_longlong_t *)&parity, (u_longlong_t *)&vdev_id,
1349             (u_longlong_t *)&spare_id) == 3) {
1350                 return (B_TRUE);
1351         }
1352
1353         return (B_FALSE);
1354 }
1355
1356 /*
1357  * Create the named pool, using the provided vdev list.  It is assumed
1358  * that the consumer has already validated the contents of the nvlist, so we
1359  * don't have to worry about error semantics.
1360  */
1361 int
1362 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
1363     nvlist_t *props, nvlist_t *fsprops)
1364 {
1365         zfs_cmd_t zc = {"\0"};
1366         nvlist_t *zc_fsprops = NULL;
1367         nvlist_t *zc_props = NULL;
1368         nvlist_t *hidden_args = NULL;
1369         uint8_t *wkeydata = NULL;
1370         uint_t wkeylen = 0;
1371         char msg[1024];
1372         int ret = -1;
1373
1374         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1375             "cannot create '%s'"), pool);
1376
1377         if (!zpool_name_valid(hdl, B_FALSE, pool))
1378                 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
1379
1380         zcmd_write_conf_nvlist(hdl, &zc, nvroot);
1381
1382         if (props) {
1383                 prop_flags_t flags = { .create = B_TRUE, .import = B_FALSE };
1384
1385                 if ((zc_props = zpool_valid_proplist(hdl, pool, props,
1386                     SPA_VERSION_1, flags, msg)) == NULL) {
1387                         goto create_failed;
1388                 }
1389         }
1390
1391         if (fsprops) {
1392                 uint64_t zoned;
1393                 char *zonestr;
1394
1395                 zoned = ((nvlist_lookup_string(fsprops,
1396                     zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
1397                     strcmp(zonestr, "on") == 0);
1398
1399                 if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
1400                     fsprops, zoned, NULL, NULL, B_TRUE, msg)) == NULL) {
1401                         goto create_failed;
1402                 }
1403
1404                 if (nvlist_exists(zc_fsprops,
1405                     zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) &&
1406                     !zpool_has_special_vdev(nvroot)) {
1407                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1408                             "%s property requires a special vdev"),
1409                             zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS));
1410                         (void) zfs_error(hdl, EZFS_BADPROP, msg);
1411                         goto create_failed;
1412                 }
1413
1414                 if (!zc_props &&
1415                     (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) {
1416                         goto create_failed;
1417                 }
1418                 if (zfs_crypto_create(hdl, NULL, zc_fsprops, props, B_TRUE,
1419                     &wkeydata, &wkeylen) != 0) {
1420                         zfs_error(hdl, EZFS_CRYPTOFAILED, msg);
1421                         goto create_failed;
1422                 }
1423                 if (nvlist_add_nvlist(zc_props,
1424                     ZPOOL_ROOTFS_PROPS, zc_fsprops) != 0) {
1425                         goto create_failed;
1426                 }
1427                 if (wkeydata != NULL) {
1428                         if (nvlist_alloc(&hidden_args, NV_UNIQUE_NAME, 0) != 0)
1429                                 goto create_failed;
1430
1431                         if (nvlist_add_uint8_array(hidden_args, "wkeydata",
1432                             wkeydata, wkeylen) != 0)
1433                                 goto create_failed;
1434
1435                         if (nvlist_add_nvlist(zc_props, ZPOOL_HIDDEN_ARGS,
1436                             hidden_args) != 0)
1437                                 goto create_failed;
1438                 }
1439         }
1440
1441         if (zc_props)
1442                 zcmd_write_src_nvlist(hdl, &zc, zc_props);
1443
1444         (void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
1445
1446         if ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_CREATE, &zc)) != 0) {
1447
1448                 zcmd_free_nvlists(&zc);
1449                 nvlist_free(zc_props);
1450                 nvlist_free(zc_fsprops);
1451                 nvlist_free(hidden_args);
1452                 if (wkeydata != NULL)
1453                         free(wkeydata);
1454
1455                 switch (errno) {
1456                 case EBUSY:
1457                         /*
1458                          * This can happen if the user has specified the same
1459                          * device multiple times.  We can't reliably detect this
1460                          * until we try to add it and see we already have a
1461                          * label.  This can also happen under if the device is
1462                          * part of an active md or lvm device.
1463                          */
1464                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1465                             "one or more vdevs refer to the same device, or "
1466                             "one of\nthe devices is part of an active md or "
1467                             "lvm device"));
1468                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1469
1470                 case ERANGE:
1471                         /*
1472                          * This happens if the record size is smaller or larger
1473                          * than the allowed size range, or not a power of 2.
1474                          *
1475                          * NOTE: although zfs_valid_proplist is called earlier,
1476                          * this case may have slipped through since the
1477                          * pool does not exist yet and it is therefore
1478                          * impossible to read properties e.g. max blocksize
1479                          * from the pool.
1480                          */
1481                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1482                             "record size invalid"));
1483                         return (zfs_error(hdl, EZFS_BADPROP, msg));
1484
1485                 case EOVERFLOW:
1486                         /*
1487                          * This occurs when one of the devices is below
1488                          * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1489                          * device was the problem device since there's no
1490                          * reliable way to determine device size from userland.
1491                          */
1492                         {
1493                                 char buf[64];
1494
1495                                 zfs_nicebytes(SPA_MINDEVSIZE, buf,
1496                                     sizeof (buf));
1497
1498                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1499                                     "one or more devices is less than the "
1500                                     "minimum size (%s)"), buf);
1501                         }
1502                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1503
1504                 case ENOSPC:
1505                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1506                             "one or more devices is out of space"));
1507                         return (zfs_error(hdl, EZFS_BADDEV, msg));
1508
1509                 case EINVAL:
1510                         if (zpool_has_draid_vdev(nvroot) &&
1511                             zfeature_lookup_name("draid", NULL) != 0) {
1512                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1513                                     "dRAID vdevs are unsupported by the "
1514                                     "kernel"));
1515                                 return (zfs_error(hdl, EZFS_BADDEV, msg));
1516                         } else {
1517                                 return (zpool_standard_error(hdl, errno, msg));
1518                         }
1519
1520                 default:
1521                         return (zpool_standard_error(hdl, errno, msg));
1522                 }
1523         }
1524
1525 create_failed:
1526         zcmd_free_nvlists(&zc);
1527         nvlist_free(zc_props);
1528         nvlist_free(zc_fsprops);
1529         nvlist_free(hidden_args);
1530         if (wkeydata != NULL)
1531                 free(wkeydata);
1532         return (ret);
1533 }
1534
1535 /*
1536  * Destroy the given pool.  It is up to the caller to ensure that there are no
1537  * datasets left in the pool.
1538  */
1539 int
1540 zpool_destroy(zpool_handle_t *zhp, const char *log_str)
1541 {
1542         zfs_cmd_t zc = {"\0"};
1543         zfs_handle_t *zfp = NULL;
1544         libzfs_handle_t *hdl = zhp->zpool_hdl;
1545         char msg[1024];
1546
1547         if (zhp->zpool_state == POOL_STATE_ACTIVE &&
1548             (zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
1549                 return (-1);
1550
1551         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1552         zc.zc_history = (uint64_t)(uintptr_t)log_str;
1553
1554         if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
1555                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1556                     "cannot destroy '%s'"), zhp->zpool_name);
1557
1558                 if (errno == EROFS) {
1559                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1560                             "one or more devices is read only"));
1561                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1562                 } else {
1563                         (void) zpool_standard_error(hdl, errno, msg);
1564                 }
1565
1566                 if (zfp)
1567                         zfs_close(zfp);
1568                 return (-1);
1569         }
1570
1571         if (zfp) {
1572                 remove_mountpoint(zfp);
1573                 zfs_close(zfp);
1574         }
1575
1576         return (0);
1577 }
1578
1579 /*
1580  * Create a checkpoint in the given pool.
1581  */
1582 int
1583 zpool_checkpoint(zpool_handle_t *zhp)
1584 {
1585         libzfs_handle_t *hdl = zhp->zpool_hdl;
1586         char msg[1024];
1587         int error;
1588
1589         error = lzc_pool_checkpoint(zhp->zpool_name);
1590         if (error != 0) {
1591                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1592                     "cannot checkpoint '%s'"), zhp->zpool_name);
1593                 (void) zpool_standard_error(hdl, error, msg);
1594                 return (-1);
1595         }
1596
1597         return (0);
1598 }
1599
1600 /*
1601  * Discard the checkpoint from the given pool.
1602  */
1603 int
1604 zpool_discard_checkpoint(zpool_handle_t *zhp)
1605 {
1606         libzfs_handle_t *hdl = zhp->zpool_hdl;
1607         char msg[1024];
1608         int error;
1609
1610         error = lzc_pool_checkpoint_discard(zhp->zpool_name);
1611         if (error != 0) {
1612                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1613                     "cannot discard checkpoint in '%s'"), zhp->zpool_name);
1614                 (void) zpool_standard_error(hdl, error, msg);
1615                 return (-1);
1616         }
1617
1618         return (0);
1619 }
1620
1621 /*
1622  * Add the given vdevs to the pool.  The caller must have already performed the
1623  * necessary verification to ensure that the vdev specification is well-formed.
1624  */
1625 int
1626 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
1627 {
1628         zfs_cmd_t zc = {"\0"};
1629         int ret;
1630         libzfs_handle_t *hdl = zhp->zpool_hdl;
1631         char msg[1024];
1632         nvlist_t **spares, **l2cache;
1633         uint_t nspares, nl2cache;
1634
1635         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
1636             "cannot add to '%s'"), zhp->zpool_name);
1637
1638         if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1639             SPA_VERSION_SPARES &&
1640             nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1641             &spares, &nspares) == 0) {
1642                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1643                     "upgraded to add hot spares"));
1644                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1645         }
1646
1647         if (zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL) <
1648             SPA_VERSION_L2CACHE &&
1649             nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
1650             &l2cache, &nl2cache) == 0) {
1651                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
1652                     "upgraded to add cache devices"));
1653                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
1654         }
1655
1656         zcmd_write_conf_nvlist(hdl, &zc, nvroot);
1657         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1658
1659         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_ADD, &zc) != 0) {
1660                 switch (errno) {
1661                 case EBUSY:
1662                         /*
1663                          * This can happen if the user has specified the same
1664                          * device multiple times.  We can't reliably detect this
1665                          * until we try to add it and see we already have a
1666                          * label.
1667                          */
1668                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1669                             "one or more vdevs refer to the same device"));
1670                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1671                         break;
1672
1673                 case EINVAL:
1674
1675                         if (zpool_has_draid_vdev(nvroot) &&
1676                             zfeature_lookup_name("draid", NULL) != 0) {
1677                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1678                                     "dRAID vdevs are unsupported by the "
1679                                     "kernel"));
1680                         } else {
1681                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1682                                     "invalid config; a pool with removing/"
1683                                     "removed vdevs does not support adding "
1684                                     "raidz or dRAID vdevs"));
1685                         }
1686
1687                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1688                         break;
1689
1690                 case EOVERFLOW:
1691                         /*
1692                          * This occurs when one of the devices is below
1693                          * SPA_MINDEVSIZE.  Unfortunately, we can't detect which
1694                          * device was the problem device since there's no
1695                          * reliable way to determine device size from userland.
1696                          */
1697                         {
1698                                 char buf[64];
1699
1700                                 zfs_nicebytes(SPA_MINDEVSIZE, buf,
1701                                     sizeof (buf));
1702
1703                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1704                                     "device is less than the minimum "
1705                                     "size (%s)"), buf);
1706                         }
1707                         (void) zfs_error(hdl, EZFS_BADDEV, msg);
1708                         break;
1709
1710                 case ENOTSUP:
1711                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1712                             "pool must be upgraded to add these vdevs"));
1713                         (void) zfs_error(hdl, EZFS_BADVERSION, msg);
1714                         break;
1715
1716                 default:
1717                         (void) zpool_standard_error(hdl, errno, msg);
1718                 }
1719
1720                 ret = -1;
1721         } else {
1722                 ret = 0;
1723         }
1724
1725         zcmd_free_nvlists(&zc);
1726
1727         return (ret);
1728 }
1729
1730 /*
1731  * Exports the pool from the system.  The caller must ensure that there are no
1732  * mounted datasets in the pool.
1733  */
1734 static int
1735 zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
1736     const char *log_str)
1737 {
1738         zfs_cmd_t zc = {"\0"};
1739
1740         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
1741         zc.zc_cookie = force;
1742         zc.zc_guid = hardforce;
1743         zc.zc_history = (uint64_t)(uintptr_t)log_str;
1744
1745         if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
1746                 switch (errno) {
1747                 case EXDEV:
1748                         zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
1749                             "use '-f' to override the following errors:\n"
1750                             "'%s' has an active shared spare which could be"
1751                             " used by other pools once '%s' is exported."),
1752                             zhp->zpool_name, zhp->zpool_name);
1753                         return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
1754                             dgettext(TEXT_DOMAIN, "cannot export '%s'"),
1755                             zhp->zpool_name));
1756                 default:
1757                         return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
1758                             dgettext(TEXT_DOMAIN, "cannot export '%s'"),
1759                             zhp->zpool_name));
1760                 }
1761         }
1762
1763         return (0);
1764 }
1765
1766 int
1767 zpool_export(zpool_handle_t *zhp, boolean_t force, const char *log_str)
1768 {
1769         return (zpool_export_common(zhp, force, B_FALSE, log_str));
1770 }
1771
1772 int
1773 zpool_export_force(zpool_handle_t *zhp, const char *log_str)
1774 {
1775         return (zpool_export_common(zhp, B_TRUE, B_TRUE, log_str));
1776 }
1777
1778 static void
1779 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1780     nvlist_t *config)
1781 {
1782         nvlist_t *nv = NULL;
1783         uint64_t rewindto;
1784         int64_t loss = -1;
1785         struct tm t;
1786         char timestr[128];
1787
1788         if (!hdl->libzfs_printerr || config == NULL)
1789                 return;
1790
1791         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1792             nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
1793                 return;
1794         }
1795
1796         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1797                 return;
1798         (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1799
1800         if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1801             strftime(timestr, 128, "%c", &t) != 0) {
1802                 if (dryrun) {
1803                         (void) printf(dgettext(TEXT_DOMAIN,
1804                             "Would be able to return %s "
1805                             "to its state as of %s.\n"),
1806                             name, timestr);
1807                 } else {
1808                         (void) printf(dgettext(TEXT_DOMAIN,
1809                             "Pool %s returned to its state as of %s.\n"),
1810                             name, timestr);
1811                 }
1812                 if (loss > 120) {
1813                         (void) printf(dgettext(TEXT_DOMAIN,
1814                             "%s approximately %lld "),
1815                             dryrun ? "Would discard" : "Discarded",
1816                             ((longlong_t)loss + 30) / 60);
1817                         (void) printf(dgettext(TEXT_DOMAIN,
1818                             "minutes of transactions.\n"));
1819                 } else if (loss > 0) {
1820                         (void) printf(dgettext(TEXT_DOMAIN,
1821                             "%s approximately %lld "),
1822                             dryrun ? "Would discard" : "Discarded",
1823                             (longlong_t)loss);
1824                         (void) printf(dgettext(TEXT_DOMAIN,
1825                             "seconds of transactions.\n"));
1826                 }
1827         }
1828 }
1829
1830 void
1831 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1832     nvlist_t *config)
1833 {
1834         nvlist_t *nv = NULL;
1835         int64_t loss = -1;
1836         uint64_t edata = UINT64_MAX;
1837         uint64_t rewindto;
1838         struct tm t;
1839         char timestr[128];
1840
1841         if (!hdl->libzfs_printerr)
1842                 return;
1843
1844         if (reason >= 0)
1845                 (void) printf(dgettext(TEXT_DOMAIN, "action: "));
1846         else
1847                 (void) printf(dgettext(TEXT_DOMAIN, "\t"));
1848
1849         /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1850         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1851             nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
1852             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1853                 goto no_info;
1854
1855         (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1856         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1857             &edata);
1858
1859         (void) printf(dgettext(TEXT_DOMAIN,
1860             "Recovery is possible, but will result in some data loss.\n"));
1861
1862         if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1863             strftime(timestr, 128, "%c", &t) != 0) {
1864                 (void) printf(dgettext(TEXT_DOMAIN,
1865                     "\tReturning the pool to its state as of %s\n"
1866                     "\tshould correct the problem.  "),
1867                     timestr);
1868         } else {
1869                 (void) printf(dgettext(TEXT_DOMAIN,
1870                     "\tReverting the pool to an earlier state "
1871                     "should correct the problem.\n\t"));
1872         }
1873
1874         if (loss > 120) {
1875                 (void) printf(dgettext(TEXT_DOMAIN,
1876                     "Approximately %lld minutes of data\n"
1877                     "\tmust be discarded, irreversibly.  "),
1878                     ((longlong_t)loss + 30) / 60);
1879         } else if (loss > 0) {
1880                 (void) printf(dgettext(TEXT_DOMAIN,
1881                     "Approximately %lld seconds of data\n"
1882                     "\tmust be discarded, irreversibly.  "),
1883                     (longlong_t)loss);
1884         }
1885         if (edata != 0 && edata != UINT64_MAX) {
1886                 if (edata == 1) {
1887                         (void) printf(dgettext(TEXT_DOMAIN,
1888                             "After rewind, at least\n"
1889                             "\tone persistent user-data error will remain.  "));
1890                 } else {
1891                         (void) printf(dgettext(TEXT_DOMAIN,
1892                             "After rewind, several\n"
1893                             "\tpersistent user-data errors will remain.  "));
1894                 }
1895         }
1896         (void) printf(dgettext(TEXT_DOMAIN,
1897             "Recovery can be attempted\n\tby executing 'zpool %s -F %s'.  "),
1898             reason >= 0 ? "clear" : "import", name);
1899
1900         (void) printf(dgettext(TEXT_DOMAIN,
1901             "A scrub of the pool\n"
1902             "\tis strongly recommended after recovery.\n"));
1903         return;
1904
1905 no_info:
1906         (void) printf(dgettext(TEXT_DOMAIN,
1907             "Destroy and re-create the pool from\n\ta backup source.\n"));
1908 }
1909
1910 /*
1911  * zpool_import() is a contracted interface. Should be kept the same
1912  * if possible.
1913  *
1914  * Applications should use zpool_import_props() to import a pool with
1915  * new properties value to be set.
1916  */
1917 int
1918 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1919     char *altroot)
1920 {
1921         nvlist_t *props = NULL;
1922         int ret;
1923
1924         if (altroot != NULL) {
1925                 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
1926                         return (zfs_error_fmt(hdl, EZFS_NOMEM,
1927                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1928                             newname));
1929                 }
1930
1931                 if (nvlist_add_string(props,
1932                     zpool_prop_to_name(ZPOOL_PROP_ALTROOT), altroot) != 0 ||
1933                     nvlist_add_string(props,
1934                     zpool_prop_to_name(ZPOOL_PROP_CACHEFILE), "none") != 0) {
1935                         nvlist_free(props);
1936                         return (zfs_error_fmt(hdl, EZFS_NOMEM,
1937                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1938                             newname));
1939                 }
1940         }
1941
1942         ret = zpool_import_props(hdl, config, newname, props,
1943             ZFS_IMPORT_NORMAL);
1944         nvlist_free(props);
1945         return (ret);
1946 }
1947
1948 static void
1949 print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
1950     int indent)
1951 {
1952         nvlist_t **child;
1953         uint_t c, children;
1954         char *vname;
1955         uint64_t is_log = 0;
1956
1957         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
1958             &is_log);
1959
1960         if (name != NULL)
1961                 (void) printf("\t%*s%s%s\n", indent, "", name,
1962                     is_log ? " [log]" : "");
1963
1964         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1965             &child, &children) != 0)
1966                 return;
1967
1968         for (c = 0; c < children; c++) {
1969                 vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID);
1970                 print_vdev_tree(hdl, vname, child[c], indent + 2);
1971                 free(vname);
1972         }
1973 }
1974
1975 void
1976 zpool_print_unsup_feat(nvlist_t *config)
1977 {
1978         nvlist_t *nvinfo, *unsup_feat;
1979
1980         nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
1981         unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT);
1982
1983         for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL);
1984             nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
1985                 char *desc = fnvpair_value_string(nvp);
1986                 if (strlen(desc) > 0)
1987                         (void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
1988                 else
1989                         (void) printf("\t%s\n", nvpair_name(nvp));
1990         }
1991 }
1992
1993 /*
1994  * Import the given pool using the known configuration and a list of
1995  * properties to be set. The configuration should have come from
1996  * zpool_find_import(). The 'newname' parameters control whether the pool
1997  * is imported with a different name.
1998  */
1999 int
2000 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
2001     nvlist_t *props, int flags)
2002 {
2003         zfs_cmd_t zc = {"\0"};
2004         zpool_load_policy_t policy;
2005         nvlist_t *nv = NULL;
2006         nvlist_t *nvinfo = NULL;
2007         nvlist_t *missing = NULL;
2008         const char *thename;
2009         char *origname;
2010         int ret;
2011         int error = 0;
2012         char errbuf[1024];
2013
2014         origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
2015
2016         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2017             "cannot import pool '%s'"), origname);
2018
2019         if (newname != NULL) {
2020                 if (!zpool_name_valid(hdl, B_FALSE, newname))
2021                         return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
2022                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2023                             newname));
2024                 thename = newname;
2025         } else {
2026                 thename = origname;
2027         }
2028
2029         if (props != NULL) {
2030                 uint64_t version;
2031                 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
2032
2033                 version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
2034
2035                 if ((props = zpool_valid_proplist(hdl, origname,
2036                     props, version, flags, errbuf)) == NULL)
2037                         return (-1);
2038                 zcmd_write_src_nvlist(hdl, &zc, props);
2039                 nvlist_free(props);
2040         }
2041
2042         (void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
2043
2044         zc.zc_guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID);
2045
2046         zcmd_write_conf_nvlist(hdl, &zc, config);
2047         zcmd_alloc_dst_nvlist(hdl, &zc, zc.zc_nvlist_conf_size * 2);
2048
2049         zc.zc_cookie = flags;
2050         while ((ret = zfs_ioctl(hdl, ZFS_IOC_POOL_IMPORT, &zc)) != 0 &&
2051             errno == ENOMEM)
2052                 zcmd_expand_dst_nvlist(hdl, &zc);
2053         if (ret != 0)
2054                 error = errno;
2055
2056         (void) zcmd_read_dst_nvlist(hdl, &zc, &nv);
2057
2058         zcmd_free_nvlists(&zc);
2059
2060         zpool_get_load_policy(config, &policy);
2061
2062         if (error) {
2063                 char desc[1024];
2064                 char aux[256];
2065
2066                 /*
2067                  * Dry-run failed, but we print out what success
2068                  * looks like if we found a best txg
2069                  */
2070                 if (policy.zlp_rewind & ZPOOL_TRY_REWIND) {
2071                         zpool_rewind_exclaim(hdl, newname ? origname : thename,
2072                             B_TRUE, nv);
2073                         nvlist_free(nv);
2074                         return (-1);
2075                 }
2076
2077                 if (newname == NULL)
2078                         (void) snprintf(desc, sizeof (desc),
2079                             dgettext(TEXT_DOMAIN, "cannot import '%s'"),
2080                             thename);
2081                 else
2082                         (void) snprintf(desc, sizeof (desc),
2083                             dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
2084                             origname, thename);
2085
2086                 switch (error) {
2087                 case ENOTSUP:
2088                         if (nv != NULL && nvlist_lookup_nvlist(nv,
2089                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
2090                             nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
2091                                 (void) printf(dgettext(TEXT_DOMAIN, "This "
2092                                     "pool uses the following feature(s) not "
2093                                     "supported by this system:\n"));
2094                                 zpool_print_unsup_feat(nv);
2095                                 if (nvlist_exists(nvinfo,
2096                                     ZPOOL_CONFIG_CAN_RDONLY)) {
2097                                         (void) printf(dgettext(TEXT_DOMAIN,
2098                                             "All unsupported features are only "
2099                                             "required for writing to the pool."
2100                                             "\nThe pool can be imported using "
2101                                             "'-o readonly=on'.\n"));
2102                                 }
2103                         }
2104                         /*
2105                          * Unsupported version.
2106                          */
2107                         (void) zfs_error(hdl, EZFS_BADVERSION, desc);
2108                         break;
2109
2110                 case EREMOTEIO:
2111                         if (nv != NULL && nvlist_lookup_nvlist(nv,
2112                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0) {
2113                                 char *hostname = "<unknown>";
2114                                 uint64_t hostid = 0;
2115                                 mmp_state_t mmp_state;
2116
2117                                 mmp_state = fnvlist_lookup_uint64(nvinfo,
2118                                     ZPOOL_CONFIG_MMP_STATE);
2119
2120                                 if (nvlist_exists(nvinfo,
2121                                     ZPOOL_CONFIG_MMP_HOSTNAME))
2122                                         hostname = fnvlist_lookup_string(nvinfo,
2123                                             ZPOOL_CONFIG_MMP_HOSTNAME);
2124
2125                                 if (nvlist_exists(nvinfo,
2126                                     ZPOOL_CONFIG_MMP_HOSTID))
2127                                         hostid = fnvlist_lookup_uint64(nvinfo,
2128                                             ZPOOL_CONFIG_MMP_HOSTID);
2129
2130                                 if (mmp_state == MMP_STATE_ACTIVE) {
2131                                         (void) snprintf(aux, sizeof (aux),
2132                                             dgettext(TEXT_DOMAIN, "pool is imp"
2133                                             "orted on host '%s' (hostid=%lx).\n"
2134                                             "Export the pool on the other "
2135                                             "system, then run 'zpool import'."),
2136                                             hostname, (unsigned long) hostid);
2137                                 } else if (mmp_state == MMP_STATE_NO_HOSTID) {
2138                                         (void) snprintf(aux, sizeof (aux),
2139                                             dgettext(TEXT_DOMAIN, "pool has "
2140                                             "the multihost property on and "
2141                                             "the\nsystem's hostid is not set. "
2142                                             "Set a unique system hostid with "
2143                                             "the zgenhostid(8) command.\n"));
2144                                 }
2145
2146                                 (void) zfs_error_aux(hdl, "%s", aux);
2147                         }
2148                         (void) zfs_error(hdl, EZFS_ACTIVE_POOL, desc);
2149                         break;
2150
2151                 case EINVAL:
2152                         (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
2153                         break;
2154
2155                 case EROFS:
2156                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2157                             "one or more devices is read only"));
2158                         (void) zfs_error(hdl, EZFS_BADDEV, desc);
2159                         break;
2160
2161                 case ENXIO:
2162                         if (nv && nvlist_lookup_nvlist(nv,
2163                             ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
2164                             nvlist_lookup_nvlist(nvinfo,
2165                             ZPOOL_CONFIG_MISSING_DEVICES, &missing) == 0) {
2166                                 (void) printf(dgettext(TEXT_DOMAIN,
2167                                     "The devices below are missing or "
2168                                     "corrupted, use '-m' to import the pool "
2169                                     "anyway:\n"));
2170                                 print_vdev_tree(hdl, NULL, missing, 2);
2171                                 (void) printf("\n");
2172                         }
2173                         (void) zpool_standard_error(hdl, error, desc);
2174                         break;
2175
2176                 case EEXIST:
2177                         (void) zpool_standard_error(hdl, error, desc);
2178                         break;
2179
2180                 case EBUSY:
2181                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2182                             "one or more devices are already in use\n"));
2183                         (void) zfs_error(hdl, EZFS_BADDEV, desc);
2184                         break;
2185                 case ENAMETOOLONG:
2186                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2187                             "new name of at least one dataset is longer than "
2188                             "the maximum allowable length"));
2189                         (void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
2190                         break;
2191                 default:
2192                         (void) zpool_standard_error(hdl, error, desc);
2193                         zpool_explain_recover(hdl,
2194                             newname ? origname : thename, -error, nv);
2195                         break;
2196                 }
2197
2198                 nvlist_free(nv);
2199                 ret = -1;
2200         } else {
2201                 zpool_handle_t *zhp;
2202
2203                 /*
2204                  * This should never fail, but play it safe anyway.
2205                  */
2206                 if (zpool_open_silent(hdl, thename, &zhp) != 0)
2207                         ret = -1;
2208                 else if (zhp != NULL)
2209                         zpool_close(zhp);
2210                 if (policy.zlp_rewind &
2211                     (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
2212                         zpool_rewind_exclaim(hdl, newname ? origname : thename,
2213                             ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0), nv);
2214                 }
2215                 nvlist_free(nv);
2216                 return (0);
2217         }
2218
2219         return (ret);
2220 }
2221
2222 /*
2223  * Translate vdev names to guids.  If a vdev_path is determined to be
2224  * unsuitable then a vd_errlist is allocated and the vdev path and errno
2225  * are added to it.
2226  */
2227 static int
2228 zpool_translate_vdev_guids(zpool_handle_t *zhp, nvlist_t *vds,
2229     nvlist_t *vdev_guids, nvlist_t *guids_to_paths, nvlist_t **vd_errlist)
2230 {
2231         nvlist_t *errlist = NULL;
2232         int error = 0;
2233
2234         for (nvpair_t *elem = nvlist_next_nvpair(vds, NULL); elem != NULL;
2235             elem = nvlist_next_nvpair(vds, elem)) {
2236                 boolean_t spare, cache;
2237
2238                 char *vd_path = nvpair_name(elem);
2239                 nvlist_t *tgt = zpool_find_vdev(zhp, vd_path, &spare, &cache,
2240                     NULL);
2241
2242                 if ((tgt == NULL) || cache || spare) {
2243                         if (errlist == NULL) {
2244                                 errlist = fnvlist_alloc();
2245                                 error = EINVAL;
2246                         }
2247
2248                         uint64_t err = (tgt == NULL) ? EZFS_NODEVICE :
2249                             (spare ? EZFS_ISSPARE : EZFS_ISL2CACHE);
2250                         fnvlist_add_int64(errlist, vd_path, err);
2251                         continue;
2252                 }
2253
2254                 uint64_t guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
2255                 fnvlist_add_uint64(vdev_guids, vd_path, guid);
2256
2257                 char msg[MAXNAMELEN];
2258                 (void) snprintf(msg, sizeof (msg), "%llu", (u_longlong_t)guid);
2259                 fnvlist_add_string(guids_to_paths, msg, vd_path);
2260         }
2261
2262         if (error != 0) {
2263                 verify(errlist != NULL);
2264                 if (vd_errlist != NULL)
2265                         *vd_errlist = errlist;
2266                 else
2267                         fnvlist_free(errlist);
2268         }
2269
2270         return (error);
2271 }
2272
2273 static int
2274 xlate_init_err(int err)
2275 {
2276         switch (err) {
2277         case ENODEV:
2278                 return (EZFS_NODEVICE);
2279         case EINVAL:
2280         case EROFS:
2281                 return (EZFS_BADDEV);
2282         case EBUSY:
2283                 return (EZFS_INITIALIZING);
2284         case ESRCH:
2285                 return (EZFS_NO_INITIALIZE);
2286         }
2287         return (err);
2288 }
2289
2290 /*
2291  * Begin, suspend, or cancel the initialization (initializing of all free
2292  * blocks) for the given vdevs in the given pool.
2293  */
2294 static int
2295 zpool_initialize_impl(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2296     nvlist_t *vds, boolean_t wait)
2297 {
2298         int err;
2299
2300         nvlist_t *vdev_guids = fnvlist_alloc();
2301         nvlist_t *guids_to_paths = fnvlist_alloc();
2302         nvlist_t *vd_errlist = NULL;
2303         nvlist_t *errlist;
2304         nvpair_t *elem;
2305
2306         err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
2307             guids_to_paths, &vd_errlist);
2308
2309         if (err != 0) {
2310                 verify(vd_errlist != NULL);
2311                 goto list_errors;
2312         }
2313
2314         err = lzc_initialize(zhp->zpool_name, cmd_type,
2315             vdev_guids, &errlist);
2316
2317         if (err != 0) {
2318                 if (errlist != NULL) {
2319                         vd_errlist = fnvlist_lookup_nvlist(errlist,
2320                             ZPOOL_INITIALIZE_VDEVS);
2321                         goto list_errors;
2322                 }
2323                 (void) zpool_standard_error(zhp->zpool_hdl, err,
2324                     dgettext(TEXT_DOMAIN, "operation failed"));
2325                 goto out;
2326         }
2327
2328         if (wait) {
2329                 for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
2330                     elem = nvlist_next_nvpair(vdev_guids, elem)) {
2331
2332                         uint64_t guid = fnvpair_value_uint64(elem);
2333
2334                         err = lzc_wait_tag(zhp->zpool_name,
2335                             ZPOOL_WAIT_INITIALIZE, guid, NULL);
2336                         if (err != 0) {
2337                                 (void) zpool_standard_error_fmt(zhp->zpool_hdl,
2338                                     err, dgettext(TEXT_DOMAIN, "error "
2339                                     "waiting for '%s' to initialize"),
2340                                     nvpair_name(elem));
2341
2342                                 goto out;
2343                         }
2344                 }
2345         }
2346         goto out;
2347
2348 list_errors:
2349         for (elem = nvlist_next_nvpair(vd_errlist, NULL); elem != NULL;
2350             elem = nvlist_next_nvpair(vd_errlist, elem)) {
2351                 int64_t vd_error = xlate_init_err(fnvpair_value_int64(elem));
2352                 char *path;
2353
2354                 if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
2355                     &path) != 0)
2356                         path = nvpair_name(elem);
2357
2358                 (void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
2359                     "cannot initialize '%s'", path);
2360         }
2361
2362 out:
2363         fnvlist_free(vdev_guids);
2364         fnvlist_free(guids_to_paths);
2365
2366         if (vd_errlist != NULL)
2367                 fnvlist_free(vd_errlist);
2368
2369         return (err == 0 ? 0 : -1);
2370 }
2371
2372 int
2373 zpool_initialize(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2374     nvlist_t *vds)
2375 {
2376         return (zpool_initialize_impl(zhp, cmd_type, vds, B_FALSE));
2377 }
2378
2379 int
2380 zpool_initialize_wait(zpool_handle_t *zhp, pool_initialize_func_t cmd_type,
2381     nvlist_t *vds)
2382 {
2383         return (zpool_initialize_impl(zhp, cmd_type, vds, B_TRUE));
2384 }
2385
2386 static int
2387 xlate_trim_err(int err)
2388 {
2389         switch (err) {
2390         case ENODEV:
2391                 return (EZFS_NODEVICE);
2392         case EINVAL:
2393         case EROFS:
2394                 return (EZFS_BADDEV);
2395         case EBUSY:
2396                 return (EZFS_TRIMMING);
2397         case ESRCH:
2398                 return (EZFS_NO_TRIM);
2399         case EOPNOTSUPP:
2400                 return (EZFS_TRIM_NOTSUP);
2401         }
2402         return (err);
2403 }
2404
2405 static int
2406 zpool_trim_wait(zpool_handle_t *zhp, nvlist_t *vdev_guids)
2407 {
2408         int err;
2409         nvpair_t *elem;
2410
2411         for (elem = nvlist_next_nvpair(vdev_guids, NULL); elem != NULL;
2412             elem = nvlist_next_nvpair(vdev_guids, elem)) {
2413
2414                 uint64_t guid = fnvpair_value_uint64(elem);
2415
2416                 err = lzc_wait_tag(zhp->zpool_name,
2417                     ZPOOL_WAIT_TRIM, guid, NULL);
2418                 if (err != 0) {
2419                         (void) zpool_standard_error_fmt(zhp->zpool_hdl,
2420                             err, dgettext(TEXT_DOMAIN, "error "
2421                             "waiting to trim '%s'"), nvpair_name(elem));
2422
2423                         return (err);
2424                 }
2425         }
2426         return (0);
2427 }
2428
2429 /*
2430  * Check errlist and report any errors, omitting ones which should be
2431  * suppressed. Returns B_TRUE if any errors were reported.
2432  */
2433 static boolean_t
2434 check_trim_errs(zpool_handle_t *zhp, trimflags_t *trim_flags,
2435     nvlist_t *guids_to_paths, nvlist_t *vds, nvlist_t *errlist)
2436 {
2437         nvpair_t *elem;
2438         boolean_t reported_errs = B_FALSE;
2439         int num_vds = 0;
2440         int num_suppressed_errs = 0;
2441
2442         for (elem = nvlist_next_nvpair(vds, NULL);
2443             elem != NULL; elem = nvlist_next_nvpair(vds, elem)) {
2444                 num_vds++;
2445         }
2446
2447         for (elem = nvlist_next_nvpair(errlist, NULL);
2448             elem != NULL; elem = nvlist_next_nvpair(errlist, elem)) {
2449                 int64_t vd_error = xlate_trim_err(fnvpair_value_int64(elem));
2450                 char *path;
2451
2452                 /*
2453                  * If only the pool was specified, and it was not a secure
2454                  * trim then suppress warnings for individual vdevs which
2455                  * do not support trimming.
2456                  */
2457                 if (vd_error == EZFS_TRIM_NOTSUP &&
2458                     trim_flags->fullpool &&
2459                     !trim_flags->secure) {
2460                         num_suppressed_errs++;
2461                         continue;
2462                 }
2463
2464                 reported_errs = B_TRUE;
2465                 if (nvlist_lookup_string(guids_to_paths, nvpair_name(elem),
2466                     &path) != 0)
2467                         path = nvpair_name(elem);
2468
2469                 (void) zfs_error_fmt(zhp->zpool_hdl, vd_error,
2470                     "cannot trim '%s'", path);
2471         }
2472
2473         if (num_suppressed_errs == num_vds) {
2474                 (void) zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
2475                     "no devices in pool support trim operations"));
2476                 (void) (zfs_error(zhp->zpool_hdl, EZFS_TRIM_NOTSUP,
2477                     dgettext(TEXT_DOMAIN, "cannot trim")));
2478                 reported_errs = B_TRUE;
2479         }
2480
2481         return (reported_errs);
2482 }
2483
2484 /*
2485  * Begin, suspend, or cancel the TRIM (discarding of all free blocks) for
2486  * the given vdevs in the given pool.
2487  */
2488 int
2489 zpool_trim(zpool_handle_t *zhp, pool_trim_func_t cmd_type, nvlist_t *vds,
2490     trimflags_t *trim_flags)
2491 {
2492         int err;
2493         int retval = 0;
2494
2495         nvlist_t *vdev_guids = fnvlist_alloc();
2496         nvlist_t *guids_to_paths = fnvlist_alloc();
2497         nvlist_t *errlist = NULL;
2498
2499         err = zpool_translate_vdev_guids(zhp, vds, vdev_guids,
2500             guids_to_paths, &errlist);
2501         if (err != 0) {
2502                 check_trim_errs(zhp, trim_flags, guids_to_paths, vds, errlist);
2503                 retval = -1;
2504                 goto out;
2505         }
2506
2507         err = lzc_trim(zhp->zpool_name, cmd_type, trim_flags->rate,
2508             trim_flags->secure, vdev_guids, &errlist);
2509         if (err != 0) {
2510                 nvlist_t *vd_errlist;
2511                 if (errlist != NULL && nvlist_lookup_nvlist(errlist,
2512                     ZPOOL_TRIM_VDEVS, &vd_errlist) == 0) {
2513                         if (check_trim_errs(zhp, trim_flags, guids_to_paths,
2514                             vds, vd_errlist)) {
2515                                 retval = -1;
2516                                 goto out;
2517                         }
2518                 } else {
2519                         char msg[1024];
2520
2521                         (void) snprintf(msg, sizeof (msg),
2522                             dgettext(TEXT_DOMAIN, "operation failed"));
2523                         zpool_standard_error(zhp->zpool_hdl, err, msg);
2524                         retval = -1;
2525                         goto out;
2526                 }
2527         }
2528
2529
2530         if (trim_flags->wait)
2531                 retval = zpool_trim_wait(zhp, vdev_guids);
2532
2533 out:
2534         if (errlist != NULL)
2535                 fnvlist_free(errlist);
2536         fnvlist_free(vdev_guids);
2537         fnvlist_free(guids_to_paths);
2538         return (retval);
2539 }
2540
2541 /*
2542  * Scan the pool.
2543  */
2544 int
2545 zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
2546 {
2547         zfs_cmd_t zc = {"\0"};
2548         char msg[1024];
2549         int err;
2550         libzfs_handle_t *hdl = zhp->zpool_hdl;
2551
2552         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
2553         zc.zc_cookie = func;
2554         zc.zc_flags = cmd;
2555
2556         if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0)
2557                 return (0);
2558
2559         err = errno;
2560
2561         /* ECANCELED on a scrub means we resumed a paused scrub */
2562         if (err == ECANCELED && func == POOL_SCAN_SCRUB &&
2563             cmd == POOL_SCRUB_NORMAL)
2564                 return (0);
2565
2566         if (err == ENOENT && func != POOL_SCAN_NONE && cmd == POOL_SCRUB_NORMAL)
2567                 return (0);
2568
2569         if (func == POOL_SCAN_SCRUB) {
2570                 if (cmd == POOL_SCRUB_PAUSE) {
2571                         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2572                             "cannot pause scrubbing %s"), zc.zc_name);
2573                 } else {
2574                         assert(cmd == POOL_SCRUB_NORMAL);
2575                         (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2576                             "cannot scrub %s"), zc.zc_name);
2577                 }
2578         } else if (func == POOL_SCAN_RESILVER) {
2579                 assert(cmd == POOL_SCRUB_NORMAL);
2580                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
2581                     "cannot restart resilver on %s"), zc.zc_name);
2582         } else if (func == POOL_SCAN_NONE) {
2583                 (void) snprintf(msg, sizeof (msg),
2584                     dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
2585                     zc.zc_name);
2586         } else {
2587                 assert(!"unexpected result");
2588         }
2589
2590         if (err == EBUSY) {
2591                 nvlist_t *nvroot;
2592                 pool_scan_stat_t *ps = NULL;
2593                 uint_t psc;
2594
2595                 nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
2596                     ZPOOL_CONFIG_VDEV_TREE);
2597                 (void) nvlist_lookup_uint64_array(nvroot,
2598                     ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
2599                 if (ps && ps->pss_func == POOL_SCAN_SCRUB &&
2600                     ps->pss_state == DSS_SCANNING) {
2601                         if (cmd == POOL_SCRUB_PAUSE)
2602                                 return (zfs_error(hdl, EZFS_SCRUB_PAUSED, msg));
2603                         else
2604                                 return (zfs_error(hdl, EZFS_SCRUBBING, msg));
2605                 } else {
2606                         return (zfs_error(hdl, EZFS_RESILVERING, msg));
2607                 }
2608         } else if (err == ENOENT) {
2609                 return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
2610         } else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) {
2611                 return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, msg));
2612         } else {
2613                 return (zpool_standard_error(hdl, err, msg));
2614         }
2615 }
2616
2617 /*
2618  * Find a vdev that matches the search criteria specified. We use the
2619  * the nvpair name to determine how we should look for the device.
2620  * 'avail_spare' is set to TRUE if the provided guid refers to an AVAIL
2621  * spare; but FALSE if its an INUSE spare.
2622  */
2623 static nvlist_t *
2624 vdev_to_nvlist_iter(nvlist_t *nv, nvlist_t *search, boolean_t *avail_spare,
2625     boolean_t *l2cache, boolean_t *log)
2626 {
2627         uint_t c, children;
2628         nvlist_t **child;
2629         nvlist_t *ret;
2630         uint64_t is_log;
2631         char *srchkey;
2632         nvpair_t *pair = nvlist_next_nvpair(search, NULL);
2633
2634         /* Nothing to look for */
2635         if (search == NULL || pair == NULL)
2636                 return (NULL);
2637
2638         /* Obtain the key we will use to search */
2639         srchkey = nvpair_name(pair);
2640
2641         switch (nvpair_type(pair)) {
2642         case DATA_TYPE_UINT64:
2643                 if (strcmp(srchkey, ZPOOL_CONFIG_GUID) == 0) {
2644                         uint64_t srchval = fnvpair_value_uint64(pair);
2645                         uint64_t theguid = fnvlist_lookup_uint64(nv,
2646                             ZPOOL_CONFIG_GUID);
2647                         if (theguid == srchval)
2648                                 return (nv);
2649                 }
2650                 break;
2651
2652         case DATA_TYPE_STRING: {
2653                 char *srchval, *val;
2654
2655                 srchval = fnvpair_value_string(pair);
2656                 if (nvlist_lookup_string(nv, srchkey, &val) != 0)
2657                         break;
2658
2659                 /*
2660                  * Search for the requested value. Special cases:
2661                  *
2662                  * - ZPOOL_CONFIG_PATH for whole disk entries.  These end in
2663                  *   "-part1", or "p1".  The suffix is hidden from the user,
2664                  *   but included in the string, so this matches around it.
2665                  * - ZPOOL_CONFIG_PATH for short names zfs_strcmp_shortname()
2666                  *   is used to check all possible expanded paths.
2667                  * - looking for a top-level vdev name (i.e. ZPOOL_CONFIG_TYPE).
2668                  *
2669                  * Otherwise, all other searches are simple string compares.
2670                  */
2671                 if (strcmp(srchkey, ZPOOL_CONFIG_PATH) == 0) {
2672                         uint64_t wholedisk = 0;
2673
2674                         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
2675                             &wholedisk);
2676                         if (zfs_strcmp_pathname(srchval, val, wholedisk) == 0)
2677                                 return (nv);
2678
2679                 } else if (strcmp(srchkey, ZPOOL_CONFIG_TYPE) == 0 && val) {
2680                         char *type, *idx, *end, *p;
2681                         uint64_t id, vdev_id;
2682
2683                         /*
2684                          * Determine our vdev type, keeping in mind
2685                          * that the srchval is composed of a type and
2686                          * vdev id pair (i.e. mirror-4).
2687                          */
2688                         if ((type = strdup(srchval)) == NULL)
2689                                 return (NULL);
2690
2691                         if ((p = strrchr(type, '-')) == NULL) {
2692                                 free(type);
2693                                 break;
2694                         }
2695                         idx = p + 1;
2696                         *p = '\0';
2697
2698                         /*
2699                          * If the types don't match then keep looking.
2700                          */
2701                         if (strncmp(val, type, strlen(val)) != 0) {
2702                                 free(type);
2703                                 break;
2704                         }
2705
2706                         verify(zpool_vdev_is_interior(type));
2707
2708                         id = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID);
2709                         errno = 0;
2710                         vdev_id = strtoull(idx, &end, 10);
2711
2712                         /*
2713                          * If we are looking for a raidz and a parity is
2714                          * specified, make sure it matches.
2715                          */
2716                         int rzlen = strlen(VDEV_TYPE_RAIDZ);
2717                         assert(rzlen == strlen(VDEV_TYPE_DRAID));
2718                         int typlen = strlen(type);
2719                         if ((strncmp(type, VDEV_TYPE_RAIDZ, rzlen) == 0 ||
2720                             strncmp(type, VDEV_TYPE_DRAID, rzlen) == 0) &&
2721                             typlen != rzlen) {
2722                                 uint64_t vdev_parity;
2723                                 int parity = *(type + rzlen) - '0';
2724
2725                                 if (parity <= 0 || parity > 3 ||
2726                                     (typlen - rzlen) != 1) {
2727                                         /*
2728                                          * Nonsense parity specified, can
2729                                          * never match
2730                                          */
2731                                         free(type);
2732                                         return (NULL);
2733                                 }
2734                                 vdev_parity = fnvlist_lookup_uint64(nv,
2735                                     ZPOOL_CONFIG_NPARITY);
2736                                 if ((int)vdev_parity != parity) {
2737                                         free(type);
2738                                         break;
2739                                 }
2740                         }
2741
2742                         free(type);
2743                         if (errno != 0)
2744                                 return (NULL);
2745
2746                         /*
2747                          * Now verify that we have the correct vdev id.
2748                          */
2749                         if (vdev_id == id)
2750                                 return (nv);
2751                 }
2752
2753                 /*
2754                  * Common case
2755                  */
2756                 if (strcmp(srchval, val) == 0)
2757                         return (nv);
2758                 break;
2759         }
2760
2761         default:
2762                 break;
2763         }
2764
2765         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
2766             &child, &children) != 0)
2767                 return (NULL);
2768
2769         for (c = 0; c < children; c++) {
2770                 if ((ret = vdev_to_nvlist_iter(child[c], search,
2771                     avail_spare, l2cache, NULL)) != NULL) {
2772                         /*
2773                          * The 'is_log' value is only set for the toplevel
2774                          * vdev, not the leaf vdevs.  So we always lookup the
2775                          * log device from the root of the vdev tree (where
2776                          * 'log' is non-NULL).
2777                          */
2778                         if (log != NULL &&
2779                             nvlist_lookup_uint64(child[c],
2780                             ZPOOL_CONFIG_IS_LOG, &is_log) == 0 &&
2781                             is_log) {
2782                                 *log = B_TRUE;
2783                         }
2784                         return (ret);
2785                 }
2786         }
2787
2788         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
2789             &child, &children) == 0) {
2790                 for (c = 0; c < children; c++) {
2791                         if ((ret = vdev_to_nvlist_iter(child[c], search,
2792                             avail_spare, l2cache, NULL)) != NULL) {
2793                                 *avail_spare = B_TRUE;
2794                                 return (ret);
2795                         }
2796                 }
2797         }
2798
2799         if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
2800             &child, &children) == 0) {
2801                 for (c = 0; c < children; c++) {
2802                         if ((ret = vdev_to_nvlist_iter(child[c], search,
2803                             avail_spare, l2cache, NULL)) != NULL) {
2804                                 *l2cache = B_TRUE;
2805                                 return (ret);
2806                         }
2807                 }
2808         }
2809
2810         return (NULL);
2811 }
2812
2813 /*
2814  * Given a physical path or guid, find the associated vdev.
2815  */
2816 nvlist_t *
2817 zpool_find_vdev_by_physpath(zpool_handle_t *zhp, const char *ppath,
2818     boolean_t *avail_spare, boolean_t *l2cache, boolean_t *log)
2819 {
2820         nvlist_t *search, *nvroot, *ret;
2821         uint64_t guid;
2822         char *end;
2823
2824         search = fnvlist_alloc();
2825
2826         guid = strtoull(ppath, &end, 0);
2827         if (guid != 0 && *end == '\0') {
2828                 fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
2829         } else {
2830                 fnvlist_add_string(search, ZPOOL_CONFIG_PHYS_PATH, ppath);
2831         }
2832
2833         nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
2834             ZPOOL_CONFIG_VDEV_TREE);
2835
2836         *avail_spare = B_FALSE;
2837         *l2cache = B_FALSE;
2838         if (log != NULL)
2839                 *log = B_FALSE;
2840         ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
2841         fnvlist_free(search);
2842
2843         return (ret);
2844 }
2845
2846 /*
2847  * Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
2848  */
2849 static boolean_t
2850 zpool_vdev_is_interior(const char *name)
2851 {
2852         if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
2853             strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 ||
2854             strncmp(name,
2855             VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 ||
2856             strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
2857                 return (B_TRUE);
2858
2859         if (strncmp(name, VDEV_TYPE_DRAID, strlen(VDEV_TYPE_DRAID)) == 0 &&
2860             !zpool_is_draid_spare(name))
2861                 return (B_TRUE);
2862
2863         return (B_FALSE);
2864 }
2865
2866 nvlist_t *
2867 zpool_find_vdev(zpool_handle_t *zhp, const char *path, boolean_t *avail_spare,
2868     boolean_t *l2cache, boolean_t *log)
2869 {
2870         char *end;
2871         nvlist_t *nvroot, *search, *ret;
2872         uint64_t guid;
2873
2874         search = fnvlist_alloc();
2875
2876         guid = strtoull(path, &end, 0);
2877         if (guid != 0 && *end == '\0') {
2878                 fnvlist_add_uint64(search, ZPOOL_CONFIG_GUID, guid);
2879         } else if (zpool_vdev_is_interior(path)) {
2880                 fnvlist_add_string(search, ZPOOL_CONFIG_TYPE, path);
2881         } else {
2882                 fnvlist_add_string(search, ZPOOL_CONFIG_PATH, path);
2883         }
2884
2885         nvroot = fnvlist_lookup_nvlist(zhp->zpool_config,
2886             ZPOOL_CONFIG_VDEV_TREE);
2887
2888         *avail_spare = B_FALSE;
2889         *l2cache = B_FALSE;
2890         if (log != NULL)
2891                 *log = B_FALSE;
2892         ret = vdev_to_nvlist_iter(nvroot, search, avail_spare, l2cache, log);
2893         fnvlist_free(search);
2894
2895         return (ret);
2896 }
2897
2898 static int
2899 vdev_is_online(nvlist_t *nv)
2900 {
2901         uint64_t ival;
2902
2903         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 ||
2904             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 ||
2905             nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0)
2906                 return (0);
2907
2908         return (1);
2909 }
2910
2911 /*
2912  * Helper function for zpool_get_physpaths().
2913  */
2914 static int
2915 vdev_get_one_physpath(nvlist_t *config, char *physpath, size_t physpath_size,
2916     size_t *bytes_written)
2917 {
2918         size_t bytes_left, pos, rsz;
2919         char *tmppath;
2920         const char *format;
2921
2922         if (nvlist_lookup_string(config, ZPOOL_CONFIG_PHYS_PATH,
2923             &tmppath) != 0)
2924                 return (EZFS_NODEVICE);
2925
2926         pos = *bytes_written;
2927         bytes_left = physpath_size - pos;
2928         format = (pos == 0) ? "%s" : " %s";
2929
2930         rsz = snprintf(physpath + pos, bytes_left, format, tmppath);
2931         *bytes_written += rsz;
2932
2933         if (rsz >= bytes_left) {
2934                 /* if physpath was not copied properly, clear it */
2935                 if (bytes_left != 0) {
2936                         physpath[pos] = 0;
2937                 }
2938                 return (EZFS_NOSPC);
2939         }
2940         return (0);
2941 }
2942
2943 static int
2944 vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
2945     size_t *rsz, boolean_t is_spare)
2946 {
2947         char *type;
2948         int ret;
2949
2950         if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
2951                 return (EZFS_INVALCONFIG);
2952
2953         if (strcmp(type, VDEV_TYPE_DISK) == 0) {
2954                 /*
2955                  * An active spare device has ZPOOL_CONFIG_IS_SPARE set.
2956                  * For a spare vdev, we only want to boot from the active
2957                  * spare device.
2958                  */
2959                 if (is_spare) {
2960                         uint64_t spare = 0;
2961                         (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_SPARE,
2962                             &spare);
2963                         if (!spare)
2964                                 return (EZFS_INVALCONFIG);
2965                 }
2966
2967                 if (vdev_is_online(nv)) {
2968                         if ((ret = vdev_get_one_physpath(nv, physpath,
2969                             phypath_size, rsz)) != 0)
2970                                 return (ret);
2971                 }
2972         } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
2973             strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
2974             strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
2975             (is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
2976                 nvlist_t **child;
2977                 uint_t count;
2978                 int i, ret;
2979
2980                 if (nvlist_lookup_nvlist_array(nv,
2981                     ZPOOL_CONFIG_CHILDREN, &child, &count) != 0)
2982                         return (EZFS_INVALCONFIG);
2983
2984                 for (i = 0; i < count; i++) {
2985                         ret = vdev_get_physpaths(child[i], physpath,
2986                             phypath_size, rsz, is_spare);
2987                         if (ret == EZFS_NOSPC)
2988                                 return (ret);
2989                 }
2990         }
2991
2992         return (EZFS_POOL_INVALARG);
2993 }
2994
2995 /*
2996  * Get phys_path for a root pool config.
2997  * Return 0 on success; non-zero on failure.
2998  */
2999 static int
3000 zpool_get_config_physpath(nvlist_t *config, char *physpath, size_t phypath_size)
3001 {
3002         size_t rsz;
3003         nvlist_t *vdev_root;
3004         nvlist_t **child;
3005         uint_t count;
3006         char *type;
3007
3008         rsz = 0;
3009
3010         if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
3011             &vdev_root) != 0)
3012                 return (EZFS_INVALCONFIG);
3013
3014         if (nvlist_lookup_string(vdev_root, ZPOOL_CONFIG_TYPE, &type) != 0 ||
3015             nvlist_lookup_nvlist_array(vdev_root, ZPOOL_CONFIG_CHILDREN,
3016             &child, &count) != 0)
3017                 return (EZFS_INVALCONFIG);
3018
3019         /*
3020          * root pool can only have a single top-level vdev.
3021          */
3022         if (strcmp(type, VDEV_TYPE_ROOT) != 0 || count != 1)
3023                 return (EZFS_POOL_INVALARG);
3024
3025         (void) vdev_get_physpaths(child[0], physpath, phypath_size, &rsz,
3026             B_FALSE);
3027
3028         /* No online devices */
3029         if (rsz == 0)
3030                 return (EZFS_NODEVICE);
3031
3032         return (0);
3033 }
3034
3035 /*
3036  * Get phys_path for a root pool
3037  * Return 0 on success; non-zero on failure.
3038  */
3039 int
3040 zpool_get_physpath(zpool_handle_t *zhp, char *physpath, size_t phypath_size)
3041 {
3042         return (zpool_get_config_physpath(zhp->zpool_config, physpath,
3043             phypath_size));
3044 }
3045
3046 /*
3047  * Convert a vdev path to a GUID.  Returns GUID or 0 on error.
3048  *
3049  * If is_spare, is_l2cache, or is_log is non-NULL, then store within it
3050  * if the VDEV is a spare, l2cache, or log device.  If they're NULL then
3051  * ignore them.
3052  */
3053 static uint64_t
3054 zpool_vdev_path_to_guid_impl(zpool_handle_t *zhp, const char *path,
3055     boolean_t *is_spare, boolean_t *is_l2cache, boolean_t *is_log)
3056 {
3057         boolean_t spare = B_FALSE, l2cache = B_FALSE, log = B_FALSE;
3058         nvlist_t *tgt;
3059
3060         if ((tgt = zpool_find_vdev(zhp, path, &spare, &l2cache,
3061             &log)) == NULL)
3062                 return (0);
3063
3064         if (is_spare != NULL)
3065                 *is_spare = spare;
3066         if (is_l2cache != NULL)
3067                 *is_l2cache = l2cache;
3068         if (is_log != NULL)
3069                 *is_log = log;
3070
3071         return (fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID));
3072 }
3073
3074 /* Convert a vdev path to a GUID.  Returns GUID or 0 on error. */
3075 uint64_t
3076 zpool_vdev_path_to_guid(zpool_handle_t *zhp, const char *path)
3077 {
3078         return (zpool_vdev_path_to_guid_impl(zhp, path, NULL, NULL, NULL));
3079 }
3080
3081 /*
3082  * Bring the specified vdev online.   The 'flags' parameter is a set of the
3083  * ZFS_ONLINE_* flags.
3084  */
3085 int
3086 zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
3087     vdev_state_t *newstate)
3088 {
3089         zfs_cmd_t zc = {"\0"};
3090         char msg[1024];
3091         nvlist_t *tgt;
3092         boolean_t avail_spare, l2cache, islog;
3093         libzfs_handle_t *hdl = zhp->zpool_hdl;
3094
3095         if (flags & ZFS_ONLINE_EXPAND) {
3096                 (void) snprintf(msg, sizeof (msg),
3097                     dgettext(TEXT_DOMAIN, "cannot expand %s"), path);
3098         } else {
3099                 (void) snprintf(msg, sizeof (msg),
3100                     dgettext(TEXT_DOMAIN, "cannot online %s"), path);
3101         }
3102
3103         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3104         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3105             &islog)) == NULL)
3106                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3107
3108         zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3109
3110         if (avail_spare)
3111                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
3112
3113 #ifndef __FreeBSD__
3114         char *pathname;
3115         if ((flags & ZFS_ONLINE_EXPAND ||
3116             zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) &&
3117             nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &pathname) == 0) {
3118                 uint64_t wholedisk = 0;
3119
3120                 (void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
3121                     &wholedisk);
3122
3123                 /*
3124                  * XXX - L2ARC 1.0 devices can't support expansion.
3125                  */
3126                 if (l2cache) {
3127                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3128                             "cannot expand cache devices"));
3129                         return (zfs_error(hdl, EZFS_VDEVNOTSUP, msg));
3130                 }
3131
3132                 if (wholedisk) {
3133                         const char *fullpath = path;
3134                         char buf[MAXPATHLEN];
3135                         int error;
3136
3137                         if (path[0] != '/') {
3138                                 error = zfs_resolve_shortname(path, buf,
3139                                     sizeof (buf));
3140                                 if (error != 0)
3141                                         return (zfs_error(hdl, EZFS_NODEVICE,
3142                                             msg));
3143
3144                                 fullpath = buf;
3145                         }
3146
3147                         error = zpool_relabel_disk(hdl, fullpath, msg);
3148                         if (error != 0)
3149                                 return (error);
3150                 }
3151         }
3152 #endif
3153
3154         zc.zc_cookie = VDEV_STATE_ONLINE;
3155         zc.zc_obj = flags;
3156
3157         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) != 0) {
3158                 if (errno == EINVAL) {
3159                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "was split "
3160                             "from this pool into a new one.  Use '%s' "
3161                             "instead"), "zpool detach");
3162                         return (zfs_error(hdl, EZFS_POSTSPLIT_ONLINE, msg));
3163                 }
3164                 return (zpool_standard_error(hdl, errno, msg));
3165         }
3166
3167         *newstate = zc.zc_cookie;
3168         return (0);
3169 }
3170
3171 /*
3172  * Take the specified vdev offline
3173  */
3174 int
3175 zpool_vdev_offline(zpool_handle_t *zhp, const char *path, boolean_t istmp)
3176 {
3177         zfs_cmd_t zc = {"\0"};
3178         char msg[1024];
3179         nvlist_t *tgt;
3180         boolean_t avail_spare, l2cache;
3181         libzfs_handle_t *hdl = zhp->zpool_hdl;
3182
3183         (void) snprintf(msg, sizeof (msg),
3184             dgettext(TEXT_DOMAIN, "cannot offline %s"), path);
3185
3186         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3187         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3188             NULL)) == NULL)
3189                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3190
3191         zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3192
3193         if (avail_spare)
3194                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
3195
3196         zc.zc_cookie = VDEV_STATE_OFFLINE;
3197         zc.zc_obj = istmp ? ZFS_OFFLINE_TEMPORARY : 0;
3198
3199         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3200                 return (0);
3201
3202         switch (errno) {
3203         case EBUSY:
3204
3205                 /*
3206                  * There are no other replicas of this device.
3207                  */
3208                 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
3209
3210         case EEXIST:
3211                 /*
3212                  * The log device has unplayed logs
3213                  */
3214                 return (zfs_error(hdl, EZFS_UNPLAYED_LOGS, msg));
3215
3216         default:
3217                 return (zpool_standard_error(hdl, errno, msg));
3218         }
3219 }
3220
3221 /*
3222  * Mark the given vdev faulted.
3223  */
3224 int
3225 zpool_vdev_fault(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3226 {
3227         zfs_cmd_t zc = {"\0"};
3228         char msg[1024];
3229         libzfs_handle_t *hdl = zhp->zpool_hdl;
3230
3231         (void) snprintf(msg, sizeof (msg),
3232             dgettext(TEXT_DOMAIN, "cannot fault %llu"), (u_longlong_t)guid);
3233
3234         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3235         zc.zc_guid = guid;
3236         zc.zc_cookie = VDEV_STATE_FAULTED;
3237         zc.zc_obj = aux;
3238
3239         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3240                 return (0);
3241
3242         switch (errno) {
3243         case EBUSY:
3244
3245                 /*
3246                  * There are no other replicas of this device.
3247                  */
3248                 return (zfs_error(hdl, EZFS_NOREPLICAS, msg));
3249
3250         default:
3251                 return (zpool_standard_error(hdl, errno, msg));
3252         }
3253
3254 }
3255
3256 /*
3257  * Mark the given vdev degraded.
3258  */
3259 int
3260 zpool_vdev_degrade(zpool_handle_t *zhp, uint64_t guid, vdev_aux_t aux)
3261 {
3262         zfs_cmd_t zc = {"\0"};
3263         char msg[1024];
3264         libzfs_handle_t *hdl = zhp->zpool_hdl;
3265
3266         (void) snprintf(msg, sizeof (msg),
3267             dgettext(TEXT_DOMAIN, "cannot degrade %llu"), (u_longlong_t)guid);
3268
3269         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3270         zc.zc_guid = guid;
3271         zc.zc_cookie = VDEV_STATE_DEGRADED;
3272         zc.zc_obj = aux;
3273
3274         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
3275                 return (0);
3276
3277         return (zpool_standard_error(hdl, errno, msg));
3278 }
3279
3280 /*
3281  * Returns TRUE if the given nvlist is a vdev that was originally swapped in as
3282  * a hot spare.
3283  */
3284 static boolean_t
3285 is_replacing_spare(nvlist_t *search, nvlist_t *tgt, int which)
3286 {
3287         nvlist_t **child;
3288         uint_t c, children;
3289
3290         if (nvlist_lookup_nvlist_array(search, ZPOOL_CONFIG_CHILDREN, &child,
3291             &children) == 0) {
3292                 char *type = fnvlist_lookup_string(search, ZPOOL_CONFIG_TYPE);
3293                 if ((strcmp(type, VDEV_TYPE_SPARE) == 0 ||
3294                     strcmp(type, VDEV_TYPE_DRAID_SPARE) == 0) &&
3295                     children == 2 && child[which] == tgt)
3296                         return (B_TRUE);
3297
3298                 for (c = 0; c < children; c++)
3299                         if (is_replacing_spare(child[c], tgt, which))
3300                                 return (B_TRUE);
3301         }
3302
3303         return (B_FALSE);
3304 }
3305
3306 /*
3307  * Attach new_disk (fully described by nvroot) to old_disk.
3308  * If 'replacing' is specified, the new disk will replace the old one.
3309  */
3310 int
3311 zpool_vdev_attach(zpool_handle_t *zhp, const char *old_disk,
3312     const char *new_disk, nvlist_t *nvroot, int replacing, boolean_t rebuild)
3313 {
3314         zfs_cmd_t zc = {"\0"};
3315         char msg[1024];
3316         int ret;
3317         nvlist_t *tgt;
3318         boolean_t avail_spare, l2cache, islog;
3319         uint64_t val;
3320         char *newname;
3321         nvlist_t **child;
3322         uint_t children;
3323         nvlist_t *config_root;
3324         libzfs_handle_t *hdl = zhp->zpool_hdl;
3325
3326         if (replacing)
3327                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
3328                     "cannot replace %s with %s"), old_disk, new_disk);
3329         else
3330                 (void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
3331                     "cannot attach %s to %s"), new_disk, old_disk);
3332
3333         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3334         if ((tgt = zpool_find_vdev(zhp, old_disk, &avail_spare, &l2cache,
3335             &islog)) == NULL)
3336                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3337
3338         if (avail_spare)
3339                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
3340
3341         if (l2cache)
3342                 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
3343
3344         zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3345         zc.zc_cookie = replacing;
3346         zc.zc_simple = rebuild;
3347
3348         if (rebuild &&
3349             zfeature_lookup_guid("org.openzfs:device_rebuild", NULL) != 0) {
3350                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3351                     "the loaded zfs module doesn't support device rebuilds"));
3352                 return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
3353         }
3354
3355         if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
3356             &child, &children) != 0 || children != 1) {
3357                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3358                     "new device must be a single disk"));
3359                 return (zfs_error(hdl, EZFS_INVALCONFIG, msg));
3360         }
3361
3362         config_root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
3363             ZPOOL_CONFIG_VDEV_TREE);
3364
3365         if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL)
3366                 return (-1);
3367
3368         /*
3369          * If the target is a hot spare that has been swapped in, we can only
3370          * replace it with another hot spare.
3371          */
3372         if (replacing &&
3373             nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_IS_SPARE, &val) == 0 &&
3374             (zpool_find_vdev(zhp, newname, &avail_spare, &l2cache,
3375             NULL) == NULL || !avail_spare) &&
3376             is_replacing_spare(config_root, tgt, 1)) {
3377                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3378                     "can only be replaced by another hot spare"));
3379                 free(newname);
3380                 return (zfs_error(hdl, EZFS_BADTARGET, msg));
3381         }
3382
3383         free(newname);
3384
3385         zcmd_write_conf_nvlist(hdl, &zc, nvroot);
3386
3387         ret = zfs_ioctl(hdl, ZFS_IOC_VDEV_ATTACH, &zc);
3388
3389         zcmd_free_nvlists(&zc);
3390
3391         if (ret == 0)
3392                 return (0);
3393
3394         switch (errno) {
3395         case ENOTSUP:
3396                 /*
3397                  * Can't attach to or replace this type of vdev.
3398                  */
3399                 if (replacing) {
3400                         uint64_t version = zpool_get_prop_int(zhp,
3401                             ZPOOL_PROP_VERSION, NULL);
3402
3403                         if (islog) {
3404                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3405                                     "cannot replace a log with a spare"));
3406                         } else if (rebuild) {
3407                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3408                                     "only mirror and dRAID vdevs support "
3409                                     "sequential reconstruction"));
3410                         } else if (zpool_is_draid_spare(new_disk)) {
3411                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3412                                     "dRAID spares can only replace child "
3413                                     "devices in their parent's dRAID vdev"));
3414                         } else if (version >= SPA_VERSION_MULTI_REPLACE) {
3415                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3416                                     "already in replacing/spare config; wait "
3417                                     "for completion or use 'zpool detach'"));
3418                         } else {
3419                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3420                                     "cannot replace a replacing device"));
3421                         }
3422                 } else {
3423                         char status[64] = {0};
3424                         zpool_prop_get_feature(zhp,
3425                             "feature@device_rebuild", status, 63);
3426                         if (rebuild &&
3427                             strncmp(status, ZFS_FEATURE_DISABLED, 64) == 0) {
3428                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3429                                     "device_rebuild feature must be enabled "
3430                                     "in order to use sequential "
3431                                     "reconstruction"));
3432                         } else {
3433                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3434                                     "can only attach to mirrors and top-level "
3435                                     "disks"));
3436                         }
3437                 }
3438                 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
3439                 break;
3440
3441         case EINVAL:
3442                 /*
3443                  * The new device must be a single disk.
3444                  */
3445                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3446                     "new device must be a single disk"));
3447                 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
3448                 break;
3449
3450         case EBUSY:
3451                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "%s is busy, "
3452                     "or device removal is in progress"),
3453                     new_disk);
3454                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
3455                 break;
3456
3457         case EOVERFLOW:
3458                 /*
3459                  * The new device is too small.
3460                  */
3461                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3462                     "device is too small"));
3463                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
3464                 break;
3465
3466         case EDOM:
3467                 /*
3468                  * The new device has a different optimal sector size.
3469                  */
3470                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3471                     "new device has a different optimal sector size; use the "
3472                     "option '-o ashift=N' to override the optimal size"));
3473                 (void) zfs_error(hdl, EZFS_BADDEV, msg);
3474                 break;
3475
3476         case ENAMETOOLONG:
3477                 /*
3478                  * The resulting top-level vdev spec won't fit in the label.
3479                  */
3480                 (void) zfs_error(hdl, EZFS_DEVOVERFLOW, msg);
3481                 break;
3482
3483         default:
3484                 (void) zpool_standard_error(hdl, errno, msg);
3485         }
3486
3487         return (-1);
3488 }
3489
3490 /*
3491  * Detach the specified device.
3492  */
3493 int
3494 zpool_vdev_detach(zpool_handle_t *zhp, const char *path)
3495 {
3496         zfs_cmd_t zc = {"\0"};
3497         char msg[1024];
3498         nvlist_t *tgt;
3499         boolean_t avail_spare, l2cache;
3500         libzfs_handle_t *hdl = zhp->zpool_hdl;
3501
3502         (void) snprintf(msg, sizeof (msg),
3503             dgettext(TEXT_DOMAIN, "cannot detach %s"), path);
3504
3505         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3506         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3507             NULL)) == NULL)
3508                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3509
3510         if (avail_spare)
3511                 return (zfs_error(hdl, EZFS_ISSPARE, msg));
3512
3513         if (l2cache)
3514                 return (zfs_error(hdl, EZFS_ISL2CACHE, msg));
3515
3516         zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3517
3518         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_DETACH, &zc) == 0)
3519                 return (0);
3520
3521         switch (errno) {
3522
3523         case ENOTSUP:
3524                 /*
3525                  * Can't detach from this type of vdev.
3526                  */
3527                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only "
3528                     "applicable to mirror and replacing vdevs"));
3529                 (void) zfs_error(hdl, EZFS_BADTARGET, msg);
3530                 break;
3531
3532         case EBUSY:
3533                 /*
3534                  * There are no other replicas of this device.
3535                  */
3536                 (void) zfs_error(hdl, EZFS_NOREPLICAS, msg);
3537                 break;
3538
3539         default:
3540                 (void) zpool_standard_error(hdl, errno, msg);
3541         }
3542
3543         return (-1);
3544 }
3545
3546 /*
3547  * Find a mirror vdev in the source nvlist.
3548  *
3549  * The mchild array contains a list of disks in one of the top-level mirrors
3550  * of the source pool.  The schild array contains a list of disks that the
3551  * user specified on the command line.  We loop over the mchild array to
3552  * see if any entry in the schild array matches.
3553  *
3554  * If a disk in the mchild array is found in the schild array, we return
3555  * the index of that entry.  Otherwise we return -1.
3556  */
3557 static int
3558 find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
3559     nvlist_t **schild, uint_t schildren)
3560 {
3561         uint_t mc;
3562
3563         for (mc = 0; mc < mchildren; mc++) {
3564                 uint_t sc;
3565                 char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
3566                     mchild[mc], 0);
3567
3568                 for (sc = 0; sc < schildren; sc++) {
3569                         char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
3570                             schild[sc], 0);
3571                         boolean_t result = (strcmp(mpath, spath) == 0);
3572
3573                         free(spath);
3574                         if (result) {
3575                                 free(mpath);
3576                                 return (mc);
3577                         }
3578                 }
3579
3580                 free(mpath);
3581         }
3582
3583         return (-1);
3584 }
3585
3586 /*
3587  * Split a mirror pool.  If newroot points to null, then a new nvlist
3588  * is generated and it is the responsibility of the caller to free it.
3589  */
3590 int
3591 zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
3592     nvlist_t *props, splitflags_t flags)
3593 {
3594         zfs_cmd_t zc = {"\0"};
3595         char msg[1024], *bias;
3596         nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
3597         nvlist_t **varray = NULL, *zc_props = NULL;
3598         uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
3599         libzfs_handle_t *hdl = zhp->zpool_hdl;
3600         uint64_t vers, readonly = B_FALSE;
3601         boolean_t freelist = B_FALSE, memory_err = B_TRUE;
3602         int retval = 0;
3603
3604         (void) snprintf(msg, sizeof (msg),
3605             dgettext(TEXT_DOMAIN, "Unable to split %s"), zhp->zpool_name);
3606
3607         if (!zpool_name_valid(hdl, B_FALSE, newname))
3608                 return (zfs_error(hdl, EZFS_INVALIDNAME, msg));
3609
3610         if ((config = zpool_get_config(zhp, NULL)) == NULL) {
3611                 (void) fprintf(stderr, gettext("Internal error: unable to "
3612                     "retrieve pool configuration\n"));
3613                 return (-1);
3614         }
3615
3616         tree = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE);
3617         vers = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
3618
3619         if (props) {
3620                 prop_flags_t flags = { .create = B_FALSE, .import = B_TRUE };
3621                 if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
3622                     props, vers, flags, msg)) == NULL)
3623                         return (-1);
3624                 (void) nvlist_lookup_uint64(zc_props,
3625                     zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly);
3626                 if (readonly) {
3627                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3628                             "property %s can only be set at import time"),
3629                             zpool_prop_to_name(ZPOOL_PROP_READONLY));
3630                         return (-1);
3631                 }
3632         }
3633
3634         if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
3635             &children) != 0) {
3636                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3637                     "Source pool is missing vdev tree"));
3638                 nvlist_free(zc_props);
3639                 return (-1);
3640         }
3641
3642         varray = zfs_alloc(hdl, children * sizeof (nvlist_t *));
3643         vcount = 0;
3644
3645         if (*newroot == NULL ||
3646             nvlist_lookup_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
3647             &newchild, &newchildren) != 0)
3648                 newchildren = 0;
3649
3650         for (c = 0; c < children; c++) {
3651                 uint64_t is_log = B_FALSE, is_hole = B_FALSE;
3652                 boolean_t is_special = B_FALSE, is_dedup = B_FALSE;
3653                 char *type;
3654                 nvlist_t **mchild, *vdev;
3655                 uint_t mchildren;
3656                 int entry;
3657
3658                 /*
3659                  * Unlike cache & spares, slogs are stored in the
3660                  * ZPOOL_CONFIG_CHILDREN array.  We filter them out here.
3661                  */
3662                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
3663                     &is_log);
3664                 (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
3665                     &is_hole);
3666                 if (is_log || is_hole) {
3667                         /*
3668                          * Create a hole vdev and put it in the config.
3669                          */
3670                         if (nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) != 0)
3671                                 goto out;
3672                         if (nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE,
3673                             VDEV_TYPE_HOLE) != 0)
3674                                 goto out;
3675                         if (nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_HOLE,
3676                             1) != 0)
3677                                 goto out;
3678                         if (lastlog == 0)
3679                                 lastlog = vcount;
3680                         varray[vcount++] = vdev;
3681                         continue;
3682                 }
3683                 lastlog = 0;
3684                 type = fnvlist_lookup_string(child[c], ZPOOL_CONFIG_TYPE);
3685
3686                 if (strcmp(type, VDEV_TYPE_INDIRECT) == 0) {
3687                         vdev = child[c];
3688                         if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
3689                                 goto out;
3690                         continue;
3691                 } else if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
3692                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3693                             "Source pool must be composed only of mirrors\n"));
3694                         retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
3695                         goto out;
3696                 }
3697
3698                 if (nvlist_lookup_string(child[c],
3699                     ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0) {
3700                         if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0)
3701                                 is_special = B_TRUE;
3702                         else if (strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0)
3703                                 is_dedup = B_TRUE;
3704                 }
3705                 verify(nvlist_lookup_nvlist_array(child[c],
3706                     ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
3707
3708                 /* find or add an entry for this top-level vdev */
3709                 if (newchildren > 0 &&
3710                     (entry = find_vdev_entry(zhp, mchild, mchildren,
3711                     newchild, newchildren)) >= 0) {
3712                         /* We found a disk that the user specified. */
3713                         vdev = mchild[entry];
3714                         ++found;
3715                 } else {
3716                         /* User didn't specify a disk for this vdev. */
3717                         vdev = mchild[mchildren - 1];
3718                 }
3719
3720                 if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
3721                         goto out;
3722
3723                 if (flags.dryrun != 0) {
3724                         if (is_dedup == B_TRUE) {
3725                                 if (nvlist_add_string(varray[vcount - 1],
3726                                     ZPOOL_CONFIG_ALLOCATION_BIAS,
3727                                     VDEV_ALLOC_BIAS_DEDUP) != 0)
3728                                         goto out;
3729                         } else if (is_special == B_TRUE) {
3730                                 if (nvlist_add_string(varray[vcount - 1],
3731                                     ZPOOL_CONFIG_ALLOCATION_BIAS,
3732                                     VDEV_ALLOC_BIAS_SPECIAL) != 0)
3733                                         goto out;
3734                         }
3735                 }
3736         }
3737
3738         /* did we find every disk the user specified? */
3739         if (found != newchildren) {
3740                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "Device list must "
3741                     "include at most one disk from each mirror"));
3742                 retval = zfs_error(hdl, EZFS_INVALCONFIG, msg);
3743                 goto out;
3744         }
3745
3746         /* Prepare the nvlist for populating. */
3747         if (*newroot == NULL) {
3748                 if (nvlist_alloc(newroot, NV_UNIQUE_NAME, 0) != 0)
3749                         goto out;
3750                 freelist = B_TRUE;
3751                 if (nvlist_add_string(*newroot, ZPOOL_CONFIG_TYPE,
3752                     VDEV_TYPE_ROOT) != 0)
3753                         goto out;
3754         } else {
3755                 verify(nvlist_remove_all(*newroot, ZPOOL_CONFIG_CHILDREN) == 0);
3756         }
3757
3758         /* Add all the children we found */
3759         if (nvlist_add_nvlist_array(*newroot, ZPOOL_CONFIG_CHILDREN,
3760             (const nvlist_t **)varray, lastlog == 0 ? vcount : lastlog) != 0)
3761                 goto out;
3762
3763         /*
3764          * If we're just doing a dry run, exit now with success.
3765          */
3766         if (flags.dryrun) {
3767                 memory_err = B_FALSE;
3768                 freelist = B_FALSE;
3769                 goto out;
3770         }
3771
3772         /* now build up the config list & call the ioctl */
3773         if (nvlist_alloc(&newconfig, NV_UNIQUE_NAME, 0) != 0)
3774                 goto out;
3775
3776         if (nvlist_add_nvlist(newconfig,
3777             ZPOOL_CONFIG_VDEV_TREE, *newroot) != 0 ||
3778             nvlist_add_string(newconfig,
3779             ZPOOL_CONFIG_POOL_NAME, newname) != 0 ||
3780             nvlist_add_uint64(newconfig, ZPOOL_CONFIG_VERSION, vers) != 0)
3781                 goto out;
3782
3783         /*
3784          * The new pool is automatically part of the namespace unless we
3785          * explicitly export it.
3786          */
3787         if (!flags.import)
3788                 zc.zc_cookie = ZPOOL_EXPORT_AFTER_SPLIT;
3789         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3790         (void) strlcpy(zc.zc_string, newname, sizeof (zc.zc_string));
3791         zcmd_write_conf_nvlist(hdl, &zc, newconfig);
3792         if (zc_props != NULL)
3793                 zcmd_write_src_nvlist(hdl, &zc, zc_props);
3794
3795         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SPLIT, &zc) != 0) {
3796                 retval = zpool_standard_error(hdl, errno, msg);
3797                 goto out;
3798         }
3799
3800         freelist = B_FALSE;
3801         memory_err = B_FALSE;
3802
3803 out:
3804         if (varray != NULL) {
3805                 int v;
3806
3807                 for (v = 0; v < vcount; v++)
3808                         nvlist_free(varray[v]);
3809                 free(varray);
3810         }
3811         zcmd_free_nvlists(&zc);
3812         nvlist_free(zc_props);
3813         nvlist_free(newconfig);
3814         if (freelist) {
3815                 nvlist_free(*newroot);
3816                 *newroot = NULL;
3817         }
3818
3819         if (retval != 0)
3820                 return (retval);
3821
3822         if (memory_err)
3823                 return (no_memory(hdl));
3824
3825         return (0);
3826 }
3827
3828 /*
3829  * Remove the given device.
3830  */
3831 int
3832 zpool_vdev_remove(zpool_handle_t *zhp, const char *path)
3833 {
3834         zfs_cmd_t zc = {"\0"};
3835         char msg[1024];
3836         nvlist_t *tgt;
3837         boolean_t avail_spare, l2cache, islog;
3838         libzfs_handle_t *hdl = zhp->zpool_hdl;
3839         uint64_t version;
3840
3841         (void) snprintf(msg, sizeof (msg),
3842             dgettext(TEXT_DOMAIN, "cannot remove %s"), path);
3843
3844         if (zpool_is_draid_spare(path)) {
3845                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3846                     "dRAID spares cannot be removed"));
3847                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3848         }
3849
3850         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3851         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3852             &islog)) == NULL)
3853                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3854
3855         version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
3856         if (islog && version < SPA_VERSION_HOLES) {
3857                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3858                     "pool must be upgraded to support log removal"));
3859                 return (zfs_error(hdl, EZFS_BADVERSION, msg));
3860         }
3861
3862         zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3863
3864         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
3865                 return (0);
3866
3867         switch (errno) {
3868
3869         case EINVAL:
3870                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3871                     "invalid config; all top-level vdevs must "
3872                     "have the same sector size and not be raidz."));
3873                 (void) zfs_error(hdl, EZFS_INVALCONFIG, msg);
3874                 break;
3875
3876         case EBUSY:
3877                 if (islog) {
3878                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3879                             "Mount encrypted datasets to replay logs."));
3880                 } else {
3881                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3882                             "Pool busy; removal may already be in progress"));
3883                 }
3884                 (void) zfs_error(hdl, EZFS_BUSY, msg);
3885                 break;
3886
3887         case EACCES:
3888                 if (islog) {
3889                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3890                             "Mount encrypted datasets to replay logs."));
3891                         (void) zfs_error(hdl, EZFS_BUSY, msg);
3892                 } else {
3893                         (void) zpool_standard_error(hdl, errno, msg);
3894                 }
3895                 break;
3896
3897         default:
3898                 (void) zpool_standard_error(hdl, errno, msg);
3899         }
3900         return (-1);
3901 }
3902
3903 int
3904 zpool_vdev_remove_cancel(zpool_handle_t *zhp)
3905 {
3906         zfs_cmd_t zc = {{0}};
3907         char msg[1024];
3908         libzfs_handle_t *hdl = zhp->zpool_hdl;
3909
3910         (void) snprintf(msg, sizeof (msg),
3911             dgettext(TEXT_DOMAIN, "cannot cancel removal"));
3912
3913         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3914         zc.zc_cookie = 1;
3915
3916         if (zfs_ioctl(hdl, ZFS_IOC_VDEV_REMOVE, &zc) == 0)
3917                 return (0);
3918
3919         return (zpool_standard_error(hdl, errno, msg));
3920 }
3921
3922 int
3923 zpool_vdev_indirect_size(zpool_handle_t *zhp, const char *path,
3924     uint64_t *sizep)
3925 {
3926         char msg[1024];
3927         nvlist_t *tgt;
3928         boolean_t avail_spare, l2cache, islog;
3929         libzfs_handle_t *hdl = zhp->zpool_hdl;
3930
3931         (void) snprintf(msg, sizeof (msg),
3932             dgettext(TEXT_DOMAIN, "cannot determine indirect size of %s"),
3933             path);
3934
3935         if ((tgt = zpool_find_vdev(zhp, path, &avail_spare, &l2cache,
3936             &islog)) == NULL)
3937                 return (zfs_error(hdl, EZFS_NODEVICE, msg));
3938
3939         if (avail_spare || l2cache || islog) {
3940                 *sizep = 0;
3941                 return (0);
3942         }
3943
3944         if (nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_INDIRECT_SIZE, sizep) != 0) {
3945                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3946                     "indirect size not available"));
3947                 return (zfs_error(hdl, EINVAL, msg));
3948         }
3949         return (0);
3950 }
3951
3952 /*
3953  * Clear the errors for the pool, or the particular device if specified.
3954  */
3955 int
3956 zpool_clear(zpool_handle_t *zhp, const char *path, nvlist_t *rewindnvl)
3957 {
3958         zfs_cmd_t zc = {"\0"};
3959         char msg[1024];
3960         nvlist_t *tgt;
3961         zpool_load_policy_t policy;
3962         boolean_t avail_spare, l2cache;
3963         libzfs_handle_t *hdl = zhp->zpool_hdl;
3964         nvlist_t *nvi = NULL;
3965         int error;
3966
3967         if (path)
3968                 (void) snprintf(msg, sizeof (msg),
3969                     dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
3970                     path);
3971         else
3972                 (void) snprintf(msg, sizeof (msg),
3973                     dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
3974                     zhp->zpool_name);
3975
3976         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
3977         if (path) {
3978                 if ((tgt = zpool_find_vdev(zhp, path, &avail_spare,
3979                     &l2cache, NULL)) == NULL)
3980                         return (zfs_error(hdl, EZFS_NODEVICE, msg));
3981
3982                 /*
3983                  * Don't allow error clearing for hot spares.  Do allow
3984                  * error clearing for l2cache devices.
3985                  */
3986                 if (avail_spare)
3987                         return (zfs_error(hdl, EZFS_ISSPARE, msg));
3988
3989                 zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
3990         }
3991
3992         zpool_get_load_policy(rewindnvl, &policy);
3993         zc.zc_cookie = policy.zlp_rewind;
3994
3995         zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size * 2);
3996         zcmd_write_src_nvlist(hdl, &zc, rewindnvl);
3997
3998         while ((error = zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc)) != 0 &&
3999             errno == ENOMEM)
4000                 zcmd_expand_dst_nvlist(hdl, &zc);
4001
4002         if (!error || ((policy.zlp_rewind & ZPOOL_TRY_REWIND) &&
4003             errno != EPERM && errno != EACCES)) {
4004                 if (policy.zlp_rewind &
4005                     (ZPOOL_DO_REWIND | ZPOOL_TRY_REWIND)) {
4006                         (void) zcmd_read_dst_nvlist(hdl, &zc, &nvi);
4007                         zpool_rewind_exclaim(hdl, zc.zc_name,
4008                             ((policy.zlp_rewind & ZPOOL_TRY_REWIND) != 0),
4009                             nvi);
4010                         nvlist_free(nvi);
4011                 }
4012                 zcmd_free_nvlists(&zc);
4013                 return (0);
4014         }
4015
4016         zcmd_free_nvlists(&zc);
4017         return (zpool_standard_error(hdl, errno, msg));
4018 }
4019
4020 /*
4021  * Similar to zpool_clear(), but takes a GUID (used by fmd).
4022  */
4023 int
4024 zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
4025 {
4026         zfs_cmd_t zc = {"\0"};
4027         char msg[1024];
4028         libzfs_handle_t *hdl = zhp->zpool_hdl;
4029
4030         (void) snprintf(msg, sizeof (msg),
4031             dgettext(TEXT_DOMAIN, "cannot clear errors for %llx"),
4032             (u_longlong_t)guid);
4033
4034         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4035         zc.zc_guid = guid;
4036         zc.zc_cookie = ZPOOL_NO_REWIND;
4037
4038         if (zfs_ioctl(hdl, ZFS_IOC_CLEAR, &zc) == 0)
4039                 return (0);
4040
4041         return (zpool_standard_error(hdl, errno, msg));
4042 }
4043
4044 /*
4045  * Change the GUID for a pool.
4046  */
4047 int
4048 zpool_reguid(zpool_handle_t *zhp)
4049 {
4050         char msg[1024];
4051         libzfs_handle_t *hdl = zhp->zpool_hdl;
4052         zfs_cmd_t zc = {"\0"};
4053
4054         (void) snprintf(msg, sizeof (msg),
4055             dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
4056
4057         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4058         if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0)
4059                 return (0);
4060
4061         return (zpool_standard_error(hdl, errno, msg));
4062 }
4063
4064 /*
4065  * Reopen the pool.
4066  */
4067 int
4068 zpool_reopen_one(zpool_handle_t *zhp, void *data)
4069 {
4070         libzfs_handle_t *hdl = zpool_get_handle(zhp);
4071         const char *pool_name = zpool_get_name(zhp);
4072         boolean_t *scrub_restart = data;
4073         int error;
4074
4075         error = lzc_reopen(pool_name, *scrub_restart);
4076         if (error) {
4077                 return (zpool_standard_error_fmt(hdl, error,
4078                     dgettext(TEXT_DOMAIN, "cannot reopen '%s'"), pool_name));
4079         }
4080
4081         return (0);
4082 }
4083
4084 /* call into libzfs_core to execute the sync IOCTL per pool */
4085 int
4086 zpool_sync_one(zpool_handle_t *zhp, void *data)
4087 {
4088         int ret;
4089         libzfs_handle_t *hdl = zpool_get_handle(zhp);
4090         const char *pool_name = zpool_get_name(zhp);
4091         boolean_t *force = data;
4092         nvlist_t *innvl = fnvlist_alloc();
4093
4094         fnvlist_add_boolean_value(innvl, "force", *force);
4095         if ((ret = lzc_sync(pool_name, innvl, NULL)) != 0) {
4096                 nvlist_free(innvl);
4097                 return (zpool_standard_error_fmt(hdl, ret,
4098                     dgettext(TEXT_DOMAIN, "sync '%s' failed"), pool_name));
4099         }
4100         nvlist_free(innvl);
4101
4102         return (0);
4103 }
4104
4105 #define PATH_BUF_LEN    64
4106
4107 /*
4108  * Given a vdev, return the name to display in iostat.  If the vdev has a path,
4109  * we use that, stripping off any leading "/dev/dsk/"; if not, we use the type.
4110  * We also check if this is a whole disk, in which case we strip off the
4111  * trailing 's0' slice name.
4112  *
4113  * This routine is also responsible for identifying when disks have been
4114  * reconfigured in a new location.  The kernel will have opened the device by
4115  * devid, but the path will still refer to the old location.  To catch this, we
4116  * first do a path -> devid translation (which is fast for the common case).  If
4117  * the devid matches, we're done.  If not, we do a reverse devid -> path
4118  * translation and issue the appropriate ioctl() to update the path of the vdev.
4119  * If 'zhp' is NULL, then this is an exported pool, and we don't need to do any
4120  * of these checks.
4121  */
4122 char *
4123 zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
4124     int name_flags)
4125 {
4126         char *type, *tpath;
4127         const char *path;
4128         uint64_t value;
4129         char buf[PATH_BUF_LEN];
4130         char tmpbuf[PATH_BUF_LEN * 2];
4131
4132         /*
4133          * vdev_name will be "root"/"root-0" for the root vdev, but it is the
4134          * zpool name that will be displayed to the user.
4135          */
4136         type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE);
4137         if (zhp != NULL && strcmp(type, "root") == 0)
4138                 return (zfs_strdup(hdl, zpool_get_name(zhp)));
4139
4140         if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_PATH"))
4141                 name_flags |= VDEV_NAME_PATH;
4142         if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_GUID"))
4143                 name_flags |= VDEV_NAME_GUID;
4144         if (libzfs_envvar_is_set("ZPOOL_VDEV_NAME_FOLLOW_LINKS"))
4145                 name_flags |= VDEV_NAME_FOLLOW_LINKS;
4146
4147         if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
4148             name_flags & VDEV_NAME_GUID) {
4149                 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
4150                 (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
4151                 path = buf;
4152         } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &tpath) == 0) {
4153                 path = tpath;
4154
4155                 if (name_flags & VDEV_NAME_FOLLOW_LINKS) {
4156                         char *rp = realpath(path, NULL);
4157                         if (rp) {
4158                                 strlcpy(buf, rp, sizeof (buf));
4159                                 path = buf;
4160                                 free(rp);
4161                         }
4162                 }
4163
4164                 /*
4165                  * For a block device only use the name.
4166                  */
4167                 if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
4168                     !(name_flags & VDEV_NAME_PATH)) {
4169                         path = zfs_strip_path(path);
4170                 }
4171
4172                 /*
4173                  * Remove the partition from the path if this is a whole disk.
4174                  */
4175                 if (strcmp(type, VDEV_TYPE_DRAID_SPARE) != 0 &&
4176                     nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
4177                     == 0 && value && !(name_flags & VDEV_NAME_PATH)) {
4178                         return (zfs_strip_partition(path));
4179                 }
4180         } else {
4181                 path = type;
4182
4183                 /*
4184                  * If it's a raidz device, we need to stick in the parity level.
4185                  */
4186                 if (strcmp(path, VDEV_TYPE_RAIDZ) == 0) {
4187                         value = fnvlist_lookup_uint64(nv, ZPOOL_CONFIG_NPARITY);
4188                         (void) snprintf(buf, sizeof (buf), "%s%llu", path,
4189                             (u_longlong_t)value);
4190                         path = buf;
4191                 }
4192
4193                 /*
4194                  * If it's a dRAID device, we add parity, groups, and spares.
4195                  */
4196                 if (strcmp(path, VDEV_TYPE_DRAID) == 0) {
4197                         uint64_t ndata, nparity, nspares;
4198                         nvlist_t **child;
4199                         uint_t children;
4200
4201                         verify(nvlist_lookup_nvlist_array(nv,
4202                             ZPOOL_CONFIG_CHILDREN, &child, &children) == 0);
4203                         nparity = fnvlist_lookup_uint64(nv,
4204                             ZPOOL_CONFIG_NPARITY);
4205                         ndata = fnvlist_lookup_uint64(nv,
4206                             ZPOOL_CONFIG_DRAID_NDATA);
4207                         nspares = fnvlist_lookup_uint64(nv,
4208                             ZPOOL_CONFIG_DRAID_NSPARES);
4209
4210                         path = zpool_draid_name(buf, sizeof (buf), ndata,
4211                             nparity, nspares, children);
4212                 }
4213
4214                 /*
4215                  * We identify each top-level vdev by using a <type-id>
4216                  * naming convention.
4217                  */
4218                 if (name_flags & VDEV_NAME_TYPE_ID) {
4219                         uint64_t id = fnvlist_lookup_uint64(nv,
4220                             ZPOOL_CONFIG_ID);
4221                         (void) snprintf(tmpbuf, sizeof (tmpbuf), "%s-%llu",
4222                             path, (u_longlong_t)id);
4223                         path = tmpbuf;
4224                 }
4225         }
4226
4227         return (zfs_strdup(hdl, path));
4228 }
4229
4230 static int
4231 zbookmark_mem_compare(const void *a, const void *b)
4232 {
4233         return (memcmp(a, b, sizeof (zbookmark_phys_t)));
4234 }
4235
4236 /*
4237  * Retrieve the persistent error log, uniquify the members, and return to the
4238  * caller.
4239  */
4240 int
4241 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
4242 {
4243         zfs_cmd_t zc = {"\0"};
4244         libzfs_handle_t *hdl = zhp->zpool_hdl;
4245         uint64_t count;
4246         zbookmark_phys_t *zb = NULL;
4247         int i;
4248
4249         /*
4250          * Retrieve the raw error list from the kernel.  If the number of errors
4251          * has increased, allocate more space and continue until we get the
4252          * entire list.
4253          */
4254         count = fnvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT);
4255         if (count == 0)
4256                 return (0);
4257         zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
4258             count * sizeof (zbookmark_phys_t));
4259         zc.zc_nvlist_dst_size = count;
4260         (void) strcpy(zc.zc_name, zhp->zpool_name);
4261         for (;;) {
4262                 if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_ERROR_LOG,
4263                     &zc) != 0) {
4264                         free((void *)(uintptr_t)zc.zc_nvlist_dst);
4265                         if (errno == ENOMEM) {
4266                                 void *dst;
4267
4268                                 count = zc.zc_nvlist_dst_size;
4269                                 dst = zfs_alloc(zhp->zpool_hdl, count *
4270                                     sizeof (zbookmark_phys_t));
4271                                 zc.zc_nvlist_dst = (uintptr_t)dst;
4272                         } else {
4273                                 return (zpool_standard_error_fmt(hdl, errno,
4274                                     dgettext(TEXT_DOMAIN, "errors: List of "
4275                                     "errors unavailable")));
4276                         }
4277                 } else {
4278                         break;
4279                 }
4280         }
4281
4282         /*
4283          * Sort the resulting bookmarks.  This is a little confusing due to the
4284          * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
4285          * to first, and 'zc_nvlist_dst_size' indicates the number of bookmarks
4286          * _not_ copied as part of the process.  So we point the start of our
4287          * array appropriate and decrement the total number of elements.
4288          */
4289         zb = ((zbookmark_phys_t *)(uintptr_t)zc.zc_nvlist_dst) +
4290             zc.zc_nvlist_dst_size;
4291         count -= zc.zc_nvlist_dst_size;
4292
4293         qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
4294
4295         verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
4296
4297         /*
4298          * Fill in the nverrlistp with nvlist's of dataset and object numbers.
4299          */
4300         for (i = 0; i < count; i++) {
4301                 nvlist_t *nv;
4302
4303                 /* ignoring zb_blkid and zb_level for now */
4304                 if (i > 0 && zb[i-1].zb_objset == zb[i].zb_objset &&
4305                     zb[i-1].zb_object == zb[i].zb_object)
4306                         continue;
4307
4308                 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) != 0)
4309                         goto nomem;
4310                 if (nvlist_add_uint64(nv, ZPOOL_ERR_DATASET,
4311                     zb[i].zb_objset) != 0) {
4312                         nvlist_free(nv);
4313                         goto nomem;
4314                 }
4315                 if (nvlist_add_uint64(nv, ZPOOL_ERR_OBJECT,
4316                     zb[i].zb_object) != 0) {
4317                         nvlist_free(nv);
4318                         goto nomem;
4319                 }
4320                 if (nvlist_add_nvlist(*nverrlistp, "ejk", nv) != 0) {
4321                         nvlist_free(nv);
4322                         goto nomem;
4323                 }
4324                 nvlist_free(nv);
4325         }
4326
4327         free((void *)(uintptr_t)zc.zc_nvlist_dst);
4328         return (0);
4329
4330 nomem:
4331         free((void *)(uintptr_t)zc.zc_nvlist_dst);
4332         return (no_memory(zhp->zpool_hdl));
4333 }
4334
4335 /*
4336  * Upgrade a ZFS pool to the latest on-disk version.
4337  */
4338 int
4339 zpool_upgrade(zpool_handle_t *zhp, uint64_t new_version)
4340 {
4341         zfs_cmd_t zc = {"\0"};
4342         libzfs_handle_t *hdl = zhp->zpool_hdl;
4343
4344         (void) strcpy(zc.zc_name, zhp->zpool_name);
4345         zc.zc_cookie = new_version;
4346
4347         if (zfs_ioctl(hdl, ZFS_IOC_POOL_UPGRADE, &zc) != 0)
4348                 return (zpool_standard_error_fmt(hdl, errno,
4349                     dgettext(TEXT_DOMAIN, "cannot upgrade '%s'"),
4350                     zhp->zpool_name));
4351         return (0);
4352 }
4353
4354 void
4355 zfs_save_arguments(int argc, char **argv, char *string, int len)
4356 {
4357         int i;
4358
4359         (void) strlcpy(string, zfs_basename(argv[0]), len);
4360         for (i = 1; i < argc; i++) {
4361                 (void) strlcat(string, " ", len);
4362                 (void) strlcat(string, argv[i], len);
4363         }
4364 }
4365
4366 int
4367 zpool_log_history(libzfs_handle_t *hdl, const char *message)
4368 {
4369         zfs_cmd_t zc = {"\0"};
4370         nvlist_t *args;
4371
4372         args = fnvlist_alloc();
4373         fnvlist_add_string(args, "message", message);
4374         zcmd_write_src_nvlist(hdl, &zc, args);
4375         int err = zfs_ioctl(hdl, ZFS_IOC_LOG_HISTORY, &zc);
4376         nvlist_free(args);
4377         zcmd_free_nvlists(&zc);
4378         return (err);
4379 }
4380
4381 /*
4382  * Perform ioctl to get some command history of a pool.
4383  *
4384  * 'buf' is the buffer to fill up to 'len' bytes.  'off' is the
4385  * logical offset of the history buffer to start reading from.
4386  *
4387  * Upon return, 'off' is the next logical offset to read from and
4388  * 'len' is the actual amount of bytes read into 'buf'.
4389  */
4390 static int
4391 get_history(zpool_handle_t *zhp, char *buf, uint64_t *off, uint64_t *len)
4392 {
4393         zfs_cmd_t zc = {"\0"};
4394         libzfs_handle_t *hdl = zhp->zpool_hdl;
4395
4396         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4397
4398         zc.zc_history = (uint64_t)(uintptr_t)buf;
4399         zc.zc_history_len = *len;
4400         zc.zc_history_offset = *off;
4401
4402         if (zfs_ioctl(hdl, ZFS_IOC_POOL_GET_HISTORY, &zc) != 0) {
4403                 switch (errno) {
4404                 case EPERM:
4405                         return (zfs_error_fmt(hdl, EZFS_PERM,
4406                             dgettext(TEXT_DOMAIN,
4407                             "cannot show history for pool '%s'"),
4408                             zhp->zpool_name));
4409                 case ENOENT:
4410                         return (zfs_error_fmt(hdl, EZFS_NOHISTORY,
4411                             dgettext(TEXT_DOMAIN, "cannot get history for pool "
4412                             "'%s'"), zhp->zpool_name));
4413                 case ENOTSUP:
4414                         return (zfs_error_fmt(hdl, EZFS_BADVERSION,
4415                             dgettext(TEXT_DOMAIN, "cannot get history for pool "
4416                             "'%s', pool must be upgraded"), zhp->zpool_name));
4417                 default:
4418                         return (zpool_standard_error_fmt(hdl, errno,
4419                             dgettext(TEXT_DOMAIN,
4420                             "cannot get history for '%s'"), zhp->zpool_name));
4421                 }
4422         }
4423
4424         *len = zc.zc_history_len;
4425         *off = zc.zc_history_offset;
4426
4427         return (0);
4428 }
4429
4430 /*
4431  * Retrieve the command history of a pool.
4432  */
4433 int
4434 zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp, uint64_t *off,
4435     boolean_t *eof)
4436 {
4437         libzfs_handle_t *hdl = zhp->zpool_hdl;
4438         char *buf;
4439         int buflen = 128 * 1024;
4440         nvlist_t **records = NULL;
4441         uint_t numrecords = 0;
4442         int err = 0, i;
4443         uint64_t start = *off;
4444
4445         buf = zfs_alloc(hdl, buflen);
4446
4447         /* process about 1MiB a time */
4448         while (*off - start < 1024 * 1024) {
4449                 uint64_t bytes_read = buflen;
4450                 uint64_t leftover;
4451
4452                 if ((err = get_history(zhp, buf, off, &bytes_read)) != 0)
4453                         break;
4454
4455                 /* if nothing else was read in, we're at EOF, just return */
4456                 if (!bytes_read) {
4457                         *eof = B_TRUE;
4458                         break;
4459                 }
4460
4461                 if ((err = zpool_history_unpack(buf, bytes_read,
4462                     &leftover, &records, &numrecords)) != 0) {
4463                         zpool_standard_error_fmt(hdl, err,
4464                             dgettext(TEXT_DOMAIN,
4465                             "cannot get history for '%s'"), zhp->zpool_name);
4466                         break;
4467                 }
4468                 *off -= leftover;
4469                 if (leftover == bytes_read) {
4470                         /*
4471                          * no progress made, because buffer is not big enough
4472                          * to hold this record; resize and retry.
4473                          */
4474                         buflen *= 2;
4475                         free(buf);
4476                         buf = zfs_alloc(hdl, buflen);
4477                 }
4478         }
4479
4480         free(buf);
4481
4482         if (!err) {
4483                 *nvhisp = fnvlist_alloc();
4484                 fnvlist_add_nvlist_array(*nvhisp, ZPOOL_HIST_RECORD,
4485                     (const nvlist_t **)records, numrecords);
4486         }
4487         for (i = 0; i < numrecords; i++)
4488                 nvlist_free(records[i]);
4489         free(records);
4490
4491         return (err);
4492 }
4493
4494 /*
4495  * Retrieve the next event given the passed 'zevent_fd' file descriptor.
4496  * If there is a new event available 'nvp' will contain a newly allocated
4497  * nvlist and 'dropped' will be set to the number of missed events since
4498  * the last call to this function.  When 'nvp' is set to NULL it indicates
4499  * no new events are available.  In either case the function returns 0 and
4500  * it is up to the caller to free 'nvp'.  In the case of a fatal error the
4501  * function will return a non-zero value.  When the function is called in
4502  * blocking mode (the default, unless the ZEVENT_NONBLOCK flag is passed),
4503  * it will not return until a new event is available.
4504  */
4505 int
4506 zpool_events_next(libzfs_handle_t *hdl, nvlist_t **nvp,
4507     int *dropped, unsigned flags, int zevent_fd)
4508 {
4509         zfs_cmd_t zc = {"\0"};
4510         int error = 0;
4511
4512         *nvp = NULL;
4513         *dropped = 0;
4514         zc.zc_cleanup_fd = zevent_fd;
4515
4516         if (flags & ZEVENT_NONBLOCK)
4517                 zc.zc_guid = ZEVENT_NONBLOCK;
4518
4519         zcmd_alloc_dst_nvlist(hdl, &zc, ZEVENT_SIZE);
4520
4521 retry:
4522         if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_NEXT, &zc) != 0) {
4523                 switch (errno) {
4524                 case ESHUTDOWN:
4525                         error = zfs_error_fmt(hdl, EZFS_POOLUNAVAIL,
4526                             dgettext(TEXT_DOMAIN, "zfs shutdown"));
4527                         goto out;
4528                 case ENOENT:
4529                         /* Blocking error case should not occur */
4530                         if (!(flags & ZEVENT_NONBLOCK))
4531                                 error = zpool_standard_error_fmt(hdl, errno,
4532                                     dgettext(TEXT_DOMAIN, "cannot get event"));
4533
4534                         goto out;
4535                 case ENOMEM:
4536                         zcmd_expand_dst_nvlist(hdl, &zc);
4537                         goto retry;
4538                 default:
4539                         error = zpool_standard_error_fmt(hdl, errno,
4540                             dgettext(TEXT_DOMAIN, "cannot get event"));
4541                         goto out;
4542                 }
4543         }
4544
4545         error = zcmd_read_dst_nvlist(hdl, &zc, nvp);
4546         if (error != 0)
4547                 goto out;
4548
4549         *dropped = (int)zc.zc_cookie;
4550 out:
4551         zcmd_free_nvlists(&zc);
4552
4553         return (error);
4554 }
4555
4556 /*
4557  * Clear all events.
4558  */
4559 int
4560 zpool_events_clear(libzfs_handle_t *hdl, int *count)
4561 {
4562         zfs_cmd_t zc = {"\0"};
4563
4564         if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_CLEAR, &zc) != 0)
4565                 return (zpool_standard_error(hdl, errno,
4566                     dgettext(TEXT_DOMAIN, "cannot clear events")));
4567
4568         if (count != NULL)
4569                 *count = (int)zc.zc_cookie; /* # of events cleared */
4570
4571         return (0);
4572 }
4573
4574 /*
4575  * Seek to a specific EID, ZEVENT_SEEK_START, or ZEVENT_SEEK_END for
4576  * the passed zevent_fd file handle.  On success zero is returned,
4577  * otherwise -1 is returned and hdl->libzfs_error is set to the errno.
4578  */
4579 int
4580 zpool_events_seek(libzfs_handle_t *hdl, uint64_t eid, int zevent_fd)
4581 {
4582         zfs_cmd_t zc = {"\0"};
4583         int error = 0;
4584
4585         zc.zc_guid = eid;
4586         zc.zc_cleanup_fd = zevent_fd;
4587
4588         if (zfs_ioctl(hdl, ZFS_IOC_EVENTS_SEEK, &zc) != 0) {
4589                 switch (errno) {
4590                 case ENOENT:
4591                         error = zfs_error_fmt(hdl, EZFS_NOENT,
4592                             dgettext(TEXT_DOMAIN, "cannot get event"));
4593                         break;
4594
4595                 case ENOMEM:
4596                         error = zfs_error_fmt(hdl, EZFS_NOMEM,
4597                             dgettext(TEXT_DOMAIN, "cannot get event"));
4598                         break;
4599
4600                 default:
4601                         error = zpool_standard_error_fmt(hdl, errno,
4602                             dgettext(TEXT_DOMAIN, "cannot get event"));
4603                         break;
4604                 }
4605         }
4606
4607         return (error);
4608 }
4609
4610 static void
4611 zpool_obj_to_path_impl(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
4612     char *pathname, size_t len, boolean_t always_unmounted)
4613 {
4614         zfs_cmd_t zc = {"\0"};
4615         boolean_t mounted = B_FALSE;
4616         char *mntpnt = NULL;
4617         char dsname[ZFS_MAX_DATASET_NAME_LEN];
4618
4619         if (dsobj == 0) {
4620                 /* special case for the MOS */
4621                 (void) snprintf(pathname, len, "<metadata>:<0x%llx>",
4622                     (longlong_t)obj);
4623                 return;
4624         }
4625
4626         /* get the dataset's name */
4627         (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
4628         zc.zc_obj = dsobj;
4629         if (zfs_ioctl(zhp->zpool_hdl,
4630             ZFS_IOC_DSOBJ_TO_DSNAME, &zc) != 0) {
4631                 /* just write out a path of two object numbers */
4632                 (void) snprintf(pathname, len, "<0x%llx>:<0x%llx>",
4633                     (longlong_t)dsobj, (longlong_t)obj);
4634                 return;
4635         }
4636         (void) strlcpy(dsname, zc.zc_value, sizeof (dsname));
4637
4638         /* find out if the dataset is mounted */
4639         mounted = !always_unmounted && is_mounted(zhp->zpool_hdl, dsname,
4640             &mntpnt);
4641
4642         /* get the corrupted object's path */
4643         (void) strlcpy(zc.zc_name, dsname, sizeof (zc.zc_name));
4644         zc.zc_obj = obj;
4645         if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_OBJ_TO_PATH,
4646             &zc) == 0) {
4647                 if (mounted) {
4648                         (void) snprintf(pathname, len, "%s%s", mntpnt,
4649                             zc.zc_value);
4650                 } else {
4651                         (void) snprintf(pathname, len, "%s:%s",
4652                             dsname, zc.zc_value);
4653                 }
4654         } else {
4655                 (void) snprintf(pathname, len, "%s:<0x%llx>", dsname,
4656                     (longlong_t)obj);
4657         }
4658         free(mntpnt);
4659 }
4660
4661 void
4662 zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
4663     char *pathname, size_t len)
4664 {
4665         zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_FALSE);
4666 }
4667
4668 void
4669 zpool_obj_to_path_ds(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
4670     char *pathname, size_t len)
4671 {
4672         zpool_obj_to_path_impl(zhp, dsobj, obj, pathname, len, B_TRUE);
4673 }
4674 /*
4675  * Wait while the specified activity is in progress in the pool.
4676  */
4677 int
4678 zpool_wait(zpool_handle_t *zhp, zpool_wait_activity_t activity)
4679 {
4680         boolean_t missing;
4681
4682         int error = zpool_wait_status(zhp, activity, &missing, NULL);
4683
4684         if (missing) {
4685                 (void) zpool_standard_error_fmt(zhp->zpool_hdl, ENOENT,
4686                     dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
4687                     zhp->zpool_name);
4688                 return (ENOENT);
4689         } else {
4690                 return (error);
4691         }
4692 }
4693
4694 /*
4695  * Wait for the given activity and return the status of the wait (whether or not
4696  * any waiting was done) in the 'waited' parameter. Non-existent pools are
4697  * reported via the 'missing' parameter, rather than by printing an error
4698  * message. This is convenient when this function is called in a loop over a
4699  * long period of time (as it is, for example, by zpool's wait cmd). In that
4700  * scenario, a pool being exported or destroyed should be considered a normal
4701  * event, so we don't want to print an error when we find that the pool doesn't
4702  * exist.
4703  */
4704 int
4705 zpool_wait_status(zpool_handle_t *zhp, zpool_wait_activity_t activity,
4706     boolean_t *missing, boolean_t *waited)
4707 {
4708         int error = lzc_wait(zhp->zpool_name, activity, waited);
4709         *missing = (error == ENOENT);
4710         if (*missing)
4711                 return (0);
4712
4713         if (error != 0) {
4714                 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
4715                     dgettext(TEXT_DOMAIN, "error waiting in pool '%s'"),
4716                     zhp->zpool_name);
4717         }
4718
4719         return (error);
4720 }
4721
4722 int
4723 zpool_set_bootenv(zpool_handle_t *zhp, const nvlist_t *envmap)
4724 {
4725         int error = lzc_set_bootenv(zhp->zpool_name, envmap);
4726         if (error != 0) {
4727                 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
4728                     dgettext(TEXT_DOMAIN,
4729                     "error setting bootenv in pool '%s'"), zhp->zpool_name);
4730         }
4731
4732         return (error);
4733 }
4734
4735 int
4736 zpool_get_bootenv(zpool_handle_t *zhp, nvlist_t **nvlp)
4737 {
4738         nvlist_t *nvl;
4739         int error;
4740
4741         nvl = NULL;
4742         error = lzc_get_bootenv(zhp->zpool_name, &nvl);
4743         if (error != 0) {
4744                 (void) zpool_standard_error_fmt(zhp->zpool_hdl, error,
4745                     dgettext(TEXT_DOMAIN,
4746                     "error getting bootenv in pool '%s'"), zhp->zpool_name);
4747         } else {
4748                 *nvlp = nvl;
4749         }
4750
4751         return (error);
4752 }
4753
4754 /*
4755  * Attempt to read and parse feature file(s) (from "compatibility" property).
4756  * Files contain zpool feature names, comma or whitespace-separated.
4757  * Comments (# character to next newline) are discarded.
4758  *
4759  * Arguments:
4760  *  compatibility : string containing feature filenames
4761  *  features : either NULL or pointer to array of boolean
4762  *  report : either NULL or pointer to string buffer
4763  *  rlen : length of "report" buffer
4764  *
4765  * compatibility is NULL (unset), "", "off", "legacy", or list of
4766  * comma-separated filenames. filenames should either be absolute,
4767  * or relative to:
4768  *   1) ZPOOL_SYSCONF_COMPAT_D (eg: /etc/zfs/compatibility.d) or
4769  *   2) ZPOOL_DATA_COMPAT_D (eg: /usr/share/zfs/compatibility.d).
4770  * (Unset), "" or "off" => enable all features
4771  * "legacy" => disable all features
4772  *
4773  * Any feature names read from files which match unames in spa_feature_table
4774  * will have the corresponding boolean set in the features array (if non-NULL).
4775  * If more than one feature set specified, only features present in *all* of
4776  * them will be set.
4777  *
4778  * "report" if not NULL will be populated with a suitable status message.
4779  *
4780  * Return values:
4781  *   ZPOOL_COMPATIBILITY_OK : files read and parsed ok
4782  *   ZPOOL_COMPATIBILITY_BADFILE : file too big or not a text file
4783  *   ZPOOL_COMPATIBILITY_BADTOKEN : SYSCONF file contains invalid feature name
4784  *   ZPOOL_COMPATIBILITY_WARNTOKEN : DATA file contains invalid feature name
4785  *   ZPOOL_COMPATIBILITY_NOFILES : no feature files found
4786  */
4787 zpool_compat_status_t
4788 zpool_load_compat(const char *compat, boolean_t *features, char *report,
4789     size_t rlen)
4790 {
4791         int sdirfd, ddirfd, featfd;
4792         struct stat fs;
4793         char *fc;
4794         char *ps, *ls, *ws;
4795         char *file, *line, *word;
4796
4797         char l_compat[ZFS_MAXPROPLEN];
4798
4799         boolean_t ret_nofiles = B_TRUE;
4800         boolean_t ret_badfile = B_FALSE;
4801         boolean_t ret_badtoken = B_FALSE;
4802         boolean_t ret_warntoken = B_FALSE;
4803
4804         /* special cases (unset), "" and "off" => enable all features */
4805         if (compat == NULL || compat[0] == '\0' ||
4806             strcmp(compat, ZPOOL_COMPAT_OFF) == 0) {
4807                 if (features != NULL)
4808                         for (uint_t i = 0; i < SPA_FEATURES; i++)
4809                                 features[i] = B_TRUE;
4810                 if (report != NULL)
4811                         strlcpy(report, gettext("all features enabled"), rlen);
4812                 return (ZPOOL_COMPATIBILITY_OK);
4813         }
4814
4815         /* Final special case "legacy" => disable all features */
4816         if (strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0) {
4817                 if (features != NULL)
4818                         for (uint_t i = 0; i < SPA_FEATURES; i++)
4819                                 features[i] = B_FALSE;
4820                 if (report != NULL)
4821                         strlcpy(report, gettext("all features disabled"), rlen);
4822                 return (ZPOOL_COMPATIBILITY_OK);
4823         }
4824
4825         /*
4826          * Start with all true; will be ANDed with results from each file
4827          */
4828         if (features != NULL)
4829                 for (uint_t i = 0; i < SPA_FEATURES; i++)
4830                         features[i] = B_TRUE;
4831
4832         char err_badfile[1024] = "";
4833         char err_badtoken[1024] = "";
4834
4835         /*
4836          * We ignore errors from the directory open()
4837          * as they're only needed if the filename is relative
4838          * which will be checked during the openat().
4839          */
4840
4841 /* O_PATH safer than O_RDONLY if system allows it */
4842 #if defined(O_PATH)
4843 #define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_PATH)
4844 #else
4845 #define ZC_DIR_FLAGS (O_DIRECTORY | O_CLOEXEC | O_RDONLY)
4846 #endif
4847
4848         sdirfd = open(ZPOOL_SYSCONF_COMPAT_D, ZC_DIR_FLAGS);
4849         ddirfd = open(ZPOOL_DATA_COMPAT_D, ZC_DIR_FLAGS);
4850
4851         (void) strlcpy(l_compat, compat, ZFS_MAXPROPLEN);
4852
4853         for (file = strtok_r(l_compat, ",", &ps);
4854             file != NULL;
4855             file = strtok_r(NULL, ",", &ps)) {
4856
4857                 boolean_t l_features[SPA_FEATURES];
4858
4859                 enum { Z_SYSCONF, Z_DATA } source;
4860
4861                 /* try sysconfdir first, then datadir */
4862                 source = Z_SYSCONF;
4863                 if ((featfd = openat(sdirfd, file, O_RDONLY | O_CLOEXEC)) < 0) {
4864                         featfd = openat(ddirfd, file, O_RDONLY | O_CLOEXEC);
4865                         source = Z_DATA;
4866                 }
4867
4868                 /* File readable and correct size? */
4869                 if (featfd < 0 ||
4870                     fstat(featfd, &fs) < 0 ||
4871                     fs.st_size < 1 ||
4872                     fs.st_size > ZPOOL_COMPAT_MAXSIZE) {
4873                         (void) close(featfd);
4874                         strlcat(err_badfile, file, ZFS_MAXPROPLEN);
4875                         strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
4876                         ret_badfile = B_TRUE;
4877                         continue;
4878                 }
4879
4880 /* Prefault the file if system allows */
4881 #if defined(MAP_POPULATE)
4882 #define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_POPULATE)
4883 #elif defined(MAP_PREFAULT_READ)
4884 #define ZC_MMAP_FLAGS (MAP_PRIVATE | MAP_PREFAULT_READ)
4885 #else
4886 #define ZC_MMAP_FLAGS (MAP_PRIVATE)
4887 #endif
4888
4889                 /* private mmap() so we can strtok safely */
4890                 fc = (char *)mmap(NULL, fs.st_size, PROT_READ | PROT_WRITE,
4891                     ZC_MMAP_FLAGS, featfd, 0);
4892                 (void) close(featfd);
4893
4894                 /* map ok, and last character == newline? */
4895                 if (fc == MAP_FAILED || fc[fs.st_size - 1] != '\n') {
4896                         (void) munmap((void *) fc, fs.st_size);
4897                         strlcat(err_badfile, file, ZFS_MAXPROPLEN);
4898                         strlcat(err_badfile, " ", ZFS_MAXPROPLEN);
4899                         ret_badfile = B_TRUE;
4900                         continue;
4901                 }
4902
4903                 ret_nofiles = B_FALSE;
4904
4905                 for (uint_t i = 0; i < SPA_FEATURES; i++)
4906                         l_features[i] = B_FALSE;
4907
4908                 /* replace final newline with NULL to ensure string ends */
4909                 fc[fs.st_size - 1] = '\0';
4910
4911                 for (line = strtok_r(fc, "\n", &ls);
4912                     line != NULL;
4913                     line = strtok_r(NULL, "\n", &ls)) {
4914                         /* discard comments */
4915                         char *r = strchr(line, '#');
4916                         if (r != NULL)
4917                                 *r = '\0';
4918
4919                         for (word = strtok_r(line, ", \t", &ws);
4920                             word != NULL;
4921                             word = strtok_r(NULL, ", \t", &ws)) {
4922                                 /* Find matching feature name */
4923                                 uint_t f;
4924                                 for (f = 0; f < SPA_FEATURES; f++) {
4925                                         zfeature_info_t *fi =
4926                                             &spa_feature_table[f];
4927                                         if (strcmp(word, fi->fi_uname) == 0) {
4928                                                 l_features[f] = B_TRUE;
4929                                                 break;
4930                                         }
4931                                 }
4932                                 if (f < SPA_FEATURES)
4933                                         continue;
4934
4935                                 /* found an unrecognized word */
4936                                 /* lightly sanitize it */
4937                                 if (strlen(word) > 32)
4938                                         word[32] = '\0';
4939                                 for (char *c = word; *c != '\0'; c++)
4940                                         if (!isprint(*c))
4941                                                 *c = '?';
4942
4943                                 strlcat(err_badtoken, word, ZFS_MAXPROPLEN);
4944                                 strlcat(err_badtoken, " ", ZFS_MAXPROPLEN);
4945                                 if (source == Z_SYSCONF)
4946                                         ret_badtoken = B_TRUE;
4947                                 else
4948                                         ret_warntoken = B_TRUE;
4949                         }
4950                 }
4951                 (void) munmap((void *) fc, fs.st_size);
4952
4953                 if (features != NULL)
4954                         for (uint_t i = 0; i < SPA_FEATURES; i++)
4955                                 features[i] &= l_features[i];
4956         }
4957         (void) close(sdirfd);
4958         (void) close(ddirfd);
4959
4960         /* Return the most serious error */
4961         if (ret_badfile) {
4962                 if (report != NULL)
4963                         snprintf(report, rlen, gettext("could not read/"
4964                             "parse feature file(s): %s"), err_badfile);
4965                 return (ZPOOL_COMPATIBILITY_BADFILE);
4966         }
4967         if (ret_nofiles) {
4968                 if (report != NULL)
4969                         strlcpy(report,
4970                             gettext("no valid compatibility files specified"),
4971                             rlen);
4972                 return (ZPOOL_COMPATIBILITY_NOFILES);
4973         }
4974         if (ret_badtoken) {
4975                 if (report != NULL)
4976                         snprintf(report, rlen, gettext("invalid feature "
4977                             "name(s) in local compatibility files: %s"),
4978                             err_badtoken);
4979                 return (ZPOOL_COMPATIBILITY_BADTOKEN);
4980         }
4981         if (ret_warntoken) {
4982                 if (report != NULL)
4983                         snprintf(report, rlen, gettext("unrecognized feature "
4984                             "name(s) in distribution compatibility files: %s"),
4985                             err_badtoken);
4986                 return (ZPOOL_COMPATIBILITY_WARNTOKEN);
4987         }
4988         if (report != NULL)
4989                 strlcpy(report, gettext("compatibility set ok"), rlen);
4990         return (ZPOOL_COMPATIBILITY_OK);
4991 }
4992
4993 static int
4994 zpool_vdev_guid(zpool_handle_t *zhp, const char *vdevname, uint64_t *vdev_guid)
4995 {
4996         nvlist_t *tgt;
4997         boolean_t avail_spare, l2cache;
4998
4999         verify(zhp != NULL);
5000         if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
5001                 char errbuf[1024];
5002                 (void) snprintf(errbuf, sizeof (errbuf),
5003                     dgettext(TEXT_DOMAIN, "pool is in an unavailable state"));
5004                 return (zfs_error(zhp->zpool_hdl, EZFS_POOLUNAVAIL, errbuf));
5005         }
5006
5007         if ((tgt = zpool_find_vdev(zhp, vdevname, &avail_spare, &l2cache,
5008             NULL)) == NULL) {
5009                 char errbuf[1024];
5010                 (void) snprintf(errbuf, sizeof (errbuf),
5011                     dgettext(TEXT_DOMAIN, "can not find %s in %s"),
5012                     vdevname, zhp->zpool_name);
5013                 return (zfs_error(zhp->zpool_hdl, EZFS_NODEVICE, errbuf));
5014         }
5015
5016         *vdev_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
5017         return (0);
5018 }
5019
5020 /*
5021  * Get a vdev property value for 'prop' and return the value in
5022  * a pre-allocated buffer.
5023  */
5024 int
5025 zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name,
5026     char *buf, size_t len, zprop_source_t *srctype, boolean_t literal)
5027 {
5028         nvlist_t *nv;
5029         char *strval;
5030         uint64_t intval;
5031         zprop_source_t src = ZPROP_SRC_NONE;
5032
5033         if (prop == VDEV_PROP_USER) {
5034                 /* user property, prop_name must contain the property name */
5035                 assert(prop_name != NULL);
5036                 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5037                         src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
5038                         strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
5039                 } else {
5040                         /* user prop not found */
5041                         return (-1);
5042                 }
5043                 (void) strlcpy(buf, strval, len);
5044                 if (srctype)
5045                         *srctype = src;
5046                 return (0);
5047         }
5048
5049         if (prop_name == NULL)
5050                 prop_name = (char *)vdev_prop_to_name(prop);
5051
5052         switch (vdev_prop_get_type(prop)) {
5053         case PROP_TYPE_STRING:
5054                 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5055                         src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
5056                         strval = fnvlist_lookup_string(nv, ZPROP_VALUE);
5057                 } else {
5058                         src = ZPROP_SRC_DEFAULT;
5059                         if ((strval = (char *)vdev_prop_default_string(prop))
5060                             == NULL)
5061                                 strval = "-";
5062                 }
5063                 (void) strlcpy(buf, strval, len);
5064                 break;
5065
5066         case PROP_TYPE_NUMBER:
5067                 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5068                         src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
5069                         intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
5070                 } else {
5071                         src = ZPROP_SRC_DEFAULT;
5072                         intval = vdev_prop_default_numeric(prop);
5073                 }
5074
5075                 switch (prop) {
5076                 case VDEV_PROP_ASIZE:
5077                 case VDEV_PROP_PSIZE:
5078                 case VDEV_PROP_SIZE:
5079                 case VDEV_PROP_BOOTSIZE:
5080                 case VDEV_PROP_ALLOCATED:
5081                 case VDEV_PROP_FREE:
5082                 case VDEV_PROP_READ_ERRORS:
5083                 case VDEV_PROP_WRITE_ERRORS:
5084                 case VDEV_PROP_CHECKSUM_ERRORS:
5085                 case VDEV_PROP_INITIALIZE_ERRORS:
5086                 case VDEV_PROP_OPS_NULL:
5087                 case VDEV_PROP_OPS_READ:
5088                 case VDEV_PROP_OPS_WRITE:
5089                 case VDEV_PROP_OPS_FREE:
5090                 case VDEV_PROP_OPS_CLAIM:
5091                 case VDEV_PROP_OPS_TRIM:
5092                 case VDEV_PROP_BYTES_NULL:
5093                 case VDEV_PROP_BYTES_READ:
5094                 case VDEV_PROP_BYTES_WRITE:
5095                 case VDEV_PROP_BYTES_FREE:
5096                 case VDEV_PROP_BYTES_CLAIM:
5097                 case VDEV_PROP_BYTES_TRIM:
5098                         if (literal) {
5099                                 (void) snprintf(buf, len, "%llu",
5100                                     (u_longlong_t)intval);
5101                         } else {
5102                                 (void) zfs_nicenum(intval, buf, len);
5103                         }
5104                         break;
5105                 case VDEV_PROP_EXPANDSZ:
5106                         if (intval == 0) {
5107                                 (void) strlcpy(buf, "-", len);
5108                         } else if (literal) {
5109                                 (void) snprintf(buf, len, "%llu",
5110                                     (u_longlong_t)intval);
5111                         } else {
5112                                 (void) zfs_nicenum(intval, buf, len);
5113                         }
5114                         break;
5115                 case VDEV_PROP_CAPACITY:
5116                         if (literal) {
5117                                 (void) snprintf(buf, len, "%llu",
5118                                     (u_longlong_t)intval);
5119                         } else {
5120                                 (void) snprintf(buf, len, "%llu%%",
5121                                     (u_longlong_t)intval);
5122                         }
5123                         break;
5124                 case VDEV_PROP_FRAGMENTATION:
5125                         if (intval == UINT64_MAX) {
5126                                 (void) strlcpy(buf, "-", len);
5127                         } else {
5128                                 (void) snprintf(buf, len, "%llu%%",
5129                                     (u_longlong_t)intval);
5130                         }
5131                         break;
5132                 case VDEV_PROP_STATE:
5133                         if (literal) {
5134                                 (void) snprintf(buf, len, "%llu",
5135                                     (u_longlong_t)intval);
5136                         } else {
5137                                 (void) strlcpy(buf, zpool_state_to_name(intval,
5138                                     VDEV_AUX_NONE), len);
5139                         }
5140                         break;
5141                 default:
5142                         (void) snprintf(buf, len, "%llu",
5143                             (u_longlong_t)intval);
5144                 }
5145                 break;
5146
5147         case PROP_TYPE_INDEX:
5148                 if (nvlist_lookup_nvlist(nvprop, prop_name, &nv) == 0) {
5149                         src = fnvlist_lookup_uint64(nv, ZPROP_SOURCE);
5150                         intval = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
5151                 } else {
5152                         src = ZPROP_SRC_DEFAULT;
5153                         intval = vdev_prop_default_numeric(prop);
5154                 }
5155                 if (vdev_prop_index_to_string(prop, intval,
5156                     (const char **)&strval) != 0)
5157                         return (-1);
5158                 (void) strlcpy(buf, strval, len);
5159                 break;
5160
5161         default:
5162                 abort();
5163         }
5164
5165         if (srctype)
5166                 *srctype = src;
5167
5168         return (0);
5169 }
5170
5171 /*
5172  * Get a vdev property value for 'prop_name' and return the value in
5173  * a pre-allocated buffer.
5174  */
5175 int
5176 zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
5177     char *prop_name, char *buf, size_t len, zprop_source_t *srctype,
5178     boolean_t literal)
5179 {
5180         nvlist_t *reqnvl, *reqprops;
5181         nvlist_t *retprops = NULL;
5182         uint64_t vdev_guid = 0;
5183         int ret;
5184
5185         if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
5186                 return (ret);
5187
5188         if (nvlist_alloc(&reqnvl, NV_UNIQUE_NAME, 0) != 0)
5189                 return (no_memory(zhp->zpool_hdl));
5190         if (nvlist_alloc(&reqprops, NV_UNIQUE_NAME, 0) != 0)
5191                 return (no_memory(zhp->zpool_hdl));
5192
5193         fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
5194
5195         if (prop != VDEV_PROP_USER) {
5196                 /* prop_name overrides prop value */
5197                 if (prop_name != NULL)
5198                         prop = vdev_name_to_prop(prop_name);
5199                 else
5200                         prop_name = (char *)vdev_prop_to_name(prop);
5201                 assert(prop < VDEV_NUM_PROPS);
5202         }
5203
5204         assert(prop_name != NULL);
5205         if (nvlist_add_uint64(reqprops, prop_name, prop) != 0) {
5206                 nvlist_free(reqnvl);
5207                 nvlist_free(reqprops);
5208                 return (no_memory(zhp->zpool_hdl));
5209         }
5210
5211         fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_PROPS_GET_PROPS, reqprops);
5212
5213         ret = lzc_get_vdev_prop(zhp->zpool_name, reqnvl, &retprops);
5214
5215         if (ret == 0) {
5216                 ret = zpool_get_vdev_prop_value(retprops, prop, prop_name, buf,
5217                     len, srctype, literal);
5218         } else {
5219                 char errbuf[1024];
5220                 (void) snprintf(errbuf, sizeof (errbuf),
5221                     dgettext(TEXT_DOMAIN, "cannot get vdev property %s from"
5222                     " %s in %s"), prop_name, vdevname, zhp->zpool_name);
5223                 (void) zpool_standard_error(zhp->zpool_hdl, ret, errbuf);
5224         }
5225
5226         nvlist_free(reqnvl);
5227         nvlist_free(reqprops);
5228         nvlist_free(retprops);
5229
5230         return (ret);
5231 }
5232
5233 /*
5234  * Get all vdev properties
5235  */
5236 int
5237 zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname,
5238     nvlist_t **outnvl)
5239 {
5240         nvlist_t *nvl = NULL;
5241         uint64_t vdev_guid = 0;
5242         int ret;
5243
5244         if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
5245                 return (ret);
5246
5247         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
5248                 return (no_memory(zhp->zpool_hdl));
5249
5250         fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);
5251
5252         ret = lzc_get_vdev_prop(zhp->zpool_name, nvl, outnvl);
5253
5254         nvlist_free(nvl);
5255
5256         if (ret) {
5257                 char errbuf[1024];
5258                 (void) snprintf(errbuf, sizeof (errbuf),
5259                     dgettext(TEXT_DOMAIN, "cannot get vdev properties for"
5260                     " %s in %s"), vdevname, zhp->zpool_name);
5261                 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
5262         }
5263
5264         return (ret);
5265 }
5266
5267 /*
5268  * Set vdev property
5269  */
5270 int
5271 zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
5272     const char *propname, const char *propval)
5273 {
5274         int ret;
5275         nvlist_t *nvl = NULL;
5276         nvlist_t *outnvl = NULL;
5277         nvlist_t *props;
5278         nvlist_t *realprops;
5279         prop_flags_t flags = { 0 };
5280         uint64_t version;
5281         uint64_t vdev_guid;
5282
5283         if ((ret = zpool_vdev_guid(zhp, vdevname, &vdev_guid)) != 0)
5284                 return (ret);
5285
5286         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
5287                 return (no_memory(zhp->zpool_hdl));
5288         if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
5289                 return (no_memory(zhp->zpool_hdl));
5290
5291         fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_SET_VDEV, vdev_guid);
5292
5293         if (nvlist_add_string(props, propname, propval) != 0) {
5294                 nvlist_free(props);
5295                 return (no_memory(zhp->zpool_hdl));
5296         }
5297
5298         char errbuf[1024];
5299         (void) snprintf(errbuf, sizeof (errbuf),
5300             dgettext(TEXT_DOMAIN, "cannot set property %s for %s on %s"),
5301             propname, vdevname, zhp->zpool_name);
5302
5303         flags.vdevprop = 1;
5304         version = zpool_get_prop_int(zhp, ZPOOL_PROP_VERSION, NULL);
5305         if ((realprops = zpool_valid_proplist(zhp->zpool_hdl,
5306             zhp->zpool_name, props, version, flags, errbuf)) == NULL) {
5307                 nvlist_free(props);
5308                 nvlist_free(nvl);
5309                 return (-1);
5310         }
5311
5312         nvlist_free(props);
5313         props = realprops;
5314
5315         fnvlist_add_nvlist(nvl, ZPOOL_VDEV_PROPS_SET_PROPS, props);
5316
5317         ret = lzc_set_vdev_prop(zhp->zpool_name, nvl, &outnvl);
5318
5319         nvlist_free(props);
5320         nvlist_free(nvl);
5321         nvlist_free(outnvl);
5322
5323         if (ret)
5324                 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
5325
5326         return (ret);
5327 }