xref: /titanic_41/usr/src/lib/libzfs/common/libzfs_dataset.c (revision 28cdc3d776761766afeb198769d1b70ed7e0f2e1)
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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <assert.h>
29 #include <ctype.h>
30 #include <errno.h>
31 #include <libdevinfo.h>
32 #include <libintl.h>
33 #include <math.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <strings.h>
37 #include <unistd.h>
38 #include <zone.h>
39 #include <fcntl.h>
40 #include <sys/mntent.h>
41 #include <sys/mnttab.h>
42 #include <sys/mount.h>
43 
44 #include <sys/spa.h>
45 #include <sys/zio.h>
46 #include <libzfs.h>
47 
48 #include "zfs_namecheck.h"
49 #include "zfs_prop.h"
50 #include "libzfs_impl.h"
51 
52 /*
53  * Given a single type (not a mask of types), return the type in a human
54  * readable form.
55  */
56 const char *
57 zfs_type_to_name(zfs_type_t type)
58 {
59 	switch (type) {
60 	case ZFS_TYPE_FILESYSTEM:
61 		return (dgettext(TEXT_DOMAIN, "filesystem"));
62 	case ZFS_TYPE_SNAPSHOT:
63 		return (dgettext(TEXT_DOMAIN, "snapshot"));
64 	case ZFS_TYPE_VOLUME:
65 		return (dgettext(TEXT_DOMAIN, "volume"));
66 	}
67 
68 	return (NULL);
69 }
70 
71 /*
72  * Given a path and mask of ZFS types, return a string describing this dataset.
73  * This is used when we fail to open a dataset and we cannot get an exact type.
74  * We guess what the type would have been based on the path and the mask of
75  * acceptable types.
76  */
77 static const char *
78 path_to_str(const char *path, int types)
79 {
80 	/*
81 	 * When given a single type, always report the exact type.
82 	 */
83 	if (types == ZFS_TYPE_SNAPSHOT)
84 		return (dgettext(TEXT_DOMAIN, "snapshot"));
85 	if (types == ZFS_TYPE_FILESYSTEM)
86 		return (dgettext(TEXT_DOMAIN, "filesystem"));
87 	if (types == ZFS_TYPE_VOLUME)
88 		return (dgettext(TEXT_DOMAIN, "volume"));
89 
90 	/*
91 	 * The user is requesting more than one type of dataset.  If this is the
92 	 * case, consult the path itself.  If we're looking for a snapshot, and
93 	 * a '@' is found, then report it as "snapshot".  Otherwise, remove the
94 	 * snapshot attribute and try again.
95 	 */
96 	if (types & ZFS_TYPE_SNAPSHOT) {
97 		if (strchr(path, '@') != NULL)
98 			return (dgettext(TEXT_DOMAIN, "snapshot"));
99 		return (path_to_str(path, types & ~ZFS_TYPE_SNAPSHOT));
100 	}
101 
102 
103 	/*
104 	 * The user has requested either filesystems or volumes.
105 	 * We have no way of knowing a priori what type this would be, so always
106 	 * report it as "filesystem" or "volume", our two primitive types.
107 	 */
108 	if (types & ZFS_TYPE_FILESYSTEM)
109 		return (dgettext(TEXT_DOMAIN, "filesystem"));
110 
111 	assert(types & ZFS_TYPE_VOLUME);
112 	return (dgettext(TEXT_DOMAIN, "volume"));
113 }
114 
115 /*
116  * Validate a ZFS path.  This is used even before trying to open the dataset, to
117  * provide a more meaningful error message.  We place a more useful message in
118  * 'buf' detailing exactly why the name was not valid.
119  */
120 static int
121 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type)
122 {
123 	namecheck_err_t why;
124 	char what;
125 
126 	if (dataset_namecheck(path, &why, &what) != 0) {
127 		if (hdl != NULL) {
128 			switch (why) {
129 			case NAME_ERR_TOOLONG:
130 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
131 				    "name is too long"));
132 				break;
133 
134 			case NAME_ERR_LEADING_SLASH:
135 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
136 				    "leading slash in name"));
137 				break;
138 
139 			case NAME_ERR_EMPTY_COMPONENT:
140 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
141 				    "empty component in name"));
142 				break;
143 
144 			case NAME_ERR_TRAILING_SLASH:
145 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
146 				    "trailing slash in name"));
147 				break;
148 
149 			case NAME_ERR_INVALCHAR:
150 				zfs_error_aux(hdl,
151 				    dgettext(TEXT_DOMAIN, "invalid character "
152 				    "'%c' in name"), what);
153 				break;
154 
155 			case NAME_ERR_MULTIPLE_AT:
156 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
157 				    "multiple '@' delimiters in name"));
158 				break;
159 			}
160 		}
161 
162 		return (0);
163 	}
164 
165 	if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
166 		if (hdl != NULL)
167 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
168 			    "snapshot delimiter '@' in filesystem name"));
169 		return (0);
170 	}
171 
172 	return (-1);
173 }
174 
175 int
176 zfs_name_valid(const char *name, zfs_type_t type)
177 {
178 	return (zfs_validate_name(NULL, name, type));
179 }
180 
181 /*
182  * Utility function to gather stats (objset and zpl) for the given object.
183  */
184 static int
185 get_stats(zfs_handle_t *zhp)
186 {
187 	zfs_cmd_t zc = { 0 };
188 
189 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
190 
191 	if ((zc.zc_config_src = (uint64_t)(uintptr_t)malloc(1024)) == NULL)
192 		return (-1);
193 	zc.zc_config_src_size = 1024;
194 
195 	while (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
196 		if (errno == ENOMEM) {
197 			free((void *)(uintptr_t)zc.zc_config_src);
198 			if ((zc.zc_config_src = (uint64_t)(uintptr_t)
199 			    malloc(zc.zc_config_src_size)) == NULL)
200 				return (-1);
201 		} else {
202 			free((void *)(uintptr_t)zc.zc_config_src);
203 			return (-1);
204 		}
205 	}
206 
207 	bcopy(&zc.zc_objset_stats, &zhp->zfs_dmustats,
208 	    sizeof (zc.zc_objset_stats));
209 
210 	(void) strcpy(zhp->zfs_root, zc.zc_root);
211 
212 	if (zhp->zfs_props) {
213 		nvlist_free(zhp->zfs_props);
214 		zhp->zfs_props = NULL;
215 	}
216 
217 	if (nvlist_unpack((void *)(uintptr_t)zc.zc_config_src,
218 	    zc.zc_config_src_size, &zhp->zfs_props, 0) != 0) {
219 		free((void *)(uintptr_t)zc.zc_config_src);
220 		return (-1);
221 	}
222 
223 	zhp->zfs_volsize = zc.zc_volsize;
224 	zhp->zfs_volblocksize = zc.zc_volblocksize;
225 
226 	free((void *)(uintptr_t)zc.zc_config_src);
227 
228 	return (0);
229 }
230 
231 /*
232  * Refresh the properties currently stored in the handle.
233  */
234 void
235 zfs_refresh_properties(zfs_handle_t *zhp)
236 {
237 	(void) get_stats(zhp);
238 }
239 
240 /*
241  * Makes a handle from the given dataset name.  Used by zfs_open() and
242  * zfs_iter_* to create child handles on the fly.
243  */
244 zfs_handle_t *
245 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
246 {
247 	zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
248 
249 	if (zhp == NULL)
250 		return (NULL);
251 
252 	zhp->zfs_hdl = hdl;
253 
254 top:
255 	(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
256 
257 	if (get_stats(zhp) != 0) {
258 		free(zhp);
259 		return (NULL);
260 	}
261 
262 	if (zhp->zfs_dmustats.dds_inconsistent) {
263 		zfs_cmd_t zc = { 0 };
264 
265 		/*
266 		 * If it is dds_inconsistent, then we've caught it in
267 		 * the middle of a 'zfs receive' or 'zfs destroy', and
268 		 * it is inconsistent from the ZPL's point of view, so
269 		 * can't be mounted.  However, it could also be that we
270 		 * have crashed in the middle of one of those
271 		 * operations, in which case we need to get rid of the
272 		 * inconsistent state.  We do that by either rolling
273 		 * back to the previous snapshot (which will fail if
274 		 * there is none), or destroying the filesystem.  Note
275 		 * that if we are still in the middle of an active
276 		 * 'receive' or 'destroy', then the rollback and destroy
277 		 * will fail with EBUSY and we will drive on as usual.
278 		 */
279 
280 		(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
281 
282 		if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
283 			(void) zvol_remove_link(hdl, zhp->zfs_name);
284 			zc.zc_objset_type = DMU_OST_ZVOL;
285 		} else {
286 			zc.zc_objset_type = DMU_OST_ZFS;
287 		}
288 
289 		/* If we can successfully roll it back, reget the stats */
290 		if (ioctl(hdl->libzfs_fd, ZFS_IOC_ROLLBACK, &zc) == 0)
291 			goto top;
292 		/*
293 		 * If we can sucessfully destroy it, pretend that it
294 		 * never existed.
295 		 */
296 		if (ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc) == 0) {
297 			free(zhp);
298 			errno = ENOENT;
299 			return (NULL);
300 		}
301 	}
302 
303 	/*
304 	 * We've managed to open the dataset and gather statistics.  Determine
305 	 * the high-level type.
306 	 */
307 	if (zhp->zfs_dmustats.dds_is_snapshot)
308 		zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
309 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
310 		zhp->zfs_type = ZFS_TYPE_VOLUME;
311 	else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
312 		zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
313 	else
314 		abort();	/* we should never see any other types */
315 
316 	return (zhp);
317 }
318 
319 /*
320  * Opens the given snapshot, filesystem, or volume.   The 'types'
321  * argument is a mask of acceptable types.  The function will print an
322  * appropriate error message and return NULL if it can't be opened.
323  */
324 zfs_handle_t *
325 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
326 {
327 	zfs_handle_t *zhp;
328 	char errbuf[1024];
329 
330 	(void) snprintf(errbuf, sizeof (errbuf),
331 	    dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
332 
333 	/*
334 	 * Validate the name before we even try to open it.
335 	 */
336 	if (!zfs_validate_name(hdl, path, ZFS_TYPE_ANY)) {
337 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
338 		    "invalid dataset name"));
339 		(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
340 		return (NULL);
341 	}
342 
343 	/*
344 	 * Try to get stats for the dataset, which will tell us if it exists.
345 	 */
346 	errno = 0;
347 	if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
348 		(void) zfs_standard_error(hdl, errno, errbuf, path);
349 		return (NULL);
350 	}
351 
352 	if (!(types & zhp->zfs_type)) {
353 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
354 		zfs_close(zhp);
355 		return (NULL);
356 	}
357 
358 	return (zhp);
359 }
360 
361 /*
362  * Release a ZFS handle.  Nothing to do but free the associated memory.
363  */
364 void
365 zfs_close(zfs_handle_t *zhp)
366 {
367 	if (zhp->zfs_mntopts)
368 		free(zhp->zfs_mntopts);
369 	if (zhp->zfs_props)
370 		nvlist_free(zhp->zfs_props);
371 	free(zhp);
372 }
373 
374 struct {
375 	const char *name;
376 	uint64_t value;
377 } checksum_table[] = {
378 	{ "on",		ZIO_CHECKSUM_ON },
379 	{ "off",	ZIO_CHECKSUM_OFF },
380 	{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
381 	{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
382 	{ "sha256",	ZIO_CHECKSUM_SHA256 },
383 	{ NULL }
384 };
385 
386 struct {
387 	const char *name;
388 	uint64_t value;
389 } compress_table[] = {
390 	{ "on",		ZIO_COMPRESS_ON },
391 	{ "off",	ZIO_COMPRESS_OFF },
392 	{ "lzjb",	ZIO_COMPRESS_LZJB },
393 	{ NULL }
394 };
395 
396 struct {
397 	const char *name;
398 	uint64_t value;
399 } snapdir_table[] = {
400 	{ "hidden",	ZFS_SNAPDIR_HIDDEN },
401 	{ "visible",	ZFS_SNAPDIR_VISIBLE },
402 	{ NULL }
403 };
404 
405 struct {
406 	const char *name;
407 	uint64_t value;
408 } acl_mode_table[] = {
409 	{ "discard",	DISCARD },
410 	{ "groupmask",	GROUPMASK },
411 	{ "passthrough", PASSTHROUGH },
412 	{ NULL }
413 };
414 
415 struct {
416 	const char *name;
417 	uint64_t value;
418 } acl_inherit_table[] = {
419 	{ "discard",	DISCARD },
420 	{ "noallow",	NOALLOW },
421 	{ "secure",	SECURE },
422 	{ "passthrough", PASSTHROUGH },
423 	{ NULL }
424 };
425 
426 
427 /*
428  * Given a numeric suffix, convert the value into a number of bits that the
429  * resulting value must be shifted.
430  */
431 static int
432 str2shift(libzfs_handle_t *hdl, const char *buf)
433 {
434 	const char *ends = "BKMGTPEZ";
435 	int i;
436 
437 	if (buf[0] == '\0')
438 		return (0);
439 	for (i = 0; i < strlen(ends); i++) {
440 		if (toupper(buf[0]) == ends[i])
441 			break;
442 	}
443 	if (i == strlen(ends)) {
444 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
445 		    "invalid numeric suffix '%s'"), buf);
446 		return (-1);
447 	}
448 
449 	/*
450 	 * We want to allow trailing 'b' characters for 'GB' or 'Mb'.  But don't
451 	 * allow 'BB' - that's just weird.
452 	 */
453 	if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
454 	    toupper(buf[0]) != 'B'))
455 		return (10*i);
456 
457 	zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
458 	    "invalid numeric suffix '%s'"), buf);
459 	return (-1);
460 }
461 
462 /*
463  * Convert a string of the form '100G' into a real number.  Used when setting
464  * properties or creating a volume.  'buf' is used to place an extended error
465  * message for the caller to use.
466  */
467 static int
468 nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
469 {
470 	char *end;
471 	int shift;
472 
473 	*num = 0;
474 
475 	/* Check to see if this looks like a number.  */
476 	if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
477 		if (hdl)
478 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
479 			    "bad numeric value '%s'"), value);
480 		return (-1);
481 	}
482 
483 	/* Rely on stroll() to process the numeric portion.  */
484 	errno = 0;
485 	*num = strtoll(value, &end, 10);
486 
487 	/*
488 	 * Check for ERANGE, which indicates that the value is too large to fit
489 	 * in a 64-bit value.
490 	 */
491 	if (errno == ERANGE) {
492 		if (hdl)
493 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
494 			    "numeric value is too large"));
495 		return (-1);
496 	}
497 
498 	/*
499 	 * If we have a decimal value, then do the computation with floating
500 	 * point arithmetic.  Otherwise, use standard arithmetic.
501 	 */
502 	if (*end == '.') {
503 		double fval = strtod(value, &end);
504 
505 		if ((shift = str2shift(hdl, end)) == -1)
506 			return (-1);
507 
508 		fval *= pow(2, shift);
509 
510 		if (fval > UINT64_MAX) {
511 			if (hdl)
512 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
513 				    "numeric value is too large"));
514 			return (-1);
515 		}
516 
517 		*num = (uint64_t)fval;
518 	} else {
519 		if ((shift = str2shift(hdl, end)) == -1)
520 			return (-1);
521 
522 		/* Check for overflow */
523 		if (shift >= 64 || (*num << shift) >> shift != *num) {
524 			if (hdl)
525 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
526 				    "numeric value is too large"));
527 			return (-1);
528 		}
529 
530 		*num <<= shift;
531 	}
532 
533 	return (0);
534 }
535 
536 int
537 zfs_nicestrtonum(const char *str, uint64_t *val)
538 {
539 	return (nicestrtonum(NULL, str, val));
540 }
541 
542 /*
543  * Given a property type and value, verify that the value is appropriate.  Used
544  * by zfs_prop_set() and some libzfs consumers.
545  */
546 int
547 zfs_prop_validate(libzfs_handle_t *hdl, zfs_prop_t prop, const char *value,
548     uint64_t *intval)
549 {
550 	const char *propname = zfs_prop_to_name(prop);
551 	uint64_t number;
552 	char errbuf[1024];
553 	int i;
554 
555 	/*
556 	 * Check to see if this a read-only property.
557 	 */
558 	if (zfs_prop_readonly(prop))
559 		return (zfs_error(hdl, EZFS_PROPREADONLY,
560 		    dgettext(TEXT_DOMAIN, "cannot set %s property"), propname));
561 
562 	(void) snprintf(errbuf, sizeof (errbuf),
563 	    dgettext(TEXT_DOMAIN, "bad %s value '%s'"), propname, value);
564 
565 	/* See if the property value is too long */
566 	if (strlen(value) >= ZFS_MAXPROPLEN) {
567 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "value is too long"));
568 		return (zfs_error(hdl, EZFS_BADPROP, errbuf));
569 	}
570 
571 	/* Perform basic checking based on property type */
572 	switch (zfs_prop_get_type(prop)) {
573 	case prop_type_boolean:
574 		if (strcmp(value, "on") == 0) {
575 			number = 1;
576 		} else if (strcmp(value, "off") == 0) {
577 			number = 0;
578 		} else {
579 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
580 			    "must be 'on' or 'off'"));
581 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
582 		}
583 		break;
584 
585 	case prop_type_number:
586 		/* treat 'none' as 0 */
587 		if (strcmp(value, "none") == 0) {
588 			number = 0;
589 			break;
590 		}
591 
592 		if (nicestrtonum(hdl, value, &number) != 0)
593 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
594 
595 		/* don't allow 0 for quota, use 'none' instead */
596 		if (prop == ZFS_PROP_QUOTA && number == 0 &&
597 		    strcmp(value, "none") != 0) {
598 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
599 			    "use 'quota=none' to disable"));
600 			return (zfs_error(hdl, EZFS_BADPROP, errbuf));
601 		}
602 
603 		/* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
604 		if (prop == ZFS_PROP_RECORDSIZE ||
605 		    prop == ZFS_PROP_VOLBLOCKSIZE) {
606 			if (number < SPA_MINBLOCKSIZE ||
607 			    number > SPA_MAXBLOCKSIZE || !ISP2(number)) {
608 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
609 				    "must be power of 2 from %u to %uk"),
610 				    (uint_t)SPA_MINBLOCKSIZE,
611 				    (uint_t)SPA_MAXBLOCKSIZE >> 10);
612 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
613 			}
614 		}
615 
616 		break;
617 
618 	case prop_type_string:
619 	case prop_type_index:
620 		/*
621 		 * The two writable string values, 'mountpoint' and
622 		 * 'checksum' need special consideration.  The 'index' types are
623 		 * specified as strings by the user, but passed to the kernel as
624 		 * integers.
625 		 */
626 		switch (prop) {
627 		case ZFS_PROP_MOUNTPOINT:
628 			if (strcmp(value, ZFS_MOUNTPOINT_NONE) == 0 ||
629 			    strcmp(value, ZFS_MOUNTPOINT_LEGACY) == 0)
630 				break;
631 
632 			if (value[0] != '/') {
633 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
634 				    "must be an absolute path, 'none', or "
635 				    "'legacy'"));
636 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
637 			}
638 			break;
639 
640 		case ZFS_PROP_CHECKSUM:
641 			for (i = 0; checksum_table[i].name != NULL; i++) {
642 				if (strcmp(value, checksum_table[i].name)
643 				    == 0) {
644 					number = checksum_table[i].value;
645 					break;
646 				}
647 			}
648 
649 			if (checksum_table[i].name == NULL) {
650 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
651 				    "must be 'on', 'off', 'fletcher2', "
652 				    "'fletcher4', or 'sha256'"));
653 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
654 			}
655 			break;
656 
657 		case ZFS_PROP_COMPRESSION:
658 			for (i = 0; compress_table[i].name != NULL; i++) {
659 				if (strcmp(value, compress_table[i].name)
660 				    == 0) {
661 					number = compress_table[i].value;
662 					break;
663 				}
664 			}
665 
666 			if (compress_table[i].name == NULL) {
667 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
668 				    "must be 'on', 'off', or 'lzjb'"));
669 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
670 			}
671 			break;
672 
673 		case ZFS_PROP_SNAPDIR:
674 			for (i = 0; snapdir_table[i].name != NULL; i++) {
675 				if (strcmp(value, snapdir_table[i].name) == 0) {
676 					number = snapdir_table[i].value;
677 					break;
678 				}
679 			}
680 
681 			if (snapdir_table[i].name == NULL) {
682 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
683 				    "must be 'hidden' or 'visible'"));
684 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
685 			}
686 			break;
687 
688 		case ZFS_PROP_ACLMODE:
689 			for (i = 0; acl_mode_table[i].name != NULL; i++) {
690 				if (strcmp(value, acl_mode_table[i].name)
691 				    == 0) {
692 					number = acl_mode_table[i].value;
693 					break;
694 				}
695 			}
696 
697 			if (acl_mode_table[i].name == NULL) {
698 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
699 				    "must be 'disacard', 'groupmask', or "
700 				    "'passthrough'"));
701 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
702 			}
703 			break;
704 
705 		case ZFS_PROP_ACLINHERIT:
706 			for (i = 0; acl_inherit_table[i].name != NULL; i++) {
707 				if (strcmp(value, acl_inherit_table[i].name)
708 				    == 0) {
709 					number = acl_inherit_table[i].value;
710 					break;
711 				}
712 			}
713 
714 			if (acl_inherit_table[i].name == NULL) {
715 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
716 				    "must be 'discard, 'noallow', 'secure', "
717 				    "or 'passthrough'"));
718 				return (zfs_error(hdl, EZFS_BADPROP, errbuf));
719 			}
720 			break;
721 
722 		case ZFS_PROP_SHARENFS:
723 			/*
724 			 * Nothing to do for 'sharenfs', this gets passed on to
725 			 * share(1M) verbatim.
726 			 */
727 			break;
728 		}
729 	}
730 
731 	if (intval != NULL)
732 		*intval = number;
733 
734 	return (0);
735 }
736 
737 /*
738  * Given a property name and value, set the property for the given dataset.
739  */
740 int
741 zfs_prop_set(zfs_handle_t *zhp, zfs_prop_t prop, const char *propval)
742 {
743 	const char *propname = zfs_prop_to_name(prop);
744 	uint64_t number;
745 	zfs_cmd_t zc = { 0 };
746 	int ret;
747 	prop_changelist_t *cl;
748 	char errbuf[1024];
749 	libzfs_handle_t *hdl = zhp->zfs_hdl;
750 
751 	if (zfs_prop_validate(zhp->zfs_hdl, prop, propval, &number) != 0)
752 		return (-1);
753 
754 
755 	(void) snprintf(errbuf, sizeof (errbuf),
756 	    dgettext(TEXT_DOMAIN, "cannot set %s for '%s'"), propname,
757 	    zhp->zfs_name);
758 
759 	/*
760 	 * Check to see if the value applies to this type
761 	 */
762 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
763 		return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
764 
765 	/*
766 	 * For the mountpoint and sharenfs properties, check if it can be set
767 	 * in a global/non-global zone based on the zoned property value:
768 	 *
769 	 *		global zone	    non-global zone
770 	 * -----------------------------------------------------
771 	 * zoned=on	mountpoint (no)	    mountpoint (yes)
772 	 *		sharenfs (no)	    sharenfs (no)
773 	 *
774 	 * zoned=off	mountpoint (yes)	N/A
775 	 *		sharenfs (yes)
776 	 */
777 	if (prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS) {
778 		if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
779 			if (getzoneid() == GLOBAL_ZONEID) {
780 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
781 				    "dataset is used in a non-global zone"));
782 				return (zfs_error(hdl, EZFS_ZONED, errbuf));
783 			} else if (prop == ZFS_PROP_SHARENFS) {
784 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
785 				    "filesystems cannot be shared in a "
786 				    "non-global zone"));
787 				return (zfs_error(hdl, EZFS_ZONED, errbuf));
788 			}
789 		} else if (getzoneid() != GLOBAL_ZONEID) {
790 			/*
791 			 * If zoned property is 'off', this must be in
792 			 * a globle zone. If not, something is wrong.
793 			 */
794 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
795 			    "dataset is used in a non-global zone, but "
796 			    "'zoned' property is not set"));
797 			return (zfs_error(hdl, EZFS_ZONED, errbuf));
798 		}
799 	}
800 
801 	if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
802 		return (-1);
803 
804 	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
805 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
806 		    "child dataset with inherited mountpoint is used "
807 		    "in a non-global zone"));
808 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
809 		goto error;
810 	}
811 
812 	if ((ret = changelist_prefix(cl)) != 0)
813 		goto error;
814 
815 	/*
816 	 * Execute the corresponding ioctl() to set this property.
817 	 */
818 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
819 
820 	switch (prop) {
821 	case ZFS_PROP_QUOTA:
822 		zc.zc_cookie = number;
823 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_QUOTA, &zc);
824 		break;
825 	case ZFS_PROP_RESERVATION:
826 		zc.zc_cookie = number;
827 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_RESERVATION,
828 		    &zc);
829 		break;
830 	case ZFS_PROP_MOUNTPOINT:
831 	case ZFS_PROP_SHARENFS:
832 		/*
833 		 * These properties are passed down as real strings.
834 		 */
835 		(void) strlcpy(zc.zc_prop_name, propname,
836 		    sizeof (zc.zc_prop_name));
837 		(void) strlcpy(zc.zc_prop_value, propval,
838 		    sizeof (zc.zc_prop_value));
839 		zc.zc_intsz = 1;
840 		zc.zc_numints = strlen(propval) + 1;
841 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_PROP, &zc);
842 		break;
843 	case ZFS_PROP_VOLSIZE:
844 		zc.zc_volsize = number;
845 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_VOLSIZE, &zc);
846 		break;
847 	case ZFS_PROP_VOLBLOCKSIZE:
848 		zc.zc_volblocksize = number;
849 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_VOLBLOCKSIZE,
850 		    &zc);
851 		break;
852 	default:
853 		(void) strlcpy(zc.zc_prop_name, propname,
854 		    sizeof (zc.zc_prop_name));
855 		/* LINTED - alignment */
856 		*(uint64_t *)zc.zc_prop_value = number;
857 		zc.zc_intsz = 8;
858 		zc.zc_numints = 1;
859 		ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SET_PROP, &zc);
860 		break;
861 	}
862 
863 	if (ret != 0) {
864 		switch (errno) {
865 
866 		case ENOSPC:
867 			/*
868 			 * For quotas and reservations, ENOSPC indicates
869 			 * something different; setting a quota or reservation
870 			 * doesn't use any disk space.
871 			 */
872 			switch (prop) {
873 			case ZFS_PROP_QUOTA:
874 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
875 				    "size is less than current used or "
876 				    "reserved space"));
877 				(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
878 				break;
879 
880 			case ZFS_PROP_RESERVATION:
881 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
882 				    "size is greater than available space"));
883 				(void) zfs_error(hdl, EZFS_PROPSPACE, errbuf);
884 				break;
885 
886 			default:
887 				(void) zfs_standard_error(hdl, errno, errbuf);
888 				break;
889 			}
890 			break;
891 
892 		case EBUSY:
893 			if (prop == ZFS_PROP_VOLBLOCKSIZE)
894 				(void) zfs_error(hdl, EZFS_VOLHASDATA, errbuf);
895 			else
896 				return (zfs_standard_error(hdl, EBUSY, errbuf));
897 			break;
898 
899 		case EROFS:
900 			(void) zfs_error(hdl, EZFS_DSREADONLY, errbuf);
901 			break;
902 
903 		case EOVERFLOW:
904 			/*
905 			 * This platform can't address a volume this big.
906 			 */
907 #ifdef _ILP32
908 			if (prop == ZFS_PROP_VOLSIZE) {
909 				(void) zfs_error(hdl, EZFS_VOLTOOBIG, errbuf);
910 				break;
911 			}
912 #endif
913 			/* FALLTHROUGH */
914 		default:
915 			(void) zfs_standard_error(hdl, errno, errbuf);
916 		}
917 	} else {
918 		/*
919 		 * Refresh the statistics so the new property value
920 		 * is reflected.
921 		 */
922 		if ((ret = changelist_postfix(cl)) != 0)
923 			goto error;
924 
925 		(void) get_stats(zhp);
926 	}
927 
928 error:
929 	changelist_free(cl);
930 	return (ret);
931 }
932 
933 /*
934  * Given a property, inherit the value from the parent dataset.
935  */
936 int
937 zfs_prop_inherit(zfs_handle_t *zhp, zfs_prop_t prop)
938 {
939 	const char *propname = zfs_prop_to_name(prop);
940 	zfs_cmd_t zc = { 0 };
941 	int ret;
942 	prop_changelist_t *cl;
943 	libzfs_handle_t *hdl = zhp->zfs_hdl;
944 	char errbuf[1024];
945 
946 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
947 	    "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
948 
949 	/*
950 	 * Verify that this property is inheritable.
951 	 */
952 	if (zfs_prop_readonly(prop))
953 		return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
954 
955 	if (!zfs_prop_inheritable(prop))
956 		return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
957 
958 	/*
959 	 * Check to see if the value applies to this type
960 	 */
961 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
962 		return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
963 
964 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
965 	(void) strlcpy(zc.zc_prop_name, propname, sizeof (zc.zc_prop_name));
966 
967 	if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
968 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
969 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
970 		    "dataset is used in a non-global zone"));
971 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
972 	}
973 
974 	/*
975 	 * Determine datasets which will be affected by this change, if any.
976 	 */
977 	if ((cl = changelist_gather(zhp, prop, 0)) == NULL)
978 		return (-1);
979 
980 	if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
981 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
982 		    "child dataset with inherited mountpoint is used "
983 		    "in a non-global zone"));
984 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
985 		goto error;
986 	}
987 
988 	if ((ret = changelist_prefix(cl)) != 0)
989 		goto error;
990 
991 	zc.zc_numints = 0;
992 
993 	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd,
994 	    ZFS_IOC_SET_PROP, &zc)) != 0) {
995 		return (zfs_standard_error(hdl, errno, errbuf));
996 	} else {
997 
998 		if ((ret = changelist_postfix(cl)) != 0)
999 			goto error;
1000 
1001 		/*
1002 		 * Refresh the statistics so the new property is reflected.
1003 		 */
1004 		(void) get_stats(zhp);
1005 	}
1006 
1007 
1008 error:
1009 	changelist_free(cl);
1010 	return (ret);
1011 }
1012 
1013 static void
1014 nicebool(int value, char *buf, size_t buflen)
1015 {
1016 	if (value)
1017 		(void) strlcpy(buf, "on", buflen);
1018 	else
1019 		(void) strlcpy(buf, "off", buflen);
1020 }
1021 
1022 /*
1023  * True DSL properties are stored in an nvlist.  The following two functions
1024  * extract them appropriately.
1025  */
1026 static uint64_t
1027 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1028 {
1029 	nvlist_t *nv;
1030 	uint64_t value;
1031 
1032 	if (nvlist_lookup_nvlist(zhp->zfs_props,
1033 	    zfs_prop_to_name(prop), &nv) == 0) {
1034 		verify(nvlist_lookup_uint64(nv, ZFS_PROP_VALUE, &value) == 0);
1035 		verify(nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source) == 0);
1036 	} else {
1037 		value = zfs_prop_default_numeric(prop);
1038 		*source = "";
1039 	}
1040 
1041 	return (value);
1042 }
1043 
1044 static char *
1045 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
1046 {
1047 	nvlist_t *nv;
1048 	char *value;
1049 
1050 	if (nvlist_lookup_nvlist(zhp->zfs_props,
1051 	    zfs_prop_to_name(prop), &nv) == 0) {
1052 		verify(nvlist_lookup_string(nv, ZFS_PROP_VALUE, &value) == 0);
1053 		verify(nvlist_lookup_string(nv, ZFS_PROP_SOURCE, source) == 0);
1054 	} else {
1055 		if ((value = (char *)zfs_prop_default_string(prop)) == NULL)
1056 			value = "";
1057 		*source = "";
1058 	}
1059 
1060 	return (value);
1061 }
1062 
1063 /*
1064  * Internal function for getting a numeric property.  Both zfs_prop_get() and
1065  * zfs_prop_get_int() are built using this interface.
1066  *
1067  * Certain properties can be overridden using 'mount -o'.  In this case, scan
1068  * the contents of the /etc/mnttab entry, searching for the appropriate options.
1069  * If they differ from the on-disk values, report the current values and mark
1070  * the source "temporary".
1071  */
1072 static int
1073 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zfs_source_t *src,
1074     char **source, uint64_t *val)
1075 {
1076 	struct mnttab mnt;
1077 
1078 	*source = NULL;
1079 
1080 	if (zhp->zfs_mntopts == NULL)
1081 		mnt.mnt_mntopts = "";
1082 	else
1083 		mnt.mnt_mntopts = zhp->zfs_mntopts;
1084 
1085 	switch (prop) {
1086 	case ZFS_PROP_ATIME:
1087 		*val = getprop_uint64(zhp, prop, source);
1088 
1089 		if (hasmntopt(&mnt, MNTOPT_ATIME) && !*val) {
1090 			*val = B_TRUE;
1091 			if (src)
1092 				*src = ZFS_SRC_TEMPORARY;
1093 		} else if (hasmntopt(&mnt, MNTOPT_NOATIME) && *val) {
1094 			*val = B_FALSE;
1095 			if (src)
1096 				*src = ZFS_SRC_TEMPORARY;
1097 		}
1098 		break;
1099 
1100 	case ZFS_PROP_AVAILABLE:
1101 		*val = zhp->zfs_dmustats.dds_available;
1102 		break;
1103 
1104 	case ZFS_PROP_DEVICES:
1105 		*val = getprop_uint64(zhp, prop, source);
1106 
1107 		if (hasmntopt(&mnt, MNTOPT_DEVICES) && !*val) {
1108 			*val = B_TRUE;
1109 			if (src)
1110 				*src = ZFS_SRC_TEMPORARY;
1111 		} else if (hasmntopt(&mnt, MNTOPT_NODEVICES) && *val) {
1112 			*val = B_FALSE;
1113 			if (src)
1114 				*src = ZFS_SRC_TEMPORARY;
1115 		}
1116 		break;
1117 
1118 	case ZFS_PROP_EXEC:
1119 		*val = getprop_uint64(zhp, prop, source);
1120 
1121 		if (hasmntopt(&mnt, MNTOPT_EXEC) && !*val) {
1122 			*val = B_TRUE;
1123 			if (src)
1124 				*src = ZFS_SRC_TEMPORARY;
1125 		} else if (hasmntopt(&mnt, MNTOPT_NOEXEC) && *val) {
1126 			*val = B_FALSE;
1127 			if (src)
1128 				*src = ZFS_SRC_TEMPORARY;
1129 		}
1130 		break;
1131 
1132 	case ZFS_PROP_RECORDSIZE:
1133 	case ZFS_PROP_COMPRESSION:
1134 	case ZFS_PROP_ZONED:
1135 		*val = getprop_uint64(zhp, prop, source);
1136 		break;
1137 
1138 	case ZFS_PROP_READONLY:
1139 		*val = getprop_uint64(zhp, prop, source);
1140 
1141 		if (hasmntopt(&mnt, MNTOPT_RO) && !*val) {
1142 			*val = B_TRUE;
1143 			if (src)
1144 				*src = ZFS_SRC_TEMPORARY;
1145 		} else if (hasmntopt(&mnt, MNTOPT_RW) && *val) {
1146 			*val = B_FALSE;
1147 			if (src)
1148 				*src = ZFS_SRC_TEMPORARY;
1149 		}
1150 		break;
1151 
1152 	case ZFS_PROP_CREATION:
1153 		*val = zhp->zfs_dmustats.dds_creation_time;
1154 		break;
1155 
1156 	case ZFS_PROP_QUOTA:
1157 		if (zhp->zfs_dmustats.dds_quota == 0)
1158 			*source = "";	/* default */
1159 		else
1160 			*source = zhp->zfs_name;
1161 		*val = zhp->zfs_dmustats.dds_quota;
1162 		break;
1163 
1164 	case ZFS_PROP_RESERVATION:
1165 		if (zhp->zfs_dmustats.dds_reserved == 0)
1166 			*source = "";	/* default */
1167 		else
1168 			*source = zhp->zfs_name;
1169 		*val = zhp->zfs_dmustats.dds_reserved;
1170 		break;
1171 
1172 	case ZFS_PROP_COMPRESSRATIO:
1173 		/*
1174 		 * Using physical space and logical space, calculate the
1175 		 * compression ratio.  We return the number as a multiple of
1176 		 * 100, so '2.5x' would be returned as 250.
1177 		 */
1178 		if (zhp->zfs_dmustats.dds_compressed_bytes == 0)
1179 			*val = 100ULL;
1180 		else
1181 			*val =
1182 			    (zhp->zfs_dmustats.dds_uncompressed_bytes * 100 /
1183 			    zhp->zfs_dmustats.dds_compressed_bytes);
1184 		break;
1185 
1186 	case ZFS_PROP_REFERENCED:
1187 		/*
1188 		 * 'referenced' refers to the amount of physical space
1189 		 * referenced (possibly shared) by this object.
1190 		 */
1191 		*val = zhp->zfs_dmustats.dds_space_refd;
1192 		break;
1193 
1194 	case ZFS_PROP_SETUID:
1195 		*val = getprop_uint64(zhp, prop, source);
1196 
1197 		if (hasmntopt(&mnt, MNTOPT_SETUID) && !*val) {
1198 			*val = B_TRUE;
1199 			if (src)
1200 				*src = ZFS_SRC_TEMPORARY;
1201 		} else if (hasmntopt(&mnt, MNTOPT_NOSETUID) && *val) {
1202 			*val = B_FALSE;
1203 			if (src)
1204 				*src = ZFS_SRC_TEMPORARY;
1205 		}
1206 		break;
1207 
1208 	case ZFS_PROP_VOLSIZE:
1209 		*val = zhp->zfs_volsize;
1210 		break;
1211 
1212 	case ZFS_PROP_VOLBLOCKSIZE:
1213 		*val = zhp->zfs_volblocksize;
1214 		break;
1215 
1216 	case ZFS_PROP_USED:
1217 		*val = zhp->zfs_dmustats.dds_space_used;
1218 		break;
1219 
1220 	case ZFS_PROP_CREATETXG:
1221 		*val = zhp->zfs_dmustats.dds_creation_txg;
1222 		break;
1223 
1224 	case ZFS_PROP_MOUNTED:
1225 		/*
1226 		 * Unlike other properties, we defer calculation of 'MOUNTED'
1227 		 * until actually requested.  This is because the getmntany()
1228 		 * call can be extremely expensive on systems with a large
1229 		 * number of filesystems, and the property isn't needed in
1230 		 * normal use cases.
1231 		 */
1232 		if (zhp->zfs_mntopts == NULL) {
1233 			struct mnttab search = { 0 }, entry;
1234 
1235 			search.mnt_special = (char *)zhp->zfs_name;
1236 			search.mnt_fstype = MNTTYPE_ZFS;
1237 			rewind(zhp->zfs_hdl->libzfs_mnttab);
1238 
1239 			if (getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry,
1240 			    &search) == 0 && (zhp->zfs_mntopts =
1241 			    zfs_strdup(zhp->zfs_hdl,
1242 			    entry.mnt_mntopts)) == NULL)
1243 				return (-1);
1244 		}
1245 		*val = (zhp->zfs_mntopts != NULL);
1246 		break;
1247 
1248 	default:
1249 		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1250 		    "cannot get non-numeric property"));
1251 		return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
1252 		    dgettext(TEXT_DOMAIN, "internal error")));
1253 	}
1254 
1255 	return (0);
1256 }
1257 
1258 /*
1259  * Calculate the source type, given the raw source string.
1260  */
1261 static void
1262 get_source(zfs_handle_t *zhp, zfs_source_t *srctype, char *source,
1263     char *statbuf, size_t statlen)
1264 {
1265 	if (statbuf == NULL || *srctype == ZFS_SRC_TEMPORARY)
1266 		return;
1267 
1268 	if (source == NULL) {
1269 		*srctype = ZFS_SRC_NONE;
1270 	} else if (source[0] == '\0') {
1271 		*srctype = ZFS_SRC_DEFAULT;
1272 	} else {
1273 		if (strcmp(source, zhp->zfs_name) == 0) {
1274 			*srctype = ZFS_SRC_LOCAL;
1275 		} else {
1276 			(void) strlcpy(statbuf, source, statlen);
1277 			*srctype = ZFS_SRC_INHERITED;
1278 		}
1279 	}
1280 
1281 }
1282 
1283 /*
1284  * Retrieve a property from the given object.  If 'literal' is specified, then
1285  * numbers are left as exact values.  Otherwise, numbers are converted to a
1286  * human-readable form.
1287  *
1288  * Returns 0 on success, or -1 on error.
1289  */
1290 int
1291 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
1292     zfs_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
1293 {
1294 	char *source = NULL;
1295 	uint64_t val;
1296 	char *str;
1297 	int i;
1298 	const char *root;
1299 
1300 	/*
1301 	 * Check to see if this property applies to our object
1302 	 */
1303 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1304 		return (-1);
1305 
1306 	if (src)
1307 		*src = ZFS_SRC_NONE;
1308 
1309 	switch (prop) {
1310 	case ZFS_PROP_ATIME:
1311 	case ZFS_PROP_READONLY:
1312 	case ZFS_PROP_SETUID:
1313 	case ZFS_PROP_ZONED:
1314 	case ZFS_PROP_DEVICES:
1315 	case ZFS_PROP_EXEC:
1316 		/*
1317 		 * Basic boolean values are built on top of
1318 		 * get_numeric_property().
1319 		 */
1320 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1321 			return (-1);
1322 		nicebool(val, propbuf, proplen);
1323 
1324 		break;
1325 
1326 	case ZFS_PROP_AVAILABLE:
1327 	case ZFS_PROP_RECORDSIZE:
1328 	case ZFS_PROP_CREATETXG:
1329 	case ZFS_PROP_REFERENCED:
1330 	case ZFS_PROP_USED:
1331 	case ZFS_PROP_VOLSIZE:
1332 	case ZFS_PROP_VOLBLOCKSIZE:
1333 		/*
1334 		 * Basic numeric values are built on top of
1335 		 * get_numeric_property().
1336 		 */
1337 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1338 			return (-1);
1339 		if (literal)
1340 			(void) snprintf(propbuf, proplen, "%llu", val);
1341 		else
1342 			zfs_nicenum(val, propbuf, proplen);
1343 		break;
1344 
1345 	case ZFS_PROP_COMPRESSION:
1346 		val = getprop_uint64(zhp, prop, &source);
1347 		for (i = 0; compress_table[i].name != NULL; i++) {
1348 			if (compress_table[i].value == val)
1349 				break;
1350 		}
1351 		assert(compress_table[i].name != NULL);
1352 		(void) strlcpy(propbuf, compress_table[i].name, proplen);
1353 		break;
1354 
1355 	case ZFS_PROP_CHECKSUM:
1356 		val = getprop_uint64(zhp, prop, &source);
1357 		for (i = 0; checksum_table[i].name != NULL; i++) {
1358 			if (checksum_table[i].value == val)
1359 				break;
1360 		}
1361 		assert(checksum_table[i].name != NULL);
1362 		(void) strlcpy(propbuf, checksum_table[i].name, proplen);
1363 		break;
1364 
1365 	case ZFS_PROP_SNAPDIR:
1366 		val = getprop_uint64(zhp, prop, &source);
1367 		for (i = 0; snapdir_table[i].name != NULL; i++) {
1368 			if (snapdir_table[i].value == val)
1369 				break;
1370 		}
1371 		assert(snapdir_table[i].name != NULL);
1372 		(void) strlcpy(propbuf, snapdir_table[i].name, proplen);
1373 		break;
1374 
1375 	case ZFS_PROP_ACLMODE:
1376 		val = getprop_uint64(zhp, prop, &source);
1377 		for (i = 0; acl_mode_table[i].name != NULL; i++) {
1378 			if (acl_mode_table[i].value == val)
1379 				break;
1380 		}
1381 		assert(acl_mode_table[i].name != NULL);
1382 		(void) strlcpy(propbuf, acl_mode_table[i].name, proplen);
1383 		break;
1384 
1385 	case ZFS_PROP_ACLINHERIT:
1386 		val = getprop_uint64(zhp, prop, &source);
1387 		for (i = 0; acl_inherit_table[i].name != NULL; i++) {
1388 			if (acl_inherit_table[i].value == val)
1389 				break;
1390 		}
1391 		assert(acl_inherit_table[i].name != NULL);
1392 		(void) strlcpy(propbuf, acl_inherit_table[i].name, proplen);
1393 		break;
1394 
1395 	case ZFS_PROP_CREATION:
1396 		/*
1397 		 * 'creation' is a time_t stored in the statistics.  We convert
1398 		 * this into a string unless 'literal' is specified.
1399 		 */
1400 		{
1401 			time_t time = (time_t)
1402 			    zhp->zfs_dmustats.dds_creation_time;
1403 			struct tm t;
1404 
1405 			if (literal ||
1406 			    localtime_r(&time, &t) == NULL ||
1407 			    strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
1408 			    &t) == 0)
1409 				(void) snprintf(propbuf, proplen, "%llu",
1410 				    zhp->zfs_dmustats.dds_creation_time);
1411 		}
1412 		break;
1413 
1414 	case ZFS_PROP_MOUNTPOINT:
1415 		/*
1416 		 * Getting the precise mountpoint can be tricky.
1417 		 *
1418 		 *  - for 'none' or 'legacy', return those values.
1419 		 *  - for default mountpoints, construct it as /zfs/<dataset>
1420 		 *  - for inherited mountpoints, we want to take everything
1421 		 *    after our ancestor and append it to the inherited value.
1422 		 *
1423 		 * If the pool has an alternate root, we want to prepend that
1424 		 * root to any values we return.
1425 		 */
1426 		root = zhp->zfs_root;
1427 		str = getprop_string(zhp, prop, &source);
1428 
1429 		if (str[0] == '\0') {
1430 			(void) snprintf(propbuf, proplen, "%s/zfs/%s",
1431 			    root, zhp->zfs_name);
1432 		} else if (str[0] == '/') {
1433 			const char *relpath = zhp->zfs_name + strlen(source);
1434 
1435 			if (relpath[0] == '/')
1436 				relpath++;
1437 			if (str[1] == '\0')
1438 				str++;
1439 
1440 			if (relpath[0] == '\0')
1441 				(void) snprintf(propbuf, proplen, "%s%s",
1442 				    root, str);
1443 			else
1444 				(void) snprintf(propbuf, proplen, "%s%s%s%s",
1445 				    root, str, relpath[0] == '@' ? "" : "/",
1446 				    relpath);
1447 		} else {
1448 			/* 'legacy' or 'none' */
1449 			(void) strlcpy(propbuf, str, proplen);
1450 		}
1451 
1452 		break;
1453 
1454 	case ZFS_PROP_SHARENFS:
1455 		(void) strlcpy(propbuf, getprop_string(zhp, prop, &source),
1456 		    proplen);
1457 		break;
1458 
1459 	case ZFS_PROP_ORIGIN:
1460 		(void) strlcpy(propbuf, zhp->zfs_dmustats.dds_clone_of,
1461 		    proplen);
1462 		/*
1463 		 * If there is no parent at all, return failure to indicate that
1464 		 * it doesn't apply to this dataset.
1465 		 */
1466 		if (propbuf[0] == '\0')
1467 			return (-1);
1468 		break;
1469 
1470 	case ZFS_PROP_QUOTA:
1471 	case ZFS_PROP_RESERVATION:
1472 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1473 			return (-1);
1474 
1475 		/*
1476 		 * If quota or reservation is 0, we translate this into 'none'
1477 		 * (unless literal is set), and indicate that it's the default
1478 		 * value.  Otherwise, we print the number nicely and indicate
1479 		 * that its set locally.
1480 		 */
1481 		if (val == 0) {
1482 			if (literal)
1483 				(void) strlcpy(propbuf, "0", proplen);
1484 			else
1485 				(void) strlcpy(propbuf, "none", proplen);
1486 		} else {
1487 			if (literal)
1488 				(void) snprintf(propbuf, proplen, "%llu", val);
1489 			else
1490 				zfs_nicenum(val, propbuf, proplen);
1491 		}
1492 		break;
1493 
1494 	case ZFS_PROP_COMPRESSRATIO:
1495 		if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
1496 			return (-1);
1497 		(void) snprintf(propbuf, proplen, "%lld.%02lldx", val / 100,
1498 		    val % 100);
1499 		break;
1500 
1501 	case ZFS_PROP_TYPE:
1502 		switch (zhp->zfs_type) {
1503 		case ZFS_TYPE_FILESYSTEM:
1504 			str = "filesystem";
1505 			break;
1506 		case ZFS_TYPE_VOLUME:
1507 			str = "volume";
1508 			break;
1509 		case ZFS_TYPE_SNAPSHOT:
1510 			str = "snapshot";
1511 			break;
1512 		default:
1513 			abort();
1514 		}
1515 		(void) snprintf(propbuf, proplen, "%s", str);
1516 		break;
1517 
1518 	case ZFS_PROP_MOUNTED:
1519 		/*
1520 		 * The 'mounted' property is a pseudo-property that described
1521 		 * whether the filesystem is currently mounted.  Even though
1522 		 * it's a boolean value, the typical values of "on" and "off"
1523 		 * don't make sense, so we translate to "yes" and "no".
1524 		 */
1525 		if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
1526 		    src, &source, &val) != 0)
1527 			return (-1);
1528 		if (val)
1529 			(void) strlcpy(propbuf, "yes", proplen);
1530 		else
1531 			(void) strlcpy(propbuf, "no", proplen);
1532 		break;
1533 
1534 	case ZFS_PROP_NAME:
1535 		/*
1536 		 * The 'name' property is a pseudo-property derived from the
1537 		 * dataset name.  It is presented as a real property to simplify
1538 		 * consumers.
1539 		 */
1540 		(void) strlcpy(propbuf, zhp->zfs_name, proplen);
1541 		break;
1542 
1543 	default:
1544 		abort();
1545 	}
1546 
1547 	get_source(zhp, src, source, statbuf, statlen);
1548 
1549 	return (0);
1550 }
1551 
1552 /*
1553  * Utility function to get the given numeric property.  Does no validation that
1554  * the given property is the appropriate type; should only be used with
1555  * hard-coded property types.
1556  */
1557 uint64_t
1558 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
1559 {
1560 	char *source;
1561 	zfs_source_t sourcetype = ZFS_SRC_NONE;
1562 	uint64_t val;
1563 
1564 	(void) get_numeric_property(zhp, prop, &sourcetype, &source, &val);
1565 
1566 	return (val);
1567 }
1568 
1569 /*
1570  * Similar to zfs_prop_get(), but returns the value as an integer.
1571  */
1572 int
1573 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
1574     zfs_source_t *src, char *statbuf, size_t statlen)
1575 {
1576 	char *source;
1577 
1578 	/*
1579 	 * Check to see if this property applies to our object
1580 	 */
1581 	if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
1582 		return (zfs_error(zhp->zfs_hdl, EZFS_PROPTYPE,
1583 		    dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
1584 		    zfs_prop_to_name(prop)));
1585 
1586 	if (src)
1587 		*src = ZFS_SRC_NONE;
1588 
1589 	if (get_numeric_property(zhp, prop, src, &source, value) != 0)
1590 		return (-1);
1591 
1592 	get_source(zhp, src, source, statbuf, statlen);
1593 
1594 	return (0);
1595 }
1596 
1597 /*
1598  * Returns the name of the given zfs handle.
1599  */
1600 const char *
1601 zfs_get_name(const zfs_handle_t *zhp)
1602 {
1603 	return (zhp->zfs_name);
1604 }
1605 
1606 /*
1607  * Returns the type of the given zfs handle.
1608  */
1609 zfs_type_t
1610 zfs_get_type(const zfs_handle_t *zhp)
1611 {
1612 	return (zhp->zfs_type);
1613 }
1614 
1615 /*
1616  * Iterate over all child filesystems
1617  */
1618 int
1619 zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1620 {
1621 	zfs_cmd_t zc = { 0 };
1622 	zfs_handle_t *nzhp;
1623 	int ret;
1624 
1625 	for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1626 	    ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
1627 	    (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
1628 		/*
1629 		 * Ignore private dataset names.
1630 		 */
1631 		if (dataset_name_hidden(zc.zc_name))
1632 			continue;
1633 
1634 		/*
1635 		 * Silently ignore errors, as the only plausible explanation is
1636 		 * that the pool has since been removed.
1637 		 */
1638 		if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
1639 		    zc.zc_name)) == NULL)
1640 			continue;
1641 
1642 		if ((ret = func(nzhp, data)) != 0)
1643 			return (ret);
1644 	}
1645 
1646 	/*
1647 	 * An errno value of ESRCH indicates normal completion.  If ENOENT is
1648 	 * returned, then the underlying dataset has been removed since we
1649 	 * obtained the handle.
1650 	 */
1651 	if (errno != ESRCH && errno != ENOENT)
1652 		return (zfs_standard_error(zhp->zfs_hdl, errno,
1653 		    dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
1654 
1655 	return (0);
1656 }
1657 
1658 /*
1659  * Iterate over all snapshots
1660  */
1661 int
1662 zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1663 {
1664 	zfs_cmd_t zc = { 0 };
1665 	zfs_handle_t *nzhp;
1666 	int ret;
1667 
1668 	for ((void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1669 	    ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
1670 	    &zc) == 0;
1671 	    (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name))) {
1672 
1673 		if ((nzhp = make_dataset_handle(zhp->zfs_hdl,
1674 		    zc.zc_name)) == NULL)
1675 			continue;
1676 
1677 		if ((ret = func(nzhp, data)) != 0)
1678 			return (ret);
1679 	}
1680 
1681 	/*
1682 	 * An errno value of ESRCH indicates normal completion.  If ENOENT is
1683 	 * returned, then the underlying dataset has been removed since we
1684 	 * obtained the handle.  Silently ignore this case, and return success.
1685 	 */
1686 	if (errno != ESRCH && errno != ENOENT)
1687 		return (zfs_standard_error(zhp->zfs_hdl, errno,
1688 		    dgettext(TEXT_DOMAIN, "cannot iterate filesystems")));
1689 
1690 	return (0);
1691 }
1692 
1693 /*
1694  * Iterate over all children, snapshots and filesystems
1695  */
1696 int
1697 zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
1698 {
1699 	int ret;
1700 
1701 	if ((ret = zfs_iter_filesystems(zhp, func, data)) != 0)
1702 		return (ret);
1703 
1704 	return (zfs_iter_snapshots(zhp, func, data));
1705 }
1706 
1707 /*
1708  * Given a complete name, return just the portion that refers to the parent.
1709  * Can return NULL if this is a pool.
1710  */
1711 static int
1712 parent_name(const char *path, char *buf, size_t buflen)
1713 {
1714 	char *loc;
1715 
1716 	if ((loc = strrchr(path, '/')) == NULL)
1717 		return (-1);
1718 
1719 	(void) strncpy(buf, path, MIN(buflen, loc - path));
1720 	buf[loc - path] = '\0';
1721 
1722 	return (0);
1723 }
1724 
1725 /*
1726  * Checks to make sure that the given path has a parent, and that it exists.
1727  */
1728 static int
1729 check_parents(libzfs_handle_t *hdl, const char *path)
1730 {
1731 	zfs_cmd_t zc = { 0 };
1732 	char parent[ZFS_MAXNAMELEN];
1733 	char *slash;
1734 	zfs_handle_t *zhp;
1735 	char errbuf[1024];
1736 
1737 	(void) snprintf(errbuf, sizeof (errbuf), "cannot create '%s'",
1738 	    path);
1739 
1740 	/* get parent, and check to see if this is just a pool */
1741 	if (parent_name(path, parent, sizeof (parent)) != 0) {
1742 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1743 		    "missing dataset name"));
1744 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1745 	}
1746 
1747 	/* check to see if the pool exists */
1748 	if ((slash = strchr(parent, '/')) == NULL)
1749 		slash = parent + strlen(parent);
1750 	(void) strncpy(zc.zc_name, parent, slash - parent);
1751 	zc.zc_name[slash - parent] = '\0';
1752 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
1753 	    errno == ENOENT) {
1754 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1755 		    "no such pool '%s'"), zc.zc_name);
1756 		return (zfs_error(hdl, EZFS_NOENT, errbuf));
1757 	}
1758 
1759 	/* check to see if the parent dataset exists */
1760 	if ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
1761 		switch (errno) {
1762 		case ENOENT:
1763 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1764 			    "parent does not exist"));
1765 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
1766 
1767 		default:
1768 			return (zfs_standard_error(hdl, errno, errbuf));
1769 		}
1770 	}
1771 
1772 	/* we are in a non-global zone, but parent is in the global zone */
1773 	if (getzoneid() != GLOBAL_ZONEID &&
1774 	    !zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1775 		(void) zfs_standard_error(hdl, EPERM, errbuf);
1776 		zfs_close(zhp);
1777 		return (-1);
1778 	}
1779 
1780 	/* make sure parent is a filesystem */
1781 	if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
1782 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1783 		    "parent is not a filesystem"));
1784 		(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
1785 		zfs_close(zhp);
1786 		return (-1);
1787 	}
1788 
1789 	zfs_close(zhp);
1790 	return (0);
1791 }
1792 
1793 /*
1794  * Create a new filesystem or volume.  'sizestr' and 'blocksizestr' are used
1795  * only for volumes, and indicate the size and blocksize of the volume.
1796  */
1797 int
1798 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
1799 	const char *sizestr, const char *blocksizestr)
1800 {
1801 	zfs_cmd_t zc = { 0 };
1802 	int ret;
1803 	uint64_t size = 0;
1804 	uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
1805 	char errbuf[1024];
1806 
1807 	/* convert sizestr into integer size */
1808 	if (sizestr != NULL && nicestrtonum(hdl, sizestr, &size) != 0)
1809 		return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
1810 		    "bad volume size '%s'"), sizestr));
1811 
1812 	/* convert blocksizestr into integer blocksize */
1813 	if (blocksizestr != NULL && nicestrtonum(hdl, blocksizestr,
1814 	    &blocksize) != 0)
1815 		return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
1816 		    "bad volume blocksize '%s'"), blocksizestr));
1817 
1818 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1819 	    "cannot create '%s'"), path);
1820 
1821 	/* validate the path, taking care to note the extended error message */
1822 	if (!zfs_validate_name(hdl, path, type))
1823 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1824 
1825 	/* validate parents exist */
1826 	if (check_parents(hdl, path) != 0)
1827 		return (-1);
1828 
1829 	/*
1830 	 * The failure modes when creating a dataset of a different type over
1831 	 * one that already exists is a little strange.  In particular, if you
1832 	 * try to create a dataset on top of an existing dataset, the ioctl()
1833 	 * will return ENOENT, not EEXIST.  To prevent this from happening, we
1834 	 * first try to see if the dataset exists.
1835 	 */
1836 	(void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
1837 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
1838 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1839 		    "dataset already exists"));
1840 		return (zfs_error(hdl, EZFS_EXISTS, errbuf));
1841 	}
1842 
1843 	if (type == ZFS_TYPE_VOLUME)
1844 		zc.zc_objset_type = DMU_OST_ZVOL;
1845 	else
1846 		zc.zc_objset_type = DMU_OST_ZFS;
1847 
1848 	if (type == ZFS_TYPE_VOLUME) {
1849 		/*
1850 		 * If we are creating a volume, the size and block size must
1851 		 * satisfy a few restraints.  First, the blocksize must be a
1852 		 * valid block size between SPA_{MIN,MAX}BLOCKSIZE.  Second, the
1853 		 * volsize must be a multiple of the block size, and cannot be
1854 		 * zero.
1855 		 */
1856 		if (size == 0) {
1857 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1858 			    "cannot be zero"));
1859 			return (zfs_error(hdl, EZFS_BADPROP,
1860 			    dgettext(TEXT_DOMAIN, "bad volume size '%s'"),
1861 			    sizestr));
1862 		}
1863 
1864 		if (blocksize < SPA_MINBLOCKSIZE ||
1865 		    blocksize > SPA_MAXBLOCKSIZE || !ISP2(blocksize)) {
1866 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1867 			    "must be power of 2 from %u to %uk"),
1868 			    (uint_t)SPA_MINBLOCKSIZE,
1869 			    (uint_t)SPA_MAXBLOCKSIZE >> 10);
1870 			return (zfs_error(hdl, EZFS_BADPROP,
1871 			    dgettext(TEXT_DOMAIN,
1872 			    "bad volume block size '%s'"), blocksizestr));
1873 		}
1874 
1875 		if (size % blocksize != 0) {
1876 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1877 			    "must be a multiple of volume block size"));
1878 			return (zfs_error(hdl, EZFS_BADPROP,
1879 			    dgettext(TEXT_DOMAIN, "bad volume size '%s'"),
1880 			    sizestr));
1881 		}
1882 
1883 		zc.zc_volsize = size;
1884 		zc.zc_volblocksize = blocksize;
1885 	}
1886 
1887 	/* create the dataset */
1888 	ret = ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
1889 
1890 	if (ret == 0 && type == ZFS_TYPE_VOLUME)
1891 		ret = zvol_create_link(hdl, path);
1892 
1893 	/* check for failure */
1894 	if (ret != 0) {
1895 		char parent[ZFS_MAXNAMELEN];
1896 		(void) parent_name(path, parent, sizeof (parent));
1897 
1898 		switch (errno) {
1899 		case ENOENT:
1900 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1901 			    "no such parent '%s'"), parent);
1902 			return (zfs_error(hdl, EZFS_NOENT, errbuf));
1903 
1904 		case EINVAL:
1905 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1906 			    "parent '%s' is not a filesysem"), parent);
1907 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
1908 
1909 		case EDOM:
1910 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1911 			    "must be power of 2 from %u to %uk"),
1912 			    (uint_t)SPA_MINBLOCKSIZE,
1913 			    (uint_t)SPA_MAXBLOCKSIZE >> 10);
1914 
1915 			return (zfs_error(hdl, EZFS_BADPROP,
1916 			    dgettext(TEXT_DOMAIN, "bad block size '%s'"),
1917 			    blocksizestr ? blocksizestr : "<unknown>"));
1918 
1919 #ifdef _ILP32
1920 		case EOVERFLOW:
1921 			/*
1922 			 * This platform can't address a volume this big.
1923 			 */
1924 			if (type == ZFS_TYPE_VOLUME)
1925 				return (zfs_error(hdl, EZFS_VOLTOOBIG,
1926 				    errbuf));
1927 #endif
1928 			/* FALLTHROUGH */
1929 		default:
1930 			return (zfs_standard_error(hdl, errno, errbuf));
1931 		}
1932 	}
1933 
1934 	return (0);
1935 }
1936 
1937 /*
1938  * Destroys the given dataset.  The caller must make sure that the filesystem
1939  * isn't mounted, and that there are no active dependents.
1940  */
1941 int
1942 zfs_destroy(zfs_handle_t *zhp)
1943 {
1944 	zfs_cmd_t zc = { 0 };
1945 	int ret;
1946 	char errbuf[1024];
1947 
1948 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1949 
1950 	/*
1951 	 * We use the check for 'zfs_volblocksize' instead of ZFS_TYPE_VOLUME
1952 	 * so that we do the right thing for snapshots of volumes.
1953 	 */
1954 	if (zhp->zfs_volblocksize != 0) {
1955 		if (zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
1956 			return (-1);
1957 
1958 		zc.zc_objset_type = DMU_OST_ZVOL;
1959 	} else {
1960 		zc.zc_objset_type = DMU_OST_ZFS;
1961 	}
1962 
1963 	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
1964 
1965 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1966 	    "cannot destroy '%s'"), zhp->zfs_name);
1967 
1968 	if (ret != 0)
1969 		return (zfs_standard_error(zhp->zfs_hdl, errno,
1970 		    dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
1971 		    zhp->zfs_name));
1972 
1973 	remove_mountpoint(zhp);
1974 
1975 	return (0);
1976 }
1977 
1978 /*
1979  * Clones the given dataset.  The target must be of the same type as the source.
1980  */
1981 int
1982 zfs_clone(zfs_handle_t *zhp, const char *target)
1983 {
1984 	zfs_cmd_t zc = { 0 };
1985 	char parent[ZFS_MAXNAMELEN];
1986 	int ret;
1987 	char errbuf[1024];
1988 	libzfs_handle_t *hdl = zhp->zfs_hdl;
1989 
1990 	assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
1991 
1992 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1993 	    "cannot create '%s'"), target);
1994 
1995 	/* validate the target name */
1996 	if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM))
1997 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
1998 
1999 	/* validate parents exist */
2000 	if (check_parents(zhp->zfs_hdl, target) != 0)
2001 		return (-1);
2002 
2003 	(void) parent_name(target, parent, sizeof (parent));
2004 
2005 	/* do the clone */
2006 	if (zhp->zfs_volblocksize != 0)
2007 		zc.zc_objset_type = DMU_OST_ZVOL;
2008 	else
2009 		zc.zc_objset_type = DMU_OST_ZFS;
2010 
2011 	(void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
2012 	(void) strlcpy(zc.zc_filename, zhp->zfs_name, sizeof (zc.zc_filename));
2013 	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
2014 
2015 	if (ret != 0) {
2016 		switch (errno) {
2017 
2018 		case ENOENT:
2019 			/*
2020 			 * The parent doesn't exist.  We should have caught this
2021 			 * above, but there may a race condition that has since
2022 			 * destroyed the parent.
2023 			 *
2024 			 * At this point, we don't know whether it's the source
2025 			 * that doesn't exist anymore, or whether the target
2026 			 * dataset doesn't exist.
2027 			 */
2028 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2029 			    "no such parent '%s'"), parent);
2030 			return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
2031 
2032 		case EXDEV:
2033 			zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2034 			    "source and target pools differ"));
2035 			return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
2036 			    errbuf));
2037 
2038 		default:
2039 			return (zfs_standard_error(zhp->zfs_hdl, errno,
2040 			    errbuf));
2041 		}
2042 	} else if (zhp->zfs_volblocksize != 0) {
2043 		ret = zvol_create_link(zhp->zfs_hdl, target);
2044 	}
2045 
2046 	return (ret);
2047 }
2048 
2049 typedef struct promote_data {
2050 	char cb_mountpoint[MAXPATHLEN];
2051 	const char *cb_target;
2052 	const char *cb_errbuf;
2053 	uint64_t cb_pivot_txg;
2054 } promote_data_t;
2055 
2056 static int
2057 promote_snap_cb(zfs_handle_t *zhp, void *data)
2058 {
2059 	promote_data_t *pd = data;
2060 	zfs_handle_t *szhp;
2061 	int err;
2062 	char snapname[MAXPATHLEN];
2063 	char *cp;
2064 
2065 	/* We don't care about snapshots after the pivot point */
2066 	if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > pd->cb_pivot_txg)
2067 		return (0);
2068 
2069 	/*
2070 	 * Unmount it.  We actually need to open it to provoke it to be
2071 	 * mounted first, because if it is not mounted, umount2 will
2072 	 * mount it!
2073 	 */
2074 	(void) strcpy(snapname, pd->cb_mountpoint);
2075 	(void) strcat(snapname, "/.zfs/snapshot/");
2076 	cp = strchr(zhp->zfs_name, '@');
2077 	(void) strcat(snapname, cp+1);
2078 	err = open(snapname, O_RDONLY);
2079 	if (err != -1)
2080 		(void) close(err);
2081 	(void) umount2(snapname, MS_FORCE);
2082 
2083 	/* Check for conflicting names */
2084 	(void) strcpy(snapname, pd->cb_target);
2085 	(void) strcat(snapname, cp);
2086 	szhp = make_dataset_handle(zhp->zfs_hdl, snapname);
2087 	if (szhp != NULL) {
2088 		zfs_close(szhp);
2089 		zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2090 		    "snapshot name '%s' from origin \n"
2091 		    "conflicts with '%s' from target"),
2092 		    zhp->zfs_name, snapname);
2093 		return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, pd->cb_errbuf));
2094 	}
2095 	return (0);
2096 }
2097 
2098 /*
2099  * Promotes the given clone fs to be the clone parent.
2100  */
2101 int
2102 zfs_promote(zfs_handle_t *zhp)
2103 {
2104 	libzfs_handle_t *hdl = zhp->zfs_hdl;
2105 	zfs_cmd_t zc = { 0 };
2106 	char parent[MAXPATHLEN];
2107 	char *cp;
2108 	int ret;
2109 	zfs_handle_t *pzhp;
2110 	promote_data_t pd;
2111 	char errbuf[1024];
2112 
2113 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2114 	    "cannot promote '%s'"), zhp->zfs_name);
2115 
2116 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
2117 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2118 		    "snapshots can not be promoted"));
2119 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2120 	}
2121 
2122 	(void) strcpy(parent, zhp->zfs_dmustats.dds_clone_of);
2123 	if (parent[0] == '\0') {
2124 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2125 		    "not a cloned filesystem"));
2126 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2127 	}
2128 	cp = strchr(parent, '@');
2129 	*cp = '\0';
2130 
2131 	/* Walk the snapshots we will be moving */
2132 	pzhp = zfs_open(hdl, zhp->zfs_dmustats.dds_clone_of, ZFS_TYPE_SNAPSHOT);
2133 	if (pzhp == NULL)
2134 		return (-1);
2135 	pd.cb_pivot_txg = zfs_prop_get_int(pzhp, ZFS_PROP_CREATETXG);
2136 	zfs_close(pzhp);
2137 	pd.cb_target = zhp->zfs_name;
2138 	pd.cb_errbuf = errbuf;
2139 	pzhp = zfs_open(hdl, parent, ZFS_TYPE_ANY);
2140 	if (pzhp == NULL)
2141 		return (-1);
2142 	(void) zfs_prop_get(pzhp, ZFS_PROP_MOUNTPOINT, pd.cb_mountpoint,
2143 	    sizeof (pd.cb_mountpoint), NULL, NULL, 0, FALSE);
2144 	ret = zfs_iter_snapshots(pzhp, promote_snap_cb, &pd);
2145 	if (ret != 0)
2146 		return (-1);
2147 
2148 	/* issue the ioctl */
2149 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2150 	ret = ioctl(hdl->libzfs_fd, ZFS_IOC_PROMOTE, &zc);
2151 
2152 	if (ret != 0) {
2153 		switch (errno) {
2154 
2155 		case EEXIST:
2156 			/*
2157 			 * There is a conflicting snapshot name.  We
2158 			 * should have caught this above, but they could
2159 			 * have renamed something in the mean time.
2160 			 */
2161 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2162 			    "conflicting snapshot name from parent '%s'"),
2163 			    parent);
2164 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2165 
2166 		default:
2167 			return (zfs_standard_error(hdl, errno, errbuf));
2168 		}
2169 	}
2170 
2171 	return (ret);
2172 }
2173 
2174 /*
2175  * Takes a snapshot of the given dataset
2176  */
2177 int
2178 zfs_snapshot(libzfs_handle_t *hdl, const char *path)
2179 {
2180 	const char *delim;
2181 	char *parent;
2182 	zfs_handle_t *zhp;
2183 	zfs_cmd_t zc = { 0 };
2184 	int ret;
2185 	char errbuf[1024];
2186 
2187 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2188 	    "cannot snapshot '%s'"), path);
2189 
2190 	/* validate the target name */
2191 	if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT))
2192 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2193 
2194 	/* make sure we have a snapshot */
2195 	if ((delim = strchr(path, '@')) == NULL) {
2196 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2197 		    "missing '@' delimeter in snapshot name"));
2198 		return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2199 	}
2200 
2201 	/* make sure the parent exists and is of the appropriate type */
2202 	if ((parent = zfs_alloc(hdl, delim - path + 1)) == NULL)
2203 		return (-1);
2204 	(void) strncpy(parent, path, delim - path);
2205 	parent[delim - path] = '\0';
2206 
2207 	if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
2208 	    ZFS_TYPE_VOLUME)) == NULL) {
2209 		free(parent);
2210 		return (-1);
2211 	}
2212 
2213 	(void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2214 
2215 	if (zhp->zfs_type == ZFS_TYPE_VOLUME)
2216 		zc.zc_objset_type = DMU_OST_ZVOL;
2217 	else
2218 		zc.zc_objset_type = DMU_OST_ZFS;
2219 
2220 	ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_CREATE, &zc);
2221 
2222 	if (ret == 0 && zhp->zfs_type == ZFS_TYPE_VOLUME) {
2223 		ret = zvol_create_link(zhp->zfs_hdl, path);
2224 		if (ret != 0)
2225 			(void) ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_DESTROY,
2226 			    &zc);
2227 	}
2228 
2229 	if (ret != 0)
2230 		(void) zfs_standard_error(hdl, errno, errbuf);
2231 
2232 	free(parent);
2233 	zfs_close(zhp);
2234 
2235 	return (ret);
2236 }
2237 
2238 /*
2239  * Dumps a backup of tosnap, incremental from fromsnap if it isn't NULL.
2240  */
2241 int
2242 zfs_send(zfs_handle_t *zhp_to, zfs_handle_t *zhp_from)
2243 {
2244 	zfs_cmd_t zc = { 0 };
2245 	int ret;
2246 	char errbuf[1024];
2247 	libzfs_handle_t *hdl = zhp_to->zfs_hdl;
2248 
2249 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2250 	    "cannot send '%s'"), zhp_to->zfs_name);
2251 
2252 	/* do the ioctl() */
2253 	(void) strlcpy(zc.zc_name, zhp_to->zfs_name, sizeof (zc.zc_name));
2254 	if (zhp_from) {
2255 		(void) strlcpy(zc.zc_prop_value, zhp_from->zfs_name,
2256 		    sizeof (zc.zc_name));
2257 	} else {
2258 		zc.zc_prop_value[0] = '\0';
2259 	}
2260 	zc.zc_cookie = STDOUT_FILENO;
2261 
2262 	ret = ioctl(zhp_to->zfs_hdl->libzfs_fd, ZFS_IOC_SENDBACKUP, &zc);
2263 	if (ret != 0) {
2264 		switch (errno) {
2265 
2266 		case EXDEV:
2267 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2268 			    "not an ealier snapshot from the same fs"));
2269 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2270 
2271 		case EDQUOT:
2272 		case EFBIG:
2273 		case EIO:
2274 		case ENOLINK:
2275 		case ENOSPC:
2276 		case ENOSTR:
2277 		case ENXIO:
2278 		case EPIPE:
2279 		case ERANGE:
2280 		case EFAULT:
2281 		case EROFS:
2282 			zfs_error_aux(hdl, strerror(errno));
2283 			return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
2284 
2285 		default:
2286 			return (zfs_standard_error(hdl, errno, errbuf));
2287 		}
2288 	}
2289 
2290 	return (ret);
2291 }
2292 
2293 /*
2294  * Restores a backup of tosnap from stdin.
2295  */
2296 int
2297 zfs_receive(libzfs_handle_t *hdl, const char *tosnap, int isprefix,
2298     int verbose, int dryrun)
2299 {
2300 	zfs_cmd_t zc = { 0 };
2301 	time_t begin_time;
2302 	int ioctl_err, err, bytes, size;
2303 	char *cp;
2304 	dmu_replay_record_t drr;
2305 	struct drr_begin *drrb = &zc.zc_begin_record;
2306 	char errbuf[1024];
2307 
2308 	begin_time = time(NULL);
2309 
2310 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2311 	    "cannot receive"));
2312 
2313 	/* trim off snapname, if any */
2314 	(void) strcpy(zc.zc_name, tosnap);
2315 	cp = strchr(zc.zc_name, '@');
2316 	if (cp)
2317 		*cp = '\0';
2318 
2319 	/* read in the BEGIN record */
2320 	cp = (char *)&drr;
2321 	bytes = 0;
2322 	do {
2323 		size = read(STDIN_FILENO, cp, sizeof (drr) - bytes);
2324 		cp += size;
2325 		bytes += size;
2326 	} while (size > 0);
2327 
2328 	if (size < 0 || bytes != sizeof (drr)) {
2329 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2330 		    "stream (failed to read first record)"));
2331 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2332 	}
2333 
2334 	zc.zc_begin_record = drr.drr_u.drr_begin;
2335 
2336 	if (drrb->drr_magic != DMU_BACKUP_MAGIC &&
2337 	    drrb->drr_magic != BSWAP_64(DMU_BACKUP_MAGIC)) {
2338 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2339 		    "stream (bad magic number)"));
2340 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2341 	}
2342 
2343 	if (drrb->drr_version != DMU_BACKUP_VERSION &&
2344 	    drrb->drr_version != BSWAP_64(DMU_BACKUP_VERSION)) {
2345 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "only version "
2346 		    "0x%llx is supported (stream is version 0x%llx)"),
2347 		    DMU_BACKUP_VERSION, drrb->drr_version);
2348 		return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2349 	}
2350 
2351 	/*
2352 	 * Determine name of destination snapshot.
2353 	 */
2354 	(void) strcpy(zc.zc_filename, tosnap);
2355 	if (isprefix) {
2356 		if (strchr(tosnap, '@') != NULL) {
2357 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2358 			    "destination must be a filesystem"));
2359 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2360 		}
2361 
2362 		cp = strchr(drr.drr_u.drr_begin.drr_toname, '/');
2363 		if (cp == NULL)
2364 			cp = drr.drr_u.drr_begin.drr_toname;
2365 		else
2366 			cp++;
2367 
2368 		(void) strcat(zc.zc_filename, "/");
2369 		(void) strcat(zc.zc_filename, cp);
2370 	} else if (strchr(tosnap, '@') == NULL) {
2371 		/*
2372 		 * they specified just a filesystem; tack on the
2373 		 * snapname from the backup.
2374 		 */
2375 		cp = strchr(drr.drr_u.drr_begin.drr_toname, '@');
2376 		if (cp == NULL || strlen(tosnap) + strlen(cp) >= MAXNAMELEN)
2377 			return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2378 		(void) strcat(zc.zc_filename, cp);
2379 	}
2380 
2381 	if (drrb->drr_fromguid) {
2382 		zfs_handle_t *h;
2383 		/* incremental backup stream */
2384 
2385 		/* do the ioctl to the containing fs */
2386 		(void) strcpy(zc.zc_name, zc.zc_filename);
2387 		cp = strchr(zc.zc_name, '@');
2388 		*cp = '\0';
2389 
2390 		/* make sure destination fs exists */
2391 		h = zfs_open(hdl, zc.zc_name,
2392 		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
2393 		if (h == NULL)
2394 			return (-1);
2395 		if (!dryrun) {
2396 			/* unmount destination fs or remove device link. */
2397 			if (h->zfs_type == ZFS_TYPE_FILESYSTEM) {
2398 				(void) zfs_unmount(h, NULL, 0);
2399 			} else {
2400 				(void) zvol_remove_link(hdl, h->zfs_name);
2401 			}
2402 		}
2403 		zfs_close(h);
2404 	} else {
2405 		/* full backup stream */
2406 
2407 		(void) strcpy(zc.zc_name, zc.zc_filename);
2408 
2409 		/* make sure they aren't trying to receive into the root */
2410 		if (strchr(zc.zc_name, '/') == NULL) {
2411 			cp = strchr(zc.zc_name, '@');
2412 			if (cp)
2413 				*cp = '\0';
2414 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2415 			    "destination '%s' already exists"), zc.zc_name);
2416 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2417 		}
2418 
2419 		if (isprefix) {
2420 			zfs_handle_t *h;
2421 
2422 			/* make sure prefix exists */
2423 			h = zfs_open(hdl, tosnap, ZFS_TYPE_FILESYSTEM);
2424 			if (h == NULL)
2425 				return (-1);
2426 			zfs_close(h);
2427 
2428 			/* create any necessary ancestors up to prefix */
2429 			zc.zc_objset_type = DMU_OST_ZFS;
2430 
2431 			/*
2432 			 * zc.zc_name is now the full name of the snap
2433 			 * we're restoring into.  Attempt to create,
2434 			 * mount, and share any ancestor filesystems, up
2435 			 * to the one that was named.
2436 			 */
2437 			for (cp = zc.zc_name + strlen(tosnap) + 1;
2438 			    cp = strchr(cp, '/'); *cp = '/', cp++) {
2439 				const char *opname;
2440 				*cp = '\0';
2441 
2442 				opname = dgettext(TEXT_DOMAIN, "create");
2443 				if (zfs_create(hdl, zc.zc_name,
2444 				    ZFS_TYPE_FILESYSTEM, NULL, NULL) != 0) {
2445 					if (errno == EEXIST)
2446 						continue;
2447 					goto ancestorerr;
2448 				}
2449 
2450 				opname = dgettext(TEXT_DOMAIN, "open");
2451 				h = zfs_open(hdl, zc.zc_name,
2452 				    ZFS_TYPE_FILESYSTEM);
2453 				if (h == NULL)
2454 					goto ancestorerr;
2455 
2456 				opname = dgettext(TEXT_DOMAIN, "mount");
2457 				if (zfs_mount(h, NULL, 0) != 0)
2458 					goto ancestorerr;
2459 
2460 				opname = dgettext(TEXT_DOMAIN, "share");
2461 				if (zfs_share(h) != 0)
2462 					goto ancestorerr;
2463 
2464 				zfs_close(h);
2465 
2466 				continue;
2467 ancestorerr:
2468 				zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2469 				    "failed to %s ancestor '%s'"), opname,
2470 				    zc.zc_name);
2471 				return (zfs_error(hdl, EZFS_BADRESTORE,
2472 				    errbuf));
2473 			}
2474 		}
2475 
2476 		/* Make sure destination fs does not exist */
2477 		cp = strchr(zc.zc_name, '@');
2478 		*cp = '\0';
2479 		if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0) {
2480 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2481 			    "destination '%s' exists"), zc.zc_name);
2482 			return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2483 		}
2484 
2485 		/* Do the recvbackup ioctl to the fs's parent. */
2486 		cp = strrchr(zc.zc_name, '/');
2487 		*cp = '\0';
2488 	}
2489 
2490 	(void) strcpy(zc.zc_prop_value, tosnap);
2491 	zc.zc_cookie = STDIN_FILENO;
2492 	zc.zc_intsz = isprefix;
2493 	if (verbose) {
2494 		(void) printf("%s %s stream of %s into %s\n",
2495 		    dryrun ? "would receive" : "receiving",
2496 		    drrb->drr_fromguid ? "incremental" : "full",
2497 		    drr.drr_u.drr_begin.drr_toname,
2498 		    zc.zc_filename);
2499 		(void) fflush(stdout);
2500 	}
2501 	if (dryrun)
2502 		return (0);
2503 	err = ioctl_err = ioctl(hdl->libzfs_fd, ZFS_IOC_RECVBACKUP, &zc);
2504 	if (ioctl_err != 0) {
2505 		switch (errno) {
2506 		case ENODEV:
2507 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2508 			    "most recent snapshot does not match incremental "
2509 			    "source"));
2510 			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
2511 			break;
2512 		case ETXTBSY:
2513 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2514 			    "destination has been modified since most recent "
2515 			    "snapshot"));
2516 			(void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
2517 			break;
2518 		case EEXIST:
2519 			if (drrb->drr_fromguid == 0) {
2520 				/* it's the containing fs that exists */
2521 				cp = strchr(zc.zc_filename, '@');
2522 				*cp = '\0';
2523 			}
2524 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2525 			    "destination already exists"));
2526 			(void) zfs_error(hdl, EZFS_EXISTS, dgettext(TEXT_DOMAIN,
2527 			    "cannot restore to %s"), zc.zc_filename);
2528 			break;
2529 		case EINVAL:
2530 			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2531 			break;
2532 		case ECKSUM:
2533 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2534 			    "invalid stream (checksum mismatch)"));
2535 			(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2536 			break;
2537 		default:
2538 			(void) zfs_standard_error(hdl, errno, errbuf);
2539 		}
2540 	}
2541 
2542 	/*
2543 	 * Mount or recreate the /dev links for the target filesystem
2544 	 * (if created, or if we tore them down to do an incremental
2545 	 * restore), and the /dev links for the new snapshot (if
2546 	 * created).
2547 	 */
2548 	cp = strchr(zc.zc_filename, '@');
2549 	if (cp && (ioctl_err == 0 || drrb->drr_fromguid)) {
2550 		zfs_handle_t *h;
2551 
2552 		*cp = '\0';
2553 		h = zfs_open(hdl, zc.zc_filename,
2554 		    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
2555 		*cp = '@';
2556 		if (h) {
2557 			if (h->zfs_type == ZFS_TYPE_FILESYSTEM) {
2558 				err = zfs_mount(h, NULL, 0);
2559 			} else {
2560 				err = zvol_create_link(hdl, h->zfs_name);
2561 				if (err == 0 && ioctl_err == 0)
2562 					err = zvol_create_link(hdl,
2563 					    zc.zc_filename);
2564 			}
2565 			zfs_close(h);
2566 		}
2567 	}
2568 
2569 	if (err || ioctl_err)
2570 		return (-1);
2571 
2572 	if (verbose) {
2573 		char buf1[64];
2574 		char buf2[64];
2575 		uint64_t bytes = zc.zc_cookie;
2576 		time_t delta = time(NULL) - begin_time;
2577 		if (delta == 0)
2578 			delta = 1;
2579 		zfs_nicenum(bytes, buf1, sizeof (buf1));
2580 		zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
2581 
2582 		(void) printf("received %sb stream in %lu seconds (%sb/sec)\n",
2583 		    buf1, delta, buf2);
2584 	}
2585 	return (0);
2586 }
2587 
2588 /*
2589  * Destroy any more recent snapshots.  We invoke this callback on any dependents
2590  * of the snapshot first.  If the 'cb_dependent' member is non-zero, then this
2591  * is a dependent and we should just destroy it without checking the transaction
2592  * group.
2593  */
2594 typedef struct rollback_data {
2595 	const char	*cb_target;		/* the snapshot */
2596 	uint64_t	cb_create;		/* creation time reference */
2597 	prop_changelist_t *cb_clp;		/* changelist pointer */
2598 	int		cb_error;
2599 	boolean_t	cb_dependent;
2600 } rollback_data_t;
2601 
2602 static int
2603 rollback_destroy(zfs_handle_t *zhp, void *data)
2604 {
2605 	rollback_data_t *cbp = data;
2606 
2607 	if (!cbp->cb_dependent) {
2608 		if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
2609 		    zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
2610 		    zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
2611 		    cbp->cb_create) {
2612 
2613 			cbp->cb_dependent = B_TRUE;
2614 			(void) zfs_iter_dependents(zhp, rollback_destroy, cbp);
2615 			cbp->cb_dependent = B_FALSE;
2616 
2617 			if (zfs_destroy(zhp) != 0)
2618 				cbp->cb_error = 1;
2619 			else
2620 				changelist_remove(zhp, cbp->cb_clp);
2621 		}
2622 	} else {
2623 		if (zfs_destroy(zhp) != 0)
2624 			cbp->cb_error = 1;
2625 		else
2626 			changelist_remove(zhp, cbp->cb_clp);
2627 	}
2628 
2629 	zfs_close(zhp);
2630 	return (0);
2631 }
2632 
2633 /*
2634  * Rollback the dataset to its latest snapshot.
2635  */
2636 static int
2637 do_rollback(zfs_handle_t *zhp)
2638 {
2639 	int ret;
2640 	zfs_cmd_t zc = { 0 };
2641 
2642 	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
2643 	    zhp->zfs_type == ZFS_TYPE_VOLUME);
2644 
2645 	if (zhp->zfs_type == ZFS_TYPE_VOLUME &&
2646 	    zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name) != 0)
2647 		return (-1);
2648 
2649 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2650 
2651 	if (zhp->zfs_volblocksize != 0)
2652 		zc.zc_objset_type = DMU_OST_ZVOL;
2653 	else
2654 		zc.zc_objset_type = DMU_OST_ZFS;
2655 
2656 	/*
2657 	 * We rely on the consumer to verify that there are no newer snapshots
2658 	 * for the given dataset.  Given these constraints, we can simply pass
2659 	 * the name on to the ioctl() call.  There is still an unlikely race
2660 	 * condition where the user has taken a snapshot since we verified that
2661 	 * this was the most recent.
2662 	 */
2663 	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_ROLLBACK,
2664 	    &zc)) != 0) {
2665 		(void) zfs_standard_error(zhp->zfs_hdl, errno,
2666 		    dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
2667 		    zhp->zfs_name);
2668 	} else if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
2669 		ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
2670 	}
2671 
2672 	return (ret);
2673 }
2674 
2675 /*
2676  * Given a dataset, rollback to a specific snapshot, discarding any
2677  * data changes since then and making it the active dataset.
2678  *
2679  * Any snapshots more recent than the target are destroyed, along with
2680  * their dependents.
2681  */
2682 int
2683 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, int flag)
2684 {
2685 	int ret;
2686 	rollback_data_t cb = { 0 };
2687 	prop_changelist_t *clp;
2688 
2689 	/*
2690 	 * Unmount all dependendents of the dataset and the dataset itself.
2691 	 * The list we need to gather is the same as for doing rename
2692 	 */
2693 	clp = changelist_gather(zhp, ZFS_PROP_NAME, flag ? MS_FORCE: 0);
2694 	if (clp == NULL)
2695 		return (-1);
2696 
2697 	if ((ret = changelist_prefix(clp)) != 0)
2698 		goto out;
2699 
2700 	/*
2701 	 * Destroy all recent snapshots and its dependends.
2702 	 */
2703 	cb.cb_target = snap->zfs_name;
2704 	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
2705 	cb.cb_clp = clp;
2706 	(void) zfs_iter_children(zhp, rollback_destroy, &cb);
2707 
2708 	if ((ret = cb.cb_error) != 0) {
2709 		(void) changelist_postfix(clp);
2710 		goto out;
2711 	}
2712 
2713 	/*
2714 	 * Now that we have verified that the snapshot is the latest,
2715 	 * rollback to the given snapshot.
2716 	 */
2717 	ret = do_rollback(zhp);
2718 
2719 	if (ret != 0) {
2720 		(void) changelist_postfix(clp);
2721 		goto out;
2722 	}
2723 
2724 	/*
2725 	 * We only want to re-mount the filesystem if it was mounted in the
2726 	 * first place.
2727 	 */
2728 	ret = changelist_postfix(clp);
2729 
2730 out:
2731 	changelist_free(clp);
2732 	return (ret);
2733 }
2734 
2735 /*
2736  * Iterate over all dependents for a given dataset.  This includes both
2737  * hierarchical dependents (children) and data dependents (snapshots and
2738  * clones).  The bulk of the processing occurs in get_dependents() in
2739  * libzfs_graph.c.
2740  */
2741 int
2742 zfs_iter_dependents(zfs_handle_t *zhp, zfs_iter_f func, void *data)
2743 {
2744 	char **dependents;
2745 	size_t count;
2746 	int i;
2747 	zfs_handle_t *child;
2748 	int ret = 0;
2749 
2750 	dependents = get_dependents(zhp->zfs_hdl, zhp->zfs_name, &count);
2751 	for (i = 0; i < count; i++) {
2752 		if ((child = make_dataset_handle(zhp->zfs_hdl,
2753 		    dependents[i])) == NULL)
2754 			continue;
2755 
2756 		if ((ret = func(child, data)) != 0)
2757 			break;
2758 	}
2759 
2760 	for (i = 0; i < count; i++)
2761 		free(dependents[i]);
2762 	free(dependents);
2763 
2764 	return (ret);
2765 }
2766 
2767 /*
2768  * Renames the given dataset.
2769  */
2770 int
2771 zfs_rename(zfs_handle_t *zhp, const char *target)
2772 {
2773 	int ret;
2774 	zfs_cmd_t zc = { 0 };
2775 	char *delim;
2776 	prop_changelist_t *cl;
2777 	char parent[ZFS_MAXNAMELEN];
2778 	libzfs_handle_t *hdl = zhp->zfs_hdl;
2779 	char errbuf[1024];
2780 
2781 	(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2782 	(void) strlcpy(zc.zc_prop_value, target, sizeof (zc.zc_prop_value));
2783 
2784 	/* if we have the same exact name, just return success */
2785 	if (strcmp(zhp->zfs_name, target) == 0)
2786 		return (0);
2787 
2788 	(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2789 	    "cannot rename to '%s'"), target);
2790 
2791 	/*
2792 	 * Make sure the target name is valid
2793 	 */
2794 	if (!zfs_validate_name(hdl, target, zhp->zfs_type))
2795 		return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2796 
2797 	if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
2798 
2799 		if ((delim = strchr(target, '@')) == NULL) {
2800 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2801 			    "not a snapshot"));
2802 			return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
2803 		}
2804 
2805 		/*
2806 		 * Make sure we're renaming within the same dataset.
2807 		 */
2808 		if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
2809 		    zhp->zfs_name[delim - target] != '@') {
2810 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2811 			    "snapshots must be part of same dataset"));
2812 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2813 		}
2814 
2815 		(void) strncpy(parent, target, delim - target);
2816 		parent[delim - target] = '\0';
2817 	} else {
2818 		/* validate parents */
2819 		if (check_parents(hdl, target) != 0)
2820 			return (-1);
2821 
2822 		(void) parent_name(target, parent, sizeof (parent));
2823 
2824 		/* make sure we're in the same pool */
2825 		verify((delim = strchr(target, '/')) != NULL);
2826 		if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
2827 		    zhp->zfs_name[delim - target] != '/') {
2828 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2829 			    "datasets must be within same pool"));
2830 			return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
2831 		}
2832 	}
2833 
2834 	(void) snprintf(errbuf, sizeof (errbuf),
2835 	    dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
2836 
2837 	if (getzoneid() == GLOBAL_ZONEID &&
2838 	    zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
2839 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2840 		    "dataset is used in a non-global zone"));
2841 		return (zfs_error(hdl, EZFS_ZONED, errbuf));
2842 	}
2843 
2844 	if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0)) == NULL)
2845 		return (-1);
2846 
2847 	if (changelist_haszonedchild(cl)) {
2848 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2849 		    "child dataset with inherited mountpoint is used "
2850 		    "in a non-global zone"));
2851 		ret = zfs_error(hdl, EZFS_ZONED, errbuf);
2852 		goto error;
2853 	}
2854 
2855 	if ((ret = changelist_prefix(cl)) != 0)
2856 		goto error;
2857 
2858 	if (zhp->zfs_volblocksize != 0)
2859 		zc.zc_objset_type = DMU_OST_ZVOL;
2860 	else
2861 		zc.zc_objset_type = DMU_OST_ZFS;
2862 
2863 	if ((ret = ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_RENAME, &zc)) != 0) {
2864 		(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
2865 
2866 		/*
2867 		 * On failure, we still want to remount any filesystems that
2868 		 * were previously mounted, so we don't alter the system state.
2869 		 */
2870 		(void) changelist_postfix(cl);
2871 	} else {
2872 		changelist_rename(cl, zfs_get_name(zhp), target);
2873 
2874 		ret = changelist_postfix(cl);
2875 	}
2876 
2877 error:
2878 	changelist_free(cl);
2879 	return (ret);
2880 }
2881 
2882 /*
2883  * Given a zvol dataset, issue the ioctl to create the appropriate minor node,
2884  * poke devfsadm to create the /dev link, and then wait for the link to appear.
2885  */
2886 int
2887 zvol_create_link(libzfs_handle_t *hdl, const char *dataset)
2888 {
2889 	zfs_cmd_t zc = { 0 };
2890 	di_devlink_handle_t dhdl;
2891 
2892 	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
2893 
2894 	/*
2895 	 * Issue the appropriate ioctl.
2896 	 */
2897 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_CREATE_MINOR, &zc) != 0) {
2898 		switch (errno) {
2899 		case EEXIST:
2900 			/*
2901 			 * Silently ignore the case where the link already
2902 			 * exists.  This allows 'zfs volinit' to be run multiple
2903 			 * times without errors.
2904 			 */
2905 			return (0);
2906 
2907 		default:
2908 			return (zfs_standard_error(hdl, errno,
2909 			    dgettext(TEXT_DOMAIN, "cannot create device links "
2910 			    "for '%s'"), dataset));
2911 		}
2912 	}
2913 
2914 	/*
2915 	 * Call devfsadm and wait for the links to magically appear.
2916 	 */
2917 	if ((dhdl = di_devlink_init(ZFS_DRIVER, DI_MAKE_LINK)) == NULL) {
2918 		zfs_error_aux(hdl, strerror(errno));
2919 		(void) zfs_error(hdl, EZFS_DEVLINKS,
2920 		    dgettext(TEXT_DOMAIN, "cannot create device links "
2921 		    "for '%s'"), dataset);
2922 		(void) ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc);
2923 		return (-1);
2924 	} else {
2925 		(void) di_devlink_fini(&dhdl);
2926 	}
2927 
2928 	return (0);
2929 }
2930 
2931 /*
2932  * Remove a minor node for the given zvol and the associated /dev links.
2933  */
2934 int
2935 zvol_remove_link(libzfs_handle_t *hdl, const char *dataset)
2936 {
2937 	zfs_cmd_t zc = { 0 };
2938 
2939 	(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
2940 
2941 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_REMOVE_MINOR, &zc) != 0) {
2942 		switch (errno) {
2943 		case ENXIO:
2944 			/*
2945 			 * Silently ignore the case where the link no longer
2946 			 * exists, so that 'zfs volfini' can be run multiple
2947 			 * times without errors.
2948 			 */
2949 			return (0);
2950 
2951 		default:
2952 			return (zfs_standard_error(hdl, errno,
2953 			    dgettext(TEXT_DOMAIN, "cannot remove device "
2954 			    "links for '%s'"), dataset));
2955 		}
2956 	}
2957 
2958 	return (0);
2959 }
2960