]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
MFC r197859:
[FreeBSD/stable/8.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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26
27 #include <assert.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <libintl.h>
31 #include <math.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35 #include <unistd.h>
36 #include <stddef.h>
37 #include <zone.h>
38 #include <fcntl.h>
39 #include <sys/mntent.h>
40 #include <sys/mnttab.h>
41 #include <sys/mount.h>
42 #include <sys/avl.h>
43 #include <priv.h>
44 #include <pwd.h>
45 #include <grp.h>
46 #include <stddef.h>
47
48 #include <sys/spa.h>
49 #include <sys/zap.h>
50 #include <libzfs.h>
51
52 #include "zfs_namecheck.h"
53 #include "zfs_prop.h"
54 #include "libzfs_impl.h"
55 #include "zfs_deleg.h"
56
57 static int zvol_create_link_common(libzfs_handle_t *, const char *, int);
58
59 /*
60  * Given a single type (not a mask of types), return the type in a human
61  * readable form.
62  */
63 const char *
64 zfs_type_to_name(zfs_type_t type)
65 {
66         switch (type) {
67         case ZFS_TYPE_FILESYSTEM:
68                 return (dgettext(TEXT_DOMAIN, "filesystem"));
69         case ZFS_TYPE_SNAPSHOT:
70                 return (dgettext(TEXT_DOMAIN, "snapshot"));
71         case ZFS_TYPE_VOLUME:
72                 return (dgettext(TEXT_DOMAIN, "volume"));
73         }
74
75         return (NULL);
76 }
77
78 /*
79  * Given a path and mask of ZFS types, return a string describing this dataset.
80  * This is used when we fail to open a dataset and we cannot get an exact type.
81  * We guess what the type would have been based on the path and the mask of
82  * acceptable types.
83  */
84 static const char *
85 path_to_str(const char *path, int types)
86 {
87         /*
88          * When given a single type, always report the exact type.
89          */
90         if (types == ZFS_TYPE_SNAPSHOT)
91                 return (dgettext(TEXT_DOMAIN, "snapshot"));
92         if (types == ZFS_TYPE_FILESYSTEM)
93                 return (dgettext(TEXT_DOMAIN, "filesystem"));
94         if (types == ZFS_TYPE_VOLUME)
95                 return (dgettext(TEXT_DOMAIN, "volume"));
96
97         /*
98          * The user is requesting more than one type of dataset.  If this is the
99          * case, consult the path itself.  If we're looking for a snapshot, and
100          * a '@' is found, then report it as "snapshot".  Otherwise, remove the
101          * snapshot attribute and try again.
102          */
103         if (types & ZFS_TYPE_SNAPSHOT) {
104                 if (strchr(path, '@') != NULL)
105                         return (dgettext(TEXT_DOMAIN, "snapshot"));
106                 return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
107         }
108
109
110         /*
111          * The user has requested either filesystems or volumes.
112          * We have no way of knowing a priori what type this would be, so always
113          * report it as "filesystem" or "volume", our two primitive types.
114          */
115         if (types & ZFS_TYPE_FILESYSTEM)
116                 return (dgettext(TEXT_DOMAIN, "filesystem"));
117
118         assert(types & ZFS_TYPE_VOLUME);
119         return (dgettext(TEXT_DOMAIN, "volume"));
120 }
121
122 /*
123  * Validate a ZFS path.  This is used even before trying to open the dataset, to
124  * provide a more meaningful error message.  We place a more useful message in
125  * 'buf' detailing exactly why the name was not valid.
126  */
127 static int
128 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
129     boolean_t modifying)
130 {
131         namecheck_err_t why;
132         char what;
133
134         if (dataset_namecheck(path, &why, &what) != 0) {
135                 if (hdl != NULL) {
136                         switch (why) {
137                         case NAME_ERR_TOOLONG:
138                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
139                                     "name is too long"));
140                                 break;
141
142                         case NAME_ERR_LEADING_SLASH:
143                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
144                                     "leading slash in name"));
145                                 break;
146
147                         case NAME_ERR_EMPTY_COMPONENT:
148                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
149                                     "empty component in name"));
150                                 break;
151
152                         case NAME_ERR_TRAILING_SLASH:
153                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
154                                     "trailing slash in name"));
155                                 break;
156
157                         case NAME_ERR_INVALCHAR:
158                                 zfs_error_aux(hdl,
159                                     dgettext(TEXT_DOMAIN, "invalid character "
160                                     "'%c' in name"), what);
161                                 break;
162
163                         case NAME_ERR_MULTIPLE_AT:
164                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
165                                     "multiple '@' delimiters in name"));
166                                 break;
167
168                         case NAME_ERR_NOLETTER:
169                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
170                                     "pool doesn't begin with a letter"));
171                                 break;
172
173                         case NAME_ERR_RESERVED:
174                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
175                                     "name is reserved"));
176                                 break;
177
178                         case NAME_ERR_DISKLIKE:
179                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
180                                     "reserved disk name"));
181                                 break;
182                         }
183                 }
184
185                 return (0);
186         }
187
188         if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
189                 if (hdl != NULL)
190                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
191                             "snapshot delimiter '@' in filesystem name"));
192                 return (0);
193         }
194
195         if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
196                 if (hdl != NULL)
197                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
198                             "missing '@' delimiter in snapshot name"));
199                 return (0);
200         }
201
202         if (modifying && strchr(path, '%') != NULL) {
203                 if (hdl != NULL)
204                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
205                             "invalid character %c in name"), '%');
206                 return (0);
207         }
208
209         return (-1);
210 }
211
212 int
213 zfs_name_valid(const char *name, zfs_type_t type)
214 {
215         if (type == ZFS_TYPE_POOL)
216                 return (zpool_name_valid(NULL, B_FALSE, name));
217         return (zfs_validate_name(NULL, name, type, B_FALSE));
218 }
219
220 /*
221  * This function takes the raw DSL properties, and filters out the user-defined
222  * properties into a separate nvlist.
223  */
224 static nvlist_t *
225 process_user_props(zfs_handle_t *zhp, nvlist_t *props)
226 {
227         libzfs_handle_t *hdl = zhp->zfs_hdl;
228         nvpair_t *elem;
229         nvlist_t *propval;
230         nvlist_t *nvl;
231
232         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
233                 (void) no_memory(hdl);
234                 return (NULL);
235         }
236
237         elem = NULL;
238         while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
239                 if (!zfs_prop_user(nvpair_name(elem)))
240                         continue;
241
242                 verify(nvpair_value_nvlist(elem, &propval) == 0);
243                 if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
244                         nvlist_free(nvl);
245                         (void) no_memory(hdl);
246                         return (NULL);
247                 }
248         }
249
250         return (nvl);
251 }
252
253 static zpool_handle_t *
254 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
255 {
256         libzfs_handle_t *hdl = zhp->zfs_hdl;
257         zpool_handle_t *zph;
258
259         if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
260                 if (hdl->libzfs_pool_handles != NULL)
261                         zph->zpool_next = hdl->libzfs_pool_handles;
262                 hdl->libzfs_pool_handles = zph;
263         }
264         return (zph);
265 }
266
267 static zpool_handle_t *
268 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
269 {
270         libzfs_handle_t *hdl = zhp->zfs_hdl;
271         zpool_handle_t *zph = hdl->libzfs_pool_handles;
272
273         while ((zph != NULL) &&
274             (strncmp(pool_name, zpool_get_name(zph), len) != 0))
275                 zph = zph->zpool_next;
276         return (zph);
277 }
278
279 /*
280  * Returns a handle to the pool that contains the provided dataset.
281  * If a handle to that pool already exists then that handle is returned.
282  * Otherwise, a new handle is created and added to the list of handles.
283  */
284 static zpool_handle_t *
285 zpool_handle(zfs_handle_t *zhp)
286 {
287         char *pool_name;
288         int len;
289         zpool_handle_t *zph;
290
291         len = strcspn(zhp->zfs_name, "/@") + 1;
292         pool_name = zfs_alloc(zhp->zfs_hdl, len);
293         (void) strlcpy(pool_name, zhp->zfs_name, len);
294
295         zph = zpool_find_handle(zhp, pool_name, len);
296         if (zph == NULL)
297                 zph = zpool_add_handle(zhp, pool_name);
298
299         free(pool_name);
300         return (zph);
301 }
302
303 void
304 zpool_free_handles(libzfs_handle_t *hdl)
305 {
306         zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
307
308         while (zph != NULL) {
309                 next = zph->zpool_next;
310                 zpool_close(zph);
311                 zph = next;
312         }
313         hdl->libzfs_pool_handles = NULL;
314 }
315
316 /*
317  * Utility function to gather stats (objset and zpl) for the given object.
318  */
319 static int
320 get_stats(zfs_handle_t *zhp)
321 {
322         zfs_cmd_t zc = { 0 };
323         libzfs_handle_t *hdl = zhp->zfs_hdl;
324         nvlist_t *allprops, *userprops;
325
326         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
327
328         if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
329                 return (-1);
330
331         while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
332                 if (errno == ENOMEM) {
333                         if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
334                                 zcmd_free_nvlists(&zc);
335                                 return (-1);
336                         }
337                 } else {
338                         zcmd_free_nvlists(&zc);
339                         return (-1);
340                 }
341         }
342
343         zhp->zfs_dmustats = zc.zc_objset_stats; /* structure assignment */
344
345         if (zcmd_read_dst_nvlist(hdl, &zc, &allprops) != 0) {
346                 zcmd_free_nvlists(&zc);
347                 return (-1);
348         }
349
350         zcmd_free_nvlists(&zc);
351
352         if ((userprops = process_user_props(zhp, allprops)) == NULL) {
353                 nvlist_free(allprops);
354                 return (-1);
355         }
356
357         nvlist_free(zhp->zfs_props);
358         nvlist_free(zhp->zfs_user_props);
359
360         zhp->zfs_props = allprops;
361         zhp->zfs_user_props = userprops;
362
363         return (0);
364 }
365
366 /*
367  * Refresh the properties currently stored in the handle.
368  */
369 void
370 zfs_refresh_properties(zfs_handle_t *zhp)
371 {
372         (void) get_stats(zhp);
373 }
374
375 /*
376  * Makes a handle from the given dataset name.  Used by zfs_open() and
377  * zfs_iter_* to create child handles on the fly.
378  */
379 zfs_handle_t *
380 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
381 {
382         zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
383         char *logstr;
384
385         if (zhp == NULL)
386                 return (NULL);
387
388         zhp->zfs_hdl = hdl;
389
390         /*
391          * Preserve history log string.
392          * any changes performed here will be
393          * logged as an internal event.
394          */
395         logstr = zhp->zfs_hdl->libzfs_log_str;
396         zhp->zfs_hdl->libzfs_log_str = NULL;
397 top:
398         (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
399
400         if (get_stats(zhp) != 0) {
401                 zhp->zfs_hdl->libzfs_log_str = logstr;
402                 free(zhp);
403                 return (NULL);
404         }
405
406         if (zhp->zfs_dmustats.dds_inconsistent) {
407                 zfs_cmd_t zc = { 0 };
408
409                 /*
410                  * If it is dds_inconsistent, then we've caught it in
411                  * the middle of a 'zfs receive' or 'zfs destroy', and
412                  * it is inconsistent from the ZPL's point of view, so
413                  * can't be mounted.  However, it could also be that we
414                  * have crashed in the middle of one of those
415                  * operations, in which case we need to get rid of the
416                  * inconsistent state.  We do that by either rolling
417                  * back to the previous snapshot (which will fail if
418                  * there is none), or destroying the filesystem.  Note
419                  * that if we are still in the middle of an active
420                  * 'receive' or 'destroy', then the rollback and destroy
421                  * will fail with EBUSY and we will drive on as usual.
422                  */
423
424                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
425
426                 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
427                         (void) zvol_remove_link(hdl, zhp->zfs_name);
428                         zc.zc_objset_type = DMU_OST_ZVOL;
429                 } else {
430                         zc.zc_objset_type = DMU_OST_ZFS;
431                 }
432
433                 /*
434                  * If we can successfully destroy it, pretend that it
435                  * never existed.
436                  */
437                 if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) {
438                         zhp->zfs_hdl->libzfs_log_str = logstr;
439                         free(zhp);
440                         errno = ENOENT;
441                         return (NULL);
442                 }
443                 /* If we can successfully roll it back, reget the stats */
444                 if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0)
445                         goto top;
446         }
447
448         /*
449          * We've managed to open the dataset and gather statistics.  Determine
450          * the high-level type.
451          */
452         if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
453                 zhp->zfs_head_type = ZFS_TYPE_VOLUME;
454         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
455                 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
456         else
457                 abort();
458
459         if (zhp->zfs_dmustats.dds_is_snapshot)
460                 zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
461         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
462                 zhp->zfs_type = ZFS_TYPE_VOLUME;
463         else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
464                 zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
465         else
466                 abort();        /* we should never see any other types */
467
468         zhp->zfs_hdl->libzfs_log_str = logstr;
469         zhp->zpool_hdl = zpool_handle(zhp);
470         return (zhp);
471 }
472
473 /*
474  * Opens the given snapshot, filesystem, or volume.   The 'types'
475  * argument is a mask of acceptable types.  The function will print an
476  * appropriate error message and return NULL if it can't be opened.
477  */
478 zfs_handle_t *
479 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
480 {
481         zfs_handle_t *zhp;
482         char errbuf[1024];
483
484         (void) snprintf(errbuf, sizeof (errbuf),
485             dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
486
487         /*
488          * Validate the name before we even try to open it.
489          */
490         if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) {
491                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
492                     "invalid dataset name"));
493                 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
494                 return (NULL);
495         }
496
497         /*
498          * Try to get stats for the dataset, which will tell us if it exists.
499          */
500         errno = 0;
501         if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
502                 (void) zfs_standard_error(hdl, errno, errbuf);
503                 return (NULL);
504         }
505
506         if (!(types & zhp->zfs_type)) {
507                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
508                 zfs_close(zhp);
509                 return (NULL);
510         }
511
512         return (zhp);
513 }
514
515 /*
516  * Release a ZFS handle.  Nothing to do but free the associated memory.
517  */
518 void
519 zfs_close(zfs_handle_t *zhp)
520 {
521         if (zhp->zfs_mntopts)
522                 free(zhp->zfs_mntopts);
523         nvlist_free(zhp->zfs_props);
524         nvlist_free(zhp->zfs_user_props);
525         free(zhp);
526 }
527
528 int
529 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
530 {
531         zpool_handle_t *zpool_handle = zhp->zpool_hdl;
532
533         if (zpool_handle == NULL)
534                 return (-1);
535
536         *spa_version = zpool_get_prop_int(zpool_handle,
537             ZPOOL_PROP_VERSION, NULL);
538         return (0);
539 }
540
541 /*
542  * The choice of reservation property depends on the SPA version.
543  */
544 static int
545 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
546 {
547         int spa_version;
548
549         if (zfs_spa_version(zhp, &spa_version) < 0)
550                 return (-1);
551
552         if (spa_version >= SPA_VERSION_REFRESERVATION)
553                 *resv_prop = ZFS_PROP_REFRESERVATION;
554         else
555                 *resv_prop = ZFS_PROP_RESERVATION;
556
557         return (0);
558 }
559
560 /*
561  * Given an nvlist of properties to set, validates that they are correct, and
562  * parses any numeric properties (index, boolean, etc) if they are specified as
563  * strings.
564  */
565 nvlist_t *
566 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
567     uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
568 {
569         nvpair_t *elem;
570         uint64_t intval;
571         char *strval;
572         zfs_prop_t prop;
573         nvlist_t *ret;
574         int chosen_normal = -1;
575         int chosen_utf = -1;
576
577         if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
578                 (void) no_memory(hdl);
579                 return (NULL);
580         }
581
582         elem = NULL;
583         while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
584                 const char *propname = nvpair_name(elem);
585
586                 /*
587                  * Make sure this property is valid and applies to this type.
588                  */
589                 if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
590                         if (!zfs_prop_user(propname)) {
591                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
592                                     "invalid property '%s'"), propname);
593                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
594                                 goto error;
595                         }
596
597                         /*
598                          * If this is a user property, make sure it's a
599                          * string, and that it's less than ZAP_MAXNAMELEN.
600                          */
601                         if (nvpair_type(elem) != DATA_TYPE_STRING) {
602                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
603                                     "'%s' must be a string"), propname);
604                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
605                                 goto error;
606                         }
607
608                         if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
609                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
610                                     "property name '%s' is too long"),
611                                     propname);
612                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
613                                 goto error;
614                         }
615
616                         (void) nvpair_value_string(elem, &strval);
617                         if (nvlist_add_string(ret, propname, strval) != 0) {
618                                 (void) no_memory(hdl);
619                                 goto error;
620                         }
621                         continue;
622                 }
623
624                 if (type == ZFS_TYPE_SNAPSHOT) {
625                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
626                             "this property can not be modified for snapshots"));
627                         (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
628                         goto error;
629                 }
630
631                 if (!zfs_prop_valid_for_type(prop, type)) {
632                         zfs_error_aux(hdl,
633                             dgettext(TEXT_DOMAIN, "'%s' does not "
634                             "apply to datasets of this type"), propname);
635                         (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
636                         goto error;
637                 }
638
639                 if (zfs_prop_readonly(prop) &&
640                     (!zfs_prop_setonce(prop) || zhp != NULL)) {
641                         zfs_error_aux(hdl,
642                             dgettext(TEXT_DOMAIN, "'%s' is readonly"),
643                             propname);
644                         (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
645                         goto error;
646                 }
647
648                 if (zprop_parse_value(hdl, elem, prop, type, ret,
649                     &strval, &intval, errbuf) != 0)
650                         goto error;
651
652                 /*
653                  * Perform some additional checks for specific properties.
654                  */
655                 switch (prop) {
656                 case ZFS_PROP_VERSION:
657                 {
658                         int version;
659
660                         if (zhp == NULL)
661                                 break;
662                         version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
663                         if (intval < version) {
664                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
665                                     "Can not downgrade; already at version %u"),
666                                     version);
667                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
668                                 goto error;
669                         }
670                         break;
671                 }
672
673                 case ZFS_PROP_RECORDSIZE:
674                 case ZFS_PROP_VOLBLOCKSIZE:
675                         /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
676                         if (intval < SPA_MINBLOCKSIZE ||
677                             intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
678                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
679                                     "'%s' must be power of 2 from %u "
680                                     "to %uk"), propname,
681                                     (uint_t)SPA_MINBLOCKSIZE,
682                                     (uint_t)SPA_MAXBLOCKSIZE >> 10);
683                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
684                                 goto error;
685                         }
686                         break;
687
688                 case ZFS_PROP_SHAREISCSI:
689                         if (strcmp(strval, "off") != 0 &&
690                             strcmp(strval, "on") != 0 &&
691                             strcmp(strval, "type=disk") != 0) {
692                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
693                                     "'%s' must be 'on', 'off', or 'type=disk'"),
694                                     propname);
695                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
696                                 goto error;
697                         }
698
699                         break;
700
701                 case ZFS_PROP_MOUNTPOINT:
702                 {
703                         namecheck_err_t why;
704
705                         if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
706                             strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
707                                 break;
708
709                         if (mountpoint_namecheck(strval, &why)) {
710                                 switch (why) {
711                                 case NAME_ERR_LEADING_SLASH:
712                                         zfs_error_aux(hdl,
713                                             dgettext(TEXT_DOMAIN,
714                                             "'%s' must be an absolute path, "
715                                             "'none', or 'legacy'"), propname);
716                                         break;
717                                 case NAME_ERR_TOOLONG:
718                                         zfs_error_aux(hdl,
719                                             dgettext(TEXT_DOMAIN,
720                                             "component of '%s' is too long"),
721                                             propname);
722                                         break;
723                                 }
724                                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
725                                 goto error;
726                         }
727                 }
728
729                         /*FALLTHRU*/
730
731                 case ZFS_PROP_SHARESMB:
732                 case ZFS_PROP_SHARENFS:
733                         /*
734                          * For the mountpoint and sharenfs or sharesmb
735                          * properties, check if it can be set in a
736                          * global/non-global zone based on
737                          * the zoned property value:
738                          *
739                          *              global zone         non-global zone
740                          * --------------------------------------------------
741                          * zoned=on     mountpoint (no)     mountpoint (yes)
742                          *              sharenfs (no)       sharenfs (no)
743                          *              sharesmb (no)       sharesmb (no)
744                          *
745                          * zoned=off    mountpoint (yes)        N/A
746                          *              sharenfs (yes)
747                          *              sharesmb (yes)
748                          */
749                         if (zoned) {
750                                 if (getzoneid() == GLOBAL_ZONEID) {
751                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
752                                             "'%s' cannot be set on "
753                                             "dataset in a non-global zone"),
754                                             propname);
755                                         (void) zfs_error(hdl, EZFS_ZONED,
756                                             errbuf);
757                                         goto error;
758                                 } else if (prop == ZFS_PROP_SHARENFS ||
759                                     prop == ZFS_PROP_SHARESMB) {
760                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
761                                             "'%s' cannot be set in "
762                                             "a non-global zone"), propname);
763                                         (void) zfs_error(hdl, EZFS_ZONED,
764                                             errbuf);
765                                         goto error;
766                                 }
767                         } else if (getzoneid() != GLOBAL_ZONEID) {
768                                 /*
769                                  * If zoned property is 'off', this must be in
770                                  * a globle zone. If not, something is wrong.
771                                  */
772                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
773                                     "'%s' cannot be set while dataset "
774                                     "'zoned' property is set"), propname);
775                                 (void) zfs_error(hdl, EZFS_ZONED, errbuf);
776                                 goto error;
777                         }
778
779                         /*
780                          * At this point, it is legitimate to set the
781                          * property. Now we want to make sure that the
782                          * property value is valid if it is sharenfs.
783                          */
784                         if ((prop == ZFS_PROP_SHARENFS ||
785                             prop == ZFS_PROP_SHARESMB) &&
786                             strcmp(strval, "on") != 0 &&
787                             strcmp(strval, "off") != 0) {
788                                 zfs_share_proto_t proto;
789
790                                 if (prop == ZFS_PROP_SHARESMB)
791                                         proto = PROTO_SMB;
792                                 else
793                                         proto = PROTO_NFS;
794
795                                 /*
796                                  * Must be an valid sharing protocol
797                                  * option string so init the libshare
798                                  * in order to enable the parser and
799                                  * then parse the options. We use the
800                                  * control API since we don't care about
801                                  * the current configuration and don't
802                                  * want the overhead of loading it
803                                  * until we actually do something.
804                                  */
805
806                                 if (zfs_init_libshare(hdl,
807                                     SA_INIT_CONTROL_API) != SA_OK) {
808                                         /*
809                                          * An error occurred so we can't do
810                                          * anything
811                                          */
812                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
813                                             "'%s' cannot be set: problem "
814                                             "in share initialization"),
815                                             propname);
816                                         (void) zfs_error(hdl, EZFS_BADPROP,
817                                             errbuf);
818                                         goto error;
819                                 }
820
821                                 if (zfs_parse_options(strval, proto) != SA_OK) {
822                                         /*
823                                          * There was an error in parsing so
824                                          * deal with it by issuing an error
825                                          * message and leaving after
826                                          * uninitializing the the libshare
827                                          * interface.
828                                          */
829                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
830                                             "'%s' cannot be set to invalid "
831                                             "options"), propname);
832                                         (void) zfs_error(hdl, EZFS_BADPROP,
833                                             errbuf);
834                                         zfs_uninit_libshare(hdl);
835                                         goto error;
836                                 }
837                                 zfs_uninit_libshare(hdl);
838                         }
839
840                         break;
841                 case ZFS_PROP_UTF8ONLY:
842                         chosen_utf = (int)intval;
843                         break;
844                 case ZFS_PROP_NORMALIZE:
845                         chosen_normal = (int)intval;
846                         break;
847                 }
848
849                 /*
850                  * For changes to existing volumes, we have some additional
851                  * checks to enforce.
852                  */
853                 if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
854                         uint64_t volsize = zfs_prop_get_int(zhp,
855                             ZFS_PROP_VOLSIZE);
856                         uint64_t blocksize = zfs_prop_get_int(zhp,
857                             ZFS_PROP_VOLBLOCKSIZE);
858                         char buf[64];
859
860                         switch (prop) {
861                         case ZFS_PROP_RESERVATION:
862                         case ZFS_PROP_REFRESERVATION:
863                                 if (intval > volsize) {
864                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
865                                             "'%s' is greater than current "
866                                             "volume size"), propname);
867                                         (void) zfs_error(hdl, EZFS_BADPROP,
868                                             errbuf);
869                                         goto error;
870                                 }
871                                 break;
872
873                         case ZFS_PROP_VOLSIZE:
874                                 if (intval % blocksize != 0) {
875                                         zfs_nicenum(blocksize, buf,
876                                             sizeof (buf));
877                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
878                                             "'%s' must be a multiple of "
879                                             "volume block size (%s)"),
880                                             propname, buf);
881                                         (void) zfs_error(hdl, EZFS_BADPROP,
882                                             errbuf);
883                                         goto error;
884                                 }
885
886                                 if (intval == 0) {
887                                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
888                                             "'%s' cannot be zero"),
889                                             propname);
890                                         (void) zfs_error(hdl, EZFS_BADPROP,
891                                             errbuf);
892                                         goto error;
893                                 }
894                                 break;
895                         }
896                 }
897         }
898
899         /*
900          * If normalization was chosen, but no UTF8 choice was made,
901          * enforce rejection of non-UTF8 names.
902          *
903          * If normalization was chosen, but rejecting non-UTF8 names
904          * was explicitly not chosen, it is an error.
905          */
906         if (chosen_normal > 0 && chosen_utf < 0) {
907                 if (nvlist_add_uint64(ret,
908                     zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
909                         (void) no_memory(hdl);
910                         goto error;
911                 }
912         } else if (chosen_normal > 0 && chosen_utf == 0) {
913                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
914                     "'%s' must be set 'on' if normalization chosen"),
915                     zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
916                 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
917                 goto error;
918         }
919
920         /*
921          * If this is an existing volume, and someone is setting the volsize,
922          * make sure that it matches the reservation, or add it if necessary.
923          */
924         if (zhp != NULL && type == ZFS_TYPE_VOLUME &&
925             nvlist_lookup_uint64(ret, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
926             &intval) == 0) {
927                 uint64_t old_volsize = zfs_prop_get_int(zhp,
928                     ZFS_PROP_VOLSIZE);
929                 uint64_t old_reservation;
930                 uint64_t new_reservation;
931                 zfs_prop_t resv_prop;
932
933                 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
934                         goto error;
935                 old_reservation = zfs_prop_get_int(zhp, resv_prop);
936
937                 if (old_volsize == old_reservation &&
938                     nvlist_lookup_uint64(ret, zfs_prop_to_name(resv_prop),
939                     &new_reservation) != 0) {
940                         if (nvlist_add_uint64(ret,
941                             zfs_prop_to_name(resv_prop), intval) != 0) {
942                                 (void) no_memory(hdl);
943                                 goto error;
944                         }
945                 }
946         }
947         return (ret);
948
949 error:
950         nvlist_free(ret);
951         return (NULL);
952 }
953
954 static int
955 zfs_get_perm_who(const char *who, zfs_deleg_who_type_t *who_type,
956     uint64_t *ret_who)
957 {
958         struct passwd *pwd;
959         struct group *grp;
960         uid_t id;
961
962         if (*who_type == ZFS_DELEG_EVERYONE || *who_type == ZFS_DELEG_CREATE ||
963             *who_type == ZFS_DELEG_NAMED_SET) {
964                 *ret_who = -1;
965                 return (0);
966         }
967         if (who == NULL && !(*who_type == ZFS_DELEG_EVERYONE))
968                 return (EZFS_BADWHO);
969
970         if (*who_type == ZFS_DELEG_WHO_UNKNOWN &&
971             strcmp(who, "everyone") == 0) {
972                 *ret_who = -1;
973                 *who_type = ZFS_DELEG_EVERYONE;
974                 return (0);
975         }
976
977         pwd = getpwnam(who);
978         grp = getgrnam(who);
979
980         if ((*who_type == ZFS_DELEG_USER) && pwd) {
981                 *ret_who = pwd->pw_uid;
982         } else if ((*who_type == ZFS_DELEG_GROUP) && grp) {
983                 *ret_who = grp->gr_gid;
984         } else if (pwd) {
985                 *ret_who = pwd->pw_uid;
986                 *who_type = ZFS_DELEG_USER;
987         } else if (grp) {
988                 *ret_who = grp->gr_gid;
989                 *who_type = ZFS_DELEG_GROUP;
990         } else {
991                 char *end;
992
993                 id = strtol(who, &end, 10);
994                 if (errno != 0 || *end != '\0') {
995                         return (EZFS_BADWHO);
996                 } else {
997                         *ret_who = id;
998                         if (*who_type == ZFS_DELEG_WHO_UNKNOWN)
999                                 *who_type = ZFS_DELEG_USER;
1000                 }
1001         }
1002
1003         return (0);
1004 }
1005
1006 static void
1007 zfs_perms_add_to_nvlist(nvlist_t *who_nvp, char *name, nvlist_t *perms_nvp)
1008 {
1009         if (perms_nvp != NULL) {
1010                 verify(nvlist_add_nvlist(who_nvp,
1011                     name, perms_nvp) == 0);
1012         } else {
1013                 verify(nvlist_add_boolean(who_nvp, name) == 0);
1014         }
1015 }
1016
1017 static void
1018 helper(zfs_deleg_who_type_t who_type, uint64_t whoid, char *whostr,
1019     zfs_deleg_inherit_t inherit, nvlist_t *who_nvp, nvlist_t *perms_nvp,
1020     nvlist_t *sets_nvp)
1021 {
1022         boolean_t do_perms, do_sets;
1023         char name[ZFS_MAX_DELEG_NAME];
1024
1025         do_perms = (nvlist_next_nvpair(perms_nvp, NULL) != NULL);
1026         do_sets = (nvlist_next_nvpair(sets_nvp, NULL) != NULL);
1027
1028         if (!do_perms && !do_sets)
1029                 do_perms = do_sets = B_TRUE;
1030
1031         if (do_perms) {
1032                 zfs_deleg_whokey(name, who_type, inherit,
1033                     (who_type == ZFS_DELEG_NAMED_SET) ?
1034                     whostr : (void *)&whoid);
1035                 zfs_perms_add_to_nvlist(who_nvp, name, perms_nvp);
1036         }
1037         if (do_sets) {
1038                 zfs_deleg_whokey(name, toupper(who_type), inherit,
1039                     (who_type == ZFS_DELEG_NAMED_SET) ?
1040                     whostr : (void *)&whoid);
1041                 zfs_perms_add_to_nvlist(who_nvp, name, sets_nvp);
1042         }
1043 }
1044
1045 static void
1046 zfs_perms_add_who_nvlist(nvlist_t *who_nvp, uint64_t whoid, void *whostr,
1047     nvlist_t *perms_nvp, nvlist_t *sets_nvp,
1048     zfs_deleg_who_type_t who_type, zfs_deleg_inherit_t inherit)
1049 {
1050         if (who_type == ZFS_DELEG_NAMED_SET || who_type == ZFS_DELEG_CREATE) {
1051                 helper(who_type, whoid, whostr, 0,
1052                     who_nvp, perms_nvp, sets_nvp);
1053         } else {
1054                 if (inherit & ZFS_DELEG_PERM_LOCAL) {
1055                         helper(who_type, whoid, whostr, ZFS_DELEG_LOCAL,
1056                             who_nvp, perms_nvp, sets_nvp);
1057                 }
1058                 if (inherit & ZFS_DELEG_PERM_DESCENDENT) {
1059                         helper(who_type, whoid, whostr, ZFS_DELEG_DESCENDENT,
1060                             who_nvp, perms_nvp, sets_nvp);
1061                 }
1062         }
1063 }
1064
1065 /*
1066  * Construct nvlist to pass down to kernel for setting/removing permissions.
1067  *
1068  * The nvlist is constructed as a series of nvpairs with an optional embedded
1069  * nvlist of permissions to remove or set.  The topmost nvpairs are the actual
1070  * base attribute named stored in the dsl.
1071  * Arguments:
1072  *
1073  * whostr:   is a comma separated list of users, groups, or a single set name.
1074  *           whostr may be null for everyone or create perms.
1075  * who_type: is the type of entry in whostr.  Typically this will be
1076  *           ZFS_DELEG_WHO_UNKNOWN.
1077  * perms:    common separated list of permissions.  May be null if user
1078  *           is requested to remove permissions by who.
1079  * inherit:  Specifies the inheritance of the permissions.  Will be either
1080  *           ZFS_DELEG_PERM_LOCAL and/or  ZFS_DELEG_PERM_DESCENDENT.
1081  * nvp       The constructed nvlist to pass to zfs_perm_set().
1082  *           The output nvp will look something like this.
1083  *              ul$1234 -> {create ; destroy }
1084  *              Ul$1234 -> { @myset }
1085  *              s-$@myset - { snapshot; checksum; compression }
1086  */
1087 int
1088 zfs_build_perms(zfs_handle_t *zhp, char *whostr, char *perms,
1089     zfs_deleg_who_type_t who_type, zfs_deleg_inherit_t inherit, nvlist_t **nvp)
1090 {
1091         nvlist_t *who_nvp;
1092         nvlist_t *perms_nvp = NULL;
1093         nvlist_t *sets_nvp = NULL;
1094         char errbuf[1024];
1095         char *who_tok, *perm;
1096         int error;
1097
1098         *nvp = NULL;
1099
1100         if (perms) {
1101                 if ((error = nvlist_alloc(&perms_nvp,
1102                     NV_UNIQUE_NAME, 0)) != 0) {
1103                         return (1);
1104                 }
1105                 if ((error = nvlist_alloc(&sets_nvp,
1106                     NV_UNIQUE_NAME, 0)) != 0) {
1107                         nvlist_free(perms_nvp);
1108                         return (1);
1109                 }
1110         }
1111
1112         if ((error = nvlist_alloc(&who_nvp, NV_UNIQUE_NAME, 0)) != 0) {
1113                 if (perms_nvp)
1114                         nvlist_free(perms_nvp);
1115                 if (sets_nvp)
1116                         nvlist_free(sets_nvp);
1117                 return (1);
1118         }
1119
1120         if (who_type == ZFS_DELEG_NAMED_SET) {
1121                 namecheck_err_t why;
1122                 char what;
1123
1124                 if ((error = permset_namecheck(whostr, &why, &what)) != 0) {
1125                         nvlist_free(who_nvp);
1126                         if (perms_nvp)
1127                                 nvlist_free(perms_nvp);
1128                         if (sets_nvp)
1129                                 nvlist_free(sets_nvp);
1130
1131                         switch (why) {
1132                         case NAME_ERR_NO_AT:
1133                                 zfs_error_aux(zhp->zfs_hdl,
1134                                     dgettext(TEXT_DOMAIN,
1135                                     "set definition must begin with an '@' "
1136                                     "character"));
1137                         }
1138                         return (zfs_error(zhp->zfs_hdl,
1139                             EZFS_BADPERMSET, whostr));
1140                 }
1141         }
1142
1143         /*
1144          * Build up nvlist(s) of permissions.  Two nvlists are maintained.
1145          * The first nvlist perms_nvp will have normal permissions and the
1146          * other sets_nvp will have only permssion set names in it.
1147          */
1148         for (perm = strtok(perms, ","); perm; perm = strtok(NULL, ",")) {
1149                 const char *perm_canonical = zfs_deleg_canonicalize_perm(perm);
1150
1151                 if (perm_canonical) {
1152                         verify(nvlist_add_boolean(perms_nvp,
1153                             perm_canonical) == 0);
1154                 } else if (perm[0] == '@') {
1155                         verify(nvlist_add_boolean(sets_nvp, perm) == 0);
1156                 } else {
1157                         nvlist_free(who_nvp);
1158                         nvlist_free(perms_nvp);
1159                         nvlist_free(sets_nvp);
1160                         return (zfs_error(zhp->zfs_hdl, EZFS_BADPERM, perm));
1161                 }
1162         }
1163
1164         if (whostr && who_type != ZFS_DELEG_CREATE) {
1165                 who_tok = strtok(whostr, ",");
1166                 if (who_tok == NULL) {
1167                         nvlist_free(who_nvp);
1168                         if (perms_nvp)
1169                                 nvlist_free(perms_nvp);
1170                         if (sets_nvp)
1171                                 nvlist_free(sets_nvp);
1172                         (void) snprintf(errbuf, sizeof (errbuf),
1173                             dgettext(TEXT_DOMAIN, "Who string is NULL"),
1174                             whostr);
1175                         return (zfs_error(zhp->zfs_hdl, EZFS_BADWHO, errbuf));
1176                 }
1177         }
1178
1179         /*
1180          * Now create the nvlist(s)
1181          */
1182         do {
1183                 uint64_t who_id;
1184
1185                 error = zfs_get_perm_who(who_tok, &who_type,
1186                     &who_id);
1187                 if (error) {
1188                         nvlist_free(who_nvp);
1189                         if (perms_nvp)
1190                                 nvlist_free(perms_nvp);
1191                         if (sets_nvp)
1192                                 nvlist_free(sets_nvp);
1193                         (void) snprintf(errbuf, sizeof (errbuf),
1194                             dgettext(TEXT_DOMAIN,
1195                             "Unable to determine uid/gid for "
1196                             "%s "), who_tok);
1197                         return (zfs_error(zhp->zfs_hdl, EZFS_BADWHO, errbuf));
1198                 }
1199
1200                 /*
1201                  * add entries for both local and descendent when required
1202                  */
1203                 zfs_perms_add_who_nvlist(who_nvp, who_id, who_tok,
1204                     perms_nvp, sets_nvp, who_type, inherit);
1205
1206         } while (who_tok = strtok(NULL, ","));
1207         *nvp = who_nvp;
1208         return (0);
1209 }
1210
1211 static int
1212 zfs_perm_set_common(zfs_handle_t *zhp, nvlist_t *nvp, boolean_t unset)
1213 {
1214         zfs_cmd_t zc = { 0 };
1215         int error;
1216         char errbuf[1024];
1217
1218         (void) snprintf(errbuf, sizeof (errbuf),
1219             dgettext(TEXT_DOMAIN, "Cannot update 'allows' for '%s'"),
1220             zhp->zfs_name);
1221
1222         if (zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, nvp))
1223                 return (-1);
1224
1225         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1226         zc.zc_perm_action = unset;
1227
1228         error = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SET_FSACL, &zc);
1229         if (error && errno == ENOTSUP) {
1230                 (void) snprintf(errbuf, sizeof (errbuf),
1231                     gettext("Pool must be upgraded to use 'allow/unallow'"));
1232                 zcmd_free_nvlists(&zc);
1233                 return (zfs_error(zhp->zfs_hdl, EZFS_BADVERSION, errbuf));
1234         } else if (error) {
1235                 return (zfs_standard_error(zhp->zfs_hdl, errno, errbuf));
1236         }
1237         zcmd_free_nvlists(&zc);
1238
1239         return (error);
1240 }
1241
1242 int
1243 zfs_perm_set(zfs_handle_t *zhp, nvlist_t *nvp)
1244 {
1245         return (zfs_perm_set_common(zhp, nvp, B_FALSE));
1246 }
1247
1248 int
1249 zfs_perm_remove(zfs_handle_t *zhp, nvlist_t *perms)
1250 {
1251         return (zfs_perm_set_common(zhp, perms, B_TRUE));
1252 }
1253
1254 static int
1255 perm_compare(const void *arg1, const void *arg2)
1256 {
1257         const zfs_perm_node_t *node1 = arg1;
1258         const zfs_perm_node_t *node2 = arg2;
1259         int ret;
1260
1261         ret = strcmp(node1->z_pname, node2->z_pname);
1262
1263         if (ret > 0)
1264                 return (1);
1265         if (ret < 0)
1266                 return (-1);
1267         else
1268                 return (0);
1269 }
1270
1271 static void
1272 zfs_destroy_perm_tree(avl_tree_t *tree)
1273 {
1274         zfs_perm_node_t *permnode;
1275         void *cookie = NULL;
1276
1277         while ((permnode = avl_destroy_nodes(tree,  &cookie)) != NULL)
1278                 free(permnode);
1279         avl_destroy(tree);
1280 }
1281
1282 static void
1283 zfs_destroy_tree(avl_tree_t *tree)
1284 {
1285         zfs_allow_node_t *allownode;
1286         void *cookie = NULL;
1287
1288         while ((allownode = avl_destroy_nodes(tree, &cookie)) != NULL) {
1289                 zfs_destroy_perm_tree(&allownode->z_localdescend);
1290                 zfs_destroy_perm_tree(&allownode->z_local);
1291                 zfs_destroy_perm_tree(&allownode->z_descend);
1292                 free(allownode);
1293         }
1294         avl_destroy(tree);
1295 }
1296
1297 void
1298 zfs_free_allows(zfs_allow_t *allow)
1299 {
1300         zfs_allow_t *allownext;
1301         zfs_allow_t *freeallow;
1302
1303         allownext = allow;
1304         while (allownext) {
1305                 zfs_destroy_tree(&allownext->z_sets);
1306                 zfs_destroy_tree(&allownext->z_crperms);
1307                 zfs_destroy_tree(&allownext->z_user);
1308                 zfs_destroy_tree(&allownext->z_group);
1309                 zfs_destroy_tree(&allownext->z_everyone);
1310                 freeallow = allownext;
1311                 allownext = allownext->z_next;
1312                 free(freeallow);
1313         }
1314 }
1315
1316 static zfs_allow_t *
1317 zfs_alloc_perm_tree(zfs_handle_t *zhp, zfs_allow_t *prev, char *setpoint)
1318 {
1319         zfs_allow_t *ptree;
1320
1321         if ((ptree = zfs_alloc(zhp->zfs_hdl,
1322             sizeof (zfs_allow_t))) == NULL) {
1323                 return (NULL);
1324         }
1325
1326         (void) strlcpy(ptree->z_setpoint, setpoint, sizeof (ptree->z_setpoint));
1327         avl_create(&ptree->z_sets,
1328             perm_compare, sizeof (zfs_allow_node_t),
1329             offsetof(zfs_allow_node_t, z_node));
1330         avl_create(&ptree->z_crperms,
1331             perm_compare, sizeof (zfs_allow_node_t),
1332             offsetof(zfs_allow_node_t, z_node));
1333         avl_create(&ptree->z_user,
1334             perm_compare, sizeof (zfs_allow_node_t),
1335             offsetof(zfs_allow_node_t, z_node));
1336         avl_create(&ptree->z_group,
1337             perm_compare, sizeof (zfs_allow_node_t),
1338             offsetof(zfs_allow_node_t, z_node));
1339         avl_create(&ptree->z_everyone,
1340             perm_compare, sizeof (zfs_allow_node_t),
1341             offsetof(zfs_allow_node_t, z_node));
1342
1343         if (prev)
1344                 prev->z_next = ptree;
1345         ptree->z_next = NULL;
1346         return (ptree);
1347 }
1348
1349 /*
1350  * Add permissions to the appropriate AVL permission tree.
1351  * The appropriate tree may not be the requested tree.
1352  * For example if ld indicates a local permission, but
1353  * same permission also exists as a descendent permission
1354  * then the permission will be removed from the descendent
1355  * tree and add the the local+descendent tree.
1356  */
1357 static int
1358 zfs_coalesce_perm(zfs_handle_t *zhp, zfs_allow_node_t *allownode,
1359     char *perm, char ld)
1360 {
1361         zfs_perm_node_t pnode, *permnode, *permnode2;
1362         zfs_perm_node_t *newnode;
1363         avl_index_t where, where2;
1364         avl_tree_t *tree, *altree;
1365
1366         (void) strlcpy(pnode.z_pname, perm, sizeof (pnode.z_pname));
1367
1368         if (ld == ZFS_DELEG_NA) {
1369                 tree =  &allownode->z_localdescend;
1370                 altree = &allownode->z_descend;
1371         } else if (ld == ZFS_DELEG_LOCAL) {
1372                 tree = &allownode->z_local;
1373                 altree = &allownode->z_descend;
1374         } else {
1375                 tree = &allownode->z_descend;
1376                 altree = &allownode->z_local;
1377         }
1378         permnode = avl_find(tree, &pnode, &where);
1379         permnode2 = avl_find(altree, &pnode, &where2);
1380
1381         if (permnode2) {
1382                 avl_remove(altree, permnode2);
1383                 free(permnode2);
1384                 if (permnode == NULL) {
1385                         tree =  &allownode->z_localdescend;
1386                 }
1387         }
1388
1389         /*
1390          * Now insert new permission in either requested location
1391          * local/descendent or into ld when perm will exist in both.
1392          */
1393         if (permnode == NULL) {
1394                 if ((newnode = zfs_alloc(zhp->zfs_hdl,
1395                     sizeof (zfs_perm_node_t))) == NULL) {
1396                         return (-1);
1397                 }
1398                 *newnode = pnode;
1399                 avl_add(tree, newnode);
1400         }
1401         return (0);
1402 }
1403
1404 /*
1405  * Uggh, this is going to be a bit complicated.
1406  * we have an nvlist coming out of the kernel that
1407  * will indicate where the permission is set and then
1408  * it will contain allow of the various "who's", and what
1409  * their permissions are.  To further complicate this
1410  * we will then have to coalesce the local,descendent
1411  * and local+descendent permissions where appropriate.
1412  * The kernel only knows about a permission as being local
1413  * or descendent, but not both.
1414  *
1415  * In order to make this easier for zfs_main to deal with
1416  * a series of AVL trees will be used to maintain
1417  * all of this, primarily for sorting purposes as well
1418  * as the ability to quickly locate a specific entry.
1419  *
1420  * What we end up with are tree's for sets, create perms,
1421  * user, groups and everyone.  With each of those trees
1422  * we have subtrees for local, descendent and local+descendent
1423  * permissions.
1424  */
1425 int
1426 zfs_perm_get(zfs_handle_t *zhp, zfs_allow_t **zfs_perms)
1427 {
1428         zfs_cmd_t zc = { 0 };
1429         int error;
1430         nvlist_t *nvlist;
1431         nvlist_t *permnv, *sourcenv;
1432         nvpair_t *who_pair, *source_pair;
1433         nvpair_t *perm_pair;
1434         char errbuf[1024];
1435         zfs_allow_t *zallowp, *newallowp;
1436         char  ld;
1437         char *nvpname;
1438         uid_t   uid;
1439         gid_t   gid;
1440         avl_tree_t *tree;
1441         avl_index_t where;
1442
1443         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1444
1445         if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
1446                 return (-1);
1447
1448         while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) {
1449                 if (errno == ENOMEM) {
1450                         if (zcmd_expand_dst_nvlist(zhp->zfs_hdl, &zc) != 0) {
1451                                 zcmd_free_nvlists(&zc);
1452                                 return (-1);
1453                         }
1454                 } else if (errno == ENOTSUP) {
1455                         zcmd_free_nvlists(&zc);
1456                         (void) snprintf(errbuf, sizeof (errbuf),
1457                             gettext("Pool must be upgraded to use 'allow'"));
1458                         return (zfs_error(zhp->zfs_hdl,
1459                             EZFS_BADVERSION, errbuf));
1460                 } else {
1461                         zcmd_free_nvlists(&zc);
1462                         return (-1);
1463                 }
1464         }
1465
1466         if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &nvlist) != 0) {
1467                 zcmd_free_nvlists(&zc);
1468                 return (-1);
1469         }
1470
1471         zcmd_free_nvlists(&zc);
1472
1473         source_pair = nvlist_next_nvpair(nvlist, NULL);
1474
1475         if (source_pair == NULL) {
1476                 *zfs_perms = NULL;
1477                 return (0);
1478         }
1479
1480         *zfs_perms = zfs_alloc_perm_tree(zhp, NULL, nvpair_name(source_pair));
1481         if (*zfs_perms == NULL) {
1482                 return (0);
1483         }
1484
1485         zallowp = *zfs_perms;
1486
1487         for (;;) {
1488                 struct passwd *pwd;
1489                 struct group *grp;
1490                 zfs_allow_node_t *allownode;
1491                 zfs_allow_node_t  findallownode;
1492                 zfs_allow_node_t *newallownode;
1493
1494                 (void) strlcpy(zallowp->z_setpoint,
1495                     nvpair_name(source_pair),
1496                     sizeof (zallowp->z_setpoint));
1497
1498                 if ((error = nvpair_value_nvlist(source_pair, &sourcenv)) != 0)
1499                         goto abort;
1500
1501                 /*
1502                  * Make sure nvlist is composed correctly
1503                  */
1504                 if (zfs_deleg_verify_nvlist(sourcenv)) {
1505                         goto abort;
1506                 }
1507
1508                 who_pair = nvlist_next_nvpair(sourcenv, NULL);
1509                 if (who_pair == NULL) {
1510                         goto abort;
1511                 }
1512
1513                 do {
1514                         error = nvpair_value_nvlist(who_pair, &permnv);
1515                         if (error) {
1516                                 goto abort;
1517                         }
1518
1519                         /*
1520                          * First build up the key to use
1521                          * for looking up in the various
1522                          * who trees.
1523                          */
1524                         ld = nvpair_name(who_pair)[1];
1525                         nvpname = nvpair_name(who_pair);
1526                         switch (nvpair_name(who_pair)[0]) {
1527                         case ZFS_DELEG_USER:
1528                         case ZFS_DELEG_USER_SETS:
1529                                 tree = &zallowp->z_user;
1530                                 uid = atol(&nvpname[3]);
1531                                 pwd = getpwuid(uid);
1532                                 (void) snprintf(findallownode.z_key,
1533                                     sizeof (findallownode.z_key), "user %s",
1534                                     (pwd) ? pwd->pw_name :
1535                                     &nvpair_name(who_pair)[3]);
1536                                 break;
1537                         case ZFS_DELEG_GROUP:
1538                         case ZFS_DELEG_GROUP_SETS:
1539                                 tree = &zallowp->z_group;
1540                                 gid = atol(&nvpname[3]);
1541                                 grp = getgrgid(gid);
1542                                 (void) snprintf(findallownode.z_key,
1543                                     sizeof (findallownode.z_key), "group %s",
1544                                     (grp) ? grp->gr_name :
1545                                     &nvpair_name(who_pair)[3]);
1546                                 break;
1547                         case ZFS_DELEG_CREATE:
1548                         case ZFS_DELEG_CREATE_SETS:
1549                                 tree = &zallowp->z_crperms;
1550                                 (void) strlcpy(findallownode.z_key, "",
1551                                     sizeof (findallownode.z_key));
1552                                 break;
1553                         case ZFS_DELEG_EVERYONE:
1554                         case ZFS_DELEG_EVERYONE_SETS:
1555                                 (void) snprintf(findallownode.z_key,
1556                                     sizeof (findallownode.z_key), "everyone");
1557                                 tree = &zallowp->z_everyone;
1558                                 break;
1559                         case ZFS_DELEG_NAMED_SET:
1560                         case ZFS_DELEG_NAMED_SET_SETS:
1561                                 (void) snprintf(findallownode.z_key,
1562                                     sizeof (findallownode.z_key), "%s",
1563                                     &nvpair_name(who_pair)[3]);
1564                                 tree = &zallowp->z_sets;
1565                                 break;
1566                         }
1567
1568                         /*
1569                          * Place who in tree
1570                          */
1571                         allownode = avl_find(tree, &findallownode, &where);
1572                         if (allownode == NULL) {
1573                                 if ((newallownode = zfs_alloc(zhp->zfs_hdl,
1574                                     sizeof (zfs_allow_node_t))) == NULL) {
1575                                         goto abort;
1576                                 }
1577                                 avl_create(&newallownode->z_localdescend,
1578                                     perm_compare,
1579                                     sizeof (zfs_perm_node_t),
1580                                     offsetof(zfs_perm_node_t, z_node));
1581                                 avl_create(&newallownode->z_local,
1582                                     perm_compare,
1583                                     sizeof (zfs_perm_node_t),
1584                                     offsetof(zfs_perm_node_t, z_node));
1585                                 avl_create(&newallownode->z_descend,
1586                                     perm_compare,
1587                                     sizeof (zfs_perm_node_t),
1588                                     offsetof(zfs_perm_node_t, z_node));
1589                                 (void) strlcpy(newallownode->z_key,
1590                                     findallownode.z_key,
1591                                     sizeof (findallownode.z_key));
1592                                 avl_insert(tree, newallownode, where);
1593                                 allownode = newallownode;
1594                         }
1595
1596                         /*
1597                          * Now iterate over the permissions and
1598                          * place them in the appropriate local,
1599                          * descendent or local+descendent tree.
1600                          *
1601                          * The permissions are added to the tree
1602                          * via zfs_coalesce_perm().
1603                          */
1604                         perm_pair = nvlist_next_nvpair(permnv, NULL);
1605                         if (perm_pair == NULL)
1606                                 goto abort;
1607                         do {
1608                                 if (zfs_coalesce_perm(zhp, allownode,
1609                                     nvpair_name(perm_pair), ld) != 0)
1610                                         goto abort;
1611                         } while (perm_pair = nvlist_next_nvpair(permnv,
1612                             perm_pair));
1613                 } while (who_pair = nvlist_next_nvpair(sourcenv, who_pair));
1614
1615                 source_pair = nvlist_next_nvpair(nvlist, source_pair);
1616                 if (source_pair == NULL)
1617                         break;
1618
1619                 /*
1620                  * allocate another node from the link list of
1621                  * zfs_allow_t structures
1622                  */
1623                 newallowp = zfs_alloc_perm_tree(zhp, zallowp,
1624                     nvpair_name(source_pair));
1625                 if (newallowp == NULL) {
1626                         goto abort;
1627                 }
1628                 zallowp = newallowp;
1629         }
1630         nvlist_free(nvlist);
1631         return (0);
1632 abort:
1633         zfs_free_allows(*zfs_perms);
1634         nvlist_free(nvlist);
1635         return (-1);
1636 }
1637
1638 static char *
1639 zfs_deleg_perm_note(zfs_deleg_note_t note)
1640 {
1641         /*
1642          * Don't put newlines on end of lines
1643          */
1644         switch (note) {
1645         case ZFS_DELEG_NOTE_CREATE:
1646                 return (dgettext(TEXT_DOMAIN,
1647                     "Must also have the 'mount' ability"));
1648         case ZFS_DELEG_NOTE_DESTROY:
1649                 return (dgettext(TEXT_DOMAIN,
1650                     "Must also have the 'mount' ability"));
1651         case ZFS_DELEG_NOTE_SNAPSHOT:
1652                 return (dgettext(TEXT_DOMAIN,
1653                     "Must also have the 'mount' ability"));
1654         case ZFS_DELEG_NOTE_ROLLBACK:
1655                 return (dgettext(TEXT_DOMAIN,
1656                     "Must also have the 'mount' ability"));
1657         case ZFS_DELEG_NOTE_CLONE:
1658                 return (dgettext(TEXT_DOMAIN, "Must also have the 'create' "
1659                     "ability and 'mount'\n"
1660                     "\t\t\t\tability in the origin file system"));
1661         case ZFS_DELEG_NOTE_PROMOTE:
1662                 return (dgettext(TEXT_DOMAIN, "Must also have the 'mount'\n"
1663                     "\t\t\t\tand 'promote' ability in the origin file system"));
1664         case ZFS_DELEG_NOTE_RENAME:
1665                 return (dgettext(TEXT_DOMAIN, "Must also have the 'mount' "
1666                     "and 'create' \n\t\t\t\tability in the new parent"));
1667         case ZFS_DELEG_NOTE_RECEIVE:
1668                 return (dgettext(TEXT_DOMAIN, "Must also have the 'mount'"
1669                     " and 'create' ability"));
1670         case ZFS_DELEG_NOTE_USERPROP:
1671                 return (dgettext(TEXT_DOMAIN,
1672                     "Allows changing any user property"));
1673         case ZFS_DELEG_NOTE_ALLOW:
1674                 return (dgettext(TEXT_DOMAIN,
1675                     "Must also have the permission that is being\n"
1676                     "\t\t\t\tallowed"));
1677         case ZFS_DELEG_NOTE_MOUNT:
1678                 return (dgettext(TEXT_DOMAIN,
1679                     "Allows mount/umount of ZFS datasets"));
1680         case ZFS_DELEG_NOTE_SHARE:
1681                 return (dgettext(TEXT_DOMAIN,
1682                     "Allows sharing file systems over NFS or SMB\n"
1683                     "\t\t\t\tprotocols"));
1684         case ZFS_DELEG_NOTE_NONE:
1685         default:
1686                 return (dgettext(TEXT_DOMAIN, ""));
1687         }
1688 }
1689
1690 typedef enum {
1691         ZFS_DELEG_SUBCOMMAND,
1692         ZFS_DELEG_PROP,
1693         ZFS_DELEG_OTHER
1694 } zfs_deleg_perm_type_t;
1695
1696 /*
1697  * is the permission a subcommand or other?
1698  */
1699 zfs_deleg_perm_type_t
1700 zfs_deleg_perm_type(const char *perm)
1701 {
1702         if (strcmp(perm, "userprop") == 0)
1703                 return (ZFS_DELEG_OTHER);
1704         else
1705                 return (ZFS_DELEG_SUBCOMMAND);
1706 }
1707
1708 static char *
1709 zfs_deleg_perm_type_str(zfs_deleg_perm_type_t type)
1710 {
1711         switch (type) {
1712         case ZFS_DELEG_SUBCOMMAND:
1713                 return (dgettext(TEXT_DOMAIN, "subcommand"));
1714         case ZFS_DELEG_PROP:
1715                 return (dgettext(TEXT_DOMAIN, "property"));
1716         case ZFS_DELEG_OTHER:
1717                 return (dgettext(TEXT_DOMAIN, "other"));
1718         }
1719         return ("");
1720 }
1721
1722 /*ARGSUSED*/
1723 static int
1724 zfs_deleg_prop_cb(int prop, void *cb)
1725 {
1726         if (zfs_prop_delegatable(prop))
1727                 (void) fprintf(stderr, "%-15s %-15s\n", zfs_prop_to_name(prop),
1728                     zfs_deleg_perm_type_str(ZFS_DELEG_PROP));
1729
1730         return (ZPROP_CONT);
1731 }
1732
1733 void
1734 zfs_deleg_permissions(void)
1735 {
1736         int i;
1737
1738         (void) fprintf(stderr, "\n%-15s %-15s\t%s\n\n", "NAME",
1739             "TYPE", "NOTES");
1740
1741         /*
1742          * First print out the subcommands
1743          */
1744         for (i = 0; zfs_deleg_perm_tab[i].z_perm != NULL; i++) {
1745                 (void) fprintf(stderr, "%-15s %-15s\t%s\n",
1746                     zfs_deleg_perm_tab[i].z_perm,
1747                     zfs_deleg_perm_type_str(
1748                     zfs_deleg_perm_type(zfs_deleg_perm_tab[i].z_perm)),
1749                     zfs_deleg_perm_note(zfs_deleg_perm_tab[i].z_note));
1750         }
1751
1752         (void) zprop_iter(zfs_deleg_prop_cb, NULL, B_FALSE, B_TRUE,
1753             ZFS_TYPE_DATASET|ZFS_TYPE_VOLUME);
1754 }
1755
1756 /*
1757  * Given a property name and value, set the property for the given dataset.
1758  */
1759 int
1760 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1761 {
1762         zfs_cmd_t zc = { 0 };
1763         int ret = -1;
1764         prop_changelist_t *cl = NULL;
1765         char errbuf[1024];
1766         libzfs_handle_t *hdl = zhp->zfs_hdl;
1767         nvlist_t *nvl = NULL, *realprops;
1768         zfs_prop_t prop;
1769         boolean_t do_prefix;
1770         uint64_t idx;
1771
1772         (void) snprintf(errbuf, sizeof (errbuf),
1773             dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1774             zhp->zfs_name);
1775
1776         if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1777             nvlist_add_string(nvl, propname, propval) != 0) {
1778                 (void) no_memory(hdl);
1779                 goto error;
1780         }
1781
1782         if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
1783             zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1784                 goto error;
1785
1786         nvlist_free(nvl);
1787         nvl = realprops;
1788
1789         prop = zfs_name_to_prop(propname);
1790
1791         /* We don't support those properties on FreeBSD. */
1792         switch (prop) {
1793         case ZFS_PROP_SHAREISCSI:
1794         case ZFS_PROP_DEVICES:
1795         case ZFS_PROP_ISCSIOPTIONS:
1796                 (void) snprintf(errbuf, sizeof (errbuf),
1797                     "property '%s' not supported on FreeBSD", propname);
1798                 ret = zfs_error(hdl, EZFS_PERM, errbuf);
1799                 goto error;
1800         }
1801
1802         if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1803                 goto error;
1804
1805         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1806                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1807                     "child dataset with inherited mountpoint is used "
1808                     "in a non-global zone"));
1809                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1810                 goto error;
1811         }
1812
1813         /*
1814          * If the dataset's canmount property is being set to noauto,
1815          * then we want to prevent unmounting & remounting it.
1816          */
1817         do_prefix = !((prop == ZFS_PROP_CANMOUNT) &&
1818             (zprop_string_to_index(prop, propval, &idx,
1819             ZFS_TYPE_DATASET) == 0) && (idx == ZFS_CANMOUNT_NOAUTO));
1820
1821         if (do_prefix && (ret = changelist_prefix(cl)) != 0)
1822                 goto error;
1823
1824         /*
1825          * Execute the corresponding ioctl() to set this property.
1826          */
1827         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1828
1829         if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1830                 goto error;
1831
1832         ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1833         if (ret != 0) {
1834                 switch (errno) {
1835
1836                 case ENOSPC:
1837                         /*
1838                          * For quotas and reservations, ENOSPC indicates
1839                          * something different; setting a quota or reservation
1840                          * doesn't use any disk space.
1841                          */
1842                         switch (prop) {
1843                         case ZFS_PROP_QUOTA:
1844                         case ZFS_PROP_REFQUOTA:
1845                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1846                                     "size is less than current used or "
1847                                     "reserved space"));
1848                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1849                                 break;
1850
1851                         case ZFS_PROP_RESERVATION:
1852                         case ZFS_PROP_REFRESERVATION:
1853                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1854                                     "size is greater than available space"));
1855                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1856                                 break;
1857
1858                         default:
1859                                 (void) zfs_standard_error(hdl, errno, errbuf);
1860                                 break;
1861                         }
1862                         break;
1863
1864                 case EBUSY:
1865                         if (prop == ZFS_PROP_VOLBLOCKSIZE)
1866                                 (void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
1867                         else
1868                                 (void) zfs_standard_error(hdl, EBUSY, errbuf);
1869                         break;
1870
1871                 case EROFS:
1872                         (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1873                         break;
1874
1875                 case ENOTSUP:
1876                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1877                             "pool and or dataset must be upgraded to set this "
1878                             "property or value"));
1879                         (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1880                         break;
1881
1882                 case ERANGE:
1883                         if (prop == ZFS_PROP_COMPRESSION) {
1884                                 (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1885                                     "property setting is not allowed on "
1886                                     "bootable datasets"));
1887                                 (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1888                         } else {
1889                                 (void) zfs_standard_error(hdl, errno, errbuf);
1890                         }
1891                         break;
1892
1893                 case EOVERFLOW:
1894                         /*
1895                          * This platform can't address a volume this big.
1896                          */
1897 #ifdef _ILP32
1898                         if (prop == ZFS_PROP_VOLSIZE) {
1899                                 (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1900                                 break;
1901                         }
1902 #endif
1903                         /* FALLTHROUGH */
1904                 default:
1905                         (void) zfs_standard_error(hdl, errno, errbuf);
1906                 }
1907         } else {
1908                 if (do_prefix)
1909                         ret = changelist_postfix(cl);
1910
1911                 /*
1912                  * Refresh the statistics so the new property value
1913                  * is reflected.
1914                  */
1915                 if (ret == 0)
1916                         (void) get_stats(zhp);
1917         }
1918
1919 error:
1920         nvlist_free(nvl);
1921         zcmd_free_nvlists(&zc);
1922         if (cl)
1923                 changelist_free(cl);
1924         return (ret);
1925 }
1926
1927 /*
1928  * Given a property, inherit the value from the parent dataset.
1929  */
1930 int
1931 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname)
1932 {
1933         zfs_cmd_t zc = { 0 };
1934         int ret;
1935         prop_changelist_t *cl;
1936         libzfs_handle_t *hdl = zhp->zfs_hdl;
1937         char errbuf[1024];
1938         zfs_prop_t prop;
1939
1940         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1941             "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1942
1943         if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1944                 /*
1945                  * For user properties, the amount of work we have to do is very
1946                  * small, so just do it here.
1947                  */
1948                 if (!zfs_prop_user(propname)) {
1949                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1950                             "invalid property"));
1951                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1952                 }
1953
1954                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1955                 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1956
1957                 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
1958                         return (zfs_standard_error(hdl, errno, errbuf));
1959
1960                 return (0);
1961         }
1962
1963         /*
1964          * Verify that this property is inheritable.
1965          */
1966         if (zfs_prop_readonly(prop))
1967                 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1968
1969         if (!zfs_prop_inheritable(prop))
1970                 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1971
1972         /*
1973          * Check to see if the value applies to this type
1974          */
1975         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1976                 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1977
1978         /*
1979          * Normalize the name, to get rid of shorthand abbrevations.
1980          */
1981         propname = zfs_prop_to_name(prop);
1982         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1983         (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1984
1985         if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1986             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1987                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1988                     "dataset is used in a non-global zone"));
1989                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
1990         }
1991
1992         /*
1993          * Determine datasets which will be affected by this change, if any.
1994          */
1995         if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1996                 return (-1);
1997
1998         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1999                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2000                     "child dataset with inherited mountpoint is used "
2001                     "in a non-global zone"));
2002                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
2003                 goto error;
2004         }
2005
2006         if ((ret = changelist_prefix(cl)) != 0)
2007                 goto error;
2008
2009         if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
2010                 return (zfs_standard_error(hdl, errno, errbuf));
2011         } else {
2012
2013                 if ((ret = changelist_postfix(cl)) != 0)
2014                         goto error;
2015
2016                 /*
2017                  * Refresh the statistics so the new property is reflected.
2018                  */
2019                 (void) get_stats(zhp);
2020         }
2021
2022 error:
2023         changelist_free(cl);
2024         return (ret);
2025 }
2026
2027 /*
2028  * True DSL properties are stored in an nvlist.  The following two functions
2029  * extract them appropriately.
2030  */
2031 static uint64_t
2032 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2033 {
2034         nvlist_t *nv;
2035         uint64_t value;
2036
2037         *source = NULL;
2038         if (nvlist_lookup_nvlist(zhp->zfs_props,
2039             zfs_prop_to_name(prop), &nv) == 0) {
2040                 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
2041                 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2042         } else {
2043                 verify(!zhp->zfs_props_table ||
2044                     zhp->zfs_props_table[prop] == B_TRUE);
2045                 value = zfs_prop_default_numeric(prop);
2046                 *source = "";
2047         }
2048
2049         return (value);
2050 }
2051
2052 static char *
2053 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2054 {
2055         nvlist_t *nv;
2056         char *value;
2057
2058         *source = NULL;
2059         if (nvlist_lookup_nvlist(zhp->zfs_props,
2060             zfs_prop_to_name(prop), &nv) == 0) {
2061                 verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0);
2062                 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2063         } else {
2064                 verify(!zhp->zfs_props_table ||
2065                     zhp->zfs_props_table[prop] == B_TRUE);
2066                 if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
2067                         value = "";
2068                 *source = "";
2069         }
2070
2071         return (value);
2072 }
2073
2074 /*
2075  * Internal function for getting a numeric property.  Both zfs_prop_get() and
2076  * zfs_prop_get_int() are built using this interface.
2077  *
2078  * Certain properties can be overridden using 'mount -o'.  In this case, scan
2079  * the contents of the /etc/mnttab entry, searching for the appropriate options.
2080  * If they differ from the on-disk values, report the current values and mark
2081  * the source "temporary".
2082  */
2083 static int
2084 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
2085     char **source, uint64_t *val)
2086 {
2087         zfs_cmd_t zc = { 0 };
2088         nvlist_t *zplprops = NULL;
2089         struct mnttab mnt;
2090         char *mntopt_on = NULL;
2091         char *mntopt_off = NULL;
2092
2093         *source = NULL;
2094
2095         switch (prop) {
2096         case ZFS_PROP_ATIME:
2097                 mntopt_on = MNTOPT_ATIME;
2098                 mntopt_off = MNTOPT_NOATIME;
2099                 break;
2100
2101         case ZFS_PROP_DEVICES:
2102                 mntopt_on = MNTOPT_DEVICES;
2103                 mntopt_off = MNTOPT_NODEVICES;
2104                 break;
2105
2106         case ZFS_PROP_EXEC:
2107                 mntopt_on = MNTOPT_EXEC;
2108                 mntopt_off = MNTOPT_NOEXEC;
2109                 break;
2110
2111         case ZFS_PROP_READONLY:
2112                 mntopt_on = MNTOPT_RO;
2113                 mntopt_off = MNTOPT_RW;
2114                 break;
2115
2116         case ZFS_PROP_SETUID:
2117                 mntopt_on = MNTOPT_SETUID;
2118                 mntopt_off = MNTOPT_NOSETUID;
2119                 break;
2120
2121         case ZFS_PROP_XATTR:
2122                 mntopt_on = MNTOPT_XATTR;
2123                 mntopt_off = MNTOPT_NOXATTR;
2124                 break;
2125
2126         case ZFS_PROP_NBMAND:
2127                 mntopt_on = MNTOPT_NBMAND;
2128                 mntopt_off = MNTOPT_NONBMAND;
2129                 break;
2130         }
2131
2132         /*
2133          * Because looking up the mount options is potentially expensive
2134          * (iterating over all of /etc/mnttab), we defer its calculation until
2135          * we're looking up a property which requires its presence.
2136          */
2137         if (!zhp->zfs_mntcheck &&
2138             (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
2139                 struct mnttab entry, search = { 0 };
2140                 FILE *mnttab = zhp->zfs_hdl->libzfs_mnttab;
2141
2142                 search.mnt_special = (char *)zhp->zfs_name;
2143                 search.mnt_fstype = MNTTYPE_ZFS;
2144                 rewind(mnttab);
2145
2146                 if (getmntany(mnttab, &entry, &search) == 0) {
2147                         zhp->zfs_mntopts = zfs_strdup(zhp->zfs_hdl,
2148                             entry.mnt_mntopts);
2149                         if (zhp->zfs_mntopts == NULL)
2150                                 return (-1);
2151                 }
2152
2153                 zhp->zfs_mntcheck = B_TRUE;
2154         }
2155
2156         if (zhp->zfs_mntopts == NULL)
2157                 mnt.mnt_mntopts = "";
2158         else
2159                 mnt.mnt_mntopts = zhp->zfs_mntopts;
2160
2161         switch (prop) {
2162         case ZFS_PROP_ATIME:
2163         case ZFS_PROP_DEVICES:
2164         case ZFS_PROP_EXEC:
2165         case ZFS_PROP_READONLY:
2166         case ZFS_PROP_SETUID:
2167         case ZFS_PROP_XATTR:
2168         case ZFS_PROP_NBMAND:
2169                 *val = getprop_uint64(zhp, prop, source);
2170
2171                 if (hasmntopt(&mnt, mntopt_on) && !*val) {
2172                         *val = B_TRUE;
2173                         if (src)
2174                                 *src = ZPROP_SRC_TEMPORARY;
2175                 } else if (hasmntopt(&mnt, mntopt_off) && *val) {
2176                         *val = B_FALSE;
2177                         if (src)
2178                                 *src = ZPROP_SRC_TEMPORARY;
2179                 }
2180                 break;
2181
2182         case ZFS_PROP_CANMOUNT:
2183                 *val = getprop_uint64(zhp, prop, source);
2184                 if (*val != ZFS_CANMOUNT_ON)
2185                         *source = zhp->zfs_name;
2186                 else
2187                         *source = "";   /* default */
2188                 break;
2189
2190         case ZFS_PROP_QUOTA:
2191         case ZFS_PROP_REFQUOTA:
2192         case ZFS_PROP_RESERVATION:
2193         case ZFS_PROP_REFRESERVATION:
2194                 *val = getprop_uint64(zhp, prop, source);
2195                 if (*val == 0)
2196                         *source = "";   /* default */
2197                 else
2198                         *source = zhp->zfs_name;
2199                 break;
2200
2201         case ZFS_PROP_MOUNTED:
2202                 *val = (zhp->zfs_mntopts != NULL);
2203                 break;
2204
2205         case ZFS_PROP_NUMCLONES:
2206                 *val = zhp->zfs_dmustats.dds_num_clones;
2207                 break;
2208
2209         case ZFS_PROP_VERSION:
2210         case ZFS_PROP_NORMALIZE:
2211         case ZFS_PROP_UTF8ONLY:
2212         case ZFS_PROP_CASE:
2213                 if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) ||
2214                     zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
2215                         return (-1);
2216                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2217                 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
2218                         zcmd_free_nvlists(&zc);
2219                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2220                             "unable to get %s property"),
2221                             zfs_prop_to_name(prop));
2222                         return (zfs_error(zhp->zfs_hdl, EZFS_BADVERSION,
2223                             dgettext(TEXT_DOMAIN, "internal error")));
2224                 }
2225                 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
2226                     nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
2227                     val) != 0) {
2228                         zcmd_free_nvlists(&zc);
2229                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2230                             "unable to get %s property"),
2231                             zfs_prop_to_name(prop));
2232                         return (zfs_error(zhp->zfs_hdl, EZFS_NOMEM,
2233                             dgettext(TEXT_DOMAIN, "internal error")));
2234                 }
2235                 if (zplprops)
2236                         nvlist_free(zplprops);
2237                 zcmd_free_nvlists(&zc);
2238                 break;
2239
2240         default:
2241                 switch (zfs_prop_get_type(prop)) {
2242                 case PROP_TYPE_NUMBER:
2243                 case PROP_TYPE_INDEX:
2244                         *val = getprop_uint64(zhp, prop, source);
2245                         /*
2246                          * If we tried to use a defalut value for a
2247                          * readonly property, it means that it was not
2248                          * present; return an error.
2249                          */
2250                         if (zfs_prop_readonly(prop) &&
2251                             *source && (*source)[0] == '\0') {
2252                                 return (-1);
2253                         }
2254                         break;
2255
2256                 case PROP_TYPE_STRING:
2257                 default:
2258                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2259                             "cannot get non-numeric property"));
2260                         return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
2261                             dgettext(TEXT_DOMAIN, "internal error")));
2262                 }
2263         }
2264
2265         return (0);
2266 }
2267
2268 /*
2269  * Calculate the source type, given the raw source string.
2270  */
2271 static void
2272 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
2273     char *statbuf, size_t statlen)
2274 {
2275         if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
2276                 return;
2277
2278         if (source == NULL) {
2279                 *srctype = ZPROP_SRC_NONE;
2280         } else if (source[0] == '\0') {
2281                 *srctype = ZPROP_SRC_DEFAULT;
2282         } else {
2283                 if (strcmp(source, zhp->zfs_name) == 0) {
2284                         *srctype = ZPROP_SRC_LOCAL;
2285                 } else {
2286                         (void) strlcpy(statbuf, source, statlen);
2287                         *srctype = ZPROP_SRC_INHERITED;
2288                 }
2289         }
2290
2291 }
2292
2293 /*
2294  * Retrieve a property from the given object.  If 'literal' is specified, then
2295  * numbers are left as exact values.  Otherwise, numbers are converted to a
2296  * human-readable form.
2297  *
2298  * Returns 0 on success, or -1 on error.
2299  */
2300 int
2301 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2302     zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
2303 {
2304         char *source = NULL;
2305         uint64_t val;
2306         char *str;
2307         const char *strval;
2308
2309         /*
2310          * Check to see if this property applies to our object
2311          */
2312         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
2313                 return (-1);
2314
2315         if (src)
2316                 *src = ZPROP_SRC_NONE;
2317
2318         switch (prop) {
2319         case ZFS_PROP_CREATION:
2320                 /*
2321                  * 'creation' is a time_t stored in the statistics.  We convert
2322                  * this into a string unless 'literal' is specified.
2323                  */
2324                 {
2325                         val = getprop_uint64(zhp, prop, &source);
2326                         time_t time = (time_t)val;
2327                         struct tm t;
2328
2329                         if (literal ||
2330                             localtime_r(&time, &t) == NULL ||
2331                             strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
2332                             &t) == 0)
2333                                 (void) snprintf(propbuf, proplen, "%llu", val);
2334                 }
2335                 break;
2336
2337         case ZFS_PROP_MOUNTPOINT:
2338                 /*
2339                  * Getting the precise mountpoint can be tricky.
2340                  *
2341                  *  - for 'none' or 'legacy', return those values.
2342                  *  - for inherited mountpoints, we want to take everything
2343                  *    after our ancestor and append it to the inherited value.
2344                  *
2345                  * If the pool has an alternate root, we want to prepend that
2346                  * root to any values we return.
2347                  */
2348
2349                 str = getprop_string(zhp, prop, &source);
2350
2351                 if (str[0] == '/') {
2352                         char buf[MAXPATHLEN];
2353                         char *root = buf;
2354                         const char *relpath = zhp->zfs_name + strlen(source);
2355
2356                         if (relpath[0] == '/')
2357                                 relpath++;
2358
2359                         if ((zpool_get_prop(zhp->zpool_hdl,
2360                             ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) ||
2361                             (strcmp(root, "-") == 0))
2362                                 root[0] = '\0';
2363                         /*
2364                          * Special case an alternate root of '/'. This will
2365                          * avoid having multiple leading slashes in the
2366                          * mountpoint path.
2367                          */
2368                         if (strcmp(root, "/") == 0)
2369                                 root++;
2370
2371                         /*
2372                          * If the mountpoint is '/' then skip over this
2373                          * if we are obtaining either an alternate root or
2374                          * an inherited mountpoint.
2375                          */
2376                         if (str[1] == '\0' && (root[0] != '\0' ||
2377                             relpath[0] != '\0'))
2378                                 str++;
2379
2380                         if (relpath[0] == '\0')
2381                                 (void) snprintf(propbuf, proplen, "%s%s",
2382                                     root, str);
2383                         else
2384                                 (void) snprintf(propbuf, proplen, "%s%s%s%s",
2385                                     root, str, relpath[0] == '@' ? "" : "/",
2386                                     relpath);
2387                 } else {
2388                         /* 'legacy' or 'none' */
2389                         (void) strlcpy(propbuf, str, proplen);
2390                 }
2391
2392                 break;
2393
2394         case ZFS_PROP_ORIGIN:
2395                 (void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
2396                     proplen);
2397                 /*
2398                  * If there is no parent at all, return failure to indicate that
2399                  * it doesn't apply to this dataset.
2400                  */
2401                 if (propbuf[0] == '\0')
2402                         return (-1);
2403                 break;
2404
2405         case ZFS_PROP_QUOTA:
2406         case ZFS_PROP_REFQUOTA:
2407         case ZFS_PROP_RESERVATION:
2408         case ZFS_PROP_REFRESERVATION:
2409
2410                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2411                         return (-1);
2412
2413                 /*
2414                  * If quota or reservation is 0, we translate this into 'none'
2415                  * (unless literal is set), and indicate that it's the default
2416                  * value.  Otherwise, we print the number nicely and indicate
2417                  * that its set locally.
2418                  */
2419                 if (val == 0) {
2420                         if (literal)
2421                                 (void) strlcpy(propbuf, "0", proplen);
2422                         else
2423                                 (void) strlcpy(propbuf, "none", proplen);
2424                 } else {
2425                         if (literal)
2426                                 (void) snprintf(propbuf, proplen, "%llu",
2427                                     (u_longlong_t)val);
2428                         else
2429                                 zfs_nicenum(val, propbuf, proplen);
2430                 }
2431                 break;
2432
2433         case ZFS_PROP_COMPRESSRATIO:
2434                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2435                         return (-1);
2436                 (void) snprintf(propbuf, proplen, "%lld.%02lldx", (longlong_t)
2437                     val / 100, (longlong_t)val % 100);
2438                 break;
2439
2440         case ZFS_PROP_TYPE:
2441                 switch (zhp->zfs_type) {
2442                 case ZFS_TYPE_FILESYSTEM:
2443                         str = "filesystem";
2444                         break;
2445                 case ZFS_TYPE_VOLUME:
2446                         str = "volume";
2447                         break;
2448                 case ZFS_TYPE_SNAPSHOT:
2449                         str = "snapshot";
2450                         break;
2451                 default:
2452                         abort();
2453                 }
2454                 (void) snprintf(propbuf, proplen, "%s", str);
2455                 break;
2456
2457         case ZFS_PROP_MOUNTED:
2458                 /*
2459                  * The 'mounted' property is a pseudo-property that described
2460                  * whether the filesystem is currently mounted.  Even though
2461                  * it's a boolean value, the typical values of "on" and "off"
2462                  * don't make sense, so we translate to "yes" and "no".
2463                  */
2464                 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
2465                     src, &source, &val) != 0)
2466                         return (-1);
2467                 if (val)
2468                         (void) strlcpy(propbuf, "yes", proplen);
2469                 else
2470                         (void) strlcpy(propbuf, "no", proplen);
2471                 break;
2472
2473         case ZFS_PROP_NAME:
2474                 /*
2475                  * The 'name' property is a pseudo-property derived from the
2476                  * dataset name.  It is presented as a real property to simplify
2477                  * consumers.
2478                  */
2479                 (void) strlcpy(propbuf, zhp->zfs_name, proplen);
2480                 break;
2481
2482         default:
2483                 switch (zfs_prop_get_type(prop)) {
2484                 case PROP_TYPE_NUMBER:
2485                         if (get_numeric_property(zhp, prop, src,
2486                             &source, &val) != 0)
2487                                 return (-1);
2488                         if (literal)
2489                                 (void) snprintf(propbuf, proplen, "%llu",
2490                                     (u_longlong_t)val);
2491                         else
2492                                 zfs_nicenum(val, propbuf, proplen);
2493                         break;
2494
2495                 case PROP_TYPE_STRING:
2496                         (void) strlcpy(propbuf,
2497                             getprop_string(zhp, prop, &source), proplen);
2498                         break;
2499
2500                 case PROP_TYPE_INDEX:
2501                         if (get_numeric_property(zhp, prop, src,
2502                             &source, &val) != 0)
2503                                 return (-1);
2504                         if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2505                                 return (-1);
2506                         (void) strlcpy(propbuf, strval, proplen);
2507                         break;
2508
2509                 default:
2510                         abort();
2511                 }
2512         }
2513
2514         get_source(zhp, src, source, statbuf, statlen);
2515
2516         return (0);
2517 }
2518
2519 /*
2520  * Utility function to get the given numeric property.  Does no validation that
2521  * the given property is the appropriate type; should only be used with
2522  * hard-coded property types.
2523  */
2524 uint64_t
2525 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2526 {
2527         char *source;
2528         uint64_t val;
2529
2530         (void) get_numeric_property(zhp, prop, NULL, &source, &val);
2531
2532         return (val);
2533 }
2534
2535 int
2536 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
2537 {
2538         char buf[64];
2539
2540         zfs_nicenum(val, buf, sizeof (buf));
2541         return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
2542 }
2543
2544 /*
2545  * Similar to zfs_prop_get(), but returns the value as an integer.
2546  */
2547 int
2548 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
2549     zprop_source_t *src, char *statbuf, size_t statlen)
2550 {
2551         char *source;
2552
2553         /*
2554          * Check to see if this property applies to our object
2555          */
2556         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) {
2557                 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
2558                     dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
2559                     zfs_prop_to_name(prop)));
2560         }
2561
2562         if (src)
2563                 *src = ZPROP_SRC_NONE;
2564
2565         if (get_numeric_property(zhp, prop, src, &source, value) != 0)
2566                 return (-1);
2567
2568         get_source(zhp, src, source, statbuf, statlen);
2569
2570         return (0);
2571 }
2572
2573 /*
2574  * Returns the name of the given zfs handle.
2575  */
2576 const char *
2577 zfs_get_name(const zfs_handle_t *zhp)
2578 {
2579         return (zhp->zfs_name);
2580 }
2581
2582 /*
2583  * Returns the type of the given zfs handle.
2584  */
2585 zfs_type_t
2586 zfs_get_type(const zfs_handle_t *zhp)
2587 {
2588         return (zhp->zfs_type);
2589 }
2590
2591 /*
2592  * Iterate over all child filesystems
2593  */
2594 int
2595 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2596 {
2597         zfs_cmd_t zc = { 0 };
2598         zfs_handle_t *nzhp;
2599         int ret;
2600
2601         if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
2602                 return (0);
2603
2604         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2605             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
2606             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
2607                 /*
2608                  * Ignore private dataset names.
2609                  */
2610                 if (dataset_name_hidden(zc.zc_name))
2611                         continue;
2612
2613                 /*
2614                  * Silently ignore errors, as the only plausible explanation is
2615                  * that the pool has since been removed.
2616                  */
2617                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
2618                     zc.zc_name)) == NULL)
2619                         continue;
2620
2621                 if ((ret = func(nzhp, data)) != 0)
2622                         return (ret);
2623         }
2624
2625         /*
2626          * An errno value of ESRCH indicates normal completion.  If ENOENT is
2627          * returned, then the underlying dataset has been removed since we
2628          * obtained the handle.
2629          */
2630         if (errno != ESRCH && errno != ENOENT)
2631                 return (zfs_standard_error(zhp->zfs_hdl, errno,
2632                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
2633
2634         return (0);
2635 }
2636
2637 /*
2638  * Iterate over all snapshots
2639  */
2640 int
2641 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2642 {
2643         zfs_cmd_t zc = { 0 };
2644         zfs_handle_t *nzhp;
2645         int ret;
2646
2647         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
2648                 return (0);
2649
2650         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2651             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
2652             &zc) == 0;
2653             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
2654
2655                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
2656                     zc.zc_name)) == NULL)
2657                         continue;
2658
2659                 if ((ret = func(nzhp, data)) != 0)
2660                         return (ret);
2661         }
2662
2663         /*
2664          * An errno value of ESRCH indicates normal completion.  If ENOENT is
2665          * returned, then the underlying dataset has been removed since we
2666          * obtained the handle.  Silently ignore this case, and return success.
2667          */
2668         if (errno != ESRCH && errno != ENOENT)
2669                 return (zfs_standard_error(zhp->zfs_hdl, errno,
2670                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
2671
2672         return (0);
2673 }
2674
2675 /*
2676  * Iterate over all children, snapshots and filesystems
2677  */
2678 int
2679 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2680 {
2681         int ret;
2682
2683         if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
2684                 return (ret);
2685
2686         return (zfs_iter_snapshots(zhp, func, data));
2687 }
2688
2689 /*
2690  * Given a complete name, return just the portion that refers to the parent.
2691  * Can return NULL if this is a pool.
2692  */
2693 static int
2694 parent_name(const char *path, char *buf, size_t buflen)
2695 {
2696         char *loc;
2697
2698         if ((loc = strrchr(path, '/')) == NULL)
2699                 return (-1);
2700
2701         (void) strncpy(buf, path, MIN(buflen, loc - path));
2702         buf[loc - path] = '\0';
2703
2704         return (0);
2705 }
2706
2707 /*
2708  * If accept_ancestor is false, then check to make sure that the given path has
2709  * a parent, and that it exists.  If accept_ancestor is true, then find the
2710  * closest existing ancestor for the given path.  In prefixlen return the
2711  * length of already existing prefix of the given path.  We also fetch the
2712  * 'zoned' property, which is used to validate property settings when creating
2713  * new datasets.
2714  */
2715 static int
2716 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
2717     boolean_t accept_ancestor, int *prefixlen)
2718 {
2719         zfs_cmd_t zc = { 0 };
2720         char parent[ZFS_MAXNAMELEN];
2721         char *slash;
2722         zfs_handle_t *zhp;
2723         char errbuf[1024];
2724
2725         (void) snprintf(errbuf, sizeof (errbuf), "cannot create '%s'",
2726             path);
2727
2728         /* get parent, and check to see if this is just a pool */
2729         if (parent_name(path, parent, sizeof (parent)) != 0) {
2730                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2731                     "missing dataset name"));
2732                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2733         }
2734
2735         /* check to see if the pool exists */
2736         if ((slash = strchr(parent, '/')) == NULL)
2737                 slash = parent + strlen(parent);
2738         (void) strncpy(zc.zc_name, parent, slash - parent);
2739         zc.zc_name[slash - parent] = '\0';
2740         if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
2741             errno == ENOENT) {
2742                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2743                     "no such pool '%s'"), zc.zc_name);
2744                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2745         }
2746
2747         /* check to see if the parent dataset exists */
2748         while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
2749                 if (errno == ENOENT && accept_ancestor) {
2750                         /*
2751                          * Go deeper to find an ancestor, give up on top level.
2752                          */
2753                         if (parent_name(parent, parent, sizeof (parent)) != 0) {
2754                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2755                                     "no such pool '%s'"), zc.zc_name);
2756                                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2757                         }
2758                 } else if (errno == ENOENT) {
2759                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2760                             "parent does not exist"));
2761                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
2762                 } else
2763                         return (zfs_standard_error(hdl, errno, errbuf));
2764         }
2765
2766         *zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
2767         /* we are in a non-global zone, but parent is in the global zone */
2768         if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) {
2769                 (void) zfs_standard_error(hdl, EPERM, errbuf);
2770                 zfs_close(zhp);
2771                 return (-1);
2772         }
2773
2774         /* make sure parent is a filesystem */
2775         if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
2776                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2777                     "parent is not a filesystem"));
2778                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
2779                 zfs_close(zhp);
2780                 return (-1);
2781         }
2782
2783         zfs_close(zhp);
2784         if (prefixlen != NULL)
2785                 *prefixlen = strlen(parent);
2786         return (0);
2787 }
2788
2789 /*
2790  * Finds whether the dataset of the given type(s) exists.
2791  */
2792 boolean_t
2793 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
2794 {
2795         zfs_handle_t *zhp;
2796
2797         if (!zfs_validate_name(hdl, path, types, B_FALSE))
2798                 return (B_FALSE);
2799
2800         /*
2801          * Try to get stats for the dataset, which will tell us if it exists.
2802          */
2803         if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
2804                 int ds_type = zhp->zfs_type;
2805
2806                 zfs_close(zhp);
2807                 if (types & ds_type)
2808                         return (B_TRUE);
2809         }
2810         return (B_FALSE);
2811 }
2812
2813 /*
2814  * Given a path to 'target', create all the ancestors between
2815  * the prefixlen portion of the path, and the target itself.
2816  * Fail if the initial prefixlen-ancestor does not already exist.
2817  */
2818 int
2819 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
2820 {
2821         zfs_handle_t *h;
2822         char *cp;
2823         const char *opname;
2824
2825         /* make sure prefix exists */
2826         cp = target + prefixlen;
2827         if (*cp != '/') {
2828                 assert(strchr(cp, '/') == NULL);
2829                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2830         } else {
2831                 *cp = '\0';
2832                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2833                 *cp = '/';
2834         }
2835         if (h == NULL)
2836                 return (-1);
2837         zfs_close(h);
2838
2839         /*
2840          * Attempt to create, mount, and share any ancestor filesystems,
2841          * up to the prefixlen-long one.
2842          */
2843         for (cp = target + prefixlen + 1;
2844             cp = strchr(cp, '/'); *cp = '/', cp++) {
2845                 char *logstr;
2846
2847                 *cp = '\0';
2848
2849                 h = make_dataset_handle(hdl, target);
2850                 if (h) {
2851                         /* it already exists, nothing to do here */
2852                         zfs_close(h);
2853                         continue;
2854                 }
2855
2856                 logstr = hdl->libzfs_log_str;
2857                 hdl->libzfs_log_str = NULL;
2858                 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2859                     NULL) != 0) {
2860                         hdl->libzfs_log_str = logstr;
2861                         opname = dgettext(TEXT_DOMAIN, "create");
2862                         goto ancestorerr;
2863                 }
2864
2865                 hdl->libzfs_log_str = logstr;
2866                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2867                 if (h == NULL) {
2868                         opname = dgettext(TEXT_DOMAIN, "open");
2869                         goto ancestorerr;
2870                 }
2871
2872                 if (zfs_mount(h, NULL, 0) != 0) {
2873                         opname = dgettext(TEXT_DOMAIN, "mount");
2874                         goto ancestorerr;
2875                 }
2876
2877                 if (zfs_share(h) != 0) {
2878                         opname = dgettext(TEXT_DOMAIN, "share");
2879                         goto ancestorerr;
2880                 }
2881
2882                 zfs_close(h);
2883         }
2884
2885         return (0);
2886
2887 ancestorerr:
2888         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2889             "failed to %s ancestor '%s'"), opname, target);
2890         return (-1);
2891 }
2892
2893 /*
2894  * Creates non-existing ancestors of the given path.
2895  */
2896 int
2897 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
2898 {
2899         int prefix;
2900         uint64_t zoned;
2901         char *path_copy;
2902         int rc;
2903
2904         if (check_parents(hdl, path, &zoned, B_TRUE, &prefix) != 0)
2905                 return (-1);
2906
2907         if ((path_copy = strdup(path)) != NULL) {
2908                 rc = create_parents(hdl, path_copy, prefix);
2909                 free(path_copy);
2910         }
2911         if (path_copy == NULL || rc != 0)
2912                 return (-1);
2913
2914         return (0);
2915 }
2916
2917 /*
2918  * Create a new filesystem or volume.
2919  */
2920 int
2921 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2922     nvlist_t *props)
2923 {
2924         zfs_cmd_t zc = { 0 };
2925         int ret;
2926         uint64_t size = 0;
2927         uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2928         char errbuf[1024];
2929         uint64_t zoned;
2930
2931         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2932             "cannot create '%s'"), path);
2933
2934         /* validate the path, taking care to note the extended error message */
2935         if (!zfs_validate_name(hdl, path, type, B_TRUE))
2936                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2937
2938         /* validate parents exist */
2939         if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
2940                 return (-1);
2941
2942         /*
2943          * The failure modes when creating a dataset of a different type over
2944          * one that already exists is a little strange.  In particular, if you
2945          * try to create a dataset on top of an existing dataset, the ioctl()
2946          * will return ENOENT, not EEXIST.  To prevent this from happening, we
2947          * first try to see if the dataset exists.
2948          */
2949         (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2950         if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
2951                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2952                     "dataset already exists"));
2953                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2954         }
2955
2956         if (type == ZFS_TYPE_VOLUME)
2957                 zc.zc_objset_type = DMU_OST_ZVOL;
2958         else
2959                 zc.zc_objset_type = DMU_OST_ZFS;
2960
2961         if (props && (props = zfs_valid_proplist(hdl, type, props,
2962             zoned, NULL, errbuf)) == 0)
2963                 return (-1);
2964
2965         if (type == ZFS_TYPE_VOLUME) {
2966                 /*
2967                  * If we are creating a volume, the size and block size must
2968                  * satisfy a few restraints.  First, the blocksize must be a
2969                  * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
2970                  * volsize must be a multiple of the block size, and cannot be
2971                  * zero.
2972                  */
2973                 if (props == NULL || nvlist_lookup_uint64(props,
2974                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
2975                         nvlist_free(props);
2976                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2977                             "missing volume size"));
2978                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2979                 }
2980
2981                 if ((ret = nvlist_lookup_uint64(props,
2982                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
2983                     &blocksize)) != 0) {
2984                         if (ret == ENOENT) {
2985                                 blocksize = zfs_prop_default_numeric(
2986                                     ZFS_PROP_VOLBLOCKSIZE);
2987                         } else {
2988                                 nvlist_free(props);
2989                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2990                                     "missing volume block size"));
2991                                 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2992                         }
2993                 }
2994
2995                 if (size == 0) {
2996                         nvlist_free(props);
2997                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2998                             "volume size cannot be zero"));
2999                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3000                 }
3001
3002                 if (size % blocksize != 0) {
3003                         nvlist_free(props);
3004                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3005                             "volume size must be a multiple of volume block "
3006                             "size"));
3007                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3008                 }
3009         }
3010
3011         if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0)
3012                 return (-1);
3013         nvlist_free(props);
3014
3015         /* create the dataset */
3016         ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc);
3017
3018         if (ret == 0 && type == ZFS_TYPE_VOLUME) {
3019                 ret = zvol_create_link(hdl, path);
3020                 if (ret) {
3021                         (void) zfs_standard_error(hdl, errno,
3022                             dgettext(TEXT_DOMAIN,
3023                             "Volume successfully created, but device links "
3024                             "were not created"));
3025                         zcmd_free_nvlists(&zc);
3026                         return (-1);
3027                 }
3028         }
3029
3030         zcmd_free_nvlists(&zc);
3031
3032         /* check for failure */
3033         if (ret != 0) {
3034                 char parent[ZFS_MAXNAMELEN];
3035                 (void) parent_name(path, parent, sizeof (parent));
3036
3037                 switch (errno) {
3038                 case ENOENT:
3039                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3040                             "no such parent '%s'"), parent);
3041                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
3042
3043                 case EINVAL:
3044                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3045                             "parent '%s' is not a filesystem"), parent);
3046                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3047
3048                 case EDOM:
3049                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3050                             "volume block size must be power of 2 from "
3051                             "%u to %uk"),
3052                             (uint_t)SPA_MINBLOCKSIZE,
3053                             (uint_t)SPA_MAXBLOCKSIZE >> 10);
3054
3055                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3056
3057                 case ENOTSUP:
3058                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3059                             "pool must be upgraded to set this "
3060                             "property or value"));
3061                         return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3062 #ifdef _ILP32
3063                 case EOVERFLOW:
3064                         /*
3065                          * This platform can't address a volume this big.
3066                          */
3067                         if (type == ZFS_TYPE_VOLUME)
3068                                 return (zfs_error(hdl, EZFS_VOLTOOBIG,
3069                                     errbuf));
3070 #endif
3071                         /* FALLTHROUGH */
3072                 default:
3073                         return (zfs_standard_error(hdl, errno, errbuf));
3074                 }
3075         }
3076
3077         return (0);
3078 }
3079
3080 /*
3081  * Destroys the given dataset.  The caller must make sure that the filesystem
3082  * isn't mounted, and that there are no active dependents.
3083  */
3084 int
3085 zfs_destroy(zfs_handle_t *zhp)
3086 {
3087         zfs_cmd_t zc = { 0 };
3088
3089         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3090
3091         if (ZFS_IS_VOLUME(zhp)) {
3092                 /*
3093                  * If user doesn't have permissions to unshare volume, then
3094                  * abort the request.  This would only happen for a
3095                  * non-privileged user.
3096                  */
3097                 if (zfs_unshare_iscsi(zhp) != 0) {
3098                         return (-1);
3099                 }
3100
3101                 if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3102                         return (-1);
3103
3104                 zc.zc_objset_type = DMU_OST_ZVOL;
3105         } else {
3106                 zc.zc_objset_type = DMU_OST_ZFS;
3107         }
3108
3109         if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0) {
3110                 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3111                     dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3112                     zhp->zfs_name));
3113         }
3114
3115         remove_mountpoint(zhp);
3116
3117         return (0);
3118 }
3119
3120 struct destroydata {
3121         char *snapname;
3122         boolean_t gotone;
3123         boolean_t closezhp;
3124 };
3125
3126 static int
3127 zfs_remove_link_cb(zfs_handle_t *zhp, void *arg)
3128 {
3129         struct destroydata *dd = arg;
3130         zfs_handle_t *szhp;
3131         char name[ZFS_MAXNAMELEN];
3132         boolean_t closezhp = dd->closezhp;
3133         int rv;
3134
3135         (void) strlcpy(name, zhp->zfs_name, sizeof (name));
3136         (void) strlcat(name, "@", sizeof (name));
3137         (void) strlcat(name, dd->snapname, sizeof (name));
3138
3139         szhp = make_dataset_handle(zhp->zfs_hdl, name);
3140         if (szhp) {
3141                 dd->gotone = B_TRUE;
3142                 zfs_close(szhp);
3143         }
3144
3145         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3146                 (void) zvol_remove_link(zhp->zfs_hdl, name);
3147                 /*
3148                  * NB: this is simply a best-effort.  We don't want to
3149                  * return an error, because then we wouldn't visit all
3150                  * the volumes.
3151                  */
3152         }
3153
3154         dd->closezhp = B_TRUE;
3155         rv = zfs_iter_filesystems(zhp, zfs_remove_link_cb, arg);
3156         if (closezhp)
3157                 zfs_close(zhp);
3158         return (rv);
3159 }
3160
3161 /*
3162  * Destroys all snapshots with the given name in zhp & descendants.
3163  */
3164 int
3165 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname)
3166 {
3167         zfs_cmd_t zc = { 0 };
3168         int ret;
3169         struct destroydata dd = { 0 };
3170
3171         dd.snapname = snapname;
3172         (void) zfs_remove_link_cb(zhp, &dd);
3173
3174         if (!dd.gotone) {
3175                 return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3176                     dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3177                     zhp->zfs_name, snapname));
3178         }
3179
3180         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3181         (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3182
3183         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS, &zc);
3184         if (ret != 0) {
3185                 char errbuf[1024];
3186
3187                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3188                     "cannot destroy '%s@%s'"), zc.zc_name, snapname);
3189
3190                 switch (errno) {
3191                 case EEXIST:
3192                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3193                             "snapshot is cloned"));
3194                         return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
3195
3196                 default:
3197                         return (zfs_standard_error(zhp->zfs_hdl, errno,
3198                             errbuf));
3199                 }
3200         }
3201
3202         return (0);
3203 }
3204
3205 /*
3206  * Clones the given dataset.  The target must be of the same type as the source.
3207  */
3208 int
3209 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3210 {
3211         zfs_cmd_t zc = { 0 };
3212         char parent[ZFS_MAXNAMELEN];
3213         int ret;
3214         char errbuf[1024];
3215         libzfs_handle_t *hdl = zhp->zfs_hdl;
3216         zfs_type_t type;
3217         uint64_t zoned;
3218
3219         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3220
3221         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3222             "cannot create '%s'"), target);
3223
3224         /* validate the target name */
3225         if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3226                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3227
3228         /* validate parents exist */
3229         if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3230                 return (-1);
3231
3232         (void) parent_name(target, parent, sizeof (parent));
3233
3234         /* do the clone */
3235         if (ZFS_IS_VOLUME(zhp)) {
3236                 zc.zc_objset_type = DMU_OST_ZVOL;
3237                 type = ZFS_TYPE_VOLUME;
3238         } else {
3239                 zc.zc_objset_type = DMU_OST_ZFS;
3240                 type = ZFS_TYPE_FILESYSTEM;
3241         }
3242
3243         if (props) {
3244                 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3245                     zhp, errbuf)) == NULL)
3246                         return (-1);
3247
3248                 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3249                         nvlist_free(props);
3250                         return (-1);
3251                 }
3252
3253                 nvlist_free(props);
3254         }
3255
3256         (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
3257         (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
3258         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CREATE, &zc);
3259
3260         zcmd_free_nvlists(&zc);
3261
3262         if (ret != 0) {
3263                 switch (errno) {
3264
3265                 case ENOENT:
3266                         /*
3267                          * The parent doesn't exist.  We should have caught this
3268                          * above, but there may a race condition that has since
3269                          * destroyed the parent.
3270                          *
3271                          * At this point, we don't know whether it's the source
3272                          * that doesn't exist anymore, or whether the target
3273                          * dataset doesn't exist.
3274                          */
3275                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3276                             "no such parent '%s'"), parent);
3277                         return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3278
3279                 case EXDEV:
3280                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3281                             "source and target pools differ"));
3282                         return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
3283                             errbuf));
3284
3285                 default:
3286                         return (zfs_standard_error(zhp->zfs_hdl, errno,
3287                             errbuf));
3288                 }
3289         } else if (ZFS_IS_VOLUME(zhp)) {
3290                 ret = zvol_create_link(zhp->zfs_hdl, target);
3291         }
3292
3293         return (ret);
3294 }
3295
3296 typedef struct promote_data {
3297         char cb_mountpoint[MAXPATHLEN];
3298         const char *cb_target;
3299         const char *cb_errbuf;
3300         uint64_t cb_pivot_txg;
3301 } promote_data_t;
3302
3303 static int
3304 promote_snap_cb(zfs_handle_t *zhp, void *data)
3305 {
3306         promote_data_t *pd = data;
3307         zfs_handle_t *szhp;
3308         char snapname[MAXPATHLEN];
3309         int rv = 0;
3310
3311         /* We don't care about snapshots after the pivot point */
3312         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg) {
3313                 zfs_close(zhp);
3314                 return (0);
3315         }
3316
3317         /* Remove the device link if it's a zvol. */
3318         if (ZFS_IS_VOLUME(zhp))
3319                 (void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
3320
3321         /* Check for conflicting names */
3322         (void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
3323         (void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
3324         szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
3325         if (szhp != NULL) {
3326                 zfs_close(szhp);
3327                 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3328                     "snapshot name '%s' from origin \n"
3329                     "conflicts with '%s' from target"),
3330                     zhp->zfs_name, snapname);
3331                 rv = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf);
3332         }
3333         zfs_close(zhp);
3334         return (rv);
3335 }
3336
3337 static int
3338 promote_snap_done_cb(zfs_handle_t *zhp, void *data)
3339 {
3340         promote_data_t *pd = data;
3341
3342         /* We don't care about snapshots after the pivot point */
3343         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) <= pd->cb_pivot_txg) {
3344                 /* Create the device link if it's a zvol. */
3345                 if (ZFS_IS_VOLUME(zhp))
3346                         (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
3347         }
3348
3349         zfs_close(zhp);
3350         return (0);
3351 }
3352
3353 /*
3354  * Promotes the given clone fs to be the clone parent.
3355  */
3356 int
3357 zfs_promote(zfs_handle_t *zhp)
3358 {
3359         libzfs_handle_t *hdl = zhp->zfs_hdl;
3360         zfs_cmd_t zc = { 0 };
3361         char parent[MAXPATHLEN];
3362         char *cp;
3363         int ret;
3364         zfs_handle_t *pzhp;
3365         promote_data_t pd;
3366         char errbuf[1024];
3367
3368         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3369             "cannot promote '%s'"), zhp->zfs_name);
3370
3371         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3372                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3373                     "snapshots can not be promoted"));
3374                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3375         }
3376
3377         (void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent));
3378         if (parent[0] == '\0') {
3379                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3380                     "not a cloned filesystem"));
3381                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3382         }
3383         cp = strchr(parent, '@');
3384         *cp = '\0';
3385
3386         /* Walk the snapshots we will be moving */
3387         pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
3388         if (pzhp == NULL)
3389                 return (-1);
3390         pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
3391         zfs_close(pzhp);
3392         pd.cb_target = zhp->zfs_name;
3393         pd.cb_errbuf = errbuf;
3394         pzhp = zfs_open(hdl, parent, ZFS_TYPE_DATASET);
3395         if (pzhp == NULL)
3396                 return (-1);
3397         (void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
3398             sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
3399         ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
3400         if (ret != 0) {
3401                 zfs_close(pzhp);
3402                 return (-1);
3403         }
3404
3405         /* issue the ioctl */
3406         (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin,
3407             sizeof (zc.zc_value));
3408         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3409         ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
3410
3411         if (ret != 0) {
3412                 int save_errno = errno;
3413
3414                 (void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
3415                 zfs_close(pzhp);
3416
3417                 switch (save_errno) {
3418                 case EEXIST:
3419                         /*
3420                          * There is a conflicting snapshot name.  We
3421                          * should have caught this above, but they could
3422                          * have renamed something in the mean time.
3423                          */
3424                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3425                             "conflicting snapshot name from parent '%s'"),
3426                             parent);
3427                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3428
3429                 default:
3430                         return (zfs_standard_error(hdl, save_errno, errbuf));
3431                 }
3432         } else {
3433                 (void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
3434         }
3435
3436         zfs_close(pzhp);
3437         return (ret);
3438 }
3439
3440 struct createdata {
3441         const char *cd_snapname;
3442         int cd_ifexists;
3443 };
3444
3445 static int
3446 zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
3447 {
3448         struct createdata *cd = arg;
3449         int ret;
3450
3451         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3452                 char name[MAXPATHLEN];
3453
3454                 (void) strlcpy(name, zhp->zfs_name, sizeof (name));
3455                 (void) strlcat(name, "@", sizeof (name));
3456                 (void) strlcat(name, cd->cd_snapname, sizeof (name));
3457                 (void) zvol_create_link_common(zhp->zfs_hdl, name,
3458                     cd->cd_ifexists);
3459                 /*
3460                  * NB: this is simply a best-effort.  We don't want to
3461                  * return an error, because then we wouldn't visit all
3462                  * the volumes.
3463                  */
3464         }
3465
3466         ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, cd);
3467
3468         zfs_close(zhp);
3469
3470         return (ret);
3471 }
3472
3473 /*
3474  * Takes a snapshot of the given dataset.
3475  */
3476 int
3477 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3478     nvlist_t *props)
3479 {
3480         const char *delim;
3481         char parent[ZFS_MAXNAMELEN];
3482         zfs_handle_t *zhp;
3483         zfs_cmd_t zc = { 0 };
3484         int ret;
3485         char errbuf[1024];
3486
3487         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3488             "cannot snapshot '%s'"), path);
3489
3490         /* validate the target name */
3491         if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3492                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3493
3494         if (props) {
3495                 if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3496                     props, B_FALSE, NULL, errbuf)) == NULL)
3497                         return (-1);
3498
3499                 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3500                         nvlist_free(props);
3501                         return (-1);
3502                 }
3503
3504                 nvlist_free(props);
3505         }
3506
3507         /* make sure the parent exists and is of the appropriate type */
3508         delim = strchr(path, '@');
3509         (void) strncpy(parent, path, delim - path);
3510         parent[delim - path] = '\0';
3511
3512         if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
3513             ZFS_TYPE_VOLUME)) == NULL) {
3514                 zcmd_free_nvlists(&zc);
3515                 return (-1);
3516         }
3517
3518         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3519         (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
3520         if (ZFS_IS_VOLUME(zhp))
3521                 zc.zc_objset_type = DMU_OST_ZVOL;
3522         else
3523                 zc.zc_objset_type = DMU_OST_ZFS;
3524         zc.zc_cookie = recursive;
3525         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc);
3526
3527         zcmd_free_nvlists(&zc);
3528
3529         /*
3530          * if it was recursive, the one that actually failed will be in
3531          * zc.zc_name.
3532          */
3533         if (ret != 0)
3534                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3535                     "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
3536
3537         if (ret == 0 && recursive) {
3538                 struct createdata cd;
3539
3540                 cd.cd_snapname = delim + 1;
3541                 cd.cd_ifexists = B_FALSE;
3542                 (void) zfs_iter_filesystems(zhp, zfs_create_link_cb, &cd);
3543         }
3544         if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
3545                 ret = zvol_create_link(zhp->zfs_hdl, path);
3546                 if (ret != 0) {
3547                         (void) zfs_standard_error(hdl, errno,
3548                             dgettext(TEXT_DOMAIN,
3549                             "Volume successfully snapshotted, but device links "
3550                             "were not created"));
3551                         zfs_close(zhp);
3552                         return (-1);
3553                 }
3554         }
3555
3556         if (ret != 0)
3557                 (void) zfs_standard_error(hdl, errno, errbuf);
3558
3559         zfs_close(zhp);
3560
3561         return (ret);
3562 }
3563
3564 /*
3565  * Destroy any more recent snapshots.  We invoke this callback on any dependents
3566  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
3567  * is a dependent and we should just destroy it without checking the transaction
3568  * group.
3569  */
3570 typedef struct rollback_data {
3571         const char      *cb_target;             /* the snapshot */
3572         uint64_t        cb_create;              /* creation time reference */
3573         boolean_t       cb_error;
3574         boolean_t       cb_dependent;
3575         boolean_t       cb_force;
3576 } rollback_data_t;
3577
3578 static int
3579 rollback_destroy(zfs_handle_t *zhp, void *data)
3580 {
3581         rollback_data_t *cbp = data;
3582
3583         if (!cbp->cb_dependent) {
3584                 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
3585                     zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
3586                     zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
3587                     cbp->cb_create) {
3588                         char *logstr;
3589
3590                         cbp->cb_dependent = B_TRUE;
3591                         cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3592                             rollback_destroy, cbp);
3593                         cbp->cb_dependent = B_FALSE;
3594
3595                         logstr = zhp->zfs_hdl->libzfs_log_str;
3596                         zhp->zfs_hdl->libzfs_log_str = NULL;
3597                         cbp->cb_error |= zfs_destroy(zhp);
3598                         zhp->zfs_hdl->libzfs_log_str = logstr;
3599                 }
3600         } else {
3601                 /* We must destroy this clone; first unmount it */
3602                 prop_changelist_t *clp;
3603
3604                 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3605                     cbp->cb_force ? MS_FORCE: 0);
3606                 if (clp == NULL || changelist_prefix(clp) != 0) {
3607                         cbp->cb_error = B_TRUE;
3608                         zfs_close(zhp);
3609                         return (0);
3610                 }
3611                 if (zfs_destroy(zhp) != 0)
3612                         cbp->cb_error = B_TRUE;
3613                 else
3614                         changelist_remove(clp, zhp->zfs_name);
3615                 (void) changelist_postfix(clp);
3616                 changelist_free(clp);
3617         }
3618
3619         zfs_close(zhp);
3620         return (0);
3621 }
3622
3623 /*
3624  * Given a dataset, rollback to a specific snapshot, discarding any
3625  * data changes since then and making it the active dataset.
3626  *
3627  * Any snapshots more recent than the target are destroyed, along with
3628  * their dependents.
3629  */
3630 int
3631 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
3632 {
3633         rollback_data_t cb = { 0 };
3634         int err;
3635         zfs_cmd_t zc = { 0 };
3636         boolean_t restore_resv = 0;
3637         uint64_t old_volsize, new_volsize;
3638         zfs_prop_t resv_prop;
3639
3640         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
3641             zhp->zfs_type == ZFS_TYPE_VOLUME);
3642
3643         /*
3644          * Destroy all recent snapshots and its dependends.
3645          */
3646         cb.cb_force = force;
3647         cb.cb_target = snap->zfs_name;
3648         cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
3649         (void) zfs_iter_children(zhp, rollback_destroy, &cb);
3650
3651         if (cb.cb_error)
3652                 return (-1);
3653
3654         /*
3655          * Now that we have verified that the snapshot is the latest,
3656          * rollback to the given snapshot.
3657          */
3658
3659         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3660                 if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3661                         return (-1);
3662                 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
3663                         return (-1);
3664                 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3665                 restore_resv =
3666                     (old_volsize == zfs_prop_get_int(zhp, resv_prop));
3667         }
3668
3669         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3670
3671         if (ZFS_IS_VOLUME(zhp))
3672                 zc.zc_objset_type = DMU_OST_ZVOL;
3673         else
3674                 zc.zc_objset_type = DMU_OST_ZFS;
3675
3676         /*
3677          * We rely on zfs_iter_children() to verify that there are no
3678          * newer snapshots for the given dataset.  Therefore, we can
3679          * simply pass the name on to the ioctl() call.  There is still
3680          * an unlikely race condition where the user has taken a
3681          * snapshot since we verified that this was the most recent.
3682          *
3683          */
3684         if ((err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_ROLLBACK, &zc)) != 0) {
3685                 (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3686                     dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
3687                     zhp->zfs_name);
3688                 return (err);
3689         }
3690
3691         /*
3692          * For volumes, if the pre-rollback volsize matched the pre-
3693          * rollback reservation and the volsize has changed then set
3694          * the reservation property to the post-rollback volsize.
3695          * Make a new handle since the rollback closed the dataset.
3696          */
3697         if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
3698             (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
3699                 if (err = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name)) {
3700                         zfs_close(zhp);
3701                         return (err);
3702                 }
3703                 if (restore_resv) {
3704                         new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3705                         if (old_volsize != new_volsize)
3706                                 err = zfs_prop_set_int(zhp, resv_prop,
3707                                     new_volsize);
3708                 }
3709                 zfs_close(zhp);
3710         }
3711         return (err);
3712 }
3713
3714 /*
3715  * Iterate over all dependents for a given dataset.  This includes both
3716  * hierarchical dependents (children) and data dependents (snapshots and
3717  * clones).  The bulk of the processing occurs in get_dependents() in
3718  * libzfs_graph.c.
3719  */
3720 int
3721 zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
3722     zfs_iter_f func, void *data)
3723 {
3724         char **dependents;
3725         size_t count;
3726         int i;
3727         zfs_handle_t *child;
3728         int ret = 0;
3729
3730         if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name,
3731             &dependents, &count) != 0)
3732                 return (-1);
3733
3734         for (i = 0; i < count; i++) {
3735                 if ((child = make_dataset_handle(zhp->zfs_hdl,
3736                     dependents[i])) == NULL)
3737                         continue;
3738
3739                 if ((ret = func(child, data)) != 0)
3740                         break;
3741         }
3742
3743         for (i = 0; i < count; i++)
3744                 free(dependents[i]);
3745         free(dependents);
3746
3747         return (ret);
3748 }
3749
3750 /*
3751  * Renames the given dataset.
3752  */
3753 int
3754 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive)
3755 {
3756         int ret;
3757         zfs_cmd_t zc = { 0 };
3758         char *delim;
3759         prop_changelist_t *cl = NULL;
3760         zfs_handle_t *zhrp = NULL;
3761         char *parentname = NULL;
3762         char parent[ZFS_MAXNAMELEN];
3763         libzfs_handle_t *hdl = zhp->zfs_hdl;
3764         char errbuf[1024];
3765
3766         /* if we have the same exact name, just return success */
3767         if (strcmp(zhp->zfs_name, target) == 0)
3768                 return (0);
3769
3770         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3771             "cannot rename to '%s'"), target);
3772
3773         /*
3774          * Make sure the target name is valid
3775          */
3776         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3777                 if ((strchr(target, '@') == NULL) ||
3778                     *target == '@') {
3779                         /*
3780                          * Snapshot target name is abbreviated,
3781                          * reconstruct full dataset name
3782                          */
3783                         (void) strlcpy(parent, zhp->zfs_name,
3784                             sizeof (parent));
3785                         delim = strchr(parent, '@');
3786                         if (strchr(target, '@') == NULL)
3787                                 *(++delim) = '\0';
3788                         else
3789                                 *delim = '\0';
3790                         (void) strlcat(parent, target, sizeof (parent));
3791                         target = parent;
3792                 } else {
3793                         /*
3794                          * Make sure we're renaming within the same dataset.
3795                          */
3796                         delim = strchr(target, '@');
3797                         if (strncmp(zhp->zfs_name, target, delim - target)
3798                             != 0 || zhp->zfs_name[delim - target] != '@') {
3799                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3800                                     "snapshots must be part of same "
3801                                     "dataset"));
3802                                 return (zfs_error(hdl, EZFS_CROSSTARGET,
3803                                     errbuf));
3804                         }
3805                 }
3806                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3807                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3808         } else {
3809                 if (recursive) {
3810                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3811                             "recursive rename must be a snapshot"));
3812                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3813                 }
3814
3815                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3816                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3817                 uint64_t unused;
3818
3819                 /* validate parents */
3820                 if (check_parents(hdl, target, &unused, B_FALSE, NULL) != 0)
3821                         return (-1);
3822
3823                 (void) parent_name(target, parent, sizeof (parent));
3824
3825                 /* make sure we're in the same pool */
3826                 verify((delim = strchr(target, '/')) != NULL);
3827                 if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
3828                     zhp->zfs_name[delim - target] != '/') {
3829                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3830                             "datasets must be within same pool"));
3831                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
3832                 }
3833
3834                 /* new name cannot be a child of the current dataset name */
3835                 if (strncmp(parent, zhp->zfs_name,
3836                     strlen(zhp->zfs_name)) == 0) {
3837                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3838                             "New dataset name cannot be a descendent of "
3839                             "current dataset name"));
3840                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3841                 }
3842         }
3843
3844         (void) snprintf(errbuf, sizeof (errbuf),
3845             dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
3846
3847         if (getzoneid() == GLOBAL_ZONEID &&
3848             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
3849                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3850                     "dataset is used in a non-global zone"));
3851                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
3852         }
3853
3854         if (recursive) {
3855                 struct destroydata dd;
3856
3857                 parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
3858                 if (parentname == NULL) {
3859                         ret = -1;
3860                         goto error;
3861                 }
3862                 delim = strchr(parentname, '@');
3863                 *delim = '\0';
3864                 zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
3865                 if (zhrp == NULL) {
3866                         ret = -1;
3867                         goto error;
3868                 }
3869
3870                 dd.snapname = delim + 1;
3871                 dd.gotone = B_FALSE;
3872                 dd.closezhp = B_TRUE;
3873
3874                 /* We remove any zvol links prior to renaming them */
3875                 ret = zfs_iter_filesystems(zhrp, zfs_remove_link_cb, &dd);
3876                 if (ret) {
3877                         goto error;
3878                 }
3879         } else {
3880                 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0)) == NULL)
3881                         return (-1);
3882
3883                 if (changelist_haszonedchild(cl)) {
3884                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3885                             "child dataset with inherited mountpoint is used "
3886                             "in a non-global zone"));
3887                         (void) zfs_error(hdl, EZFS_ZONED, errbuf);
3888                         goto error;
3889                 }
3890
3891                 if ((ret = changelist_prefix(cl)) != 0)
3892                         goto error;
3893         }
3894
3895         if (ZFS_IS_VOLUME(zhp))
3896                 zc.zc_objset_type = DMU_OST_ZVOL;
3897         else
3898                 zc.zc_objset_type = DMU_OST_ZFS;
3899
3900         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3901         (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
3902
3903         zc.zc_cookie = recursive;
3904
3905         if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
3906                 /*
3907                  * if it was recursive, the one that actually failed will
3908                  * be in zc.zc_name
3909                  */
3910                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3911                     "cannot rename '%s'"), zc.zc_name);
3912
3913                 if (recursive && errno == EEXIST) {
3914                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3915                             "a child dataset already has a snapshot "
3916                             "with the new name"));
3917                         (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3918                 } else {
3919                         (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
3920                 }
3921
3922                 /*
3923                  * On failure, we still want to remount any filesystems that
3924                  * were previously mounted, so we don't alter the system state.
3925                  */
3926                 if (recursive) {
3927                         struct createdata cd;
3928
3929                         /* only create links for datasets that had existed */
3930                         cd.cd_snapname = delim + 1;
3931                         cd.cd_ifexists = B_TRUE;
3932                         (void) zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3933                             &cd);
3934                 } else {
3935                         (void) changelist_postfix(cl);
3936                 }
3937         } else {
3938                 if (recursive) {
3939                         struct createdata cd;
3940
3941                         /* only create links for datasets that had existed */
3942                         cd.cd_snapname = strchr(target, '@') + 1;
3943                         cd.cd_ifexists = B_TRUE;
3944                         ret = zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3945                             &cd);
3946                 } else {
3947                         changelist_rename(cl, zfs_get_name(zhp), target);
3948                         ret = changelist_postfix(cl);
3949                 }
3950         }
3951
3952 error:
3953         if (parentname) {
3954                 free(parentname);
3955         }
3956         if (zhrp) {
3957                 zfs_close(zhrp);
3958         }
3959         if (cl) {
3960                 changelist_free(cl);
3961         }
3962         return (ret);
3963 }
3964
3965 /*
3966  * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
3967  * poke devfsadm to create the /dev link, and then wait for the link to appear.
3968  */
3969 int
3970 zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
3971 {
3972         return (zvol_create_link_common(hdl, dataset, B_FALSE));
3973 }
3974
3975 static int
3976 zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
3977 {
3978         zfs_cmd_t zc = { 0 };
3979 #if 0
3980         di_devlink_handle_t dhdl;
3981         priv_set_t *priv_effective;
3982         int privileged;
3983 #endif
3984
3985         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3986
3987         /*
3988          * Issue the appropriate ioctl.
3989          */
3990         if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
3991                 switch (errno) {
3992                 case EEXIST:
3993                         /*
3994                          * Silently ignore the case where the link already
3995                          * exists.  This allows 'zfs volinit' to be run multiple
3996                          * times without errors.
3997                          */
3998                         return (0);
3999
4000                 case ENOENT:
4001                         /*
4002                          * Dataset does not exist in the kernel.  If we
4003                          * don't care (see zfs_rename), then ignore the
4004                          * error quietly.
4005                          */
4006                         if (ifexists) {
4007                                 return (0);
4008                         }
4009
4010                         /* FALLTHROUGH */
4011
4012                 default:
4013                         return (zfs_standard_error_fmt(hdl, errno,
4014                             dgettext(TEXT_DOMAIN, "cannot create device links "
4015                             "for '%s'"), dataset));
4016                 }
4017         }
4018
4019 #if 0
4020         /*
4021          * If privileged call devfsadm and wait for the links to
4022          * magically appear.
4023          * Otherwise, print out an informational message.
4024          */
4025
4026         priv_effective = priv_allocset();
4027         (void) getppriv(PRIV_EFFECTIVE, priv_effective);
4028         privileged = (priv_isfullset(priv_effective) == B_TRUE);
4029         priv_freeset(priv_effective);
4030
4031         if (privileged) {
4032                 if ((dhdl = di_devlink_init(ZFS_DRIVER,
4033                     DI_MAKE_LINK)) == NULL) {
4034                         zfs_error_aux(hdl, strerror(errno));
4035                         (void) zfs_error_fmt(hdl, errno,
4036                             dgettext(TEXT_DOMAIN, "cannot create device links "
4037                             "for '%s'"), dataset);
4038                         (void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
4039                         return (-1);
4040                 } else {
4041                         (void) di_devlink_fini(&dhdl);
4042                 }
4043         } else {
4044                 char pathname[MAXPATHLEN];
4045                 struct stat64 statbuf;
4046                 int i;
4047
4048 #define MAX_WAIT        10
4049
4050                 /*
4051                  * This is the poor mans way of waiting for the link
4052                  * to show up.  If after 10 seconds we still don't
4053                  * have it, then print out a message.
4054                  */
4055                 (void) snprintf(pathname, sizeof (pathname), "/dev/zvol/dsk/%s",
4056                     dataset);
4057
4058                 for (i = 0; i != MAX_WAIT; i++) {
4059                         if (stat64(pathname, &statbuf) == 0)
4060                                 break;
4061                         (void) sleep(1);
4062                 }
4063                 if (i == MAX_WAIT)
4064                         (void) printf(gettext("%s may not be immediately "
4065                             "available\n"), pathname);
4066         }
4067 #endif
4068
4069         return (0);
4070 }
4071
4072 /*
4073  * Remove a minor node for the given zvol and the associated /dev links.
4074  */
4075 int
4076 zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
4077 {
4078         zfs_cmd_t zc = { 0 };
4079
4080         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4081
4082         if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
4083                 switch (errno) {
4084                 case ENXIO:
4085                         /*
4086                          * Silently ignore the case where the link no longer
4087                          * exists, so that 'zfs volfini' can be run multiple
4088                          * times without errors.
4089                          */
4090                         return (0);
4091
4092                 default:
4093                         return (zfs_standard_error_fmt(hdl, errno,
4094                             dgettext(TEXT_DOMAIN, "cannot remove device "
4095                             "links for '%s'"), dataset));
4096                 }
4097         }
4098
4099         return (0);
4100 }
4101
4102 nvlist_t *
4103 zfs_get_user_props(zfs_handle_t *zhp)
4104 {
4105         return (zhp->zfs_user_props);
4106 }
4107
4108 /*
4109  * This function is used by 'zfs list' to determine the exact set of columns to
4110  * display, and their maximum widths.  This does two main things:
4111  *
4112  *      - If this is a list of all properties, then expand the list to include
4113  *        all native properties, and set a flag so that for each dataset we look
4114  *        for new unique user properties and add them to the list.
4115  *
4116  *      - For non fixed-width properties, keep track of the maximum width seen
4117  *        so that we can size the column appropriately.
4118  */
4119 int
4120 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp)
4121 {
4122         libzfs_handle_t *hdl = zhp->zfs_hdl;
4123         zprop_list_t *entry;
4124         zprop_list_t **last, **start;
4125         nvlist_t *userprops, *propval;
4126         nvpair_t *elem;
4127         char *strval;
4128         char buf[ZFS_MAXPROPLEN];
4129
4130         if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
4131                 return (-1);
4132
4133         userprops = zfs_get_user_props(zhp);
4134
4135         entry = *plp;
4136         if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
4137                 /*
4138                  * Go through and add any user properties as necessary.  We
4139                  * start by incrementing our list pointer to the first
4140                  * non-native property.
4141                  */
4142                 start = plp;
4143                 while (*start != NULL) {
4144                         if ((*start)->pl_prop == ZPROP_INVAL)
4145                                 break;
4146                         start = &(*start)->pl_next;
4147                 }
4148
4149                 elem = NULL;
4150                 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
4151                         /*
4152                          * See if we've already found this property in our list.
4153                          */
4154                         for (last = start; *last != NULL;
4155                             last = &(*last)->pl_next) {
4156                                 if (strcmp((*last)->pl_user_prop,
4157                                     nvpair_name(elem)) == 0)
4158                                         break;
4159                         }
4160
4161                         if (*last == NULL) {
4162                                 if ((entry = zfs_alloc(hdl,
4163                                     sizeof (zprop_list_t))) == NULL ||
4164                                     ((entry->pl_user_prop = zfs_strdup(hdl,
4165                                     nvpair_name(elem)))) == NULL) {
4166                                         free(entry);
4167                                         return (-1);
4168                                 }
4169
4170                                 entry->pl_prop = ZPROP_INVAL;
4171                                 entry->pl_width = strlen(nvpair_name(elem));
4172                                 entry->pl_all = B_TRUE;
4173                                 *last = entry;
4174                         }
4175                 }
4176         }
4177
4178         /*
4179          * Now go through and check the width of any non-fixed columns
4180          */
4181         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
4182                 if (entry->pl_fixed)
4183                         continue;
4184
4185                 if (entry->pl_prop != ZPROP_INVAL) {
4186                         if (zfs_prop_get(zhp, entry->pl_prop,
4187                             buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
4188                                 if (strlen(buf) > entry->pl_width)
4189                                         entry->pl_width = strlen(buf);
4190                         }
4191                 } else if (nvlist_lookup_nvlist(userprops,
4192                     entry->pl_user_prop, &propval)  == 0) {
4193                         verify(nvlist_lookup_string(propval,
4194                             ZPROP_VALUE, &strval) == 0);
4195                         if (strlen(strval) > entry->pl_width)
4196                                 entry->pl_width = strlen(strval);
4197                 }
4198         }
4199
4200         return (0);
4201 }
4202
4203 #ifdef TODO
4204 int
4205 zfs_iscsi_perm_check(libzfs_handle_t *hdl, char *dataset, ucred_t *cred)
4206 {
4207         zfs_cmd_t zc = { 0 };
4208         nvlist_t *nvp;
4209         gid_t gid;
4210         uid_t uid;
4211         const gid_t *groups;
4212         int group_cnt;
4213         int error;
4214
4215         if (nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0) != 0)
4216                 return (no_memory(hdl));
4217
4218         uid = ucred_geteuid(cred);
4219         gid = ucred_getegid(cred);
4220         group_cnt = ucred_getgroups(cred, &groups);
4221
4222         if (uid == (uid_t)-1 || gid == (uid_t)-1 || group_cnt == (uid_t)-1)
4223                 return (1);
4224
4225         if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_UID, uid) != 0) {
4226                 nvlist_free(nvp);
4227                 return (1);
4228         }
4229
4230         if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_GID, gid) != 0) {
4231                 nvlist_free(nvp);
4232                 return (1);
4233         }
4234
4235         if (nvlist_add_uint32_array(nvp,
4236             ZFS_DELEG_PERM_GROUPS, (uint32_t *)groups, group_cnt) != 0) {
4237                 nvlist_free(nvp);
4238                 return (1);
4239         }
4240         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4241
4242         if (zcmd_write_src_nvlist(hdl, &zc, nvp))
4243                 return (-1);
4244
4245         error = ioctl(hdl->libzfs_fd, ZFS_IOC_ISCSI_PERM_CHECK, &zc);
4246         nvlist_free(nvp);
4247         return (error);
4248 }
4249 #endif
4250
4251 int
4252 zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
4253     void *export, void *sharetab, int sharemax, zfs_share_op_t operation)
4254 {
4255         zfs_cmd_t zc = { 0 };
4256         int error;
4257
4258         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4259         (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4260         zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab;
4261         zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export;
4262         zc.zc_share.z_sharetype = operation;
4263         zc.zc_share.z_sharemax = sharemax;
4264
4265         error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc);
4266         return (error);
4267 }
4268
4269 void
4270 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
4271 {
4272         nvpair_t *curr;
4273
4274         /*
4275          * Keep a reference to the props-table against which we prune the
4276          * properties.
4277          */
4278         zhp->zfs_props_table = props;
4279
4280         curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
4281
4282         while (curr) {
4283                 zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
4284                 nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr);
4285
4286                 /*
4287                  * We leave user:props in the nvlist, so there will be
4288                  * some ZPROP_INVAL.  To be extra safe, don't prune
4289                  * those.
4290                  */
4291                 if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
4292                         (void) nvlist_remove(zhp->zfs_props,
4293                             nvpair_name(curr), nvpair_type(curr));
4294                 curr = next;
4295         }
4296 }
4297
4298 /*
4299  * Attach/detach the given filesystem to/from the given jail.
4300  */
4301 int
4302 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
4303 {
4304         libzfs_handle_t *hdl = zhp->zfs_hdl;
4305         zfs_cmd_t zc = { 0 };
4306         char errbuf[1024];
4307         int cmd, ret;
4308
4309         if (attach) {
4310                 (void) snprintf(errbuf, sizeof (errbuf),
4311                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
4312         } else {
4313                 (void) snprintf(errbuf, sizeof (errbuf),
4314                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
4315         }
4316
4317         switch (zhp->zfs_type) {
4318         case ZFS_TYPE_VOLUME:
4319                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4320                     "volumes can not be jailed"));
4321                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4322         case ZFS_TYPE_SNAPSHOT:
4323                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4324                     "snapshots can not be jailed"));
4325                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4326         }
4327         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4328
4329         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4330         zc.zc_objset_type = DMU_OST_ZFS;
4331         zc.zc_jailid = jailid;
4332
4333         cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
4334         if ((ret = ioctl(hdl->libzfs_fd, cmd, &zc)) != 0)
4335                 zfs_standard_error(hdl, errno, errbuf);
4336
4337         return (ret);
4338 }