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