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