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