]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / cddl / contrib / opensolaris / lib / libzfs / common / libzfs_dataset.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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #pragma ident   "%Z%%M% %I%     %E% SMI"
28
29 #include <assert.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include <libintl.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <strings.h>
37 #include <unistd.h>
38 #include <zone.h>
39 #include <fcntl.h>
40 #include <sys/mntent.h>
41 #include <sys/mnttab.h>
42 #include <sys/mount.h>
43
44 #include <sys/spa.h>
45 #include <sys/zio.h>
46 #include <sys/zap.h>
47 #include <libzfs.h>
48
49 #include "zfs_namecheck.h"
50 #include "zfs_prop.h"
51 #include "libzfs_impl.h"
52
53 static int zvol_create_link_common(libzfs_handle_t *, const char *, int);
54
55 /*
56  * Given a single type (not a mask of types), return the type in a human
57  * readable form.
58  */
59 const char *
60 zfs_type_to_name(zfs_type_t type)
61 {
62         switch (type) {
63         case ZFS_TYPE_FILESYSTEM:
64                 return (dgettext(TEXT_DOMAIN, "filesystem"));
65         case ZFS_TYPE_SNAPSHOT:
66                 return (dgettext(TEXT_DOMAIN, "snapshot"));
67         case ZFS_TYPE_VOLUME:
68                 return (dgettext(TEXT_DOMAIN, "volume"));
69         }
70
71         return (NULL);
72 }
73
74 /*
75  * Given a path and mask of ZFS types, return a string describing this dataset.
76  * This is used when we fail to open a dataset and we cannot get an exact type.
77  * We guess what the type would have been based on the path and the mask of
78  * acceptable types.
79  */
80 static const char *
81 path_to_str(const char *path, int types)
82 {
83         /*
84          * When given a single type, always report the exact type.
85          */
86         if (types == ZFS_TYPE_SNAPSHOT)
87                 return (dgettext(TEXT_DOMAIN, "snapshot"));
88         if (types == ZFS_TYPE_FILESYSTEM)
89                 return (dgettext(TEXT_DOMAIN, "filesystem"));
90         if (types == ZFS_TYPE_VOLUME)
91                 return (dgettext(TEXT_DOMAIN, "volume"));
92
93         /*
94          * The user is requesting more than one type of dataset.  If this is the
95          * case, consult the path itself.  If we're looking for a snapshot, and
96          * a '@' is found, then report it as "snapshot".  Otherwise, remove the
97          * snapshot attribute and try again.
98          */
99         if (types & ZFS_TYPE_SNAPSHOT) {
100                 if (strchr(path, '@') != NULL)
101                         return (dgettext(TEXT_DOMAIN, "snapshot"));
102                 return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
103         }
104
105
106         /*
107          * The user has requested either filesystems or volumes.
108          * We have no way of knowing a priori what type this would be, so always
109          * report it as "filesystem" or "volume", our two primitive types.
110          */
111         if (types & ZFS_TYPE_FILESYSTEM)
112                 return (dgettext(TEXT_DOMAIN, "filesystem"));
113
114         assert(types & ZFS_TYPE_VOLUME);
115         return (dgettext(TEXT_DOMAIN, "volume"));
116 }
117
118 /*
119  * Validate a ZFS path.  This is used even before trying to open the dataset, to
120  * provide a more meaningful error message.  We place a more useful message in
121  * 'buf' detailing exactly why the name was not valid.
122  */
123 static int
124 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type)
125 {
126         namecheck_err_t why;
127         char what;
128
129         if (dataset_namecheck(path, &why, &what) != 0) {
130                 if (hdl != NULL) {
131                         switch (why) {
132                         case NAME_ERR_TOOLONG:
133                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
134                                     "name is too long"));
135                                 break;
136
137                         case NAME_ERR_LEADING_SLASH:
138                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
139                                     "leading slash in name"));
140                                 break;
141
142                         case NAME_ERR_EMPTY_COMPONENT:
143                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
144                                     "empty component in name"));
145                                 break;
146
147                         case NAME_ERR_TRAILING_SLASH:
148                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
149                                     "trailing slash in name"));
150                                 break;
151
152                         case NAME_ERR_INVALCHAR:
153                                 zfs_error_aux(hdl,
154                                     dgettext(TEXT_DOMAIN, "invalid character "
155                                     "'%c' in name"), what);
156                                 break;
157
158                         case NAME_ERR_MULTIPLE_AT:
159                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
160                                     "multiple '@' delimiters in name"));
161                                 break;
162
163                         case NAME_ERR_NOLETTER:
164                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
165                                     "pool doesn't begin with a letter"));
166                                 break;
167
168                         case NAME_ERR_RESERVED:
169                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
170                                     "name is reserved"));
171                                 break;
172
173                         case NAME_ERR_DISKLIKE:
174                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
175                                     "reserved disk name"));
176                                 break;
177                         }
178                 }
179
180                 return (0);
181         }
182
183         if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
184                 if (hdl != NULL)
185                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
186                             "snapshot delimiter '@' in filesystem name"));
187                 return (0);
188         }
189
190         if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
191                 if (hdl != NULL)
192                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
193                             "missing '@' delimiter in snapshot name"));
194                 return (0);
195         }
196
197         return (-1);
198 }
199
200 int
201 zfs_name_valid(const char *name, zfs_type_t type)
202 {
203         return (zfs_validate_name(NULL, name, type));
204 }
205
206 /*
207  * This function takes the raw DSL properties, and filters out the user-defined
208  * properties into a separate nvlist.
209  */
210 static int
211 process_user_props(zfs_handle_t *zhp)
212 {
213         libzfs_handle_t *hdl = zhp->zfs_hdl;
214         nvpair_t *elem;
215         nvlist_t *propval;
216
217         nvlist_free(zhp->zfs_user_props);
218
219         if (nvlist_alloc(&zhp->zfs_user_props, NV_UNIQUE_NAME, 0) != 0)
220                 return (no_memory(hdl));
221
222         elem = NULL;
223         while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
224                 if (!zfs_prop_user(nvpair_name(elem)))
225                         continue;
226
227                 verify(nvpair_value_nvlist(elem, &propval) == 0);
228                 if (nvlist_add_nvlist(zhp->zfs_user_props,
229                     nvpair_name(elem), propval) != 0)
230                         return (no_memory(hdl));
231         }
232
233         return (0);
234 }
235
236 /*
237  * Utility function to gather stats (objset and zpl) for the given object.
238  */
239 static int
240 get_stats(zfs_handle_t *zhp)
241 {
242         zfs_cmd_t zc = { 0 };
243         libzfs_handle_t *hdl = zhp->zfs_hdl;
244
245         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
246
247         if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
248                 return (-1);
249
250         while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
251                 if (errno == ENOMEM) {
252                         if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
253                                 zcmd_free_nvlists(&zc);
254                                 return (-1);
255                         }
256                 } else {
257                         zcmd_free_nvlists(&zc);
258                         return (-1);
259                 }
260         }
261
262         zhp->zfs_dmustats = zc.zc_objset_stats; /* structure assignment */
263
264         (void) strlcpy(zhp->zfs_root, zc.zc_value, sizeof (zhp->zfs_root));
265
266         if (zhp->zfs_props) {
267                 nvlist_free(zhp->zfs_props);
268                 zhp->zfs_props = NULL;
269         }
270
271         if (zcmd_read_dst_nvlist(hdl, &zc, &zhp->zfs_props) != 0) {
272                 zcmd_free_nvlists(&zc);
273                 return (-1);
274         }
275
276         zcmd_free_nvlists(&zc);
277
278         if (process_user_props(zhp) != 0)
279                 return (-1);
280
281         return (0);
282 }
283
284 /*
285  * Refresh the properties currently stored in the handle.
286  */
287 void
288 zfs_refresh_properties(zfs_handle_t *zhp)
289 {
290         (void) get_stats(zhp);
291 }
292
293 /*
294  * Makes a handle from the given dataset name.  Used by zfs_open() and
295  * zfs_iter_* to create child handles on the fly.
296  */
297 zfs_handle_t *
298 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
299 {
300         zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
301
302         if (zhp == NULL)
303                 return (NULL);
304
305         zhp->zfs_hdl = hdl;
306
307 top:
308         (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
309
310         if (get_stats(zhp) != 0) {
311                 free(zhp);
312                 return (NULL);
313         }
314
315         if (zhp->zfs_dmustats.dds_inconsistent) {
316                 zfs_cmd_t zc = { 0 };
317
318                 /*
319                  * If it is dds_inconsistent, then we've caught it in
320                  * the middle of a 'zfs receive' or 'zfs destroy', and
321                  * it is inconsistent from the ZPL's point of view, so
322                  * can't be mounted.  However, it could also be that we
323                  * have crashed in the middle of one of those
324                  * operations, in which case we need to get rid of the
325                  * inconsistent state.  We do that by either rolling
326                  * back to the previous snapshot (which will fail if
327                  * there is none), or destroying the filesystem.  Note
328                  * that if we are still in the middle of an active
329                  * 'receive' or 'destroy', then the rollback and destroy
330                  * will fail with EBUSY and we will drive on as usual.
331                  */
332
333                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
334
335                 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
336                         (void) zvol_remove_link(hdl, zhp->zfs_name);
337                         zc.zc_objset_type = DMU_OST_ZVOL;
338                 } else {
339                         zc.zc_objset_type = DMU_OST_ZFS;
340                 }
341
342                 /* If we can successfully roll it back, reget the stats */
343                 if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0)
344                         goto top;
345                 /*
346                  * If we can sucessfully destroy it, pretend that it
347                  * never existed.
348                  */
349                 if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) {
350                         free(zhp);
351                         errno = ENOENT;
352                         return (NULL);
353                 }
354         }
355
356         /*
357          * We've managed to open the dataset and gather statistics.  Determine
358          * the high-level type.
359          */
360         if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
361                 zhp->zfs_head_type = ZFS_TYPE_VOLUME;
362         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
363                 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
364         else
365                 abort();
366
367         if (zhp->zfs_dmustats.dds_is_snapshot)
368                 zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
369         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
370                 zhp->zfs_type = ZFS_TYPE_VOLUME;
371         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
372                 zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
373         else
374                 abort();        /* we should never see any other types */
375
376         return (zhp);
377 }
378
379 /*
380  * Opens the given snapshot, filesystem, or volume.   The 'types'
381  * argument is a mask of acceptable types.  The function will print an
382  * appropriate error message and return NULL if it can't be opened.
383  */
384 zfs_handle_t *
385 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
386 {
387         zfs_handle_t *zhp;
388         char errbuf[1024];
389
390         (void) snprintf(errbuf, sizeof (errbuf),
391             dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
392
393         /*
394          * Validate the name before we even try to open it.
395          */
396         if (!zfs_validate_name(hdl, path, ZFS_TYPE_ANY)) {
397                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
398                     "invalid dataset name"));
399                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
400                 return (NULL);
401         }
402
403         /*
404          * Try to get stats for the dataset, which will tell us if it exists.
405          */
406         errno = 0;
407         if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
408                 (void) zfs_standard_error(hdl, errno, errbuf);
409                 return (NULL);
410         }
411
412         if (!(types & zhp->zfs_type)) {
413                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
414                 zfs_close(zhp);
415                 return (NULL);
416         }
417
418         return (zhp);
419 }
420
421 /*
422  * Release a ZFS handle.  Nothing to do but free the associated memory.
423  */
424 void
425 zfs_close(zfs_handle_t *zhp)
426 {
427         if (zhp->zfs_mntopts)
428                 free(zhp->zfs_mntopts);
429         nvlist_free(zhp->zfs_props);
430         nvlist_free(zhp->zfs_user_props);
431         free(zhp);
432 }
433
434 /*
435  * Given a numeric suffix, convert the value into a number of bits that the
436  * resulting value must be shifted.
437  */
438 static int
439 str2shift(libzfs_handle_t *hdl, const char *buf)
440 {
441         const char *ends = "BKMGTPEZ";
442         int i;
443
444         if (buf[0] == '\0')
445                 return (0);
446         for (i = 0; i < strlen(ends); i++) {
447                 if (toupper(buf[0]) == ends[i])
448                         break;
449         }
450         if (i == strlen(ends)) {
451                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
452                     "invalid numeric suffix '%s'"), buf);
453                 return (-1);
454         }
455
456         /*
457          * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
458          * allow 'BB' - that's just weird.
459          */
460         if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
461             toupper(buf[0]) != 'B'))
462                 return (10*i);
463
464         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
465             "invalid numeric suffix '%s'"), buf);
466         return (-1);
467 }
468
469 /*
470  * Convert a string of the form '100G' into a real number.  Used when setting
471  * properties or creating a volume.  'buf' is used to place an extended error
472  * message for the caller to use.
473  */
474 static int
475 nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
476 {
477         char *end;
478         int shift;
479
480         *num = 0;
481
482         /* Check to see if this looks like a number.  */
483         if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
484                 if (hdl)
485                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
486                             "bad numeric value '%s'"), value);
487                 return (-1);
488         }
489
490         /* Rely on stroll() to process the numeric portion.  */
491         errno = 0;
492         *num = strtoll(value, &end, 10);
493
494         /*
495          * Check for ERANGE, which indicates that the value is too large to fit
496          * in a 64-bit value.
497          */
498         if (errno == ERANGE) {
499                 if (hdl)
500                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
501                             "numeric value is too large"));
502                 return (-1);
503         }
504
505         /*
506          * If we have a decimal value, then do the computation with floating
507          * point arithmetic.  Otherwise, use standard arithmetic.
508          */
509         if (*end == '.') {
510                 double fval = strtod(value, &end);
511
512                 if ((shift = str2shift(hdl, end)) == -1)
513                         return (-1);
514
515                 fval *= pow(2, shift);
516
517                 if (fval > UINT64_MAX) {
518                         if (hdl)
519                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
520                                     "numeric value is too large"));
521                         return (-1);
522                 }
523
524                 *num = (uint64_t)fval;
525         } else {
526                 if ((shift = str2shift(hdl, end)) == -1)
527                         return (-1);
528
529                 /* Check for overflow */
530                 if (shift >= 64 || (*num << shift) >> shift != *num) {
531                         if (hdl)
532                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
533                                     "numeric value is too large"));
534                         return (-1);
535                 }
536
537                 *num <<= shift;
538         }
539
540         return (0);
541 }
542
543 int
544 zfs_nicestrtonum(libzfs_handle_t *hdl, const char *str, uint64_t *val)
545 {
546         return (nicestrtonum(hdl, str, val));
547 }
548
549 /*
550  * The prop_parse_*() functions are designed to allow flexibility in callers
551  * when setting properties.  At the DSL layer, all properties are either 64-bit
552  * numbers or strings.  We want the user to be able to ignore this fact and
553  * specify properties as native values (boolean, for example) or as strings (to
554  * simplify command line utilities).  This also handles converting index types
555  * (compression, checksum, etc) from strings to their on-disk index.
556  */
557
558 static int
559 prop_parse_boolean(libzfs_handle_t *hdl, nvpair_t *elem, uint64_t *val)
560 {
561         uint64_t ret;
562
563         switch (nvpair_type(elem)) {
564         case DATA_TYPE_STRING:
565                 {
566                         char *value;
567                         verify(nvpair_value_string(elem, &value) == 0);
568
569                         if (strcmp(value, "on") == 0) {
570                                 ret = 1;
571                         } else if (strcmp(value, "off") == 0) {
572                                 ret = 0;
573                         } else {
574                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
575                                     "property '%s' must be 'on' or 'off'"),
576                                     nvpair_name(elem));
577                                 return (-1);
578                         }
579                         break;
580                 }
581
582         case DATA_TYPE_UINT64:
583                 {
584                         verify(nvpair_value_uint64(elem, &ret) == 0);
585                         if (ret > 1) {
586                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
587                                     "'%s' must be a boolean value"),
588                                     nvpair_name(elem));
589                                 return (-1);
590                         }
591                         break;
592                 }
593
594         case DATA_TYPE_BOOLEAN_VALUE:
595                 {
596                         boolean_t value;
597                         verify(nvpair_value_boolean_value(elem, &value) == 0);
598                         ret = value;
599                         break;
600                 }
601
602         default:
603                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
604                     "'%s' must be a boolean value"),
605                     nvpair_name(elem));
606                 return (-1);
607         }
608
609         *val = ret;
610         return (0);
611 }
612
613 static int
614 prop_parse_number(libzfs_handle_t *hdl, nvpair_t *elem, zfs_prop_t prop,
615     uint64_t *val)
616 {
617         uint64_t ret;
618         boolean_t isnone = B_FALSE;
619
620         switch (nvpair_type(elem)) {
621         case DATA_TYPE_STRING:
622                 {
623                         char *value;
624                         (void) nvpair_value_string(elem, &value);
625                         if (strcmp(value, "none") == 0) {
626                                 isnone = B_TRUE;
627                                 ret = 0;
628                         } else if (nicestrtonum(hdl, value, &ret) != 0) {
629                                 return (-1);
630                         }
631                         break;
632                 }
633
634         case DATA_TYPE_UINT64:
635                 (void) nvpair_value_uint64(elem, &ret);
636                 break;
637
638         default:
639                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
640                     "'%s' must be a number"),
641                     nvpair_name(elem));
642                 return (-1);
643         }
644
645         /*
646          * Quota special: force 'none' and don't allow 0.
647          */
648         if (ret == 0 && !isnone && prop == ZFS_PROP_QUOTA) {
649                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
650                     "use 'none' to disable quota"));
651                 return (-1);
652         }
653
654         *val = ret;
655         return (0);
656 }
657
658 static int
659 prop_parse_index(libzfs_handle_t *hdl, nvpair_t *elem, zfs_prop_t prop,
660     uint64_t *val)
661 {
662         char *propname = nvpair_name(elem);
663         char *value;
664
665         if (nvpair_type(elem) != DATA_TYPE_STRING) {
666                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
667                     "'%s' must be a string"), propname);
668                 return (-1);
669         }
670
671         (void) nvpair_value_string(elem, &value);
672
673         if (zfs_prop_string_to_index(prop, value, val) != 0) {
674                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
675                     "'%s' must be one of '%s'"), propname,
676                     zfs_prop_values(prop));
677                 return (-1);
678         }
679
680         return (0);
681 }
682
683 /*
684  * Check if the bootfs name has the same pool name as it is set to.
685  * Assuming bootfs is a valid dataset name.
686  */
687 static boolean_t
688 bootfs_poolname_valid(char *pool, char *bootfs)
689 {
690         char ch, *pname;
691
692         /* get the pool name from the bootfs name */
693         pname = bootfs;
694         while (*bootfs && !isspace(*bootfs) && *bootfs != '/')
695                 bootfs++;
696
697         ch = *bootfs;
698         *bootfs = 0;
699
700         if (strcmp(pool, pname) == 0) {
701                 *bootfs = ch;
702                 return (B_TRUE);
703         }
704
705         *bootfs = ch;
706         return (B_FALSE);
707 }
708
709 /*
710  * Given an nvlist of properties to set, validates that they are correct, and
711  * parses any numeric properties (index, boolean, etc) if they are specified as
712  * strings.
713  */
714 nvlist_t *
715 zfs_validate_properties(libzfs_handle_t *hdl, zfs_type_t type, char *pool_name,
716     nvlist_t *nvl, uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
717 {
718         nvpair_t *elem;
719         const char *propname;
720         zfs_prop_t prop;
721         uint64_t intval;
722         char *strval;
723         nvlist_t *ret;
724         int isuser;
725
726         if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
727                 (void) no_memory(hdl);
728                 return (NULL);
729         }
730
731         if (type == ZFS_TYPE_SNAPSHOT) {
732                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
733                     "snapshot properties cannot be modified"));
734                 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
735                 goto error;
736         }
737
738         elem = NULL;
739         while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
740                 propname = nvpair_name(elem);
741
742                 /*
743                  * Make sure this property is valid and applies to this type.
744                  */
745                 if ((prop = zfs_name_to_prop_common(propname, type))
746                     == ZFS_PROP_INVAL) {
747                         isuser = zfs_prop_user(propname);
748                         if (!isuser || (isuser && (type & ZFS_TYPE_POOL))) {
749                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
750                                     "invalid property '%s'"),
751                                     propname);
752                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
753                                 goto error;
754                         } else {
755                                 /*
756                                  * If this is a user property, make sure it's a
757                                  * string, and that it's less than
758                                  * ZAP_MAXNAMELEN.
759                                  */
760                                 if (nvpair_type(elem) != DATA_TYPE_STRING) {
761                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
762                                             "'%s' must be a string"),
763                                             propname);
764                                         (void) zfs_error(hdl, EZFS_BADPROP,
765                                             errbuf);
766                                         goto error;
767                                 }
768
769                                 if (strlen(nvpair_name(elem)) >=
770                                     ZAP_MAXNAMELEN) {
771                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
772                                             "property name '%s' is too long"),
773                                             propname);
774                                         (void) zfs_error(hdl, EZFS_BADPROP,
775                                             errbuf);
776                                         goto error;
777                                 }
778                         }
779
780                         (void) nvpair_value_string(elem, &strval);
781                         if (nvlist_add_string(ret, propname, strval) != 0) {
782                                 (void) no_memory(hdl);
783                                 goto error;
784                         }
785                         continue;
786                 }
787
788                 /*
789                  * Normalize the name, to get rid of shorthand abbrevations.
790                  */
791                 propname = zfs_prop_to_name(prop);
792
793                 if (!zfs_prop_valid_for_type(prop, type)) {
794                         zfs_error_aux(hdl,
795                             dgettext(TEXT_DOMAIN, "'%s' does not "
796                             "apply to datasets of this type"), propname);
797                         (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
798                         goto error;
799                 }
800
801                 if (zfs_prop_readonly(prop) &&
802                     (prop != ZFS_PROP_VOLBLOCKSIZE || zhp != NULL)) {
803                         zfs_error_aux(hdl,
804                             dgettext(TEXT_DOMAIN, "'%s' is readonly"),
805                             propname);
806                         (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
807                         goto error;
808                 }
809
810                 /*
811                  * Convert any properties to the internal DSL value types.
812                  */
813                 strval = NULL;
814                 switch (zfs_prop_get_type(prop)) {
815                 case prop_type_boolean:
816                         if (prop_parse_boolean(hdl, elem, &intval) != 0) {
817                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
818                                 goto error;
819                         }
820                         break;
821
822                 case prop_type_string:
823                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
824                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
825                                     "'%s' must be a string"),
826                                     propname);
827                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
828                                 goto error;
829                         }
830                         (void) nvpair_value_string(elem, &strval);
831                         if (strlen(strval) >= ZFS_MAXPROPLEN) {
832                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
833                                     "'%s' is too long"), propname);
834                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
835                                 goto error;
836                         }
837                         break;
838
839                 case prop_type_number:
840                         if (prop_parse_number(hdl, elem, prop, &intval) != 0) {
841                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
842                                 goto error;
843                         }
844                         break;
845
846                 case prop_type_index:
847                         if (prop_parse_index(hdl, elem, prop, &intval) != 0) {
848                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
849                                 goto error;
850                         }
851                         break;
852
853                 default:
854                         abort();
855                 }
856
857                 /*
858                  * Add the result to our return set of properties.
859                  */
860                 if (strval) {
861                         if (nvlist_add_string(ret, propname, strval) != 0) {
862                                 (void) no_memory(hdl);
863                                 goto error;
864                         }
865                 } else if (nvlist_add_uint64(ret, propname, intval) != 0) {
866                         (void) no_memory(hdl);
867                         goto error;
868                 }
869
870                 /*
871                  * Perform some additional checks for specific properties.
872                  */
873                 switch (prop) {
874                 case ZFS_PROP_RECORDSIZE:
875                 case ZFS_PROP_VOLBLOCKSIZE:
876                         /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
877                         if (intval < SPA_MINBLOCKSIZE ||
878                             intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
879                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
880                                     "'%s' must be power of 2 from %u "
881                                     "to %uk"), propname,
882                                     (uint_t)SPA_MINBLOCKSIZE,
883                                     (uint_t)SPA_MAXBLOCKSIZE >> 10);
884                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
885                                 goto error;
886                         }
887                         break;
888
889                 case ZFS_PROP_SHAREISCSI:
890                         if (strcmp(strval, "off") != 0 &&
891                             strcmp(strval, "on") != 0 &&
892                             strcmp(strval, "type=disk") != 0) {
893                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
894                                     "'%s' must be 'on', 'off', or 'type=disk'"),
895                                     propname);
896                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
897                                 goto error;
898                         }
899
900                         break;
901
902                 case ZFS_PROP_MOUNTPOINT:
903                         if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
904                             strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
905                                 break;
906
907                         if (strval[0] != '/') {
908                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
909                                     "'%s' must be an absolute path, "
910                                     "'none', or 'legacy'"), propname);
911                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
912                                 goto error;
913                         }
914                         /*FALLTHRU*/
915
916                 case ZFS_PROP_SHARENFS:
917                         /*
918                          * For the mountpoint and sharenfs properties, check if
919                          * it can be set in a global/non-global zone based on
920                          * the zoned property value:
921                          *
922                          *              global zone         non-global zone
923                          * --------------------------------------------------
924                          * zoned=on     mountpoint (no)     mountpoint (yes)
925                          *              sharenfs (no)       sharenfs (no)
926                          *
927                          * zoned=off    mountpoint (yes)        N/A
928                          *              sharenfs (yes)
929                          */
930                         if (zoned) {
931                                 if (getzoneid() == GLOBAL_ZONEID) {
932                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
933                                             "'%s' cannot be set on "
934                                             "dataset in a non-global zone"),
935                                             propname);
936                                         (void) zfs_error(hdl, EZFS_ZONED,
937                                             errbuf);
938                                         goto error;
939                                 } else if (prop == ZFS_PROP_SHARENFS) {
940                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
941                                             "'%s' cannot be set in "
942                                             "a non-global zone"), propname);
943                                         (void) zfs_error(hdl, EZFS_ZONED,
944                                             errbuf);
945                                         goto error;
946                                 }
947                         } else if (getzoneid() != GLOBAL_ZONEID) {
948                                 /*
949                                  * If zoned property is 'off', this must be in
950                                  * a globle zone. If not, something is wrong.
951                                  */
952                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
953                                     "'%s' cannot be set while dataset "
954                                     "'zoned' property is set"), propname);
955                                 (void) zfs_error(hdl, EZFS_ZONED, errbuf);
956                                 goto error;
957                         }
958
959                         break;
960
961                 case ZFS_PROP_BOOTFS:
962                         /*
963                          * bootfs property value has to be a dataset name and
964                          * the dataset has to be in the same pool as it sets to.
965                          */
966                         if (strval[0] != '\0' && (!zfs_name_valid(strval,
967                             ZFS_TYPE_FILESYSTEM) || !bootfs_poolname_valid(
968                             pool_name, strval))) {
969
970                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
971                                     "is an invalid name"), strval);
972                                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
973                                 goto error;
974                         }
975                         break;
976                 }
977
978                 /*
979                  * For changes to existing volumes, we have some additional
980                  * checks to enforce.
981                  */
982                 if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
983                         uint64_t volsize = zfs_prop_get_int(zhp,
984                             ZFS_PROP_VOLSIZE);
985                         uint64_t blocksize = zfs_prop_get_int(zhp,
986                             ZFS_PROP_VOLBLOCKSIZE);
987                         char buf[64];
988
989                         switch (prop) {
990                         case ZFS_PROP_RESERVATION:
991                                 if (intval > volsize) {
992                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
993                                             "'%s' is greater than current "
994                                             "volume size"), propname);
995                                         (void) zfs_error(hdl, EZFS_BADPROP,
996                                             errbuf);
997                                         goto error;
998                                 }
999                                 break;
1000
1001                         case ZFS_PROP_VOLSIZE:
1002                                 if (intval % blocksize != 0) {
1003                                         zfs_nicenum(blocksize, buf,
1004                                             sizeof (buf));
1005                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1006                                             "'%s' must be a multiple of "
1007                                             "volume block size (%s)"),
1008                                             propname, buf);
1009                                         (void) zfs_error(hdl, EZFS_BADPROP,
1010                                             errbuf);
1011                                         goto error;
1012                                 }
1013
1014                                 if (intval == 0) {
1015                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1016                                             "'%s' cannot be zero"),
1017                                             propname);
1018                                         (void) zfs_error(hdl, EZFS_BADPROP,
1019                                             errbuf);
1020                                         goto error;
1021                                 }
1022                                 break;
1023                         }
1024                 }
1025         }
1026
1027         /*
1028          * If this is an existing volume, and someone is setting the volsize,
1029          * make sure that it matches the reservation, or add it if necessary.
1030          */
1031         if (zhp != NULL && type == ZFS_TYPE_VOLUME &&
1032             nvlist_lookup_uint64(ret, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1033             &intval) == 0) {
1034                 uint64_t old_volsize = zfs_prop_get_int(zhp,
1035                     ZFS_PROP_VOLSIZE);
1036                 uint64_t old_reservation = zfs_prop_get_int(zhp,
1037                     ZFS_PROP_RESERVATION);
1038                 uint64_t new_reservation;
1039
1040                 if (old_volsize == old_reservation &&
1041                     nvlist_lookup_uint64(ret,
1042                     zfs_prop_to_name(ZFS_PROP_RESERVATION),
1043                     &new_reservation) != 0) {
1044                         if (nvlist_add_uint64(ret,
1045                             zfs_prop_to_name(ZFS_PROP_RESERVATION),
1046                             intval) != 0) {
1047                                 (void) no_memory(hdl);
1048                                 goto error;
1049                         }
1050                 }
1051         }
1052
1053         return (ret);
1054
1055 error:
1056         nvlist_free(ret);
1057         return (NULL);
1058 }
1059
1060 /*
1061  * Given a property name and value, set the property for the given dataset.
1062  */
1063 int
1064 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1065 {
1066         zfs_cmd_t zc = { 0 };
1067         int ret = -1;
1068         prop_changelist_t *cl = NULL;
1069         char errbuf[1024];
1070         libzfs_handle_t *hdl = zhp->zfs_hdl;
1071         nvlist_t *nvl = NULL, *realprops;
1072         zfs_prop_t prop;
1073
1074         (void) snprintf(errbuf, sizeof (errbuf),
1075             dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1076             zhp->zfs_name);
1077
1078         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1079             nvlist_add_string(nvl, propname, propval) != 0) {
1080                 (void) no_memory(hdl);
1081                 goto error;
1082         }
1083
1084         if ((realprops = zfs_validate_properties(hdl, zhp->zfs_type, NULL, nvl,
1085             zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1086                 goto error;
1087         nvlist_free(nvl);
1088         nvl = realprops;
1089
1090         prop = zfs_name_to_prop(propname);
1091
1092         /* We don't support those properties on FreeBSD. */
1093         switch (prop) {
1094         case ZFS_PROP_SHAREISCSI:
1095         case ZFS_PROP_DEVICES:
1096         case ZFS_PROP_ACLMODE:
1097         case ZFS_PROP_ACLINHERIT:
1098         case ZFS_PROP_ISCSIOPTIONS:
1099                 (void) snprintf(errbuf, sizeof (errbuf),
1100                     "property '%s' not supported on FreeBSD", propname);
1101                 ret = zfs_error(hdl, EZFS_PERM, errbuf);
1102                 goto error;
1103         }
1104
1105         if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
1106                 goto error;
1107
1108         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1109                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1110                     "child dataset with inherited mountpoint is used "
1111                     "in a non-global zone"));
1112                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1113                 goto error;
1114         }
1115
1116         if ((ret = changelist_prefix(cl)) != 0)
1117                 goto error;
1118
1119         /*
1120          * Execute the corresponding ioctl() to set this property.
1121          */
1122         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1123
1124         if (zcmd_write_src_nvlist(hdl, &zc, nvl, NULL) != 0)
1125                 goto error;
1126
1127         ret = ioctl(hdl->libzfs_fd, ZFS_IOC_SET_PROP, &zc);
1128
1129         if (ret != 0) {
1130                 switch (errno) {
1131
1132                 case ENOSPC:
1133                         /*
1134                          * For quotas and reservations, ENOSPC indicates
1135                          * something different; setting a quota or reservation
1136                          * doesn't use any disk space.
1137                          */
1138                         switch (prop) {
1139                         case ZFS_PROP_QUOTA:
1140                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1141                                     "size is less than current used or "
1142                                     "reserved space"));
1143                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1144                                 break;
1145
1146                         case ZFS_PROP_RESERVATION:
1147                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1148                                     "size is greater than available space"));
1149                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1150                                 break;
1151
1152                         default:
1153                                 (void) zfs_standard_error(hdl, errno, errbuf);
1154                                 break;
1155                         }
1156                         break;
1157
1158                 case EBUSY:
1159                         if (prop == ZFS_PROP_VOLBLOCKSIZE)
1160                                 (void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
1161                         else
1162                                 (void) zfs_standard_error(hdl, EBUSY, errbuf);
1163                         break;
1164
1165                 case EROFS:
1166                         (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1167                         break;
1168
1169                 case ENOTSUP:
1170                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1171                             "pool must be upgraded to allow gzip compression"));
1172                         (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1173                         break;
1174
1175                 case EOVERFLOW:
1176                         /*
1177                          * This platform can't address a volume this big.
1178                          */
1179 #ifdef _ILP32
1180                         if (prop == ZFS_PROP_VOLSIZE) {
1181                                 (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1182                                 break;
1183                         }
1184 #endif
1185                         /* FALLTHROUGH */
1186                 default:
1187                         (void) zfs_standard_error(hdl, errno, errbuf);
1188                 }
1189         } else {
1190                 /*
1191                  * Refresh the statistics so the new property value
1192                  * is reflected.
1193                  */
1194                 if ((ret = changelist_postfix(cl)) == 0)
1195                         (void) get_stats(zhp);
1196         }
1197
1198 error:
1199         nvlist_free(nvl);
1200         zcmd_free_nvlists(&zc);
1201         if (cl)
1202                 changelist_free(cl);
1203         return (ret);
1204 }
1205
1206 /*
1207  * Given a property, inherit the value from the parent dataset.
1208  */
1209 int
1210 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname)
1211 {
1212         zfs_cmd_t zc = { 0 };
1213         int ret;
1214         prop_changelist_t *cl;
1215         libzfs_handle_t *hdl = zhp->zfs_hdl;
1216         char errbuf[1024];
1217         zfs_prop_t prop;
1218
1219         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1220             "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1221
1222         if ((prop = zfs_name_to_prop(propname)) == ZFS_PROP_INVAL) {
1223                 /*
1224                  * For user properties, the amount of work we have to do is very
1225                  * small, so just do it here.
1226                  */
1227                 if (!zfs_prop_user(propname)) {
1228                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1229                             "invalid property"));
1230                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1231                 }
1232
1233                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1234                 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1235
1236                 if (ioctl(zhp->zfs_hdl->libzfs_fd,
1237                     ZFS_IOC_SET_PROP, &zc) != 0)
1238                         return (zfs_standard_error(hdl, errno, errbuf));
1239
1240                 return (0);
1241         }
1242
1243         /*
1244          * Verify that this property is inheritable.
1245          */
1246         if (zfs_prop_readonly(prop))
1247                 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1248
1249         if (!zfs_prop_inheritable(prop))
1250                 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1251
1252         /*
1253          * Check to see if the value applies to this type
1254          */
1255         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1256                 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1257
1258         /*
1259          * Normalize the name, to get rid of shorthand abbrevations.
1260          */
1261         propname = zfs_prop_to_name(prop);
1262         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1263         (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1264
1265         if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1266             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1267                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1268                     "dataset is used in a non-global zone"));
1269                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
1270         }
1271
1272         /*
1273          * Determine datasets which will be affected by this change, if any.
1274          */
1275         if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
1276                 return (-1);
1277
1278         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1279                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1280                     "child dataset with inherited mountpoint is used "
1281                     "in a non-global zone"));
1282                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1283                 goto error;
1284         }
1285
1286         if ((ret = changelist_prefix(cl)) != 0)
1287                 goto error;
1288
1289         if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd,
1290             ZFS_IOC_SET_PROP, &zc)) != 0) {
1291                 return (zfs_standard_error(hdl, errno, errbuf));
1292         } else {
1293
1294                 if ((ret = changelist_postfix(cl)) != 0)
1295                         goto error;
1296
1297                 /*
1298                  * Refresh the statistics so the new property is reflected.
1299                  */
1300                 (void) get_stats(zhp);
1301         }
1302
1303 error:
1304         changelist_free(cl);
1305         return (ret);
1306 }
1307
1308 void
1309 nicebool(int value, char *buf, size_t buflen)
1310 {
1311         if (value)
1312                 (void) strlcpy(buf, "on", buflen);
1313         else
1314                 (void) strlcpy(buf, "off", buflen);
1315 }
1316
1317 /*
1318  * True DSL properties are stored in an nvlist.  The following two functions
1319  * extract them appropriately.
1320  */
1321 static uint64_t
1322 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1323 {
1324         nvlist_t *nv;
1325         uint64_t value;
1326
1327         *source = NULL;
1328         if (nvlist_lookup_nvlist(zhp->zfs_props,
1329             zfs_prop_to_name(prop), &nv) == 0) {
1330                 verify(nvlist_lookup_uint64(nv, ZFS_PROP_VALUE, &value) == 0);
1331                 (void) nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source);
1332         } else {
1333                 value = zfs_prop_default_numeric(prop);
1334                 *source = "";
1335         }
1336
1337         return (value);
1338 }
1339
1340 static char *
1341 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1342 {
1343         nvlist_t *nv;
1344         char *value;
1345
1346         *source = NULL;
1347         if (nvlist_lookup_nvlist(zhp->zfs_props,
1348             zfs_prop_to_name(prop), &nv) == 0) {
1349                 verify(nvlist_lookup_string(nv, ZFS_PROP_VALUE, &value) == 0);
1350                 (void) nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source);
1351         } else {
1352                 if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
1353                         value = "";
1354                 *source = "";
1355         }
1356
1357         return (value);
1358 }
1359
1360 /*
1361  * Internal function for getting a numeric property.  Both zfs_prop_get() and
1362  * zfs_prop_get_int() are built using this interface.
1363  *
1364  * Certain properties can be overridden using 'mount -o'.  In this case, scan
1365  * the contents of the /etc/mnttab entry, searching for the appropriate options.
1366  * If they differ from the on-disk values, report the current values and mark
1367  * the source "temporary".
1368  */
1369 static int
1370 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zfs_source_t *src,
1371     char **source, uint64_t *val)
1372 {
1373         struct mnttab mnt;
1374         char *mntopt_on = NULL;
1375         char *mntopt_off = NULL;
1376
1377         *source = NULL;
1378
1379         switch (prop) {
1380         case ZFS_PROP_ATIME:
1381                 mntopt_on = MNTOPT_ATIME;
1382                 mntopt_off = MNTOPT_NOATIME;
1383                 break;
1384
1385         case ZFS_PROP_DEVICES:
1386                 mntopt_on = MNTOPT_DEVICES;
1387                 mntopt_off = MNTOPT_NODEVICES;
1388                 break;
1389
1390         case ZFS_PROP_EXEC:
1391                 mntopt_on = MNTOPT_EXEC;
1392                 mntopt_off = MNTOPT_NOEXEC;
1393                 break;
1394
1395         case ZFS_PROP_READONLY:
1396                 mntopt_on = MNTOPT_RO;
1397                 mntopt_off = MNTOPT_RW;
1398                 break;
1399
1400         case ZFS_PROP_SETUID:
1401                 mntopt_on = MNTOPT_SETUID;
1402                 mntopt_off = MNTOPT_NOSETUID;
1403                 break;
1404
1405         case ZFS_PROP_XATTR:
1406                 mntopt_on = MNTOPT_XATTR;
1407                 mntopt_off = MNTOPT_NOXATTR;
1408                 break;
1409         }
1410
1411         /*
1412          * Because looking up the mount options is potentially expensive
1413          * (iterating over all of /etc/mnttab), we defer its calculation until
1414          * we're looking up a property which requires its presence.
1415          */
1416         if (!zhp->zfs_mntcheck &&
1417             (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
1418                 struct mnttab entry, search = { 0 };
1419                 FILE *mnttab = zhp->zfs_hdl->libzfs_mnttab;
1420
1421                 search.mnt_special = (char *)zhp->zfs_name;
1422                 search.mnt_fstype = MNTTYPE_ZFS;
1423                 rewind(mnttab);
1424
1425                 if (getmntany(mnttab, &entry, &search) == 0) {
1426                         zhp->zfs_mntopts = zfs_strdup(zhp->zfs_hdl,
1427                             entry.mnt_mntopts);
1428                         if (zhp->zfs_mntopts == NULL)
1429                                 return (-1);
1430                 }
1431
1432                 zhp->zfs_mntcheck = B_TRUE;
1433         }
1434
1435         if (zhp->zfs_mntopts == NULL)
1436                 mnt.mnt_mntopts = "";
1437         else
1438                 mnt.mnt_mntopts = zhp->zfs_mntopts;
1439
1440         switch (prop) {
1441         case ZFS_PROP_ATIME:
1442         case ZFS_PROP_DEVICES:
1443         case ZFS_PROP_EXEC:
1444         case ZFS_PROP_READONLY:
1445         case ZFS_PROP_SETUID:
1446         case ZFS_PROP_XATTR:
1447                 *val = getprop_uint64(zhp, prop, source);
1448
1449                 if (hasmntopt(&mnt, mntopt_on) && !*val) {
1450                         *val = B_TRUE;
1451                         if (src)
1452                                 *src = ZFS_SRC_TEMPORARY;
1453                 } else if (hasmntopt(&mnt, mntopt_off) && *val) {
1454                         *val = B_FALSE;
1455                         if (src)
1456                                 *src = ZFS_SRC_TEMPORARY;
1457                 }
1458                 break;
1459
1460         case ZFS_PROP_RECORDSIZE:
1461         case ZFS_PROP_COMPRESSION:
1462         case ZFS_PROP_ZONED:
1463         case ZFS_PROP_CREATION:
1464         case ZFS_PROP_COMPRESSRATIO:
1465         case ZFS_PROP_REFERENCED:
1466         case ZFS_PROP_USED:
1467         case ZFS_PROP_CREATETXG:
1468         case ZFS_PROP_AVAILABLE:
1469         case ZFS_PROP_VOLSIZE:
1470         case ZFS_PROP_VOLBLOCKSIZE:
1471                 *val = getprop_uint64(zhp, prop, source);
1472                 break;
1473
1474         case ZFS_PROP_CANMOUNT:
1475                 *val = getprop_uint64(zhp, prop, source);
1476                 if (*val == 0)
1477                         *source = zhp->zfs_name;
1478                 else
1479                         *source = "";   /* default */
1480                 break;
1481
1482         case ZFS_PROP_QUOTA:
1483         case ZFS_PROP_RESERVATION:
1484                 *val = getprop_uint64(zhp, prop, source);
1485                 if (*val == 0)
1486                         *source = "";   /* default */
1487                 else
1488                         *source = zhp->zfs_name;
1489                 break;
1490
1491         case ZFS_PROP_MOUNTED:
1492                 *val = (zhp->zfs_mntopts != NULL);
1493                 break;
1494
1495         case ZFS_PROP_NUMCLONES:
1496                 *val = zhp->zfs_dmustats.dds_num_clones;
1497                 break;
1498
1499         default:
1500                 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1501                     "cannot get non-numeric property"));
1502                 return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
1503                     dgettext(TEXT_DOMAIN, "internal error")));
1504         }
1505
1506         return (0);
1507 }
1508
1509 /*
1510  * Calculate the source type, given the raw source string.
1511  */
1512 static void
1513 get_source(zfs_handle_t *zhp, zfs_source_t *srctype, char *source,
1514     char *statbuf, size_t statlen)
1515 {
1516         if (statbuf == NULL || *srctype == ZFS_SRC_TEMPORARY)
1517                 return;
1518
1519         if (source == NULL) {
1520                 *srctype = ZFS_SRC_NONE;
1521         } else if (source[0] == '\0') {
1522                 *srctype = ZFS_SRC_DEFAULT;
1523         } else {
1524                 if (strcmp(source, zhp->zfs_name) == 0) {
1525                         *srctype = ZFS_SRC_LOCAL;
1526                 } else {
1527                         (void) strlcpy(statbuf, source, statlen);
1528                         *srctype = ZFS_SRC_INHERITED;
1529                 }
1530         }
1531
1532 }
1533
1534 /*
1535  * Retrieve a property from the given object.  If 'literal' is specified, then
1536  * numbers are left as exact values.  Otherwise, numbers are converted to a
1537  * human-readable form.
1538  *
1539  * Returns 0 on success, or -1 on error.
1540  */
1541 int
1542 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
1543     zfs_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
1544 {
1545         char *source = NULL;
1546         uint64_t val;
1547         char *str;
1548         const char *root;
1549         const char *strval;
1550
1551         /*
1552          * Check to see if this property applies to our object
1553          */
1554         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1555                 return (-1);
1556
1557         if (src)
1558                 *src = ZFS_SRC_NONE;
1559
1560         switch (prop) {
1561         case ZFS_PROP_ATIME:
1562         case ZFS_PROP_READONLY:
1563         case ZFS_PROP_SETUID:
1564         case ZFS_PROP_ZONED:
1565         case ZFS_PROP_DEVICES:
1566         case ZFS_PROP_EXEC:
1567         case ZFS_PROP_CANMOUNT:
1568         case ZFS_PROP_XATTR:
1569                 /*
1570                  * Basic boolean values are built on top of
1571                  * get_numeric_property().
1572                  */
1573                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1574                         return (-1);
1575                 nicebool(val, propbuf, proplen);
1576
1577                 break;
1578
1579         case ZFS_PROP_AVAILABLE:
1580         case ZFS_PROP_RECORDSIZE:
1581         case ZFS_PROP_CREATETXG:
1582         case ZFS_PROP_REFERENCED:
1583         case ZFS_PROP_USED:
1584         case ZFS_PROP_VOLSIZE:
1585         case ZFS_PROP_VOLBLOCKSIZE:
1586         case ZFS_PROP_NUMCLONES:
1587                 /*
1588                  * Basic numeric values are built on top of
1589                  * get_numeric_property().
1590                  */
1591                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1592                         return (-1);
1593                 if (literal)
1594                         (void) snprintf(propbuf, proplen, "%llu",
1595                             (u_longlong_t)val);
1596                 else
1597                         zfs_nicenum(val, propbuf, proplen);
1598                 break;
1599
1600         case ZFS_PROP_COMPRESSION:
1601         case ZFS_PROP_CHECKSUM:
1602         case ZFS_PROP_SNAPDIR:
1603 #ifdef  ZFS_NO_ACL
1604         case ZFS_PROP_ACLMODE:
1605         case ZFS_PROP_ACLINHERIT:
1606         case ZFS_PROP_COPIES:
1607                 val = getprop_uint64(zhp, prop, &source);
1608                 verify(zfs_prop_index_to_string(prop, val, &strval) == 0);
1609                 (void) strlcpy(propbuf, strval, proplen);
1610                 break;
1611 #else   /* ZFS_NO_ACL */
1612         case ZFS_PROP_ACLMODE:
1613         case ZFS_PROP_ACLINHERIT:
1614                 (void) strlcpy(propbuf, "<unsupported>", proplen);
1615                 break;
1616 #endif  /* ZFS_NO_ACL */
1617
1618         case ZFS_PROP_CREATION:
1619                 /*
1620                  * 'creation' is a time_t stored in the statistics.  We convert
1621                  * this into a string unless 'literal' is specified.
1622                  */
1623                 {
1624                         val = getprop_uint64(zhp, prop, &source);
1625                         time_t time = (time_t)val;
1626                         struct tm t;
1627
1628                         if (literal ||
1629                             localtime_r(&time, &t) == NULL ||
1630                             strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
1631                             &t) == 0)
1632                                 (void) snprintf(propbuf, proplen, "%llu", val);
1633                 }
1634                 break;
1635
1636         case ZFS_PROP_MOUNTPOINT:
1637                 /*
1638                  * Getting the precise mountpoint can be tricky.
1639                  *
1640                  *  - for 'none' or 'legacy', return those values.
1641                  *  - for default mountpoints, construct it as /zfs/<dataset>
1642                  *  - for inherited mountpoints, we want to take everything
1643                  *    after our ancestor and append it to the inherited value.
1644                  *
1645                  * If the pool has an alternate root, we want to prepend that
1646                  * root to any values we return.
1647                  */
1648                 root = zhp->zfs_root;
1649                 str = getprop_string(zhp, prop, &source);
1650
1651                 if (str[0] == '\0') {
1652                         (void) snprintf(propbuf, proplen, "%s/zfs/%s",
1653                             root, zhp->zfs_name);
1654                 } else if (str[0] == '/') {
1655                         const char *relpath = zhp->zfs_name + strlen(source);
1656
1657                         if (relpath[0] == '/')
1658                                 relpath++;
1659                         if (str[1] == '\0')
1660                                 str++;
1661
1662                         if (relpath[0] == '\0')
1663                                 (void) snprintf(propbuf, proplen, "%s%s",
1664                                     root, str);
1665                         else
1666                                 (void) snprintf(propbuf, proplen, "%s%s%s%s",
1667                                     root, str, relpath[0] == '@' ? "" : "/",
1668                                     relpath);
1669                 } else {
1670                         /* 'legacy' or 'none' */
1671                         (void) strlcpy(propbuf, str, proplen);
1672                 }
1673
1674                 break;
1675
1676         case ZFS_PROP_SHARENFS:
1677         case ZFS_PROP_SHAREISCSI:
1678         case ZFS_PROP_ISCSIOPTIONS:
1679                 (void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
1680                     proplen);
1681                 break;
1682
1683         case ZFS_PROP_ORIGIN:
1684                 (void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
1685                     proplen);
1686                 /*
1687                  * If there is no parent at all, return failure to indicate that
1688                  * it doesn't apply to this dataset.
1689                  */
1690                 if (propbuf[0] == '\0')
1691                         return (-1);
1692                 break;
1693
1694         case ZFS_PROP_QUOTA:
1695         case ZFS_PROP_RESERVATION:
1696                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1697                         return (-1);
1698
1699                 /*
1700                  * If quota or reservation is 0, we translate this into 'none'
1701                  * (unless literal is set), and indicate that it's the default
1702                  * value.  Otherwise, we print the number nicely and indicate
1703                  * that its set locally.
1704                  */
1705                 if (val == 0) {
1706                         if (literal)
1707                                 (void) strlcpy(propbuf, "0", proplen);
1708                         else
1709                                 (void) strlcpy(propbuf, "none", proplen);
1710                 } else {
1711                         if (literal)
1712                                 (void) snprintf(propbuf, proplen, "%llu",
1713                                     (u_longlong_t)val);
1714                         else
1715                                 zfs_nicenum(val, propbuf, proplen);
1716                 }
1717                 break;
1718
1719         case ZFS_PROP_COMPRESSRATIO:
1720                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1721                         return (-1);
1722                 (void) snprintf(propbuf, proplen, "%lld.%02lldx", (longlong_t)
1723                     val / 100, (longlong_t)val % 100);
1724                 break;
1725
1726         case ZFS_PROP_TYPE:
1727                 switch (zhp->zfs_type) {
1728                 case ZFS_TYPE_FILESYSTEM:
1729                         str = "filesystem";
1730                         break;
1731                 case ZFS_TYPE_VOLUME:
1732                         str = "volume";
1733                         break;
1734                 case ZFS_TYPE_SNAPSHOT:
1735                         str = "snapshot";
1736                         break;
1737                 default:
1738                         abort();
1739                 }
1740                 (void) snprintf(propbuf, proplen, "%s", str);
1741                 break;
1742
1743         case ZFS_PROP_MOUNTED:
1744                 /*
1745                  * The 'mounted' property is a pseudo-property that described
1746                  * whether the filesystem is currently mounted.  Even though
1747                  * it's a boolean value, the typical values of "on" and "off"
1748                  * don't make sense, so we translate to "yes" and "no".
1749                  */
1750                 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
1751                     src, &source, &val) != 0)
1752                         return (-1);
1753                 if (val)
1754                         (void) strlcpy(propbuf, "yes", proplen);
1755                 else
1756                         (void) strlcpy(propbuf, "no", proplen);
1757                 break;
1758
1759         case ZFS_PROP_NAME:
1760                 /*
1761                  * The 'name' property is a pseudo-property derived from the
1762                  * dataset name.  It is presented as a real property to simplify
1763                  * consumers.
1764                  */
1765                 (void) strlcpy(propbuf, zhp->zfs_name, proplen);
1766                 break;
1767
1768         default:
1769                 abort();
1770         }
1771
1772         get_source(zhp, src, source, statbuf, statlen);
1773
1774         return (0);
1775 }
1776
1777 /*
1778  * Utility function to get the given numeric property.  Does no validation that
1779  * the given property is the appropriate type; should only be used with
1780  * hard-coded property types.
1781  */
1782 uint64_t
1783 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
1784 {
1785         char *source;
1786         zfs_source_t sourcetype = ZFS_SRC_NONE;
1787         uint64_t val;
1788
1789         (void) get_numeric_property(zhp, prop, &sourcetype, &source, &val);
1790
1791         return (val);
1792 }
1793
1794 /*
1795  * Similar to zfs_prop_get(), but returns the value as an integer.
1796  */
1797 int
1798 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
1799     zfs_source_t *src, char *statbuf, size_t statlen)
1800 {
1801         char *source;
1802
1803         /*
1804          * Check to see if this property applies to our object
1805          */
1806         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1807                 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
1808                     dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
1809                     zfs_prop_to_name(prop)));
1810
1811         if (src)
1812                 *src = ZFS_SRC_NONE;
1813
1814         if (get_numeric_property(zhp, prop, src, &source, value) != 0)
1815                 return (-1);
1816
1817         get_source(zhp, src, source, statbuf, statlen);
1818
1819         return (0);
1820 }
1821
1822 /*
1823  * Returns the name of the given zfs handle.
1824  */
1825 const char *
1826 zfs_get_name(const zfs_handle_t *zhp)
1827 {
1828         return (zhp->zfs_name);
1829 }
1830
1831 /*
1832  * Returns the type of the given zfs handle.
1833  */
1834 zfs_type_t
1835 zfs_get_type(const zfs_handle_t *zhp)
1836 {
1837         return (zhp->zfs_type);
1838 }
1839
1840 /*
1841  * Iterate over all child filesystems
1842  */
1843 int
1844 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1845 {
1846         zfs_cmd_t zc = { 0 };
1847         zfs_handle_t *nzhp;
1848         int ret;
1849
1850         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1851             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
1852             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
1853                 /*
1854                  * Ignore private dataset names.
1855                  */
1856                 if (dataset_name_hidden(zc.zc_name))
1857                         continue;
1858
1859                 /*
1860                  * Silently ignore errors, as the only plausible explanation is
1861                  * that the pool has since been removed.
1862                  */
1863                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
1864                     zc.zc_name)) == NULL)
1865                         continue;
1866
1867                 if ((ret = func(nzhp, data)) != 0)
1868                         return (ret);
1869         }
1870
1871         /*
1872          * An errno value of ESRCH indicates normal completion.  If ENOENT is
1873          * returned, then the underlying dataset has been removed since we
1874          * obtained the handle.
1875          */
1876         if (errno != ESRCH && errno != ENOENT)
1877                 return (zfs_standard_error(zhp->zfs_hdl, errno,
1878                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
1879
1880         return (0);
1881 }
1882
1883 /*
1884  * Iterate over all snapshots
1885  */
1886 int
1887 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1888 {
1889         zfs_cmd_t zc = { 0 };
1890         zfs_handle_t *nzhp;
1891         int ret;
1892
1893         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1894             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
1895             &zc) == 0;
1896             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
1897
1898                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
1899                     zc.zc_name)) == NULL)
1900                         continue;
1901
1902                 if ((ret = func(nzhp, data)) != 0)
1903                         return (ret);
1904         }
1905
1906         /*
1907          * An errno value of ESRCH indicates normal completion.  If ENOENT is
1908          * returned, then the underlying dataset has been removed since we
1909          * obtained the handle.  Silently ignore this case, and return success.
1910          */
1911         if (errno != ESRCH && errno != ENOENT)
1912                 return (zfs_standard_error(zhp->zfs_hdl, errno,
1913                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
1914
1915         return (0);
1916 }
1917
1918 /*
1919  * Iterate over all children, snapshots and filesystems
1920  */
1921 int
1922 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1923 {
1924         int ret;
1925
1926         if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
1927                 return (ret);
1928
1929         return (zfs_iter_snapshots(zhp, func, data));
1930 }
1931
1932 /*
1933  * Given a complete name, return just the portion that refers to the parent.
1934  * Can return NULL if this is a pool.
1935  */
1936 static int
1937 parent_name(const char *path, char *buf, size_t buflen)
1938 {
1939         char *loc;
1940
1941         if ((loc = strrchr(path, '/')) == NULL)
1942                 return (-1);
1943
1944         (void) strncpy(buf, path, MIN(buflen, loc - path));
1945         buf[loc - path] = '\0';
1946
1947         return (0);
1948 }
1949
1950 /*
1951  * Checks to make sure that the given path has a parent, and that it exists.  We
1952  * also fetch the 'zoned' property, which is used to validate property settings
1953  * when creating new datasets.
1954  */
1955 static int
1956 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned)
1957 {
1958         zfs_cmd_t zc = { 0 };
1959         char parent[ZFS_MAXNAMELEN];
1960         char *slash;
1961         zfs_handle_t *zhp;
1962         char errbuf[1024];
1963
1964         (void) snprintf(errbuf, sizeof (errbuf), "cannot create '%s'",
1965             path);
1966
1967         /* get parent, and check to see if this is just a pool */
1968         if (parent_name(path, parent, sizeof (parent)) != 0) {
1969                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1970                     "missing dataset name"));
1971                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1972         }
1973
1974         /* check to see if the pool exists */
1975         if ((slash = strchr(parent, '/')) == NULL)
1976                 slash = parent + strlen(parent);
1977         (void) strncpy(zc.zc_name, parent, slash - parent);
1978         zc.zc_name[slash - parent] = '\0';
1979         if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
1980             errno == ENOENT) {
1981                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1982                     "no such pool '%s'"), zc.zc_name);
1983                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
1984         }
1985
1986         /* check to see if the parent dataset exists */
1987         if ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
1988                 switch (errno) {
1989                 case ENOENT:
1990                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1991                             "parent does not exist"));
1992                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
1993
1994                 default:
1995                         return (zfs_standard_error(hdl, errno, errbuf));
1996                 }
1997         }
1998
1999         *zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
2000         /* we are in a non-global zone, but parent is in the global zone */
2001         if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) {
2002                 (void) zfs_standard_error(hdl, EPERM, errbuf);
2003                 zfs_close(zhp);
2004                 return (-1);
2005         }
2006
2007         /* make sure parent is a filesystem */
2008         if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
2009                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2010                     "parent is not a filesystem"));
2011                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
2012                 zfs_close(zhp);
2013                 return (-1);
2014         }
2015
2016         zfs_close(zhp);
2017         return (0);
2018 }
2019
2020 /*
2021  * Create a new filesystem or volume.
2022  */
2023 int
2024 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2025     nvlist_t *props)
2026 {
2027         zfs_cmd_t zc = { 0 };
2028         int ret;
2029         uint64_t size = 0;
2030         uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2031         char errbuf[1024];
2032         uint64_t zoned;
2033
2034         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2035             "cannot create '%s'"), path);
2036
2037         /* validate the path, taking care to note the extended error message */
2038         if (!zfs_validate_name(hdl, path, type))
2039                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2040
2041         /* validate parents exist */
2042         if (check_parents(hdl, path, &zoned) != 0)
2043                 return (-1);
2044
2045         /*
2046          * The failure modes when creating a dataset of a different type over
2047          * one that already exists is a little strange.  In particular, if you
2048          * try to create a dataset on top of an existing dataset, the ioctl()
2049          * will return ENOENT, not EEXIST.  To prevent this from happening, we
2050          * first try to see if the dataset exists.
2051          */
2052         (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2053         if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
2054                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2055                     "dataset already exists"));
2056                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2057         }
2058
2059         if (type == ZFS_TYPE_VOLUME)
2060                 zc.zc_objset_type = DMU_OST_ZVOL;
2061         else
2062                 zc.zc_objset_type = DMU_OST_ZFS;
2063
2064         if (props && (props = zfs_validate_properties(hdl, type, NULL, props,
2065             zoned, NULL, errbuf)) == 0)
2066                 return (-1);
2067
2068         if (type == ZFS_TYPE_VOLUME) {
2069                 /*
2070                  * If we are creating a volume, the size and block size must
2071                  * satisfy a few restraints.  First, the blocksize must be a
2072                  * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
2073                  * volsize must be a multiple of the block size, and cannot be
2074                  * zero.
2075                  */
2076                 if (props == NULL || nvlist_lookup_uint64(props,
2077                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
2078                         nvlist_free(props);
2079                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2080                             "missing volume size"));
2081                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2082                 }
2083
2084                 if ((ret = nvlist_lookup_uint64(props,
2085                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
2086                     &blocksize)) != 0) {
2087                         if (ret == ENOENT) {
2088                                 blocksize = zfs_prop_default_numeric(
2089                                     ZFS_PROP_VOLBLOCKSIZE);
2090                         } else {
2091                                 nvlist_free(props);
2092                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2093                                     "missing volume block size"));
2094                                 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2095                         }
2096                 }
2097
2098                 if (size == 0) {
2099                         nvlist_free(props);
2100                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2101                             "volume size cannot be zero"));
2102                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2103                 }
2104
2105                 if (size % blocksize != 0) {
2106                         nvlist_free(props);
2107                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2108                             "volume size must be a multiple of volume block "
2109                             "size"));
2110                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2111                 }
2112         }
2113
2114         if (props &&
2115             zcmd_write_src_nvlist(hdl, &zc, props, NULL) != 0)
2116                 return (-1);
2117         nvlist_free(props);
2118
2119         /* create the dataset */
2120         ret = ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
2121
2122         if (ret == 0 && type == ZFS_TYPE_VOLUME) {
2123                 ret = zvol_create_link(hdl, path);
2124                 if (ret) {
2125                         (void) zfs_standard_error(hdl, errno,
2126                             dgettext(TEXT_DOMAIN,
2127                             "Volume successfully created, but device links "
2128                             "were not created"));
2129                         zcmd_free_nvlists(&zc);
2130                         return (-1);
2131                 }
2132         }
2133
2134         zcmd_free_nvlists(&zc);
2135
2136         /* check for failure */
2137         if (ret != 0) {
2138                 char parent[ZFS_MAXNAMELEN];
2139                 (void) parent_name(path, parent, sizeof (parent));
2140
2141                 switch (errno) {
2142                 case ENOENT:
2143                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2144                             "no such parent '%s'"), parent);
2145                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
2146
2147                 case EINVAL:
2148                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2149                             "parent '%s' is not a filesystem"), parent);
2150                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2151
2152                 case EDOM:
2153                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2154                             "volume block size must be power of 2 from "
2155                             "%u to %uk"),
2156                             (uint_t)SPA_MINBLOCKSIZE,
2157                             (uint_t)SPA_MAXBLOCKSIZE >> 10);
2158
2159                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2160
2161 #ifdef _ILP32
2162                 case EOVERFLOW:
2163                         /*
2164                          * This platform can't address a volume this big.
2165                          */
2166                         if (type == ZFS_TYPE_VOLUME)
2167                                 return (zfs_error(hdl, EZFS_VOLTOOBIG,
2168                                     errbuf));
2169 #endif
2170                         /* FALLTHROUGH */
2171                 default:
2172                         return (zfs_standard_error(hdl, errno, errbuf));
2173                 }
2174         }
2175
2176         return (0);
2177 }
2178
2179 /*
2180  * Destroys the given dataset.  The caller must make sure that the filesystem
2181  * isn't mounted, and that there are no active dependents.
2182  */
2183 int
2184 zfs_destroy(zfs_handle_t *zhp)
2185 {
2186         zfs_cmd_t zc = { 0 };
2187
2188         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2189
2190         if (ZFS_IS_VOLUME(zhp)) {
2191                 /*
2192                  * Unconditionally unshare this zvol ignoring failure as it
2193                  * indicates only that the volume wasn't shared initially.
2194                  */
2195                 (void) zfs_unshare_iscsi(zhp);
2196
2197                 if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
2198                         return (-1);
2199
2200                 zc.zc_objset_type = DMU_OST_ZVOL;
2201         } else {
2202                 zc.zc_objset_type = DMU_OST_ZFS;
2203         }
2204
2205         if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) != 0) {
2206                 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
2207                     dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
2208                     zhp->zfs_name));
2209         }
2210
2211         remove_mountpoint(zhp);
2212
2213         return (0);
2214 }
2215
2216 struct destroydata {
2217         char *snapname;
2218         boolean_t gotone;
2219         boolean_t closezhp;
2220 };
2221
2222 static int
2223 zfs_remove_link_cb(zfs_handle_t *zhp, void *arg)
2224 {
2225         struct destroydata *dd = arg;
2226         zfs_handle_t *szhp;
2227         char name[ZFS_MAXNAMELEN];
2228         boolean_t closezhp = dd->closezhp;
2229         int rv;
2230
2231         (void) strlcpy(name, zhp->zfs_name, sizeof (name));
2232         (void) strlcat(name, "@", sizeof (name));
2233         (void) strlcat(name, dd->snapname, sizeof (name));
2234
2235         szhp = make_dataset_handle(zhp->zfs_hdl, name);
2236         if (szhp) {
2237                 dd->gotone = B_TRUE;
2238                 zfs_close(szhp);
2239         }
2240
2241         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2242                 (void) zvol_remove_link(zhp->zfs_hdl, name);
2243                 /*
2244                  * NB: this is simply a best-effort.  We don't want to
2245                  * return an error, because then we wouldn't visit all
2246                  * the volumes.
2247                  */
2248         }
2249
2250         dd->closezhp = B_TRUE;
2251         rv = zfs_iter_filesystems(zhp, zfs_remove_link_cb, arg);
2252         if (closezhp)
2253                 zfs_close(zhp);
2254         return (rv);
2255 }
2256
2257 /*
2258  * Destroys all snapshots with the given name in zhp & descendants.
2259  */
2260 int
2261 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname)
2262 {
2263         zfs_cmd_t zc = { 0 };
2264         int ret;
2265         struct destroydata dd = { 0 };
2266
2267         dd.snapname = snapname;
2268         (void) zfs_remove_link_cb(zhp, &dd);
2269
2270         if (!dd.gotone) {
2271                 return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
2272                     dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
2273                     zhp->zfs_name, snapname));
2274         }
2275
2276         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2277         (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
2278
2279         ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY_SNAPS, &zc);
2280         if (ret != 0) {
2281                 char errbuf[1024];
2282
2283                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2284                     "cannot destroy '%s@%s'"), zc.zc_name, snapname);
2285
2286                 switch (errno) {
2287                 case EEXIST:
2288                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2289                             "snapshot is cloned"));
2290                         return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
2291
2292                 default:
2293                         return (zfs_standard_error(zhp->zfs_hdl, errno,
2294                             errbuf));
2295                 }
2296         }
2297
2298         return (0);
2299 }
2300
2301 /*
2302  * Clones the given dataset.  The target must be of the same type as the source.
2303  */
2304 int
2305 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
2306 {
2307         zfs_cmd_t zc = { 0 };
2308         char parent[ZFS_MAXNAMELEN];
2309         int ret;
2310         char errbuf[1024];
2311         libzfs_handle_t *hdl = zhp->zfs_hdl;
2312         zfs_type_t type;
2313         uint64_t zoned;
2314
2315         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
2316
2317         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2318             "cannot create '%s'"), target);
2319
2320         /* validate the target name */
2321         if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM))
2322                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2323
2324         /* validate parents exist */
2325         if (check_parents(hdl, target, &zoned) != 0)
2326                 return (-1);
2327
2328         (void) parent_name(target, parent, sizeof (parent));
2329
2330         /* do the clone */
2331         if (ZFS_IS_VOLUME(zhp)) {
2332                 zc.zc_objset_type = DMU_OST_ZVOL;
2333                 type = ZFS_TYPE_VOLUME;
2334         } else {
2335                 zc.zc_objset_type = DMU_OST_ZFS;
2336                 type = ZFS_TYPE_FILESYSTEM;
2337         }
2338
2339         if (props) {
2340                 if ((props = zfs_validate_properties(hdl, type, NULL, props,
2341                     zoned, zhp, errbuf)) == NULL)
2342                         return (-1);
2343
2344                 if (zcmd_write_src_nvlist(hdl, &zc, props, NULL) != 0) {
2345                         nvlist_free(props);
2346                         return (-1);
2347                 }
2348
2349                 nvlist_free(props);
2350         }
2351
2352         (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
2353         (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
2354         ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
2355
2356         zcmd_free_nvlists(&zc);
2357
2358         if (ret != 0) {
2359                 switch (errno) {
2360
2361                 case ENOENT:
2362                         /*
2363                          * The parent doesn't exist.  We should have caught this
2364                          * above, but there may a race condition that has since
2365                          * destroyed the parent.
2366                          *
2367                          * At this point, we don't know whether it's the source
2368                          * that doesn't exist anymore, or whether the target
2369                          * dataset doesn't exist.
2370                          */
2371                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2372                             "no such parent '%s'"), parent);
2373                         return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
2374
2375                 case EXDEV:
2376                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2377                             "source and target pools differ"));
2378                         return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
2379                             errbuf));
2380
2381                 default:
2382                         return (zfs_standard_error(zhp->zfs_hdl, errno,
2383                             errbuf));
2384                 }
2385         } else if (ZFS_IS_VOLUME(zhp)) {
2386                 ret = zvol_create_link(zhp->zfs_hdl, target);
2387         }
2388
2389         return (ret);
2390 }
2391
2392 typedef struct promote_data {
2393         char cb_mountpoint[MAXPATHLEN];
2394         const char *cb_target;
2395         const char *cb_errbuf;
2396         uint64_t cb_pivot_txg;
2397 } promote_data_t;
2398
2399 static int
2400 promote_snap_cb(zfs_handle_t *zhp, void *data)
2401 {
2402         promote_data_t *pd = data;
2403         zfs_handle_t *szhp;
2404         char snapname[MAXPATHLEN];
2405         int rv = 0;
2406
2407         /* We don't care about snapshots after the pivot point */
2408         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg) {
2409                 zfs_close(zhp);
2410                 return (0);
2411         }
2412
2413         /* Remove the device link if it's a zvol. */
2414         if (ZFS_IS_VOLUME(zhp))
2415                 (void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
2416
2417         /* Check for conflicting names */
2418         (void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
2419         (void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
2420         szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
2421         if (szhp != NULL) {
2422                 zfs_close(szhp);
2423                 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2424                     "snapshot name '%s' from origin \n"
2425                     "conflicts with '%s' from target"),
2426                     zhp->zfs_name, snapname);
2427                 rv = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf);
2428         }
2429         zfs_close(zhp);
2430         return (rv);
2431 }
2432
2433 static int
2434 promote_snap_done_cb(zfs_handle_t *zhp, void *data)
2435 {
2436         promote_data_t *pd = data;
2437
2438         /* We don't care about snapshots after the pivot point */
2439         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) <= pd->cb_pivot_txg) {
2440                 /* Create the device link if it's a zvol. */
2441                 if (ZFS_IS_VOLUME(zhp))
2442                         (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
2443         }
2444
2445         zfs_close(zhp);
2446         return (0);
2447 }
2448
2449 /*
2450  * Promotes the given clone fs to be the clone parent.
2451  */
2452 int
2453 zfs_promote(zfs_handle_t *zhp)
2454 {
2455         libzfs_handle_t *hdl = zhp->zfs_hdl;
2456         zfs_cmd_t zc = { 0 };
2457         char parent[MAXPATHLEN];
2458         char *cp;
2459         int ret;
2460         zfs_handle_t *pzhp;
2461         promote_data_t pd;
2462         char errbuf[1024];
2463
2464         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2465             "cannot promote '%s'"), zhp->zfs_name);
2466
2467         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
2468                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2469                     "snapshots can not be promoted"));
2470                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2471         }
2472
2473         (void) strlcpy(parent, zhp->zfs_dmustats.dds_clone_of, sizeof (parent));
2474         if (parent[0] == '\0') {
2475                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2476                     "not a cloned filesystem"));
2477                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2478         }
2479         cp = strchr(parent, '@');
2480         *cp = '\0';
2481
2482         /* Walk the snapshots we will be moving */
2483         pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_clone_of, ZFS_TYPE_SNAPSHOT);
2484         if (pzhp == NULL)
2485                 return (-1);
2486         pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
2487         zfs_close(pzhp);
2488         pd.cb_target = zhp->zfs_name;
2489         pd.cb_errbuf = errbuf;
2490         pzhp = zfs_open(hdl, parent, ZFS_TYPE_ANY);
2491         if (pzhp == NULL)
2492                 return (-1);
2493         (void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
2494             sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
2495         ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
2496         if (ret != 0) {
2497                 zfs_close(pzhp);
2498                 return (-1);
2499         }
2500
2501         /* issue the ioctl */
2502         (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_clone_of,
2503             sizeof (zc.zc_value));
2504         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2505         ret = ioctl(hdl->libzfs_fd, ZFS_IOC_PROMOTE, &zc);
2506
2507         if (ret != 0) {
2508                 int save_errno = errno;
2509
2510                 (void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
2511                 zfs_close(pzhp);
2512
2513                 switch (save_errno) {
2514                 case EEXIST:
2515                         /*
2516                          * There is a conflicting snapshot name.  We
2517                          * should have caught this above, but they could
2518                          * have renamed something in the mean time.
2519                          */
2520                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2521                             "conflicting snapshot name from parent '%s'"),
2522                             parent);
2523                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2524
2525                 default:
2526                         return (zfs_standard_error(hdl, save_errno, errbuf));
2527                 }
2528         } else {
2529                 (void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
2530         }
2531
2532         zfs_close(pzhp);
2533         return (ret);
2534 }
2535
2536 struct createdata {
2537         const char *cd_snapname;
2538         int cd_ifexists;
2539 };
2540
2541 static int
2542 zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
2543 {
2544         struct createdata *cd = arg;
2545         int ret;
2546
2547         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2548                 char name[MAXPATHLEN];
2549
2550                 (void) strlcpy(name, zhp->zfs_name, sizeof (name));
2551                 (void) strlcat(name, "@", sizeof (name));
2552                 (void) strlcat(name, cd->cd_snapname, sizeof (name));
2553                 (void) zvol_create_link_common(zhp->zfs_hdl, name,
2554                     cd->cd_ifexists);
2555                 /*
2556                  * NB: this is simply a best-effort.  We don't want to
2557                  * return an error, because then we wouldn't visit all
2558                  * the volumes.
2559                  */
2560         }
2561
2562         ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, cd);
2563
2564         zfs_close(zhp);
2565
2566         return (ret);
2567 }
2568
2569 /*
2570  * Takes a snapshot of the given dataset.
2571  */
2572 int
2573 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive)
2574 {
2575         const char *delim;
2576         char *parent;
2577         zfs_handle_t *zhp;
2578         zfs_cmd_t zc = { 0 };
2579         int ret;
2580         char errbuf[1024];
2581
2582         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2583             "cannot snapshot '%s'"), path);
2584
2585         /* validate the target name */
2586         if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT))
2587                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2588
2589         /* make sure the parent exists and is of the appropriate type */
2590         delim = strchr(path, '@');
2591         if ((parent = zfs_alloc(hdl, delim - path + 1)) == NULL)
2592                 return (-1);
2593         (void) strncpy(parent, path, delim - path);
2594         parent[delim - path] = '\0';
2595
2596         if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
2597             ZFS_TYPE_VOLUME)) == NULL) {
2598                 free(parent);
2599                 return (-1);
2600         }
2601
2602         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2603         (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
2604         zc.zc_cookie = recursive;
2605         ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT, &zc);
2606
2607         /*
2608          * if it was recursive, the one that actually failed will be in
2609          * zc.zc_name.
2610          */
2611         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2612             "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
2613         if (ret == 0 && recursive) {
2614                 struct createdata cd;
2615
2616                 cd.cd_snapname = delim + 1;
2617                 cd.cd_ifexists = B_FALSE;
2618                 (void) zfs_iter_filesystems(zhp, zfs_create_link_cb, &cd);
2619         }
2620         if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
2621                 ret = zvol_create_link(zhp->zfs_hdl, path);
2622                 if (ret != 0) {
2623                         (void) ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY,
2624                             &zc);
2625                 }
2626         }
2627
2628         if (ret != 0)
2629                 (void) zfs_standard_error(hdl, errno, errbuf);
2630
2631         free(parent);
2632         zfs_close(zhp);
2633
2634         return (ret);
2635 }
2636
2637 /*
2638  * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
2639  * NULL) to the file descriptor specified by outfd.
2640  */
2641 int
2642 zfs_send(zfs_handle_t *zhp, const char *fromsnap, int outfd)
2643 {
2644         zfs_cmd_t zc = { 0 };
2645         char errbuf[1024];
2646         libzfs_handle_t *hdl = zhp->zfs_hdl;
2647
2648         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
2649
2650         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2651         if (fromsnap)
2652                 (void) strlcpy(zc.zc_value, fromsnap, sizeof (zc.zc_name));
2653         zc.zc_cookie = outfd;
2654
2655         if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SENDBACKUP, &zc) != 0) {
2656                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2657                     "cannot send '%s'"), zhp->zfs_name);
2658
2659                 switch (errno) {
2660
2661                 case EXDEV:
2662                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2663                             "not an earlier snapshot from the same fs"));
2664                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2665
2666                 case EDQUOT:
2667                 case EFBIG:
2668                 case EIO:
2669                 case ENOLINK:
2670                 case ENOSPC:
2671                 case ENXIO:
2672                 case EPIPE:
2673                 case ERANGE:
2674                 case EFAULT:
2675                 case EROFS:
2676                         zfs_error_aux(hdl, strerror(errno));
2677                         return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
2678
2679                 default:
2680                         return (zfs_standard_error(hdl, errno, errbuf));
2681                 }
2682         }
2683
2684         return (0);
2685 }
2686
2687 /*
2688  * Create ancestors of 'target', but not target itself, and not
2689  * ancestors whose names are shorter than prefixlen.  Die if
2690  * prefixlen-ancestor does not exist.
2691  */
2692 static int
2693 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
2694 {
2695         zfs_handle_t *h;
2696         char *cp;
2697
2698         /* make sure prefix exists */
2699         cp = strchr(target + prefixlen, '/');
2700         *cp = '\0';
2701         h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2702         *cp = '/';
2703         if (h == NULL)
2704                 return (-1);
2705         zfs_close(h);
2706
2707         /*
2708          * Attempt to create, mount, and share any ancestor filesystems,
2709          * up to the prefixlen-long one.
2710          */
2711         for (cp = target + prefixlen + 1;
2712             cp = strchr(cp, '/'); *cp = '/', cp++) {
2713                 const char *opname;
2714
2715                 *cp = '\0';
2716
2717                 h = make_dataset_handle(hdl, target);
2718                 if (h) {
2719                         /* it already exists, nothing to do here */
2720                         zfs_close(h);
2721                         continue;
2722                 }
2723
2724                 opname = dgettext(TEXT_DOMAIN, "create");
2725                 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2726                     NULL) != 0)
2727                         goto ancestorerr;
2728
2729                 opname = dgettext(TEXT_DOMAIN, "open");
2730                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2731                 if (h == NULL)
2732                         goto ancestorerr;
2733
2734                 opname = dgettext(TEXT_DOMAIN, "mount");
2735                 if (zfs_mount(h, NULL, 0) != 0)
2736                         goto ancestorerr;
2737
2738                 opname = dgettext(TEXT_DOMAIN, "share");
2739                 if (zfs_share(h) != 0)
2740                         goto ancestorerr;
2741
2742                 zfs_close(h);
2743
2744                 continue;
2745 ancestorerr:
2746                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2747                     "failed to %s ancestor '%s'"), opname, target);
2748                 return (-1);
2749         }
2750
2751         return (0);
2752 }
2753
2754 /*
2755  * Restores a backup of tosnap from the file descriptor specified by infd.
2756  */
2757 int
2758 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, int isprefix,
2759     int verbose, int dryrun, boolean_t force, int infd)
2760 {
2761         zfs_cmd_t zc = { 0 };
2762         time_t begin_time;
2763         int ioctl_err, err, bytes, size, choplen;
2764         char *cp;
2765         dmu_replay_record_t drr;
2766         struct drr_begin *drrb = &zc.zc_begin_record;
2767         char errbuf[1024];
2768         prop_changelist_t *clp;
2769         char chopprefix[ZFS_MAXNAMELEN];
2770
2771         begin_time = time(NULL);
2772
2773         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2774             "cannot receive"));
2775
2776         /* read in the BEGIN record */
2777         cp = (char *)&drr;
2778         bytes = 0;
2779         do {
2780                 size = read(infd, cp, sizeof (drr) - bytes);
2781                 cp += size;
2782                 bytes += size;
2783         } while (size > 0);
2784
2785         if (size < 0 || bytes != sizeof (drr)) {
2786                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2787                     "stream (failed to read first record)"));
2788                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2789         }
2790
2791         zc.zc_begin_record = drr.drr_u.drr_begin;
2792
2793         if (drrb->drr_magic != DMU_BACKUP_MAGIC &&
2794             drrb->drr_magic != BSWAP_64(DMU_BACKUP_MAGIC)) {
2795                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2796                     "stream (bad magic number)"));
2797                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2798         }
2799
2800         if (drrb->drr_version != DMU_BACKUP_VERSION &&
2801             drrb->drr_version != BSWAP_64(DMU_BACKUP_VERSION)) {
2802                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only version "
2803                     "0x%llx is supported (stream is version 0x%llx)"),
2804                     DMU_BACKUP_VERSION, drrb->drr_version);
2805                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2806         }
2807
2808         if (strchr(drr.drr_u.drr_begin.drr_toname, '@') == NULL) {
2809                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2810                     "stream (bad snapshot name)"));
2811                 return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2812         }
2813         /*
2814          * Determine how much of the snapshot name stored in the stream
2815          * we are going to tack on to the name they specified on the
2816          * command line, and how much we are going to chop off.
2817          *
2818          * If they specified a snapshot, chop the entire name stored in
2819          * the stream.
2820          */
2821         (void) strcpy(chopprefix, drr.drr_u.drr_begin.drr_toname);
2822         if (isprefix) {
2823                 /*
2824                  * They specified a fs with -d, we want to tack on
2825                  * everything but the pool name stored in the stream
2826                  */
2827                 if (strchr(tosnap, '@')) {
2828                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2829                             "argument - snapshot not allowed with -d"));
2830                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2831                 }
2832                 cp = strchr(chopprefix, '/');
2833                 if (cp == NULL)
2834                         cp = strchr(chopprefix, '@');
2835                 *cp = '\0';
2836         } else if (strchr(tosnap, '@') == NULL) {
2837                 /*
2838                  * If they specified a filesystem without -d, we want to
2839                  * tack on everything after the fs specified in the
2840                  * first name from the stream.
2841                  */
2842                 cp = strchr(chopprefix, '@');
2843                 *cp = '\0';
2844         }
2845         choplen = strlen(chopprefix);
2846
2847         /*
2848          * Determine name of destination snapshot, store in zc_value.
2849          */
2850         (void) strcpy(zc.zc_value, tosnap);
2851         (void) strncat(zc.zc_value, drr.drr_u.drr_begin.drr_toname+choplen,
2852             sizeof (zc.zc_value));
2853         if (!zfs_validate_name(hdl, zc.zc_value, ZFS_TYPE_SNAPSHOT))
2854                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2855
2856         (void) strcpy(zc.zc_name, zc.zc_value);
2857         if (drrb->drr_fromguid) {
2858                 /* incremental backup stream */
2859                 zfs_handle_t *h;
2860
2861                 /* do the recvbackup ioctl to the containing fs */
2862                 *strchr(zc.zc_name, '@') = '\0';
2863
2864                 /* make sure destination fs exists */
2865                 h = zfs_open(hdl, zc.zc_name,
2866                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
2867                 if (h == NULL)
2868                         return (-1);
2869                 if (!dryrun) {
2870                         /*
2871                          * We need to unmount all the dependents of the dataset
2872                          * and the dataset itself. If it's a volume
2873                          * then remove device link.
2874                          */
2875                         if (h->zfs_type == ZFS_TYPE_FILESYSTEM) {
2876                                 clp = changelist_gather(h, ZFS_PROP_NAME, 0);
2877                                 if (clp == NULL)
2878                                         return (-1);
2879                                 if (changelist_prefix(clp) != 0) {
2880                                         changelist_free(clp);
2881                                         return (-1);
2882                                 }
2883                         } else {
2884                                 (void) zvol_remove_link(hdl, h->zfs_name);
2885                         }
2886                 }
2887                 zfs_close(h);
2888         } else {
2889                 /* full backup stream */
2890
2891                 /* Make sure destination fs does not exist */
2892                 *strchr(zc.zc_name, '@') = '\0';
2893                 if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
2894                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2895                             "destination '%s' exists"), zc.zc_name);
2896                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2897                 }
2898
2899                 if (strchr(zc.zc_name, '/') == NULL) {
2900                         /*
2901                          * they're trying to do a recv into a
2902                          * nonexistant topmost filesystem.
2903                          */
2904                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2905                             "destination does not exist"), zc.zc_name);
2906                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2907                 }
2908
2909                 /* Do the recvbackup ioctl to the fs's parent. */
2910                 *strrchr(zc.zc_name, '/') = '\0';
2911
2912                 if (isprefix && (err = create_parents(hdl,
2913                     zc.zc_value, strlen(tosnap))) != 0) {
2914                         return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
2915                 }
2916
2917         }
2918
2919         zc.zc_cookie = infd;
2920         zc.zc_guid = force;
2921         if (verbose) {
2922                 (void) printf("%s %s stream of %s into %s\n",
2923                     dryrun ? "would receive" : "receiving",
2924                     drrb->drr_fromguid ? "incremental" : "full",
2925                     drr.drr_u.drr_begin.drr_toname,
2926                     zc.zc_value);
2927                 (void) fflush(stdout);
2928         }
2929         if (dryrun)
2930                 return (0);
2931         err = ioctl_err = ioctl(hdl->libzfs_fd, ZFS_IOC_RECVBACKUP, &zc);
2932         if (ioctl_err != 0) {
2933                 switch (errno) {
2934                 case ENODEV:
2935                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2936                             "most recent snapshot does not match incremental "
2937                             "source"));
2938                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
2939                         break;
2940                 case ETXTBSY:
2941                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2942                             "destination has been modified since most recent "
2943                             "snapshot"));
2944                         (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
2945                         break;
2946                 case EEXIST:
2947                         if (drrb->drr_fromguid == 0) {
2948                                 /* it's the containing fs that exists */
2949                                 cp = strchr(zc.zc_value, '@');
2950                                 *cp = '\0';
2951                         }
2952                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2953                             "destination already exists"));
2954                         (void) zfs_error_fmt(hdl, EZFS_EXISTS,
2955                             dgettext(TEXT_DOMAIN, "cannot restore to %s"),
2956                             zc.zc_value);
2957                         break;
2958                 case EINVAL:
2959                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2960                         break;
2961                 case ECKSUM:
2962                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2963                             "invalid stream (checksum mismatch)"));
2964                         (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2965                         break;
2966                 default:
2967                         (void) zfs_standard_error(hdl, errno, errbuf);
2968                 }
2969         }
2970
2971         /*
2972          * Mount or recreate the /dev links for the target filesystem
2973          * (if created, or if we tore them down to do an incremental
2974          * restore), and the /dev links for the new snapshot (if
2975          * created). Also mount any children of the target filesystem
2976          * if we did an incremental receive.
2977          */
2978         cp = strchr(zc.zc_value, '@');
2979         if (cp && (ioctl_err == 0 || drrb->drr_fromguid)) {
2980                 zfs_handle_t *h;
2981
2982                 *cp = '\0';
2983                 h = zfs_open(hdl, zc.zc_value,
2984                     ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
2985                 *cp = '@';
2986                 if (h) {
2987                         if (h->zfs_type == ZFS_TYPE_VOLUME) {
2988                                 err = zvol_create_link(hdl, h->zfs_name);
2989                                 if (err == 0 && ioctl_err == 0)
2990                                         err = zvol_create_link(hdl,
2991                                             zc.zc_value);
2992                         } else {
2993                                 if (drrb->drr_fromguid) {
2994                                         err = changelist_postfix(clp);
2995                                         changelist_free(clp);
2996                                 } else {
2997                                         err = zfs_mount(h, NULL, 0);
2998                                 }
2999                         }
3000                 zfs_close(h);
3001                 }
3002         }
3003
3004         if (err || ioctl_err)
3005                 return (-1);
3006
3007         if (verbose) {
3008                 char buf1[64];
3009                 char buf2[64];
3010                 uint64_t bytes = zc.zc_cookie;
3011                 time_t delta = time(NULL) - begin_time;
3012                 if (delta == 0)
3013                         delta = 1;
3014                 zfs_nicenum(bytes, buf1, sizeof (buf1));
3015                 zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
3016
3017                 (void) printf("received %sb stream in %lu seconds (%sb/sec)\n",
3018                     buf1, delta, buf2);
3019         }
3020
3021         return (0);
3022 }
3023
3024 /*
3025  * Destroy any more recent snapshots.  We invoke this callback on any dependents
3026  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
3027  * is a dependent and we should just destroy it without checking the transaction
3028  * group.
3029  */
3030 typedef struct rollback_data {
3031         const char      *cb_target;             /* the snapshot */
3032         uint64_t        cb_create;              /* creation time reference */
3033         prop_changelist_t *cb_clp;              /* changelist pointer */
3034         int             cb_error;
3035         boolean_t       cb_dependent;
3036 } rollback_data_t;
3037
3038 static int
3039 rollback_destroy(zfs_handle_t *zhp, void *data)
3040 {
3041         rollback_data_t *cbp = data;
3042
3043         if (!cbp->cb_dependent) {
3044                 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
3045                     zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
3046                     zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
3047                     cbp->cb_create) {
3048
3049                         cbp->cb_dependent = B_TRUE;
3050                         if (zfs_iter_dependents(zhp, B_FALSE, rollback_destroy,
3051                             cbp) != 0)
3052                                 cbp->cb_error = 1;
3053                         cbp->cb_dependent = B_FALSE;
3054
3055                         if (zfs_destroy(zhp) != 0)
3056                                 cbp->cb_error = 1;
3057                         else
3058                                 changelist_remove(zhp, cbp->cb_clp);
3059                 }
3060         } else {
3061                 if (zfs_destroy(zhp) != 0)
3062                         cbp->cb_error = 1;
3063                 else
3064                         changelist_remove(zhp, cbp->cb_clp);
3065         }
3066
3067         zfs_close(zhp);
3068         return (0);
3069 }
3070
3071 /*
3072  * Rollback the dataset to its latest snapshot.
3073  */
3074 static int
3075 do_rollback(zfs_handle_t *zhp)
3076 {
3077         int ret;
3078         zfs_cmd_t zc = { 0 };
3079
3080         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
3081             zhp->zfs_type == ZFS_TYPE_VOLUME);
3082
3083         if (zhp->zfs_type == ZFS_TYPE_VOLUME &&
3084             zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3085                 return (-1);
3086
3087         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3088
3089         if (ZFS_IS_VOLUME(zhp))
3090                 zc.zc_objset_type = DMU_OST_ZVOL;
3091         else
3092                 zc.zc_objset_type = DMU_OST_ZFS;
3093
3094         /*
3095          * We rely on the consumer to verify that there are no newer snapshots
3096          * for the given dataset.  Given these constraints, we can simply pass
3097          * the name on to the ioctl() call.  There is still an unlikely race
3098          * condition where the user has taken a snapshot since we verified that
3099          * this was the most recent.
3100          */
3101         if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_ROLLBACK,
3102             &zc)) != 0) {
3103                 (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3104                     dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
3105                     zhp->zfs_name);
3106         } else if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3107                 ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
3108         }
3109
3110         return (ret);
3111 }
3112
3113 /*
3114  * Given a dataset, rollback to a specific snapshot, discarding any
3115  * data changes since then and making it the active dataset.
3116  *
3117  * Any snapshots more recent than the target are destroyed, along with
3118  * their dependents.
3119  */
3120 int
3121 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, int flag)
3122 {
3123         int ret;
3124         rollback_data_t cb = { 0 };
3125         prop_changelist_t *clp;
3126
3127         /*
3128          * Unmount all dependendents of the dataset and the dataset itself.
3129          * The list we need to gather is the same as for doing rename
3130          */
3131         clp = changelist_gather(zhp, ZFS_PROP_NAME, flag ? MS_FORCE: 0);
3132         if (clp == NULL)
3133                 return (-1);
3134
3135         if ((ret = changelist_prefix(clp)) != 0)
3136                 goto out;
3137
3138         /*
3139          * Destroy all recent snapshots and its dependends.
3140          */
3141         cb.cb_target = snap->zfs_name;
3142         cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
3143         cb.cb_clp = clp;
3144         (void) zfs_iter_children(zhp, rollback_destroy, &cb);
3145
3146         if ((ret = cb.cb_error) != 0) {
3147                 (void) changelist_postfix(clp);
3148                 goto out;
3149         }
3150
3151         /*
3152          * Now that we have verified that the snapshot is the latest,
3153          * rollback to the given snapshot.
3154          */
3155         ret = do_rollback(zhp);
3156
3157         if (ret != 0) {
3158                 (void) changelist_postfix(clp);
3159                 goto out;
3160         }
3161
3162         /*
3163          * We only want to re-mount the filesystem if it was mounted in the
3164          * first place.
3165          */
3166         ret = changelist_postfix(clp);
3167
3168 out:
3169         changelist_free(clp);
3170         return (ret);
3171 }
3172
3173 /*
3174  * Iterate over all dependents for a given dataset.  This includes both
3175  * hierarchical dependents (children) and data dependents (snapshots and
3176  * clones).  The bulk of the processing occurs in get_dependents() in
3177  * libzfs_graph.c.
3178  */
3179 int
3180 zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
3181     zfs_iter_f func, void *data)
3182 {
3183         char **dependents;
3184         size_t count;
3185         int i;
3186         zfs_handle_t *child;
3187         int ret = 0;
3188
3189         if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name,
3190             &dependents, &count) != 0)
3191                 return (-1);
3192
3193         for (i = 0; i < count; i++) {
3194                 if ((child = make_dataset_handle(zhp->zfs_hdl,
3195                     dependents[i])) == NULL)
3196                         continue;
3197
3198                 if ((ret = func(child, data)) != 0)
3199                         break;
3200         }
3201
3202         for (i = 0; i < count; i++)
3203                 free(dependents[i]);
3204         free(dependents);
3205
3206         return (ret);
3207 }
3208
3209 /*
3210  * Renames the given dataset.
3211  */
3212 int
3213 zfs_rename(zfs_handle_t *zhp, const char *target, int recursive)
3214 {
3215         int ret;
3216         zfs_cmd_t zc = { 0 };
3217         char *delim;
3218         prop_changelist_t *cl = NULL;
3219         zfs_handle_t *zhrp = NULL;
3220         char *parentname = NULL;
3221         char parent[ZFS_MAXNAMELEN];
3222         libzfs_handle_t *hdl = zhp->zfs_hdl;
3223         char errbuf[1024];
3224
3225         /* if we have the same exact name, just return success */
3226         if (strcmp(zhp->zfs_name, target) == 0)
3227                 return (0);
3228
3229         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3230             "cannot rename to '%s'"), target);
3231
3232         /*
3233          * Make sure the target name is valid
3234          */
3235         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3236                 if ((strchr(target, '@') == NULL) ||
3237                     *target == '@') {
3238                         /*
3239                          * Snapshot target name is abbreviated,
3240                          * reconstruct full dataset name
3241                          */
3242                         (void) strlcpy(parent, zhp->zfs_name,
3243                             sizeof (parent));
3244                         delim = strchr(parent, '@');
3245                         if (strchr(target, '@') == NULL)
3246                                 *(++delim) = '\0';
3247                         else
3248                                 *delim = '\0';
3249                         (void) strlcat(parent, target, sizeof (parent));
3250                         target = parent;
3251                 } else {
3252                         /*
3253                          * Make sure we're renaming within the same dataset.
3254                          */
3255                         delim = strchr(target, '@');
3256                         if (strncmp(zhp->zfs_name, target, delim - target)
3257                             != 0 || zhp->zfs_name[delim - target] != '@') {
3258                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3259                                     "snapshots must be part of same "
3260                                     "dataset"));
3261                                 return (zfs_error(hdl, EZFS_CROSSTARGET,
3262                                     errbuf));
3263                         }
3264                 }
3265                 if (!zfs_validate_name(hdl, target, zhp->zfs_type))
3266                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3267         } else {
3268                 if (recursive) {
3269                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3270                             "recursive rename must be a snapshot"));
3271                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3272                 }
3273
3274                 if (!zfs_validate_name(hdl, target, zhp->zfs_type))
3275                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3276                 uint64_t unused;
3277
3278                 /* validate parents */
3279                 if (check_parents(hdl, target, &unused) != 0)
3280                         return (-1);
3281
3282                 (void) parent_name(target, parent, sizeof (parent));
3283
3284                 /* make sure we're in the same pool */
3285                 verify((delim = strchr(target, '/')) != NULL);
3286                 if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
3287                     zhp->zfs_name[delim - target] != '/') {
3288                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3289                             "datasets must be within same pool"));
3290                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
3291                 }
3292
3293                 /* new name cannot be a child of the current dataset name */
3294                 if (strncmp(parent, zhp->zfs_name,
3295                     strlen(zhp->zfs_name)) == 0) {
3296                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3297                             "New dataset name cannot be a descendent of "
3298                             "current dataset name"));
3299                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3300                 }
3301         }
3302
3303         (void) snprintf(errbuf, sizeof (errbuf),
3304             dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
3305
3306         if (getzoneid() == GLOBAL_ZONEID &&
3307             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
3308                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3309                     "dataset is used in a non-global zone"));
3310                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
3311         }
3312
3313         if (recursive) {
3314                 struct destroydata dd;
3315
3316                 parentname = strdup(zhp->zfs_name);
3317                 delim = strchr(parentname, '@');
3318                 *delim = '\0';
3319                 zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_ANY);
3320                 if (zhrp == NULL) {
3321                         return (-1);
3322                 }
3323
3324                 dd.snapname = delim + 1;
3325                 dd.gotone = B_FALSE;
3326                 dd.closezhp = B_FALSE;
3327
3328                 /* We remove any zvol links prior to renaming them */
3329                 ret = zfs_iter_filesystems(zhrp, zfs_remove_link_cb, &dd);
3330                 if (ret) {
3331                         goto error;
3332                 }
3333         } else {
3334                 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0)) == NULL)
3335                         return (-1);
3336
3337                 if (changelist_haszonedchild(cl)) {
3338                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3339                             "child dataset with inherited mountpoint is used "
3340                             "in a non-global zone"));
3341                         (void) zfs_error(hdl, EZFS_ZONED, errbuf);
3342                         goto error;
3343                 }
3344
3345                 if ((ret = changelist_prefix(cl)) != 0)
3346                         goto error;
3347         }
3348
3349         if (ZFS_IS_VOLUME(zhp))
3350                 zc.zc_objset_type = DMU_OST_ZVOL;
3351         else
3352                 zc.zc_objset_type = DMU_OST_ZFS;
3353
3354         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3355         (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
3356
3357         zc.zc_cookie = recursive;
3358
3359         if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_RENAME, &zc)) != 0) {
3360                 /*
3361                  * if it was recursive, the one that actually failed will
3362                  * be in zc.zc_name
3363                  */
3364                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3365                     "cannot rename to '%s'"), zc.zc_name);
3366
3367                 if (recursive && errno == EEXIST) {
3368                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3369                             "a child dataset already has a snapshot "
3370                             "with the new name"));
3371                         (void) zfs_error(hdl, EZFS_CROSSTARGET, errbuf);
3372                 } else {
3373                         (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
3374                 }
3375
3376                 /*
3377                  * On failure, we still want to remount any filesystems that
3378                  * were previously mounted, so we don't alter the system state.
3379                  */
3380                 if (recursive) {
3381                         struct createdata cd;
3382
3383                         /* only create links for datasets that had existed */
3384                         cd.cd_snapname = delim + 1;
3385                         cd.cd_ifexists = B_TRUE;
3386                         (void) zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3387                             &cd);
3388                 } else {
3389                         (void) changelist_postfix(cl);
3390                 }
3391         } else {
3392                 if (recursive) {
3393                         struct createdata cd;
3394
3395                         /* only create links for datasets that had existed */
3396                         cd.cd_snapname = strchr(target, '@') + 1;
3397                         cd.cd_ifexists = B_TRUE;
3398                         ret = zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3399                             &cd);
3400                 } else {
3401                         changelist_rename(cl, zfs_get_name(zhp), target);
3402                         ret = changelist_postfix(cl);
3403                 }
3404         }
3405
3406 error:
3407         if (parentname) {
3408                 free(parentname);
3409         }
3410         if (zhrp) {
3411                 zfs_close(zhrp);
3412         }
3413         if (cl) {
3414                 changelist_free(cl);
3415         }
3416         return (ret);
3417 }
3418
3419 /*
3420  * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
3421  * poke devfsadm to create the /dev link, and then wait for the link to appear.
3422  */
3423 int
3424 zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
3425 {
3426         return (zvol_create_link_common(hdl, dataset, B_FALSE));
3427 }
3428
3429 static int
3430 zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
3431 {
3432         zfs_cmd_t zc = { 0 };
3433 #if 0
3434         di_devlink_handle_t dhdl;
3435 #endif
3436
3437         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3438
3439         /*
3440          * Issue the appropriate ioctl.
3441          */
3442         if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
3443                 switch (errno) {
3444                 case EEXIST:
3445                         /*
3446                          * Silently ignore the case where the link already
3447                          * exists.  This allows 'zfs volinit' to be run multiple
3448                          * times without errors.
3449                          */
3450                         return (0);
3451
3452                 case ENOENT:
3453                         /*
3454                          * Dataset does not exist in the kernel.  If we
3455                          * don't care (see zfs_rename), then ignore the
3456                          * error quietly.
3457                          */
3458                         if (ifexists) {
3459                                 return (0);
3460                         }
3461
3462                         /* FALLTHROUGH */
3463
3464                 default:
3465                         return (zfs_standard_error_fmt(hdl, errno,
3466                             dgettext(TEXT_DOMAIN, "cannot create device links "
3467                             "for '%s'"), dataset));
3468                 }
3469         }
3470
3471 #if 0
3472         /*
3473          * Call devfsadm and wait for the links to magically appear.
3474          */
3475         if ((dhdl = di_devlink_init(ZFS_DRIVER, DI_MAKE_LINK)) == NULL) {
3476                 zfs_error_aux(hdl, strerror(errno));
3477                 (void) zfs_error_fmt(hdl, EZFS_DEVLINKS,
3478                     dgettext(TEXT_DOMAIN, "cannot create device links "
3479                     "for '%s'"), dataset);
3480                 (void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
3481                 return (-1);
3482         } else {
3483                 (void) di_devlink_fini(&dhdl);
3484         }
3485 #endif
3486
3487         return (0);
3488 }
3489
3490 /*
3491  * Remove a minor node for the given zvol and the associated /dev links.
3492  */
3493 int
3494 zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
3495 {
3496         zfs_cmd_t zc = { 0 };
3497
3498         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3499
3500         if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
3501                 switch (errno) {
3502                 case ENXIO:
3503                         /*
3504                          * Silently ignore the case where the link no longer
3505                          * exists, so that 'zfs volfini' can be run multiple
3506                          * times without errors.
3507                          */
3508                         return (0);
3509
3510                 default:
3511                         return (zfs_standard_error_fmt(hdl, errno,
3512                             dgettext(TEXT_DOMAIN, "cannot remove device "
3513                             "links for '%s'"), dataset));
3514                 }
3515         }
3516
3517         return (0);
3518 }
3519
3520 nvlist_t *
3521 zfs_get_user_props(zfs_handle_t *zhp)
3522 {
3523         return (zhp->zfs_user_props);
3524 }
3525
3526 /*
3527  * Given a comma-separated list of properties, contruct a property list
3528  * containing both user-defined and native properties.  This function will
3529  * return a NULL list if 'all' is specified, which can later be expanded on a
3530  * per-dataset basis by zfs_expand_proplist().
3531  */
3532 int
3533 zfs_get_proplist_common(libzfs_handle_t *hdl, char *fields,
3534     zfs_proplist_t **listp, zfs_type_t type)
3535 {
3536         size_t len;
3537         char *s, *p;
3538         char c;
3539         zfs_prop_t prop;
3540         zfs_proplist_t *entry;
3541         zfs_proplist_t **last;
3542
3543         *listp = NULL;
3544         last = listp;
3545
3546         /*
3547          * If 'all' is specified, return a NULL list.
3548          */
3549         if (strcmp(fields, "all") == 0)
3550                 return (0);
3551
3552         /*
3553          * If no fields were specified, return an error.
3554          */
3555         if (fields[0] == '\0') {
3556                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3557                     "no properties specified"));
3558                 return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
3559                     "bad property list")));
3560         }
3561
3562         /*
3563          * It would be nice to use getsubopt() here, but the inclusion of column
3564          * aliases makes this more effort than it's worth.
3565          */
3566         s = fields;
3567         while (*s != '\0') {
3568                 if ((p = strchr(s, ',')) == NULL) {
3569                         len = strlen(s);
3570                         p = s + len;
3571                 } else {
3572                         len = p - s;
3573                 }
3574
3575                 /*
3576                  * Check for empty options.
3577                  */
3578                 if (len == 0) {
3579                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3580                             "empty property name"));
3581                         return (zfs_error(hdl, EZFS_BADPROP,
3582                             dgettext(TEXT_DOMAIN, "bad property list")));
3583                 }
3584
3585                 /*
3586                  * Check all regular property names.
3587                  */
3588                 c = s[len];
3589                 s[len] = '\0';
3590                 prop = zfs_name_to_prop_common(s, type);
3591
3592                 if (prop != ZFS_PROP_INVAL &&
3593                     !zfs_prop_valid_for_type(prop, type))
3594                         prop = ZFS_PROP_INVAL;
3595
3596                 /*
3597                  * When no property table entry can be found, return failure if
3598                  * this is a pool property or if this isn't a user-defined
3599                  * dataset property,
3600                  */
3601                 if (prop == ZFS_PROP_INVAL &&
3602                     (type & ZFS_TYPE_POOL || !zfs_prop_user(s))) {
3603                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3604                             "invalid property '%s'"), s);
3605                         return (zfs_error(hdl, EZFS_BADPROP,
3606                             dgettext(TEXT_DOMAIN, "bad property list")));
3607                 }
3608
3609                 if ((entry = zfs_alloc(hdl, sizeof (zfs_proplist_t))) == NULL)
3610                         return (-1);
3611
3612                 entry->pl_prop = prop;
3613                 if (prop == ZFS_PROP_INVAL) {
3614                         if ((entry->pl_user_prop =
3615                             zfs_strdup(hdl, s)) == NULL) {
3616                                 free(entry);
3617                                 return (-1);
3618                         }
3619                         entry->pl_width = strlen(s);
3620                 } else {
3621                         entry->pl_width = zfs_prop_width(prop,
3622                             &entry->pl_fixed);
3623                 }
3624
3625                 *last = entry;
3626                 last = &entry->pl_next;
3627
3628                 s = p;
3629                 if (c == ',')
3630                         s++;
3631         }
3632
3633         return (0);
3634 }
3635
3636 int
3637 zfs_get_proplist(libzfs_handle_t *hdl, char *fields, zfs_proplist_t **listp)
3638 {
3639         return (zfs_get_proplist_common(hdl, fields, listp, ZFS_TYPE_ANY));
3640 }
3641
3642 void
3643 zfs_free_proplist(zfs_proplist_t *pl)
3644 {
3645         zfs_proplist_t *next;
3646
3647         while (pl != NULL) {
3648                 next = pl->pl_next;
3649                 free(pl->pl_user_prop);
3650                 free(pl);
3651                 pl = next;
3652         }
3653 }
3654
3655 typedef struct expand_data {
3656         zfs_proplist_t  **last;
3657         libzfs_handle_t *hdl;
3658 } expand_data_t;
3659
3660 static zfs_prop_t
3661 zfs_expand_proplist_cb(zfs_prop_t prop, void *cb)
3662 {
3663         zfs_proplist_t *entry;
3664         expand_data_t *edp = cb;
3665
3666         if ((entry = zfs_alloc(edp->hdl, sizeof (zfs_proplist_t))) == NULL)
3667                 return (ZFS_PROP_INVAL);
3668
3669         entry->pl_prop = prop;
3670         entry->pl_width = zfs_prop_width(prop, &entry->pl_fixed);
3671         entry->pl_all = B_TRUE;
3672
3673         *(edp->last) = entry;
3674         edp->last = &entry->pl_next;
3675
3676         return (ZFS_PROP_CONT);
3677 }
3678
3679 int
3680 zfs_expand_proplist_common(libzfs_handle_t *hdl, zfs_proplist_t **plp,
3681         zfs_type_t type)
3682 {
3683         zfs_proplist_t *entry;
3684         zfs_proplist_t **last;
3685         expand_data_t exp;
3686
3687         if (*plp == NULL) {
3688                 /*
3689                  * If this is the very first time we've been called for an 'all'
3690                  * specification, expand the list to include all native
3691                  * properties.
3692                  */
3693                 last = plp;
3694
3695                 exp.last = last;
3696                 exp.hdl = hdl;
3697
3698                 if (zfs_prop_iter_common(zfs_expand_proplist_cb, &exp, type,
3699                     B_FALSE) == ZFS_PROP_INVAL)
3700                         return (-1);
3701
3702                 /*
3703                  * Add 'name' to the beginning of the list, which is handled
3704                  * specially.
3705                  */
3706                 if ((entry = zfs_alloc(hdl,
3707                     sizeof (zfs_proplist_t))) == NULL)
3708                         return (-1);
3709
3710                 entry->pl_prop = ZFS_PROP_NAME;
3711                 entry->pl_width = zfs_prop_width(ZFS_PROP_NAME,
3712                     &entry->pl_fixed);
3713                 entry->pl_all = B_TRUE;
3714                 entry->pl_next = *plp;
3715                 *plp = entry;
3716         }
3717         return (0);
3718 }
3719
3720 /*
3721  * This function is used by 'zfs list' to determine the exact set of columns to
3722  * display, and their maximum widths.  This does two main things:
3723  *
3724  *      - If this is a list of all properties, then expand the list to include
3725  *        all native properties, and set a flag so that for each dataset we look
3726  *        for new unique user properties and add them to the list.
3727  *
3728  *      - For non fixed-width properties, keep track of the maximum width seen
3729  *        so that we can size the column appropriately.
3730  */
3731 int
3732 zfs_expand_proplist(zfs_handle_t *zhp, zfs_proplist_t **plp)
3733 {
3734         libzfs_handle_t *hdl = zhp->zfs_hdl;
3735         zfs_proplist_t *entry;
3736         zfs_proplist_t **last, **start;
3737         nvlist_t *userprops, *propval;
3738         nvpair_t *elem;
3739         char *strval;
3740         char buf[ZFS_MAXPROPLEN];
3741
3742         if (zfs_expand_proplist_common(hdl, plp, ZFS_TYPE_ANY) != 0)
3743                 return (-1);
3744
3745         userprops = zfs_get_user_props(zhp);
3746
3747         entry = *plp;
3748         if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
3749                 /*
3750                  * Go through and add any user properties as necessary.  We
3751                  * start by incrementing our list pointer to the first
3752                  * non-native property.
3753                  */
3754                 start = plp;
3755                 while (*start != NULL) {
3756                         if ((*start)->pl_prop == ZFS_PROP_INVAL)
3757                                 break;
3758                         start = &(*start)->pl_next;
3759                 }
3760
3761                 elem = NULL;
3762                 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
3763                         /*
3764                          * See if we've already found this property in our list.
3765                          */
3766                         for (last = start; *last != NULL;
3767                             last = &(*last)->pl_next) {
3768                                 if (strcmp((*last)->pl_user_prop,
3769                                     nvpair_name(elem)) == 0)
3770                                         break;
3771                         }
3772
3773                         if (*last == NULL) {
3774                                 if ((entry = zfs_alloc(hdl,
3775                                     sizeof (zfs_proplist_t))) == NULL ||
3776                                     ((entry->pl_user_prop = zfs_strdup(hdl,
3777                                     nvpair_name(elem)))) == NULL) {
3778                                         free(entry);
3779                                         return (-1);
3780                                 }
3781
3782                                 entry->pl_prop = ZFS_PROP_INVAL;
3783                                 entry->pl_width = strlen(nvpair_name(elem));
3784                                 entry->pl_all = B_TRUE;
3785                                 *last = entry;
3786                         }
3787                 }
3788         }
3789
3790         /*
3791          * Now go through and check the width of any non-fixed columns
3792          */
3793         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
3794                 if (entry->pl_fixed)
3795                         continue;
3796
3797                 if (entry->pl_prop != ZFS_PROP_INVAL) {
3798                         if (zfs_prop_get(zhp, entry->pl_prop,
3799                             buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
3800                                 if (strlen(buf) > entry->pl_width)
3801                                         entry->pl_width = strlen(buf);
3802                         }
3803                 } else if (nvlist_lookup_nvlist(userprops,
3804                     entry->pl_user_prop, &propval)  == 0) {
3805                         verify(nvlist_lookup_string(propval,
3806                             ZFS_PROP_VALUE, &strval) == 0);
3807                         if (strlen(strval) > entry->pl_width)
3808                                 entry->pl_width = strlen(strval);
3809                 }
3810         }
3811
3812         return (0);
3813 }
3814
3815 /*
3816  * Attach/detach the given filesystem to/from the given jail.
3817  */
3818 int
3819 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
3820 {
3821         libzfs_handle_t *hdl = zhp->zfs_hdl;
3822         zfs_cmd_t zc = { 0 };
3823         char errbuf[1024];
3824         int cmd, ret;
3825
3826         if (attach) {
3827                 (void) snprintf(errbuf, sizeof (errbuf),
3828                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
3829         } else {
3830                 (void) snprintf(errbuf, sizeof (errbuf),
3831                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
3832         }
3833
3834         switch (zhp->zfs_type) {
3835         case ZFS_TYPE_VOLUME:
3836                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3837                     "volumes can not be jailed"));
3838                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3839         case ZFS_TYPE_SNAPSHOT:
3840                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3841                     "snapshots can not be jailed"));
3842                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3843         }
3844         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
3845
3846         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3847         zc.zc_objset_type = DMU_OST_ZFS;
3848         zc.zc_jailid = jailid;
3849
3850         cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
3851         if ((ret = ioctl(hdl->libzfs_fd, cmd, &zc)) != 0)
3852                 zfs_standard_error(hdl, errno, errbuf);
3853
3854         return (ret);
3855 }