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