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