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