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