]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.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 2008 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_ACLMODE:
1796         case ZFS_PROP_ACLINHERIT:
1797         case ZFS_PROP_ISCSIOPTIONS:
1798                 (void) snprintf(errbuf, sizeof (errbuf),
1799                     "property '%s' not supported on FreeBSD", propname);
1800                 ret = zfs_error(hdl, EZFS_PERM, errbuf);
1801                 goto error;
1802         }
1803
1804         if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1805                 goto error;
1806
1807         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1808                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1809                     "child dataset with inherited mountpoint is used "
1810                     "in a non-global zone"));
1811                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1812                 goto error;
1813         }
1814
1815         /*
1816          * If the dataset's canmount property is being set to noauto,
1817          * then we want to prevent unmounting & remounting it.
1818          */
1819         do_prefix = !((prop == ZFS_PROP_CANMOUNT) &&
1820             (zprop_string_to_index(prop, propval, &idx,
1821             ZFS_TYPE_DATASET) == 0) && (idx == ZFS_CANMOUNT_NOAUTO));
1822
1823         if (do_prefix && (ret = changelist_prefix(cl)) != 0)
1824                 goto error;
1825
1826         /*
1827          * Execute the corresponding ioctl() to set this property.
1828          */
1829         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1830
1831         if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1832                 goto error;
1833
1834         ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1835         if (ret != 0) {
1836                 switch (errno) {
1837
1838                 case ENOSPC:
1839                         /*
1840                          * For quotas and reservations, ENOSPC indicates
1841                          * something different; setting a quota or reservation
1842                          * doesn't use any disk space.
1843                          */
1844                         switch (prop) {
1845                         case ZFS_PROP_QUOTA:
1846                         case ZFS_PROP_REFQUOTA:
1847                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1848                                     "size is less than current used or "
1849                                     "reserved space"));
1850                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1851                                 break;
1852
1853                         case ZFS_PROP_RESERVATION:
1854                         case ZFS_PROP_REFRESERVATION:
1855                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1856                                     "size is greater than available space"));
1857                                 (void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
1858                                 break;
1859
1860                         default:
1861                                 (void) zfs_standard_error(hdl, errno, errbuf);
1862                                 break;
1863                         }
1864                         break;
1865
1866                 case EBUSY:
1867                         if (prop == ZFS_PROP_VOLBLOCKSIZE)
1868                                 (void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
1869                         else
1870                                 (void) zfs_standard_error(hdl, EBUSY, errbuf);
1871                         break;
1872
1873                 case EROFS:
1874                         (void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
1875                         break;
1876
1877                 case ENOTSUP:
1878                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1879                             "pool and or dataset must be upgraded to set this "
1880                             "property or value"));
1881                         (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
1882                         break;
1883
1884                 case ERANGE:
1885                         if (prop == ZFS_PROP_COMPRESSION) {
1886                                 (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1887                                     "property setting is not allowed on "
1888                                     "bootable datasets"));
1889                                 (void) zfs_error(hdl, EZFS_NOTSUP, errbuf);
1890                         } else {
1891                                 (void) zfs_standard_error(hdl, errno, errbuf);
1892                         }
1893                         break;
1894
1895                 case EOVERFLOW:
1896                         /*
1897                          * This platform can't address a volume this big.
1898                          */
1899 #ifdef _ILP32
1900                         if (prop == ZFS_PROP_VOLSIZE) {
1901                                 (void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
1902                                 break;
1903                         }
1904 #endif
1905                         /* FALLTHROUGH */
1906                 default:
1907                         (void) zfs_standard_error(hdl, errno, errbuf);
1908                 }
1909         } else {
1910                 if (do_prefix)
1911                         ret = changelist_postfix(cl);
1912
1913                 /*
1914                  * Refresh the statistics so the new property value
1915                  * is reflected.
1916                  */
1917                 if (ret == 0)
1918                         (void) get_stats(zhp);
1919         }
1920
1921 error:
1922         nvlist_free(nvl);
1923         zcmd_free_nvlists(&zc);
1924         if (cl)
1925                 changelist_free(cl);
1926         return (ret);
1927 }
1928
1929 /*
1930  * Given a property, inherit the value from the parent dataset.
1931  */
1932 int
1933 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname)
1934 {
1935         zfs_cmd_t zc = { 0 };
1936         int ret;
1937         prop_changelist_t *cl;
1938         libzfs_handle_t *hdl = zhp->zfs_hdl;
1939         char errbuf[1024];
1940         zfs_prop_t prop;
1941
1942         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1943             "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1944
1945         if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1946                 /*
1947                  * For user properties, the amount of work we have to do is very
1948                  * small, so just do it here.
1949                  */
1950                 if (!zfs_prop_user(propname)) {
1951                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1952                             "invalid property"));
1953                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1954                 }
1955
1956                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1957                 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1958
1959                 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
1960                         return (zfs_standard_error(hdl, errno, errbuf));
1961
1962                 return (0);
1963         }
1964
1965         /*
1966          * Verify that this property is inheritable.
1967          */
1968         if (zfs_prop_readonly(prop))
1969                 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1970
1971         if (!zfs_prop_inheritable(prop))
1972                 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1973
1974         /*
1975          * Check to see if the value applies to this type
1976          */
1977         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1978                 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1979
1980         /*
1981          * Normalize the name, to get rid of shorthand abbrevations.
1982          */
1983         propname = zfs_prop_to_name(prop);
1984         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1985         (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1986
1987         if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1988             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1989                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1990                     "dataset is used in a non-global zone"));
1991                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
1992         }
1993
1994         /*
1995          * Determine datasets which will be affected by this change, if any.
1996          */
1997         if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1998                 return (-1);
1999
2000         if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
2001                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2002                     "child dataset with inherited mountpoint is used "
2003                     "in a non-global zone"));
2004                 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
2005                 goto error;
2006         }
2007
2008         if ((ret = changelist_prefix(cl)) != 0)
2009                 goto error;
2010
2011         if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
2012                 return (zfs_standard_error(hdl, errno, errbuf));
2013         } else {
2014
2015                 if ((ret = changelist_postfix(cl)) != 0)
2016                         goto error;
2017
2018                 /*
2019                  * Refresh the statistics so the new property is reflected.
2020                  */
2021                 (void) get_stats(zhp);
2022         }
2023
2024 error:
2025         changelist_free(cl);
2026         return (ret);
2027 }
2028
2029 /*
2030  * True DSL properties are stored in an nvlist.  The following two functions
2031  * extract them appropriately.
2032  */
2033 static uint64_t
2034 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2035 {
2036         nvlist_t *nv;
2037         uint64_t value;
2038
2039         *source = NULL;
2040         if (nvlist_lookup_nvlist(zhp->zfs_props,
2041             zfs_prop_to_name(prop), &nv) == 0) {
2042                 verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0);
2043                 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2044         } else {
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                 if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
2065                         value = "";
2066                 *source = "";
2067         }
2068
2069         return (value);
2070 }
2071
2072 /*
2073  * Internal function for getting a numeric property.  Both zfs_prop_get() and
2074  * zfs_prop_get_int() are built using this interface.
2075  *
2076  * Certain properties can be overridden using 'mount -o'.  In this case, scan
2077  * the contents of the /etc/mnttab entry, searching for the appropriate options.
2078  * If they differ from the on-disk values, report the current values and mark
2079  * the source "temporary".
2080  */
2081 static int
2082 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
2083     char **source, uint64_t *val)
2084 {
2085         zfs_cmd_t zc = { 0 };
2086         nvlist_t *zplprops = NULL;
2087         struct mnttab mnt;
2088         char *mntopt_on = NULL;
2089         char *mntopt_off = NULL;
2090
2091         *source = NULL;
2092
2093         switch (prop) {
2094         case ZFS_PROP_ATIME:
2095                 mntopt_on = MNTOPT_ATIME;
2096                 mntopt_off = MNTOPT_NOATIME;
2097                 break;
2098
2099         case ZFS_PROP_DEVICES:
2100                 mntopt_on = MNTOPT_DEVICES;
2101                 mntopt_off = MNTOPT_NODEVICES;
2102                 break;
2103
2104         case ZFS_PROP_EXEC:
2105                 mntopt_on = MNTOPT_EXEC;
2106                 mntopt_off = MNTOPT_NOEXEC;
2107                 break;
2108
2109         case ZFS_PROP_READONLY:
2110                 mntopt_on = MNTOPT_RO;
2111                 mntopt_off = MNTOPT_RW;
2112                 break;
2113
2114         case ZFS_PROP_SETUID:
2115                 mntopt_on = MNTOPT_SETUID;
2116                 mntopt_off = MNTOPT_NOSETUID;
2117                 break;
2118
2119         case ZFS_PROP_XATTR:
2120                 mntopt_on = MNTOPT_XATTR;
2121                 mntopt_off = MNTOPT_NOXATTR;
2122                 break;
2123
2124         case ZFS_PROP_NBMAND:
2125                 mntopt_on = MNTOPT_NBMAND;
2126                 mntopt_off = MNTOPT_NONBMAND;
2127                 break;
2128         }
2129
2130         /*
2131          * Because looking up the mount options is potentially expensive
2132          * (iterating over all of /etc/mnttab), we defer its calculation until
2133          * we're looking up a property which requires its presence.
2134          */
2135         if (!zhp->zfs_mntcheck &&
2136             (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
2137                 struct mnttab entry, search = { 0 };
2138                 FILE *mnttab = zhp->zfs_hdl->libzfs_mnttab;
2139
2140                 search.mnt_special = (char *)zhp->zfs_name;
2141                 search.mnt_fstype = MNTTYPE_ZFS;
2142                 rewind(mnttab);
2143
2144                 if (getmntany(mnttab, &entry, &search) == 0) {
2145                         zhp->zfs_mntopts = zfs_strdup(zhp->zfs_hdl,
2146                             entry.mnt_mntopts);
2147                         if (zhp->zfs_mntopts == NULL)
2148                                 return (-1);
2149                 }
2150
2151                 zhp->zfs_mntcheck = B_TRUE;
2152         }
2153
2154         if (zhp->zfs_mntopts == NULL)
2155                 mnt.mnt_mntopts = "";
2156         else
2157                 mnt.mnt_mntopts = zhp->zfs_mntopts;
2158
2159         switch (prop) {
2160         case ZFS_PROP_ATIME:
2161         case ZFS_PROP_DEVICES:
2162         case ZFS_PROP_EXEC:
2163         case ZFS_PROP_READONLY:
2164         case ZFS_PROP_SETUID:
2165         case ZFS_PROP_XATTR:
2166         case ZFS_PROP_NBMAND:
2167                 *val = getprop_uint64(zhp, prop, source);
2168
2169                 if (hasmntopt(&mnt, mntopt_on) && !*val) {
2170                         *val = B_TRUE;
2171                         if (src)
2172                                 *src = ZPROP_SRC_TEMPORARY;
2173                 } else if (hasmntopt(&mnt, mntopt_off) && *val) {
2174                         *val = B_FALSE;
2175                         if (src)
2176                                 *src = ZPROP_SRC_TEMPORARY;
2177                 }
2178                 break;
2179
2180         case ZFS_PROP_CANMOUNT:
2181                 *val = getprop_uint64(zhp, prop, source);
2182                 if (*val != ZFS_CANMOUNT_ON)
2183                         *source = zhp->zfs_name;
2184                 else
2185                         *source = "";   /* default */
2186                 break;
2187
2188         case ZFS_PROP_QUOTA:
2189         case ZFS_PROP_REFQUOTA:
2190         case ZFS_PROP_RESERVATION:
2191         case ZFS_PROP_REFRESERVATION:
2192                 *val = getprop_uint64(zhp, prop, source);
2193                 if (*val == 0)
2194                         *source = "";   /* default */
2195                 else
2196                         *source = zhp->zfs_name;
2197                 break;
2198
2199         case ZFS_PROP_MOUNTED:
2200                 *val = (zhp->zfs_mntopts != NULL);
2201                 break;
2202
2203         case ZFS_PROP_NUMCLONES:
2204                 *val = zhp->zfs_dmustats.dds_num_clones;
2205                 break;
2206
2207         case ZFS_PROP_VERSION:
2208         case ZFS_PROP_NORMALIZE:
2209         case ZFS_PROP_UTF8ONLY:
2210         case ZFS_PROP_CASE:
2211                 if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) ||
2212                     zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
2213                         return (-1);
2214                 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2215                 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
2216                         zcmd_free_nvlists(&zc);
2217                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2218                             "unable to get %s property"),
2219                             zfs_prop_to_name(prop));
2220                         return (zfs_error(zhp->zfs_hdl, EZFS_BADVERSION,
2221                             dgettext(TEXT_DOMAIN, "internal error")));
2222                 }
2223                 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
2224                     nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
2225                     val) != 0) {
2226                         zcmd_free_nvlists(&zc);
2227                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2228                             "unable to get %s property"),
2229                             zfs_prop_to_name(prop));
2230                         return (zfs_error(zhp->zfs_hdl, EZFS_NOMEM,
2231                             dgettext(TEXT_DOMAIN, "internal error")));
2232                 }
2233                 if (zplprops)
2234                         nvlist_free(zplprops);
2235                 zcmd_free_nvlists(&zc);
2236                 break;
2237
2238         default:
2239                 switch (zfs_prop_get_type(prop)) {
2240                 case PROP_TYPE_NUMBER:
2241                 case PROP_TYPE_INDEX:
2242                         *val = getprop_uint64(zhp, prop, source);
2243                         /*
2244                          * If we tried to use a defalut value for a
2245                          * readonly property, it means that it was not
2246                          * present; return an error.
2247                          */
2248                         if (zfs_prop_readonly(prop) &&
2249                             *source && (*source)[0] == '\0') {
2250                                 return (-1);
2251                         }
2252                         break;
2253
2254                 case PROP_TYPE_STRING:
2255                 default:
2256                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2257                             "cannot get non-numeric property"));
2258                         return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
2259                             dgettext(TEXT_DOMAIN, "internal error")));
2260                 }
2261         }
2262
2263         return (0);
2264 }
2265
2266 /*
2267  * Calculate the source type, given the raw source string.
2268  */
2269 static void
2270 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
2271     char *statbuf, size_t statlen)
2272 {
2273         if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
2274                 return;
2275
2276         if (source == NULL) {
2277                 *srctype = ZPROP_SRC_NONE;
2278         } else if (source[0] == '\0') {
2279                 *srctype = ZPROP_SRC_DEFAULT;
2280         } else {
2281                 if (strcmp(source, zhp->zfs_name) == 0) {
2282                         *srctype = ZPROP_SRC_LOCAL;
2283                 } else {
2284                         (void) strlcpy(statbuf, source, statlen);
2285                         *srctype = ZPROP_SRC_INHERITED;
2286                 }
2287         }
2288
2289 }
2290
2291 /*
2292  * Retrieve a property from the given object.  If 'literal' is specified, then
2293  * numbers are left as exact values.  Otherwise, numbers are converted to a
2294  * human-readable form.
2295  *
2296  * Returns 0 on success, or -1 on error.
2297  */
2298 int
2299 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2300     zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
2301 {
2302         char *source = NULL;
2303         uint64_t val;
2304         char *str;
2305         const char *strval;
2306
2307         /*
2308          * Check to see if this property applies to our object
2309          */
2310         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
2311                 return (-1);
2312
2313         if (src)
2314                 *src = ZPROP_SRC_NONE;
2315
2316         switch (prop) {
2317         case ZFS_PROP_CREATION:
2318                 /*
2319                  * 'creation' is a time_t stored in the statistics.  We convert
2320                  * this into a string unless 'literal' is specified.
2321                  */
2322                 {
2323                         val = getprop_uint64(zhp, prop, &source);
2324                         time_t time = (time_t)val;
2325                         struct tm t;
2326
2327                         if (literal ||
2328                             localtime_r(&time, &t) == NULL ||
2329                             strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
2330                             &t) == 0)
2331                                 (void) snprintf(propbuf, proplen, "%llu", val);
2332                 }
2333                 break;
2334
2335         case ZFS_PROP_MOUNTPOINT:
2336                 /*
2337                  * Getting the precise mountpoint can be tricky.
2338                  *
2339                  *  - for 'none' or 'legacy', return those values.
2340                  *  - for inherited mountpoints, we want to take everything
2341                  *    after our ancestor and append it to the inherited value.
2342                  *
2343                  * If the pool has an alternate root, we want to prepend that
2344                  * root to any values we return.
2345                  */
2346
2347                 str = getprop_string(zhp, prop, &source);
2348
2349                 if (str[0] == '/') {
2350                         char buf[MAXPATHLEN];
2351                         char *root = buf;
2352                         const char *relpath = zhp->zfs_name + strlen(source);
2353
2354                         if (relpath[0] == '/')
2355                                 relpath++;
2356
2357                         if ((zpool_get_prop(zhp->zpool_hdl,
2358                             ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) ||
2359                             (strcmp(root, "-") == 0))
2360                                 root[0] = '\0';
2361                         /*
2362                          * Special case an alternate root of '/'. This will
2363                          * avoid having multiple leading slashes in the
2364                          * mountpoint path.
2365                          */
2366                         if (strcmp(root, "/") == 0)
2367                                 root++;
2368
2369                         /*
2370                          * If the mountpoint is '/' then skip over this
2371                          * if we are obtaining either an alternate root or
2372                          * an inherited mountpoint.
2373                          */
2374                         if (str[1] == '\0' && (root[0] != '\0' ||
2375                             relpath[0] != '\0'))
2376                                 str++;
2377
2378                         if (relpath[0] == '\0')
2379                                 (void) snprintf(propbuf, proplen, "%s%s",
2380                                     root, str);
2381                         else
2382                                 (void) snprintf(propbuf, proplen, "%s%s%s%s",
2383                                     root, str, relpath[0] == '@' ? "" : "/",
2384                                     relpath);
2385                 } else {
2386                         /* 'legacy' or 'none' */
2387                         (void) strlcpy(propbuf, str, proplen);
2388                 }
2389
2390                 break;
2391
2392         case ZFS_PROP_ORIGIN:
2393                 (void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
2394                     proplen);
2395                 /*
2396                  * If there is no parent at all, return failure to indicate that
2397                  * it doesn't apply to this dataset.
2398                  */
2399                 if (propbuf[0] == '\0')
2400                         return (-1);
2401                 break;
2402
2403         case ZFS_PROP_QUOTA:
2404         case ZFS_PROP_REFQUOTA:
2405         case ZFS_PROP_RESERVATION:
2406         case ZFS_PROP_REFRESERVATION:
2407
2408                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2409                         return (-1);
2410
2411                 /*
2412                  * If quota or reservation is 0, we translate this into 'none'
2413                  * (unless literal is set), and indicate that it's the default
2414                  * value.  Otherwise, we print the number nicely and indicate
2415                  * that its set locally.
2416                  */
2417                 if (val == 0) {
2418                         if (literal)
2419                                 (void) strlcpy(propbuf, "0", proplen);
2420                         else
2421                                 (void) strlcpy(propbuf, "none", proplen);
2422                 } else {
2423                         if (literal)
2424                                 (void) snprintf(propbuf, proplen, "%llu",
2425                                     (u_longlong_t)val);
2426                         else
2427                                 zfs_nicenum(val, propbuf, proplen);
2428                 }
2429                 break;
2430
2431         case ZFS_PROP_COMPRESSRATIO:
2432                 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2433                         return (-1);
2434                 (void) snprintf(propbuf, proplen, "%lld.%02lldx", (longlong_t)
2435                     val / 100, (longlong_t)val % 100);
2436                 break;
2437
2438         case ZFS_PROP_TYPE:
2439                 switch (zhp->zfs_type) {
2440                 case ZFS_TYPE_FILESYSTEM:
2441                         str = "filesystem";
2442                         break;
2443                 case ZFS_TYPE_VOLUME:
2444                         str = "volume";
2445                         break;
2446                 case ZFS_TYPE_SNAPSHOT:
2447                         str = "snapshot";
2448                         break;
2449                 default:
2450                         abort();
2451                 }
2452                 (void) snprintf(propbuf, proplen, "%s", str);
2453                 break;
2454
2455         case ZFS_PROP_MOUNTED:
2456                 /*
2457                  * The 'mounted' property is a pseudo-property that described
2458                  * whether the filesystem is currently mounted.  Even though
2459                  * it's a boolean value, the typical values of "on" and "off"
2460                  * don't make sense, so we translate to "yes" and "no".
2461                  */
2462                 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
2463                     src, &source, &val) != 0)
2464                         return (-1);
2465                 if (val)
2466                         (void) strlcpy(propbuf, "yes", proplen);
2467                 else
2468                         (void) strlcpy(propbuf, "no", proplen);
2469                 break;
2470
2471         case ZFS_PROP_NAME:
2472                 /*
2473                  * The 'name' property is a pseudo-property derived from the
2474                  * dataset name.  It is presented as a real property to simplify
2475                  * consumers.
2476                  */
2477                 (void) strlcpy(propbuf, zhp->zfs_name, proplen);
2478                 break;
2479
2480         default:
2481                 switch (zfs_prop_get_type(prop)) {
2482                 case PROP_TYPE_NUMBER:
2483                         if (get_numeric_property(zhp, prop, src,
2484                             &source, &val) != 0)
2485                                 return (-1);
2486                         if (literal)
2487                                 (void) snprintf(propbuf, proplen, "%llu",
2488                                     (u_longlong_t)val);
2489                         else
2490                                 zfs_nicenum(val, propbuf, proplen);
2491                         break;
2492
2493                 case PROP_TYPE_STRING:
2494                         (void) strlcpy(propbuf,
2495                             getprop_string(zhp, prop, &source), proplen);
2496                         break;
2497
2498                 case PROP_TYPE_INDEX:
2499                         if (get_numeric_property(zhp, prop, src,
2500                             &source, &val) != 0)
2501                                 return (-1);
2502                         if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2503                                 return (-1);
2504                         (void) strlcpy(propbuf, strval, proplen);
2505                         break;
2506
2507                 default:
2508                         abort();
2509                 }
2510         }
2511
2512         get_source(zhp, src, source, statbuf, statlen);
2513
2514         return (0);
2515 }
2516
2517 /*
2518  * Utility function to get the given numeric property.  Does no validation that
2519  * the given property is the appropriate type; should only be used with
2520  * hard-coded property types.
2521  */
2522 uint64_t
2523 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2524 {
2525         char *source;
2526         uint64_t val;
2527
2528         (void) get_numeric_property(zhp, prop, NULL, &source, &val);
2529
2530         return (val);
2531 }
2532
2533 int
2534 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
2535 {
2536         char buf[64];
2537
2538         zfs_nicenum(val, buf, sizeof (buf));
2539         return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
2540 }
2541
2542 /*
2543  * Similar to zfs_prop_get(), but returns the value as an integer.
2544  */
2545 int
2546 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
2547     zprop_source_t *src, char *statbuf, size_t statlen)
2548 {
2549         char *source;
2550
2551         /*
2552          * Check to see if this property applies to our object
2553          */
2554         if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) {
2555                 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
2556                     dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
2557                     zfs_prop_to_name(prop)));
2558         }
2559
2560         if (src)
2561                 *src = ZPROP_SRC_NONE;
2562
2563         if (get_numeric_property(zhp, prop, src, &source, value) != 0)
2564                 return (-1);
2565
2566         get_source(zhp, src, source, statbuf, statlen);
2567
2568         return (0);
2569 }
2570
2571 /*
2572  * Returns the name of the given zfs handle.
2573  */
2574 const char *
2575 zfs_get_name(const zfs_handle_t *zhp)
2576 {
2577         return (zhp->zfs_name);
2578 }
2579
2580 /*
2581  * Returns the type of the given zfs handle.
2582  */
2583 zfs_type_t
2584 zfs_get_type(const zfs_handle_t *zhp)
2585 {
2586         return (zhp->zfs_type);
2587 }
2588
2589 /*
2590  * Iterate over all child filesystems
2591  */
2592 int
2593 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2594 {
2595         zfs_cmd_t zc = { 0 };
2596         zfs_handle_t *nzhp;
2597         int ret;
2598
2599         if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM)
2600                 return (0);
2601
2602         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2603             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
2604             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
2605                 /*
2606                  * Ignore private dataset names.
2607                  */
2608                 if (dataset_name_hidden(zc.zc_name))
2609                         continue;
2610
2611                 /*
2612                  * Silently ignore errors, as the only plausible explanation is
2613                  * that the pool has since been removed.
2614                  */
2615                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
2616                     zc.zc_name)) == NULL)
2617                         continue;
2618
2619                 if ((ret = func(nzhp, data)) != 0)
2620                         return (ret);
2621         }
2622
2623         /*
2624          * An errno value of ESRCH indicates normal completion.  If ENOENT is
2625          * returned, then the underlying dataset has been removed since we
2626          * obtained the handle.
2627          */
2628         if (errno != ESRCH && errno != ENOENT)
2629                 return (zfs_standard_error(zhp->zfs_hdl, errno,
2630                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
2631
2632         return (0);
2633 }
2634
2635 /*
2636  * Iterate over all snapshots
2637  */
2638 int
2639 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2640 {
2641         zfs_cmd_t zc = { 0 };
2642         zfs_handle_t *nzhp;
2643         int ret;
2644
2645         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
2646                 return (0);
2647
2648         for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2649             ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
2650             &zc) == 0;
2651             (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
2652
2653                 if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
2654                     zc.zc_name)) == NULL)
2655                         continue;
2656
2657                 if ((ret = func(nzhp, data)) != 0)
2658                         return (ret);
2659         }
2660
2661         /*
2662          * An errno value of ESRCH indicates normal completion.  If ENOENT is
2663          * returned, then the underlying dataset has been removed since we
2664          * obtained the handle.  Silently ignore this case, and return success.
2665          */
2666         if (errno != ESRCH && errno != ENOENT)
2667                 return (zfs_standard_error(zhp->zfs_hdl, errno,
2668                     dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
2669
2670         return (0);
2671 }
2672
2673 /*
2674  * Iterate over all children, snapshots and filesystems
2675  */
2676 int
2677 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2678 {
2679         int ret;
2680
2681         if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
2682                 return (ret);
2683
2684         return (zfs_iter_snapshots(zhp, func, data));
2685 }
2686
2687 /*
2688  * Given a complete name, return just the portion that refers to the parent.
2689  * Can return NULL if this is a pool.
2690  */
2691 static int
2692 parent_name(const char *path, char *buf, size_t buflen)
2693 {
2694         char *loc;
2695
2696         if ((loc = strrchr(path, '/')) == NULL)
2697                 return (-1);
2698
2699         (void) strncpy(buf, path, MIN(buflen, loc - path));
2700         buf[loc - path] = '\0';
2701
2702         return (0);
2703 }
2704
2705 /*
2706  * If accept_ancestor is false, then check to make sure that the given path has
2707  * a parent, and that it exists.  If accept_ancestor is true, then find the
2708  * closest existing ancestor for the given path.  In prefixlen return the
2709  * length of already existing prefix of the given path.  We also fetch the
2710  * 'zoned' property, which is used to validate property settings when creating
2711  * new datasets.
2712  */
2713 static int
2714 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
2715     boolean_t accept_ancestor, int *prefixlen)
2716 {
2717         zfs_cmd_t zc = { 0 };
2718         char parent[ZFS_MAXNAMELEN];
2719         char *slash;
2720         zfs_handle_t *zhp;
2721         char errbuf[1024];
2722
2723         (void) snprintf(errbuf, sizeof (errbuf), "cannot create '%s'",
2724             path);
2725
2726         /* get parent, and check to see if this is just a pool */
2727         if (parent_name(path, parent, sizeof (parent)) != 0) {
2728                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2729                     "missing dataset name"));
2730                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2731         }
2732
2733         /* check to see if the pool exists */
2734         if ((slash = strchr(parent, '/')) == NULL)
2735                 slash = parent + strlen(parent);
2736         (void) strncpy(zc.zc_name, parent, slash - parent);
2737         zc.zc_name[slash - parent] = '\0';
2738         if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
2739             errno == ENOENT) {
2740                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2741                     "no such pool '%s'"), zc.zc_name);
2742                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2743         }
2744
2745         /* check to see if the parent dataset exists */
2746         while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
2747                 if (errno == ENOENT && accept_ancestor) {
2748                         /*
2749                          * Go deeper to find an ancestor, give up on top level.
2750                          */
2751                         if (parent_name(parent, parent, sizeof (parent)) != 0) {
2752                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2753                                     "no such pool '%s'"), zc.zc_name);
2754                                 return (zfs_error(hdl, EZFS_NOENT, errbuf));
2755                         }
2756                 } else if (errno == ENOENT) {
2757                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2758                             "parent does not exist"));
2759                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
2760                 } else
2761                         return (zfs_standard_error(hdl, errno, errbuf));
2762         }
2763
2764         *zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
2765         /* we are in a non-global zone, but parent is in the global zone */
2766         if (getzoneid() != GLOBAL_ZONEID && !(*zoned)) {
2767                 (void) zfs_standard_error(hdl, EPERM, errbuf);
2768                 zfs_close(zhp);
2769                 return (-1);
2770         }
2771
2772         /* make sure parent is a filesystem */
2773         if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
2774                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2775                     "parent is not a filesystem"));
2776                 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
2777                 zfs_close(zhp);
2778                 return (-1);
2779         }
2780
2781         zfs_close(zhp);
2782         if (prefixlen != NULL)
2783                 *prefixlen = strlen(parent);
2784         return (0);
2785 }
2786
2787 /*
2788  * Finds whether the dataset of the given type(s) exists.
2789  */
2790 boolean_t
2791 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
2792 {
2793         zfs_handle_t *zhp;
2794
2795         if (!zfs_validate_name(hdl, path, types, B_FALSE))
2796                 return (B_FALSE);
2797
2798         /*
2799          * Try to get stats for the dataset, which will tell us if it exists.
2800          */
2801         if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
2802                 int ds_type = zhp->zfs_type;
2803
2804                 zfs_close(zhp);
2805                 if (types & ds_type)
2806                         return (B_TRUE);
2807         }
2808         return (B_FALSE);
2809 }
2810
2811 /*
2812  * Given a path to 'target', create all the ancestors between
2813  * the prefixlen portion of the path, and the target itself.
2814  * Fail if the initial prefixlen-ancestor does not already exist.
2815  */
2816 int
2817 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
2818 {
2819         zfs_handle_t *h;
2820         char *cp;
2821         const char *opname;
2822
2823         /* make sure prefix exists */
2824         cp = target + prefixlen;
2825         if (*cp != '/') {
2826                 assert(strchr(cp, '/') == NULL);
2827                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2828         } else {
2829                 *cp = '\0';
2830                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2831                 *cp = '/';
2832         }
2833         if (h == NULL)
2834                 return (-1);
2835         zfs_close(h);
2836
2837         /*
2838          * Attempt to create, mount, and share any ancestor filesystems,
2839          * up to the prefixlen-long one.
2840          */
2841         for (cp = target + prefixlen + 1;
2842             cp = strchr(cp, '/'); *cp = '/', cp++) {
2843                 char *logstr;
2844
2845                 *cp = '\0';
2846
2847                 h = make_dataset_handle(hdl, target);
2848                 if (h) {
2849                         /* it already exists, nothing to do here */
2850                         zfs_close(h);
2851                         continue;
2852                 }
2853
2854                 logstr = hdl->libzfs_log_str;
2855                 hdl->libzfs_log_str = NULL;
2856                 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2857                     NULL) != 0) {
2858                         hdl->libzfs_log_str = logstr;
2859                         opname = dgettext(TEXT_DOMAIN, "create");
2860                         goto ancestorerr;
2861                 }
2862
2863                 hdl->libzfs_log_str = logstr;
2864                 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2865                 if (h == NULL) {
2866                         opname = dgettext(TEXT_DOMAIN, "open");
2867                         goto ancestorerr;
2868                 }
2869
2870                 if (zfs_mount(h, NULL, 0) != 0) {
2871                         opname = dgettext(TEXT_DOMAIN, "mount");
2872                         goto ancestorerr;
2873                 }
2874
2875                 if (zfs_share(h) != 0) {
2876                         opname = dgettext(TEXT_DOMAIN, "share");
2877                         goto ancestorerr;
2878                 }
2879
2880                 zfs_close(h);
2881         }
2882
2883         return (0);
2884
2885 ancestorerr:
2886         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2887             "failed to %s ancestor '%s'"), opname, target);
2888         return (-1);
2889 }
2890
2891 /*
2892  * Creates non-existing ancestors of the given path.
2893  */
2894 int
2895 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
2896 {
2897         int prefix;
2898         uint64_t zoned;
2899         char *path_copy;
2900         int rc;
2901
2902         if (check_parents(hdl, path, &zoned, B_TRUE, &prefix) != 0)
2903                 return (-1);
2904
2905         if ((path_copy = strdup(path)) != NULL) {
2906                 rc = create_parents(hdl, path_copy, prefix);
2907                 free(path_copy);
2908         }
2909         if (path_copy == NULL || rc != 0)
2910                 return (-1);
2911
2912         return (0);
2913 }
2914
2915 /*
2916  * Create a new filesystem or volume.
2917  */
2918 int
2919 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2920     nvlist_t *props)
2921 {
2922         zfs_cmd_t zc = { 0 };
2923         int ret;
2924         uint64_t size = 0;
2925         uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2926         char errbuf[1024];
2927         uint64_t zoned;
2928
2929         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2930             "cannot create '%s'"), path);
2931
2932         /* validate the path, taking care to note the extended error message */
2933         if (!zfs_validate_name(hdl, path, type, B_TRUE))
2934                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2935
2936         /* validate parents exist */
2937         if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
2938                 return (-1);
2939
2940         /*
2941          * The failure modes when creating a dataset of a different type over
2942          * one that already exists is a little strange.  In particular, if you
2943          * try to create a dataset on top of an existing dataset, the ioctl()
2944          * will return ENOENT, not EEXIST.  To prevent this from happening, we
2945          * first try to see if the dataset exists.
2946          */
2947         (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2948         if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
2949                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2950                     "dataset already exists"));
2951                 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2952         }
2953
2954         if (type == ZFS_TYPE_VOLUME)
2955                 zc.zc_objset_type = DMU_OST_ZVOL;
2956         else
2957                 zc.zc_objset_type = DMU_OST_ZFS;
2958
2959         if (props && (props = zfs_valid_proplist(hdl, type, props,
2960             zoned, NULL, errbuf)) == 0)
2961                 return (-1);
2962
2963         if (type == ZFS_TYPE_VOLUME) {
2964                 /*
2965                  * If we are creating a volume, the size and block size must
2966                  * satisfy a few restraints.  First, the blocksize must be a
2967                  * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
2968                  * volsize must be a multiple of the block size, and cannot be
2969                  * zero.
2970                  */
2971                 if (props == NULL || nvlist_lookup_uint64(props,
2972                     zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
2973                         nvlist_free(props);
2974                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2975                             "missing volume size"));
2976                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2977                 }
2978
2979                 if ((ret = nvlist_lookup_uint64(props,
2980                     zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
2981                     &blocksize)) != 0) {
2982                         if (ret == ENOENT) {
2983                                 blocksize = zfs_prop_default_numeric(
2984                                     ZFS_PROP_VOLBLOCKSIZE);
2985                         } else {
2986                                 nvlist_free(props);
2987                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2988                                     "missing volume block size"));
2989                                 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2990                         }
2991                 }
2992
2993                 if (size == 0) {
2994                         nvlist_free(props);
2995                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2996                             "volume size cannot be zero"));
2997                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2998                 }
2999
3000                 if (size % blocksize != 0) {
3001                         nvlist_free(props);
3002                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3003                             "volume size must be a multiple of volume block "
3004                             "size"));
3005                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3006                 }
3007         }
3008
3009         if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0)
3010                 return (-1);
3011         nvlist_free(props);
3012
3013         /* create the dataset */
3014         ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc);
3015
3016         if (ret == 0 && type == ZFS_TYPE_VOLUME) {
3017                 ret = zvol_create_link(hdl, path);
3018                 if (ret) {
3019                         (void) zfs_standard_error(hdl, errno,
3020                             dgettext(TEXT_DOMAIN,
3021                             "Volume successfully created, but device links "
3022                             "were not created"));
3023                         zcmd_free_nvlists(&zc);
3024                         return (-1);
3025                 }
3026         }
3027
3028         zcmd_free_nvlists(&zc);
3029
3030         /* check for failure */
3031         if (ret != 0) {
3032                 char parent[ZFS_MAXNAMELEN];
3033                 (void) parent_name(path, parent, sizeof (parent));
3034
3035                 switch (errno) {
3036                 case ENOENT:
3037                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3038                             "no such parent '%s'"), parent);
3039                         return (zfs_error(hdl, EZFS_NOENT, errbuf));
3040
3041                 case EINVAL:
3042                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3043                             "parent '%s' is not a filesystem"), parent);
3044                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3045
3046                 case EDOM:
3047                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3048                             "volume block size must be power of 2 from "
3049                             "%u to %uk"),
3050                             (uint_t)SPA_MINBLOCKSIZE,
3051                             (uint_t)SPA_MAXBLOCKSIZE >> 10);
3052
3053                         return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3054
3055                 case ENOTSUP:
3056                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3057                             "pool must be upgraded to set this "
3058                             "property or value"));
3059                         return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3060 #ifdef _ILP32
3061                 case EOVERFLOW:
3062                         /*
3063                          * This platform can't address a volume this big.
3064                          */
3065                         if (type == ZFS_TYPE_VOLUME)
3066                                 return (zfs_error(hdl, EZFS_VOLTOOBIG,
3067                                     errbuf));
3068 #endif
3069                         /* FALLTHROUGH */
3070                 default:
3071                         return (zfs_standard_error(hdl, errno, errbuf));
3072                 }
3073         }
3074
3075         return (0);
3076 }
3077
3078 /*
3079  * Destroys the given dataset.  The caller must make sure that the filesystem
3080  * isn't mounted, and that there are no active dependents.
3081  */
3082 int
3083 zfs_destroy(zfs_handle_t *zhp)
3084 {
3085         zfs_cmd_t zc = { 0 };
3086
3087         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3088
3089         if (ZFS_IS_VOLUME(zhp)) {
3090                 /*
3091                  * If user doesn't have permissions to unshare volume, then
3092                  * abort the request.  This would only happen for a
3093                  * non-privileged user.
3094                  */
3095                 if (zfs_unshare_iscsi(zhp) != 0) {
3096                         return (-1);
3097                 }
3098
3099                 if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3100                         return (-1);
3101
3102                 zc.zc_objset_type = DMU_OST_ZVOL;
3103         } else {
3104                 zc.zc_objset_type = DMU_OST_ZFS;
3105         }
3106
3107         if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY, &zc) != 0) {
3108                 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3109                     dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3110                     zhp->zfs_name));
3111         }
3112
3113         remove_mountpoint(zhp);
3114
3115         return (0);
3116 }
3117
3118 struct destroydata {
3119         char *snapname;
3120         boolean_t gotone;
3121         boolean_t closezhp;
3122 };
3123
3124 static int
3125 zfs_remove_link_cb(zfs_handle_t *zhp, void *arg)
3126 {
3127         struct destroydata *dd = arg;
3128         zfs_handle_t *szhp;
3129         char name[ZFS_MAXNAMELEN];
3130         boolean_t closezhp = dd->closezhp;
3131         int rv;
3132
3133         (void) strlcpy(name, zhp->zfs_name, sizeof (name));
3134         (void) strlcat(name, "@", sizeof (name));
3135         (void) strlcat(name, dd->snapname, sizeof (name));
3136
3137         szhp = make_dataset_handle(zhp->zfs_hdl, name);
3138         if (szhp) {
3139                 dd->gotone = B_TRUE;
3140                 zfs_close(szhp);
3141         }
3142
3143         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3144                 (void) zvol_remove_link(zhp->zfs_hdl, name);
3145                 /*
3146                  * NB: this is simply a best-effort.  We don't want to
3147                  * return an error, because then we wouldn't visit all
3148                  * the volumes.
3149                  */
3150         }
3151
3152         dd->closezhp = B_TRUE;
3153         rv = zfs_iter_filesystems(zhp, zfs_remove_link_cb, arg);
3154         if (closezhp)
3155                 zfs_close(zhp);
3156         return (rv);
3157 }
3158
3159 /*
3160  * Destroys all snapshots with the given name in zhp & descendants.
3161  */
3162 int
3163 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname)
3164 {
3165         zfs_cmd_t zc = { 0 };
3166         int ret;
3167         struct destroydata dd = { 0 };
3168
3169         dd.snapname = snapname;
3170         (void) zfs_remove_link_cb(zhp, &dd);
3171
3172         if (!dd.gotone) {
3173                 return (zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3174                     dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3175                     zhp->zfs_name, snapname));
3176         }
3177
3178         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3179         (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3180
3181         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS, &zc);
3182         if (ret != 0) {
3183                 char errbuf[1024];
3184
3185                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3186                     "cannot destroy '%s@%s'"), zc.zc_name, snapname);
3187
3188                 switch (errno) {
3189                 case EEXIST:
3190                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3191                             "snapshot is cloned"));
3192                         return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
3193
3194                 default:
3195                         return (zfs_standard_error(zhp->zfs_hdl, errno,
3196                             errbuf));
3197                 }
3198         }
3199
3200         return (0);
3201 }
3202
3203 /*
3204  * Clones the given dataset.  The target must be of the same type as the source.
3205  */
3206 int
3207 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3208 {
3209         zfs_cmd_t zc = { 0 };
3210         char parent[ZFS_MAXNAMELEN];
3211         int ret;
3212         char errbuf[1024];
3213         libzfs_handle_t *hdl = zhp->zfs_hdl;
3214         zfs_type_t type;
3215         uint64_t zoned;
3216
3217         assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3218
3219         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3220             "cannot create '%s'"), target);
3221
3222         /* validate the target name */
3223         if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3224                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3225
3226         /* validate parents exist */
3227         if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3228                 return (-1);
3229
3230         (void) parent_name(target, parent, sizeof (parent));
3231
3232         /* do the clone */
3233         if (ZFS_IS_VOLUME(zhp)) {
3234                 zc.zc_objset_type = DMU_OST_ZVOL;
3235                 type = ZFS_TYPE_VOLUME;
3236         } else {
3237                 zc.zc_objset_type = DMU_OST_ZFS;
3238                 type = ZFS_TYPE_FILESYSTEM;
3239         }
3240
3241         if (props) {
3242                 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3243                     zhp, errbuf)) == NULL)
3244                         return (-1);
3245
3246                 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3247                         nvlist_free(props);
3248                         return (-1);
3249                 }
3250
3251                 nvlist_free(props);
3252         }
3253
3254         (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
3255         (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
3256         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CREATE, &zc);
3257
3258         zcmd_free_nvlists(&zc);
3259
3260         if (ret != 0) {
3261                 switch (errno) {
3262
3263                 case ENOENT:
3264                         /*
3265                          * The parent doesn't exist.  We should have caught this
3266                          * above, but there may a race condition that has since
3267                          * destroyed the parent.
3268                          *
3269                          * At this point, we don't know whether it's the source
3270                          * that doesn't exist anymore, or whether the target
3271                          * dataset doesn't exist.
3272                          */
3273                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3274                             "no such parent '%s'"), parent);
3275                         return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3276
3277                 case EXDEV:
3278                         zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3279                             "source and target pools differ"));
3280                         return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
3281                             errbuf));
3282
3283                 default:
3284                         return (zfs_standard_error(zhp->zfs_hdl, errno,
3285                             errbuf));
3286                 }
3287         } else if (ZFS_IS_VOLUME(zhp)) {
3288                 ret = zvol_create_link(zhp->zfs_hdl, target);
3289         }
3290
3291         return (ret);
3292 }
3293
3294 typedef struct promote_data {
3295         char cb_mountpoint[MAXPATHLEN];
3296         const char *cb_target;
3297         const char *cb_errbuf;
3298         uint64_t cb_pivot_txg;
3299 } promote_data_t;
3300
3301 static int
3302 promote_snap_cb(zfs_handle_t *zhp, void *data)
3303 {
3304         promote_data_t *pd = data;
3305         zfs_handle_t *szhp;
3306         char snapname[MAXPATHLEN];
3307         int rv = 0;
3308
3309         /* We don't care about snapshots after the pivot point */
3310         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg) {
3311                 zfs_close(zhp);
3312                 return (0);
3313         }
3314
3315         /* Remove the device link if it's a zvol. */
3316         if (ZFS_IS_VOLUME(zhp))
3317                 (void) zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
3318
3319         /* Check for conflicting names */
3320         (void) strlcpy(snapname, pd->cb_target, sizeof (snapname));
3321         (void) strlcat(snapname, strchr(zhp->zfs_name, '@'), sizeof (snapname));
3322         szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
3323         if (szhp != NULL) {
3324                 zfs_close(szhp);
3325                 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3326                     "snapshot name '%s' from origin \n"
3327                     "conflicts with '%s' from target"),
3328                     zhp->zfs_name, snapname);
3329                 rv = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf);
3330         }
3331         zfs_close(zhp);
3332         return (rv);
3333 }
3334
3335 static int
3336 promote_snap_done_cb(zfs_handle_t *zhp, void *data)
3337 {
3338         promote_data_t *pd = data;
3339
3340         /* We don't care about snapshots after the pivot point */
3341         if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) <= pd->cb_pivot_txg) {
3342                 /* Create the device link if it's a zvol. */
3343                 if (ZFS_IS_VOLUME(zhp))
3344                         (void) zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
3345         }
3346
3347         zfs_close(zhp);
3348         return (0);
3349 }
3350
3351 /*
3352  * Promotes the given clone fs to be the clone parent.
3353  */
3354 int
3355 zfs_promote(zfs_handle_t *zhp)
3356 {
3357         libzfs_handle_t *hdl = zhp->zfs_hdl;
3358         zfs_cmd_t zc = { 0 };
3359         char parent[MAXPATHLEN];
3360         char *cp;
3361         int ret;
3362         zfs_handle_t *pzhp;
3363         promote_data_t pd;
3364         char errbuf[1024];
3365
3366         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3367             "cannot promote '%s'"), zhp->zfs_name);
3368
3369         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3370                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3371                     "snapshots can not be promoted"));
3372                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3373         }
3374
3375         (void) strlcpy(parent, zhp->zfs_dmustats.dds_origin, sizeof (parent));
3376         if (parent[0] == '\0') {
3377                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3378                     "not a cloned filesystem"));
3379                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3380         }
3381         cp = strchr(parent, '@');
3382         *cp = '\0';
3383
3384         /* Walk the snapshots we will be moving */
3385         pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
3386         if (pzhp == NULL)
3387                 return (-1);
3388         pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
3389         zfs_close(pzhp);
3390         pd.cb_target = zhp->zfs_name;
3391         pd.cb_errbuf = errbuf;
3392         pzhp = zfs_open(hdl, parent, ZFS_TYPE_DATASET);
3393         if (pzhp == NULL)
3394                 return (-1);
3395         (void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
3396             sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
3397         ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
3398         if (ret != 0) {
3399                 zfs_close(pzhp);
3400                 return (-1);
3401         }
3402
3403         /* issue the ioctl */
3404         (void) strlcpy(zc.zc_value, zhp->zfs_dmustats.dds_origin,
3405             sizeof (zc.zc_value));
3406         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3407         ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
3408
3409         if (ret != 0) {
3410                 int save_errno = errno;
3411
3412                 (void) zfs_iter_snapshots(pzhp, promote_snap_done_cb, &pd);
3413                 zfs_close(pzhp);
3414
3415                 switch (save_errno) {
3416                 case EEXIST:
3417                         /*
3418                          * There is a conflicting snapshot name.  We
3419                          * should have caught this above, but they could
3420                          * have renamed something in the mean time.
3421                          */
3422                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3423                             "conflicting snapshot name from parent '%s'"),
3424                             parent);
3425                         return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3426
3427                 default:
3428                         return (zfs_standard_error(hdl, save_errno, errbuf));
3429                 }
3430         } else {
3431                 (void) zfs_iter_snapshots(zhp, promote_snap_done_cb, &pd);
3432         }
3433
3434         zfs_close(pzhp);
3435         return (ret);
3436 }
3437
3438 struct createdata {
3439         const char *cd_snapname;
3440         int cd_ifexists;
3441 };
3442
3443 static int
3444 zfs_create_link_cb(zfs_handle_t *zhp, void *arg)
3445 {
3446         struct createdata *cd = arg;
3447         int ret;
3448
3449         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3450                 char name[MAXPATHLEN];
3451
3452                 (void) strlcpy(name, zhp->zfs_name, sizeof (name));
3453                 (void) strlcat(name, "@", sizeof (name));
3454                 (void) strlcat(name, cd->cd_snapname, sizeof (name));
3455                 (void) zvol_create_link_common(zhp->zfs_hdl, name,
3456                     cd->cd_ifexists);
3457                 /*
3458                  * NB: this is simply a best-effort.  We don't want to
3459                  * return an error, because then we wouldn't visit all
3460                  * the volumes.
3461                  */
3462         }
3463
3464         ret = zfs_iter_filesystems(zhp, zfs_create_link_cb, cd);
3465
3466         zfs_close(zhp);
3467
3468         return (ret);
3469 }
3470
3471 /*
3472  * Takes a snapshot of the given dataset.
3473  */
3474 int
3475 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3476     nvlist_t *props)
3477 {
3478         const char *delim;
3479         char parent[ZFS_MAXNAMELEN];
3480         zfs_handle_t *zhp;
3481         zfs_cmd_t zc = { 0 };
3482         int ret;
3483         char errbuf[1024];
3484
3485         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3486             "cannot snapshot '%s'"), path);
3487
3488         /* validate the target name */
3489         if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3490                 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3491
3492         if (props) {
3493                 if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3494                     props, B_FALSE, NULL, errbuf)) == NULL)
3495                         return (-1);
3496
3497                 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3498                         nvlist_free(props);
3499                         return (-1);
3500                 }
3501
3502                 nvlist_free(props);
3503         }
3504
3505         /* make sure the parent exists and is of the appropriate type */
3506         delim = strchr(path, '@');
3507         (void) strncpy(parent, path, delim - path);
3508         parent[delim - path] = '\0';
3509
3510         if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
3511             ZFS_TYPE_VOLUME)) == NULL) {
3512                 zcmd_free_nvlists(&zc);
3513                 return (-1);
3514         }
3515
3516         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3517         (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
3518         if (ZFS_IS_VOLUME(zhp))
3519                 zc.zc_objset_type = DMU_OST_ZVOL;
3520         else
3521                 zc.zc_objset_type = DMU_OST_ZFS;
3522         zc.zc_cookie = recursive;
3523         ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc);
3524
3525         zcmd_free_nvlists(&zc);
3526
3527         /*
3528          * if it was recursive, the one that actually failed will be in
3529          * zc.zc_name.
3530          */
3531         if (ret != 0)
3532                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3533                     "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
3534
3535         if (ret == 0 && recursive) {
3536                 struct createdata cd;
3537
3538                 cd.cd_snapname = delim + 1;
3539                 cd.cd_ifexists = B_FALSE;
3540                 (void) zfs_iter_filesystems(zhp, zfs_create_link_cb, &cd);
3541         }
3542         if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
3543                 ret = zvol_create_link(zhp->zfs_hdl, path);
3544                 if (ret != 0) {
3545                         (void) zfs_standard_error(hdl, errno,
3546                             dgettext(TEXT_DOMAIN,
3547                             "Volume successfully snapshotted, but device links "
3548                             "were not created"));
3549                         zfs_close(zhp);
3550                         return (-1);
3551                 }
3552         }
3553
3554         if (ret != 0)
3555                 (void) zfs_standard_error(hdl, errno, errbuf);
3556
3557         zfs_close(zhp);
3558
3559         return (ret);
3560 }
3561
3562 /*
3563  * Destroy any more recent snapshots.  We invoke this callback on any dependents
3564  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
3565  * is a dependent and we should just destroy it without checking the transaction
3566  * group.
3567  */
3568 typedef struct rollback_data {
3569         const char      *cb_target;             /* the snapshot */
3570         uint64_t        cb_create;              /* creation time reference */
3571         boolean_t       cb_error;
3572         boolean_t       cb_dependent;
3573         boolean_t       cb_force;
3574 } rollback_data_t;
3575
3576 static int
3577 rollback_destroy(zfs_handle_t *zhp, void *data)
3578 {
3579         rollback_data_t *cbp = data;
3580
3581         if (!cbp->cb_dependent) {
3582                 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
3583                     zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
3584                     zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
3585                     cbp->cb_create) {
3586                         char *logstr;
3587
3588                         cbp->cb_dependent = B_TRUE;
3589                         cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3590                             rollback_destroy, cbp);
3591                         cbp->cb_dependent = B_FALSE;
3592
3593                         logstr = zhp->zfs_hdl->libzfs_log_str;
3594                         zhp->zfs_hdl->libzfs_log_str = NULL;
3595                         cbp->cb_error |= zfs_destroy(zhp);
3596                         zhp->zfs_hdl->libzfs_log_str = logstr;
3597                 }
3598         } else {
3599                 /* We must destroy this clone; first unmount it */
3600                 prop_changelist_t *clp;
3601
3602                 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3603                     cbp->cb_force ? MS_FORCE: 0);
3604                 if (clp == NULL || changelist_prefix(clp) != 0) {
3605                         cbp->cb_error = B_TRUE;
3606                         zfs_close(zhp);
3607                         return (0);
3608                 }
3609                 if (zfs_destroy(zhp) != 0)
3610                         cbp->cb_error = B_TRUE;
3611                 else
3612                         changelist_remove(clp, zhp->zfs_name);
3613                 (void) changelist_postfix(clp);
3614                 changelist_free(clp);
3615         }
3616
3617         zfs_close(zhp);
3618         return (0);
3619 }
3620
3621 /*
3622  * Given a dataset, rollback to a specific snapshot, discarding any
3623  * data changes since then and making it the active dataset.
3624  *
3625  * Any snapshots more recent than the target are destroyed, along with
3626  * their dependents.
3627  */
3628 int
3629 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
3630 {
3631         rollback_data_t cb = { 0 };
3632         int err;
3633         zfs_cmd_t zc = { 0 };
3634         boolean_t restore_resv = 0;
3635         uint64_t old_volsize, new_volsize;
3636         zfs_prop_t resv_prop;
3637
3638         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
3639             zhp->zfs_type == ZFS_TYPE_VOLUME);
3640
3641         /*
3642          * Destroy all recent snapshots and its dependends.
3643          */
3644         cb.cb_force = force;
3645         cb.cb_target = snap->zfs_name;
3646         cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
3647         (void) zfs_iter_children(zhp, rollback_destroy, &cb);
3648
3649         if (cb.cb_error)
3650                 return (-1);
3651
3652         /*
3653          * Now that we have verified that the snapshot is the latest,
3654          * rollback to the given snapshot.
3655          */
3656
3657         if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
3658                 if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
3659                         return (-1);
3660                 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
3661                         return (-1);
3662                 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3663                 restore_resv =
3664                     (old_volsize == zfs_prop_get_int(zhp, resv_prop));
3665         }
3666
3667         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3668
3669         if (ZFS_IS_VOLUME(zhp))
3670                 zc.zc_objset_type = DMU_OST_ZVOL;
3671         else
3672                 zc.zc_objset_type = DMU_OST_ZFS;
3673
3674         /*
3675          * We rely on zfs_iter_children() to verify that there are no
3676          * newer snapshots for the given dataset.  Therefore, we can
3677          * simply pass the name on to the ioctl() call.  There is still
3678          * an unlikely race condition where the user has taken a
3679          * snapshot since we verified that this was the most recent.
3680          *
3681          */
3682         if ((err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_ROLLBACK, &zc)) != 0) {
3683                 (void) zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3684                     dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
3685                     zhp->zfs_name);
3686                 return (err);
3687         }
3688
3689         /*
3690          * For volumes, if the pre-rollback volsize matched the pre-
3691          * rollback reservation and the volsize has changed then set
3692          * the reservation property to the post-rollback volsize.
3693          * Make a new handle since the rollback closed the dataset.
3694          */
3695         if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
3696             (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
3697                 if (err = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name)) {
3698                         zfs_close(zhp);
3699                         return (err);
3700                 }
3701                 if (restore_resv) {
3702                         new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
3703                         if (old_volsize != new_volsize)
3704                                 err = zfs_prop_set_int(zhp, resv_prop,
3705                                     new_volsize);
3706                 }
3707                 zfs_close(zhp);
3708         }
3709         return (err);
3710 }
3711
3712 /*
3713  * Iterate over all dependents for a given dataset.  This includes both
3714  * hierarchical dependents (children) and data dependents (snapshots and
3715  * clones).  The bulk of the processing occurs in get_dependents() in
3716  * libzfs_graph.c.
3717  */
3718 int
3719 zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
3720     zfs_iter_f func, void *data)
3721 {
3722         char **dependents;
3723         size_t count;
3724         int i;
3725         zfs_handle_t *child;
3726         int ret = 0;
3727
3728         if (get_dependents(zhp->zfs_hdl, allowrecursion, zhp->zfs_name,
3729             &dependents, &count) != 0)
3730                 return (-1);
3731
3732         for (i = 0; i < count; i++) {
3733                 if ((child = make_dataset_handle(zhp->zfs_hdl,
3734                     dependents[i])) == NULL)
3735                         continue;
3736
3737                 if ((ret = func(child, data)) != 0)
3738                         break;
3739         }
3740
3741         for (i = 0; i < count; i++)
3742                 free(dependents[i]);
3743         free(dependents);
3744
3745         return (ret);
3746 }
3747
3748 /*
3749  * Renames the given dataset.
3750  */
3751 int
3752 zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive)
3753 {
3754         int ret;
3755         zfs_cmd_t zc = { 0 };
3756         char *delim;
3757         prop_changelist_t *cl = NULL;
3758         zfs_handle_t *zhrp = NULL;
3759         char *parentname = NULL;
3760         char parent[ZFS_MAXNAMELEN];
3761         libzfs_handle_t *hdl = zhp->zfs_hdl;
3762         char errbuf[1024];
3763
3764         /* if we have the same exact name, just return success */
3765         if (strcmp(zhp->zfs_name, target) == 0)
3766                 return (0);
3767
3768         (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3769             "cannot rename to '%s'"), target);
3770
3771         /*
3772          * Make sure the target name is valid
3773          */
3774         if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3775                 if ((strchr(target, '@') == NULL) ||
3776                     *target == '@') {
3777                         /*
3778                          * Snapshot target name is abbreviated,
3779                          * reconstruct full dataset name
3780                          */
3781                         (void) strlcpy(parent, zhp->zfs_name,
3782                             sizeof (parent));
3783                         delim = strchr(parent, '@');
3784                         if (strchr(target, '@') == NULL)
3785                                 *(++delim) = '\0';
3786                         else
3787                                 *delim = '\0';
3788                         (void) strlcat(parent, target, sizeof (parent));
3789                         target = parent;
3790                 } else {
3791                         /*
3792                          * Make sure we're renaming within the same dataset.
3793                          */
3794                         delim = strchr(target, '@');
3795                         if (strncmp(zhp->zfs_name, target, delim - target)
3796                             != 0 || zhp->zfs_name[delim - target] != '@') {
3797                                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3798                                     "snapshots must be part of same "
3799                                     "dataset"));
3800                                 return (zfs_error(hdl, EZFS_CROSSTARGET,
3801                                     errbuf));
3802                         }
3803                 }
3804                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3805                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3806         } else {
3807                 if (recursive) {
3808                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3809                             "recursive rename must be a snapshot"));
3810                         return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3811                 }
3812
3813                 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
3814                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3815                 uint64_t unused;
3816
3817                 /* validate parents */
3818                 if (check_parents(hdl, target, &unused, B_FALSE, NULL) != 0)
3819                         return (-1);
3820
3821                 (void) parent_name(target, parent, sizeof (parent));
3822
3823                 /* make sure we're in the same pool */
3824                 verify((delim = strchr(target, '/')) != NULL);
3825                 if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
3826                     zhp->zfs_name[delim - target] != '/') {
3827                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3828                             "datasets must be within same pool"));
3829                         return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
3830                 }
3831
3832                 /* new name cannot be a child of the current dataset name */
3833                 if (strncmp(parent, zhp->zfs_name,
3834                     strlen(zhp->zfs_name)) == 0) {
3835                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3836                             "New dataset name cannot be a descendent of "
3837                             "current dataset name"));
3838                         return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3839                 }
3840         }
3841
3842         (void) snprintf(errbuf, sizeof (errbuf),
3843             dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
3844
3845         if (getzoneid() == GLOBAL_ZONEID &&
3846             zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
3847                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3848                     "dataset is used in a non-global zone"));
3849                 return (zfs_error(hdl, EZFS_ZONED, errbuf));
3850         }
3851
3852         if (recursive) {
3853                 struct destroydata dd;
3854
3855                 parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
3856                 if (parentname == NULL) {
3857                         ret = -1;
3858                         goto error;
3859                 }
3860                 delim = strchr(parentname, '@');
3861                 *delim = '\0';
3862                 zhrp = zfs_open(zhp->zfs_hdl, parentname, ZFS_TYPE_DATASET);
3863                 if (zhrp == NULL) {
3864                         ret = -1;
3865                         goto error;
3866                 }
3867
3868                 dd.snapname = delim + 1;
3869                 dd.gotone = B_FALSE;
3870                 dd.closezhp = B_TRUE;
3871
3872                 /* We remove any zvol links prior to renaming them */
3873                 ret = zfs_iter_filesystems(zhrp, zfs_remove_link_cb, &dd);
3874                 if (ret) {
3875                         goto error;
3876                 }
3877         } else {
3878                 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0)) == NULL)
3879                         return (-1);
3880
3881                 if (changelist_haszonedchild(cl)) {
3882                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3883                             "child dataset with inherited mountpoint is used "
3884                             "in a non-global zone"));
3885                         (void) zfs_error(hdl, EZFS_ZONED, errbuf);
3886                         goto error;
3887                 }
3888
3889                 if ((ret = changelist_prefix(cl)) != 0)
3890                         goto error;
3891         }
3892
3893         if (ZFS_IS_VOLUME(zhp))
3894                 zc.zc_objset_type = DMU_OST_ZVOL;
3895         else
3896                 zc.zc_objset_type = DMU_OST_ZFS;
3897
3898         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3899         (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
3900
3901         zc.zc_cookie = recursive;
3902
3903         if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
3904                 /*
3905                  * if it was recursive, the one that actually failed will
3906                  * be in zc.zc_name
3907                  */
3908                 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3909                     "cannot rename '%s'"), zc.zc_name);
3910
3911                 if (recursive && errno == EEXIST) {
3912                         zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3913                             "a child dataset already has a snapshot "
3914                             "with the new name"));
3915                         (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3916                 } else {
3917                         (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
3918                 }
3919
3920                 /*
3921                  * On failure, we still want to remount any filesystems that
3922                  * were previously mounted, so we don't alter the system state.
3923                  */
3924                 if (recursive) {
3925                         struct createdata cd;
3926
3927                         /* only create links for datasets that had existed */
3928                         cd.cd_snapname = delim + 1;
3929                         cd.cd_ifexists = B_TRUE;
3930                         (void) zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3931                             &cd);
3932                 } else {
3933                         (void) changelist_postfix(cl);
3934                 }
3935         } else {
3936                 if (recursive) {
3937                         struct createdata cd;
3938
3939                         /* only create links for datasets that had existed */
3940                         cd.cd_snapname = strchr(target, '@') + 1;
3941                         cd.cd_ifexists = B_TRUE;
3942                         ret = zfs_iter_filesystems(zhrp, zfs_create_link_cb,
3943                             &cd);
3944                 } else {
3945                         changelist_rename(cl, zfs_get_name(zhp), target);
3946                         ret = changelist_postfix(cl);
3947                 }
3948         }
3949
3950 error:
3951         if (parentname) {
3952                 free(parentname);
3953         }
3954         if (zhrp) {
3955                 zfs_close(zhrp);
3956         }
3957         if (cl) {
3958                 changelist_free(cl);
3959         }
3960         return (ret);
3961 }
3962
3963 /*
3964  * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
3965  * poke devfsadm to create the /dev link, and then wait for the link to appear.
3966  */
3967 int
3968 zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
3969 {
3970         return (zvol_create_link_common(hdl, dataset, B_FALSE));
3971 }
3972
3973 static int
3974 zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
3975 {
3976         zfs_cmd_t zc = { 0 };
3977 #if 0
3978         di_devlink_handle_t dhdl;
3979         priv_set_t *priv_effective;
3980         int privileged;
3981 #endif
3982
3983         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
3984
3985         /*
3986          * Issue the appropriate ioctl.
3987          */
3988         if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
3989                 switch (errno) {
3990                 case EEXIST:
3991                         /*
3992                          * Silently ignore the case where the link already
3993                          * exists.  This allows 'zfs volinit' to be run multiple
3994                          * times without errors.
3995                          */
3996                         return (0);
3997
3998                 case ENOENT:
3999                         /*
4000                          * Dataset does not exist in the kernel.  If we
4001                          * don't care (see zfs_rename), then ignore the
4002                          * error quietly.
4003                          */
4004                         if (ifexists) {
4005                                 return (0);
4006                         }
4007
4008                         /* FALLTHROUGH */
4009
4010                 default:
4011                         return (zfs_standard_error_fmt(hdl, errno,
4012                             dgettext(TEXT_DOMAIN, "cannot create device links "
4013                             "for '%s'"), dataset));
4014                 }
4015         }
4016
4017 #if 0
4018         /*
4019          * If privileged call devfsadm and wait for the links to
4020          * magically appear.
4021          * Otherwise, print out an informational message.
4022          */
4023
4024         priv_effective = priv_allocset();
4025         (void) getppriv(PRIV_EFFECTIVE, priv_effective);
4026         privileged = (priv_isfullset(priv_effective) == B_TRUE);
4027         priv_freeset(priv_effective);
4028
4029         if (privileged) {
4030                 if ((dhdl = di_devlink_init(ZFS_DRIVER,
4031                     DI_MAKE_LINK)) == NULL) {
4032                         zfs_error_aux(hdl, strerror(errno));
4033                         (void) zfs_error_fmt(hdl, errno,
4034                             dgettext(TEXT_DOMAIN, "cannot create device links "
4035                             "for '%s'"), dataset);
4036                         (void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
4037                         return (-1);
4038                 } else {
4039                         (void) di_devlink_fini(&dhdl);
4040                 }
4041         } else {
4042                 char pathname[MAXPATHLEN];
4043                 struct stat64 statbuf;
4044                 int i;
4045
4046 #define MAX_WAIT        10
4047
4048                 /*
4049                  * This is the poor mans way of waiting for the link
4050                  * to show up.  If after 10 seconds we still don't
4051                  * have it, then print out a message.
4052                  */
4053                 (void) snprintf(pathname, sizeof (pathname), "/dev/zvol/dsk/%s",
4054                     dataset);
4055
4056                 for (i = 0; i != MAX_WAIT; i++) {
4057                         if (stat64(pathname, &statbuf) == 0)
4058                                 break;
4059                         (void) sleep(1);
4060                 }
4061                 if (i == MAX_WAIT)
4062                         (void) printf(gettext("%s may not be immediately "
4063                             "available\n"), pathname);
4064         }
4065 #endif
4066
4067         return (0);
4068 }
4069
4070 /*
4071  * Remove a minor node for the given zvol and the associated /dev links.
4072  */
4073 int
4074 zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
4075 {
4076         zfs_cmd_t zc = { 0 };
4077
4078         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4079
4080         if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
4081                 switch (errno) {
4082                 case ENXIO:
4083                         /*
4084                          * Silently ignore the case where the link no longer
4085                          * exists, so that 'zfs volfini' can be run multiple
4086                          * times without errors.
4087                          */
4088                         return (0);
4089
4090                 default:
4091                         return (zfs_standard_error_fmt(hdl, errno,
4092                             dgettext(TEXT_DOMAIN, "cannot remove device "
4093                             "links for '%s'"), dataset));
4094                 }
4095         }
4096
4097         return (0);
4098 }
4099
4100 nvlist_t *
4101 zfs_get_user_props(zfs_handle_t *zhp)
4102 {
4103         return (zhp->zfs_user_props);
4104 }
4105
4106 /*
4107  * This function is used by 'zfs list' to determine the exact set of columns to
4108  * display, and their maximum widths.  This does two main things:
4109  *
4110  *      - If this is a list of all properties, then expand the list to include
4111  *        all native properties, and set a flag so that for each dataset we look
4112  *        for new unique user properties and add them to the list.
4113  *
4114  *      - For non fixed-width properties, keep track of the maximum width seen
4115  *        so that we can size the column appropriately.
4116  */
4117 int
4118 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp)
4119 {
4120         libzfs_handle_t *hdl = zhp->zfs_hdl;
4121         zprop_list_t *entry;
4122         zprop_list_t **last, **start;
4123         nvlist_t *userprops, *propval;
4124         nvpair_t *elem;
4125         char *strval;
4126         char buf[ZFS_MAXPROPLEN];
4127
4128         if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
4129                 return (-1);
4130
4131         userprops = zfs_get_user_props(zhp);
4132
4133         entry = *plp;
4134         if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
4135                 /*
4136                  * Go through and add any user properties as necessary.  We
4137                  * start by incrementing our list pointer to the first
4138                  * non-native property.
4139                  */
4140                 start = plp;
4141                 while (*start != NULL) {
4142                         if ((*start)->pl_prop == ZPROP_INVAL)
4143                                 break;
4144                         start = &(*start)->pl_next;
4145                 }
4146
4147                 elem = NULL;
4148                 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
4149                         /*
4150                          * See if we've already found this property in our list.
4151                          */
4152                         for (last = start; *last != NULL;
4153                             last = &(*last)->pl_next) {
4154                                 if (strcmp((*last)->pl_user_prop,
4155                                     nvpair_name(elem)) == 0)
4156                                         break;
4157                         }
4158
4159                         if (*last == NULL) {
4160                                 if ((entry = zfs_alloc(hdl,
4161                                     sizeof (zprop_list_t))) == NULL ||
4162                                     ((entry->pl_user_prop = zfs_strdup(hdl,
4163                                     nvpair_name(elem)))) == NULL) {
4164                                         free(entry);
4165                                         return (-1);
4166                                 }
4167
4168                                 entry->pl_prop = ZPROP_INVAL;
4169                                 entry->pl_width = strlen(nvpair_name(elem));
4170                                 entry->pl_all = B_TRUE;
4171                                 *last = entry;
4172                         }
4173                 }
4174         }
4175
4176         /*
4177          * Now go through and check the width of any non-fixed columns
4178          */
4179         for (entry = *plp; entry != NULL; entry = entry->pl_next) {
4180                 if (entry->pl_fixed)
4181                         continue;
4182
4183                 if (entry->pl_prop != ZPROP_INVAL) {
4184                         if (zfs_prop_get(zhp, entry->pl_prop,
4185                             buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
4186                                 if (strlen(buf) > entry->pl_width)
4187                                         entry->pl_width = strlen(buf);
4188                         }
4189                 } else if (nvlist_lookup_nvlist(userprops,
4190                     entry->pl_user_prop, &propval)  == 0) {
4191                         verify(nvlist_lookup_string(propval,
4192                             ZPROP_VALUE, &strval) == 0);
4193                         if (strlen(strval) > entry->pl_width)
4194                                 entry->pl_width = strlen(strval);
4195                 }
4196         }
4197
4198         return (0);
4199 }
4200
4201 #ifdef TODO
4202 int
4203 zfs_iscsi_perm_check(libzfs_handle_t *hdl, char *dataset, ucred_t *cred)
4204 {
4205         zfs_cmd_t zc = { 0 };
4206         nvlist_t *nvp;
4207         gid_t gid;
4208         uid_t uid;
4209         const gid_t *groups;
4210         int group_cnt;
4211         int error;
4212
4213         if (nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0) != 0)
4214                 return (no_memory(hdl));
4215
4216         uid = ucred_geteuid(cred);
4217         gid = ucred_getegid(cred);
4218         group_cnt = ucred_getgroups(cred, &groups);
4219
4220         if (uid == (uid_t)-1 || gid == (uid_t)-1 || group_cnt == (uid_t)-1)
4221                 return (1);
4222
4223         if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_UID, uid) != 0) {
4224                 nvlist_free(nvp);
4225                 return (1);
4226         }
4227
4228         if (nvlist_add_uint32(nvp, ZFS_DELEG_PERM_GID, gid) != 0) {
4229                 nvlist_free(nvp);
4230                 return (1);
4231         }
4232
4233         if (nvlist_add_uint32_array(nvp,
4234             ZFS_DELEG_PERM_GROUPS, (uint32_t *)groups, group_cnt) != 0) {
4235                 nvlist_free(nvp);
4236                 return (1);
4237         }
4238         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4239
4240         if (zcmd_write_src_nvlist(hdl, &zc, nvp))
4241                 return (-1);
4242
4243         error = ioctl(hdl->libzfs_fd, ZFS_IOC_ISCSI_PERM_CHECK, &zc);
4244         nvlist_free(nvp);
4245         return (error);
4246 }
4247 #endif
4248
4249 int
4250 zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path,
4251     void *export, void *sharetab, int sharemax, zfs_share_op_t operation)
4252 {
4253         zfs_cmd_t zc = { 0 };
4254         int error;
4255
4256         (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4257         (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4258         zc.zc_share.z_sharedata = (uint64_t)(uintptr_t)sharetab;
4259         zc.zc_share.z_exportdata = (uint64_t)(uintptr_t)export;
4260         zc.zc_share.z_sharetype = operation;
4261         zc.zc_share.z_sharemax = sharemax;
4262
4263         error = ioctl(hdl->libzfs_fd, ZFS_IOC_SHARE, &zc);
4264         return (error);
4265 }
4266
4267 /*
4268  * Attach/detach the given filesystem to/from the given jail.
4269  */
4270 int
4271 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
4272 {
4273         libzfs_handle_t *hdl = zhp->zfs_hdl;
4274         zfs_cmd_t zc = { 0 };
4275         char errbuf[1024];
4276         int cmd, ret;
4277
4278         if (attach) {
4279                 (void) snprintf(errbuf, sizeof (errbuf),
4280                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
4281         } else {
4282                 (void) snprintf(errbuf, sizeof (errbuf),
4283                     dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
4284         }
4285
4286         switch (zhp->zfs_type) {
4287         case ZFS_TYPE_VOLUME:
4288                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4289                     "volumes can not be jailed"));
4290                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4291         case ZFS_TYPE_SNAPSHOT:
4292                 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4293                     "snapshots can not be jailed"));
4294                 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4295         }
4296         assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
4297
4298         (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4299         zc.zc_objset_type = DMU_OST_ZFS;
4300         zc.zc_jailid = jailid;
4301
4302         cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
4303         if ((ret = ioctl(hdl->libzfs_fd, cmd, &zc)) != 0)
4304                 zfs_standard_error(hdl, errno, errbuf);
4305
4306         return (ret);
4307 }