Home | History | Annotate | Download | only in zfs
      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 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include <assert.h>
     28 #include <ctype.h>
     29 #include <errno.h>
     30 #include <libgen.h>
     31 #include <libintl.h>
     32 #include <libuutil.h>
     33 #include <libnvpair.h>
     34 #include <locale.h>
     35 #include <stddef.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <strings.h>
     39 #include <unistd.h>
     40 #include <fcntl.h>
     41 #include <zone.h>
     42 #include <sys/mkdev.h>
     43 #include <sys/mntent.h>
     44 #include <sys/mnttab.h>
     45 #include <sys/mount.h>
     46 #include <sys/stat.h>
     47 #include <sys/avl.h>
     48 
     49 #include <libzfs.h>
     50 #include <libuutil.h>
     51 
     52 #include "zfs_iter.h"
     53 #include "zfs_util.h"
     54 
     55 libzfs_handle_t *g_zfs;
     56 
     57 static FILE *mnttab_file;
     58 static char history_str[HIS_MAX_RECORD_LEN];
     59 
     60 static int zfs_do_clone(int argc, char **argv);
     61 static int zfs_do_create(int argc, char **argv);
     62 static int zfs_do_destroy(int argc, char **argv);
     63 static int zfs_do_get(int argc, char **argv);
     64 static int zfs_do_inherit(int argc, char **argv);
     65 static int zfs_do_list(int argc, char **argv);
     66 static int zfs_do_mount(int argc, char **argv);
     67 static int zfs_do_rename(int argc, char **argv);
     68 static int zfs_do_rollback(int argc, char **argv);
     69 static int zfs_do_set(int argc, char **argv);
     70 static int zfs_do_upgrade(int argc, char **argv);
     71 static int zfs_do_snapshot(int argc, char **argv);
     72 static int zfs_do_unmount(int argc, char **argv);
     73 static int zfs_do_share(int argc, char **argv);
     74 static int zfs_do_unshare(int argc, char **argv);
     75 static int zfs_do_send(int argc, char **argv);
     76 static int zfs_do_receive(int argc, char **argv);
     77 static int zfs_do_promote(int argc, char **argv);
     78 static int zfs_do_allow(int argc, char **argv);
     79 static int zfs_do_unallow(int argc, char **argv);
     80 
     81 /*
     82  * Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
     83  */
     84 
     85 #ifdef DEBUG
     86 const char *
     87 _umem_debug_init(void)
     88 {
     89 	return ("default,verbose"); /* $UMEM_DEBUG setting */
     90 }
     91 
     92 const char *
     93 _umem_logging_init(void)
     94 {
     95 	return ("fail,contents"); /* $UMEM_LOGGING setting */
     96 }
     97 #endif
     98 
     99 typedef enum {
    100 	HELP_CLONE,
    101 	HELP_CREATE,
    102 	HELP_DESTROY,
    103 	HELP_GET,
    104 	HELP_INHERIT,
    105 	HELP_UPGRADE,
    106 	HELP_LIST,
    107 	HELP_MOUNT,
    108 	HELP_PROMOTE,
    109 	HELP_RECEIVE,
    110 	HELP_RENAME,
    111 	HELP_ROLLBACK,
    112 	HELP_SEND,
    113 	HELP_SET,
    114 	HELP_SHARE,
    115 	HELP_SNAPSHOT,
    116 	HELP_UNMOUNT,
    117 	HELP_UNSHARE,
    118 	HELP_ALLOW,
    119 	HELP_UNALLOW
    120 } zfs_help_t;
    121 
    122 typedef struct zfs_command {
    123 	const char	*name;
    124 	int		(*func)(int argc, char **argv);
    125 	zfs_help_t	usage;
    126 } zfs_command_t;
    127 
    128 /*
    129  * Master command table.  Each ZFS command has a name, associated function, and
    130  * usage message.  The usage messages need to be internationalized, so we have
    131  * to have a function to return the usage message based on a command index.
    132  *
    133  * These commands are organized according to how they are displayed in the usage
    134  * message.  An empty command (one with a NULL name) indicates an empty line in
    135  * the generic usage message.
    136  */
    137 static zfs_command_t command_table[] = {
    138 	{ "create",	zfs_do_create,		HELP_CREATE		},
    139 	{ "destroy",	zfs_do_destroy,		HELP_DESTROY		},
    140 	{ NULL },
    141 	{ "snapshot",	zfs_do_snapshot,	HELP_SNAPSHOT		},
    142 	{ "rollback",	zfs_do_rollback,	HELP_ROLLBACK		},
    143 	{ "clone",	zfs_do_clone,		HELP_CLONE		},
    144 	{ "promote",	zfs_do_promote,		HELP_PROMOTE		},
    145 	{ "rename",	zfs_do_rename,		HELP_RENAME		},
    146 	{ NULL },
    147 	{ "list",	zfs_do_list,		HELP_LIST		},
    148 	{ NULL },
    149 	{ "set",	zfs_do_set,		HELP_SET		},
    150 	{ "get", 	zfs_do_get,		HELP_GET		},
    151 	{ "inherit",	zfs_do_inherit,		HELP_INHERIT		},
    152 	{ "upgrade",	zfs_do_upgrade,		HELP_UPGRADE		},
    153 	{ NULL },
    154 	{ "mount",	zfs_do_mount,		HELP_MOUNT		},
    155 	{ "unmount",	zfs_do_unmount,		HELP_UNMOUNT		},
    156 	{ "share",	zfs_do_share,		HELP_SHARE		},
    157 	{ "unshare",	zfs_do_unshare,		HELP_UNSHARE		},
    158 	{ NULL },
    159 	{ "send",	zfs_do_send,		HELP_SEND		},
    160 	{ "receive",	zfs_do_receive,		HELP_RECEIVE		},
    161 	{ NULL },
    162 	{ "allow",	zfs_do_allow,		HELP_ALLOW		},
    163 	{ NULL },
    164 	{ "unallow",	zfs_do_unallow,		HELP_UNALLOW		},
    165 };
    166 
    167 #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
    168 
    169 zfs_command_t *current_command;
    170 
    171 static const char *
    172 get_usage(zfs_help_t idx)
    173 {
    174 	switch (idx) {
    175 	case HELP_CLONE:
    176 		return (gettext("\tclone [-p] [-o property=value] ... "
    177 		    "<snapshot> <filesystem|volume>\n"));
    178 	case HELP_CREATE:
    179 		return (gettext("\tcreate [-p] [-o property=value] ... "
    180 		    "<filesystem>\n"
    181 		    "\tcreate [-ps] [-b blocksize] [-o property=value] ... "
    182 		    "-V <size> <volume>\n"));
    183 	case HELP_DESTROY:
    184 		return (gettext("\tdestroy [-rRf] "
    185 		    "<filesystem|volume|snapshot>\n"));
    186 	case HELP_GET:
    187 		return (gettext("\tget [-rHp] [-o field[,...]] "
    188 		    "[-s source[,...]]\n"
    189 		    "\t    <\"all\" | property[,...]> "
    190 		    "[filesystem|volume|snapshot] ...\n"));
    191 	case HELP_INHERIT:
    192 		return (gettext("\tinherit [-r] <property> "
    193 		    "<filesystem|volume|snapshot> ...\n"));
    194 	case HELP_UPGRADE:
    195 		return (gettext("\tupgrade [-v]\n"
    196 		    "\tupgrade [-r] [-V version] <-a | filesystem ...>\n"));
    197 	case HELP_LIST:
    198 		return (gettext("\tlist [-rH] [-o property[,...]] "
    199 		    "[-t type[,...]] [-s property] ...\n"
    200 		    "\t    [-S property] ... "
    201 		    "[filesystem|volume|snapshot] ...\n"));
    202 	case HELP_MOUNT:
    203 		return (gettext("\tmount\n"
    204 		    "\tmount [-vO] [-o opts] <-a | filesystem>\n"));
    205 	case HELP_PROMOTE:
    206 		return (gettext("\tpromote <clone-filesystem>\n"));
    207 	case HELP_RECEIVE:
    208 		return (gettext("\treceive [-vnF] <filesystem|volume|"
    209 		"snapshot>\n"
    210 		"\treceive [-vnF] -d <filesystem>\n"));
    211 	case HELP_RENAME:
    212 		return (gettext("\trename <filesystem|volume|snapshot> "
    213 		    "<filesystem|volume|snapshot>\n"
    214 		    "\trename -p <filesystem|volume> <filesystem|volume>\n"
    215 		    "\trename -r <snapshot> <snapshot>"));
    216 	case HELP_ROLLBACK:
    217 		return (gettext("\trollback [-rRf] <snapshot>\n"));
    218 	case HELP_SEND:
    219 		return (gettext("\tsend [-R] [-[iI] snapshot] <snapshot>\n"));
    220 	case HELP_SET:
    221 		return (gettext("\tset <property=value> "
    222 		    "<filesystem|volume|snapshot> ...\n"));
    223 	case HELP_SHARE:
    224 		return (gettext("\tshare <-a | filesystem>\n"));
    225 	case HELP_SNAPSHOT:
    226 		return (gettext("\tsnapshot [-r] [-o property=value] ... "
    227 		    "<filesystem@snapname|volume@snapname>\n"));
    228 	case HELP_UNMOUNT:
    229 		return (gettext("\tunmount [-f] "
    230 		    "<-a | filesystem|mountpoint>\n"));
    231 	case HELP_UNSHARE:
    232 		return (gettext("\tunshare [-f] "
    233 		    "<-a | filesystem|mountpoint>\n"));
    234 	case HELP_ALLOW:
    235 		return (gettext("\tallow [-ldug] "
    236 		    "<\"everyone\"|user|group>[,...] <perm|@setname>[,...]\n"
    237 		    "\t    <filesystem|volume>\n"
    238 		    "\tallow [-ld] -e <perm|@setname>[,...] "
    239 		    "<filesystem|volume>\n"
    240 		    "\tallow -c <perm|@setname>[,...] <filesystem|volume>\n"
    241 		    "\tallow -s @setname <perm|@setname>[,...] "
    242 		    "<filesystem|volume>\n"));
    243 	case HELP_UNALLOW:
    244 		return (gettext("\tunallow [-rldug] "
    245 		    "<\"everyone\"|user|group>[,...]\n"
    246 		    "\t    [<perm|@setname>[,...]] <filesystem|volume>\n"
    247 		    "\tunallow [-rld] -e [<perm|@setname>[,...]] "
    248 		    "<filesystem|volume>\n"
    249 		    "\tunallow [-r] -c [<perm|@setname>[,...]] "
    250 		    "<filesystem|volume>\n"
    251 		    "\tunallow [-r] -s @setname [<perm|@setname>[,...]] "
    252 		    "<filesystem|volume>\n"));
    253 	}
    254 
    255 	abort();
    256 	/* NOTREACHED */
    257 }
    258 
    259 /*
    260  * Utility function to guarantee malloc() success.
    261  */
    262 void *
    263 safe_malloc(size_t size)
    264 {
    265 	void *data;
    266 
    267 	if ((data = calloc(1, size)) == NULL) {
    268 		(void) fprintf(stderr, "internal error: out of memory\n");
    269 		exit(1);
    270 	}
    271 
    272 	return (data);
    273 }
    274 
    275 /*
    276  * Callback routine that will print out information for each of
    277  * the properties.
    278  */
    279 static int
    280 usage_prop_cb(int prop, void *cb)
    281 {
    282 	FILE *fp = cb;
    283 
    284 	(void) fprintf(fp, "\t%-15s ", zfs_prop_to_name(prop));
    285 
    286 	if (zfs_prop_readonly(prop))
    287 		(void) fprintf(fp, " NO    ");
    288 	else
    289 		(void) fprintf(fp, "YES    ");
    290 
    291 	if (zfs_prop_inheritable(prop))
    292 		(void) fprintf(fp, "  YES   ");
    293 	else
    294 		(void) fprintf(fp, "   NO   ");
    295 
    296 	if (zfs_prop_values(prop) == NULL)
    297 		(void) fprintf(fp, "-\n");
    298 	else
    299 		(void) fprintf(fp, "%s\n", zfs_prop_values(prop));
    300 
    301 	return (ZPROP_CONT);
    302 }
    303 
    304 /*
    305  * Display usage message.  If we're inside a command, display only the usage for
    306  * that command.  Otherwise, iterate over the entire command table and display
    307  * a complete usage message.
    308  */
    309 static void
    310 usage(boolean_t requested)
    311 {
    312 	int i;
    313 	boolean_t show_properties = B_FALSE;
    314 	boolean_t show_permissions = B_FALSE;
    315 	FILE *fp = requested ? stdout : stderr;
    316 
    317 	if (current_command == NULL) {
    318 
    319 		(void) fprintf(fp, gettext("usage: zfs command args ...\n"));
    320 		(void) fprintf(fp,
    321 		    gettext("where 'command' is one of the following:\n\n"));
    322 
    323 		for (i = 0; i < NCOMMAND; i++) {
    324 			if (command_table[i].name == NULL)
    325 				(void) fprintf(fp, "\n");
    326 			else
    327 				(void) fprintf(fp, "%s",
    328 				    get_usage(command_table[i].usage));
    329 		}
    330 
    331 		(void) fprintf(fp, gettext("\nEach dataset is of the form: "
    332 		    "pool/[dataset/]*dataset[@name]\n"));
    333 	} else {
    334 		(void) fprintf(fp, gettext("usage:\n"));
    335 		(void) fprintf(fp, "%s", get_usage(current_command->usage));
    336 	}
    337 
    338 	if (current_command != NULL &&
    339 	    (strcmp(current_command->name, "set") == 0 ||
    340 	    strcmp(current_command->name, "get") == 0 ||
    341 	    strcmp(current_command->name, "inherit") == 0 ||
    342 	    strcmp(current_command->name, "list") == 0))
    343 		show_properties = B_TRUE;
    344 
    345 	if (current_command != NULL &&
    346 	    (strcmp(current_command->name, "allow") == 0 ||
    347 	    strcmp(current_command->name, "unallow") == 0))
    348 		show_permissions = B_TRUE;
    349 
    350 	if (show_properties) {
    351 
    352 		(void) fprintf(fp,
    353 		    gettext("\nThe following properties are supported:\n"));
    354 
    355 		(void) fprintf(fp, "\n\t%-14s %s  %s   %s\n\n",
    356 		    "PROPERTY", "EDIT", "INHERIT", "VALUES");
    357 
    358 		/* Iterate over all properties */
    359 		(void) zprop_iter(usage_prop_cb, fp, B_FALSE, B_TRUE,
    360 		    ZFS_TYPE_DATASET);
    361 
    362 		(void) fprintf(fp, gettext("\nSizes are specified in bytes "
    363 		    "with standard units such as K, M, G, etc.\n"));
    364 		(void) fprintf(fp, gettext("\n\nUser-defined properties can "
    365 		    "be specified by using a name containing a colon (:).\n"));
    366 
    367 	} else if (show_permissions) {
    368 		(void) fprintf(fp,
    369 		    gettext("\nThe following permissions are supported:\n"));
    370 
    371 		zfs_deleg_permissions();
    372 	} else {
    373 		/*
    374 		 * TRANSLATION NOTE:
    375 		 * "zfs set|get" must not be localised this is the
    376 		 * command name and arguments.
    377 		 */
    378 
    379 		(void) fprintf(fp,
    380 		    gettext("\nFor the property list, run: zfs set|get\n"));
    381 
    382 		(void) fprintf(fp,
    383 		    gettext("\nFor the delegated permission list, run:"
    384 		    " zfs allow|unallow\n"));
    385 	}
    386 
    387 	/*
    388 	 * See comments at end of main().
    389 	 */
    390 	if (getenv("ZFS_ABORT") != NULL) {
    391 		(void) printf("dumping core by request\n");
    392 		abort();
    393 	}
    394 
    395 	exit(requested ? 0 : 2);
    396 }
    397 
    398 static int
    399 parseprop(nvlist_t *props)
    400 {
    401 	char *propname = optarg;
    402 	char *propval, *strval;
    403 
    404 	if ((propval = strchr(propname, '=')) == NULL) {
    405 		(void) fprintf(stderr, gettext("missing "
    406 		    "'=' for -o option\n"));
    407 		return (-1);
    408 	}
    409 	*propval = '\0';
    410 	propval++;
    411 	if (nvlist_lookup_string(props, propname, &strval) == 0) {
    412 		(void) fprintf(stderr, gettext("property '%s' "
    413 		    "specified multiple times\n"), propname);
    414 		return (-1);
    415 	}
    416 	if (nvlist_add_string(props, propname, propval) != 0) {
    417 		(void) fprintf(stderr, gettext("internal "
    418 		    "error: out of memory\n"));
    419 		return (-1);
    420 	}
    421 	return (0);
    422 
    423 }
    424 
    425 /*
    426  * zfs clone [-p] [-o prop=value] ... <snap> <fs | vol>
    427  *
    428  * Given an existing dataset, create a writable copy whose initial contents
    429  * are the same as the source.  The newly created dataset maintains a
    430  * dependency on the original; the original cannot be destroyed so long as
    431  * the clone exists.
    432  *
    433  * The '-p' flag creates all the non-existing ancestors of the target first.
    434  */
    435 static int
    436 zfs_do_clone(int argc, char **argv)
    437 {
    438 	zfs_handle_t *zhp = NULL;
    439 	boolean_t parents = B_FALSE;
    440 	nvlist_t *props;
    441 	int ret;
    442 	int c;
    443 
    444 	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
    445 		(void) fprintf(stderr, gettext("internal error: "
    446 		    "out of memory\n"));
    447 		return (1);
    448 	}
    449 
    450 	/* check options */
    451 	while ((c = getopt(argc, argv, "o:p")) != -1) {
    452 		switch (c) {
    453 		case 'o':
    454 			if (parseprop(props))
    455 				return (1);
    456 			break;
    457 		case 'p':
    458 			parents = B_TRUE;
    459 			break;
    460 		case '?':
    461 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    462 			    optopt);
    463 			goto usage;
    464 		}
    465 	}
    466 
    467 	argc -= optind;
    468 	argv += optind;
    469 
    470 	/* check number of arguments */
    471 	if (argc < 1) {
    472 		(void) fprintf(stderr, gettext("missing source dataset "
    473 		    "argument\n"));
    474 		goto usage;
    475 	}
    476 	if (argc < 2) {
    477 		(void) fprintf(stderr, gettext("missing target dataset "
    478 		    "argument\n"));
    479 		goto usage;
    480 	}
    481 	if (argc > 2) {
    482 		(void) fprintf(stderr, gettext("too many arguments\n"));
    483 		goto usage;
    484 	}
    485 
    486 	/* open the source dataset */
    487 	if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_SNAPSHOT)) == NULL)
    488 		return (1);
    489 
    490 	if (parents && zfs_name_valid(argv[1], ZFS_TYPE_FILESYSTEM |
    491 	    ZFS_TYPE_VOLUME)) {
    492 		/*
    493 		 * Now create the ancestors of the target dataset.  If the
    494 		 * target already exists and '-p' option was used we should not
    495 		 * complain.
    496 		 */
    497 		if (zfs_dataset_exists(g_zfs, argv[1], ZFS_TYPE_FILESYSTEM |
    498 		    ZFS_TYPE_VOLUME))
    499 			return (0);
    500 		if (zfs_create_ancestors(g_zfs, argv[1]) != 0)
    501 			return (1);
    502 	}
    503 
    504 	/* pass to libzfs */
    505 	ret = zfs_clone(zhp, argv[1], props);
    506 
    507 	/* create the mountpoint if necessary */
    508 	if (ret == 0) {
    509 		zfs_handle_t *clone;
    510 
    511 		clone = zfs_open(g_zfs, argv[1], ZFS_TYPE_DATASET);
    512 		if (clone != NULL) {
    513 			if ((ret = zfs_mount(clone, NULL, 0)) == 0)
    514 				ret = zfs_share(clone);
    515 			zfs_close(clone);
    516 		}
    517 	}
    518 
    519 	zfs_close(zhp);
    520 	nvlist_free(props);
    521 
    522 	return (!!ret);
    523 
    524 usage:
    525 	if (zhp)
    526 		zfs_close(zhp);
    527 	nvlist_free(props);
    528 	usage(B_FALSE);
    529 	return (-1);
    530 }
    531 
    532 /*
    533  * zfs create [-p] [-o prop=value] ... fs
    534  * zfs create [-ps] [-b blocksize] [-o prop=value] ... -V vol size
    535  *
    536  * Create a new dataset.  This command can be used to create filesystems
    537  * and volumes.  Snapshot creation is handled by 'zfs snapshot'.
    538  * For volumes, the user must specify a size to be used.
    539  *
    540  * The '-s' flag applies only to volumes, and indicates that we should not try
    541  * to set the reservation for this volume.  By default we set a reservation
    542  * equal to the size for any volume.  For pools with SPA_VERSION >=
    543  * SPA_VERSION_REFRESERVATION, we set a refreservation instead.
    544  *
    545  * The '-p' flag creates all the non-existing ancestors of the target first.
    546  */
    547 static int
    548 zfs_do_create(int argc, char **argv)
    549 {
    550 	zfs_type_t type = ZFS_TYPE_FILESYSTEM;
    551 	zfs_handle_t *zhp = NULL;
    552 	uint64_t volsize;
    553 	int c;
    554 	boolean_t noreserve = B_FALSE;
    555 	boolean_t bflag = B_FALSE;
    556 	boolean_t parents = B_FALSE;
    557 	int ret = 1;
    558 	nvlist_t *props;
    559 	uint64_t intval;
    560 	int canmount;
    561 
    562 	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
    563 		(void) fprintf(stderr, gettext("internal error: "
    564 		    "out of memory\n"));
    565 		return (1);
    566 	}
    567 
    568 	/* check options */
    569 	while ((c = getopt(argc, argv, ":V:b:so:p")) != -1) {
    570 		switch (c) {
    571 		case 'V':
    572 			type = ZFS_TYPE_VOLUME;
    573 			if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
    574 				(void) fprintf(stderr, gettext("bad volume "
    575 				    "size '%s': %s\n"), optarg,
    576 				    libzfs_error_description(g_zfs));
    577 				goto error;
    578 			}
    579 
    580 			if (nvlist_add_uint64(props,
    581 			    zfs_prop_to_name(ZFS_PROP_VOLSIZE),
    582 			    intval) != 0) {
    583 				(void) fprintf(stderr, gettext("internal "
    584 				    "error: out of memory\n"));
    585 				goto error;
    586 			}
    587 			volsize = intval;
    588 			break;
    589 		case 'p':
    590 			parents = B_TRUE;
    591 			break;
    592 		case 'b':
    593 			bflag = B_TRUE;
    594 			if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
    595 				(void) fprintf(stderr, gettext("bad volume "
    596 				    "block size '%s': %s\n"), optarg,
    597 				    libzfs_error_description(g_zfs));
    598 				goto error;
    599 			}
    600 
    601 			if (nvlist_add_uint64(props,
    602 			    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
    603 			    intval) != 0) {
    604 				(void) fprintf(stderr, gettext("internal "
    605 				    "error: out of memory\n"));
    606 				goto error;
    607 			}
    608 			break;
    609 		case 'o':
    610 			if (parseprop(props))
    611 				goto error;
    612 			break;
    613 		case 's':
    614 			noreserve = B_TRUE;
    615 			break;
    616 		case ':':
    617 			(void) fprintf(stderr, gettext("missing size "
    618 			    "argument\n"));
    619 			goto badusage;
    620 			break;
    621 		case '?':
    622 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    623 			    optopt);
    624 			goto badusage;
    625 		}
    626 	}
    627 
    628 	if ((bflag || noreserve) && type != ZFS_TYPE_VOLUME) {
    629 		(void) fprintf(stderr, gettext("'-s' and '-b' can only be "
    630 		    "used when creating a volume\n"));
    631 		goto badusage;
    632 	}
    633 
    634 	argc -= optind;
    635 	argv += optind;
    636 
    637 	/* check number of arguments */
    638 	if (argc == 0) {
    639 		(void) fprintf(stderr, gettext("missing %s argument\n"),
    640 		    zfs_type_to_name(type));
    641 		goto badusage;
    642 	}
    643 	if (argc > 1) {
    644 		(void) fprintf(stderr, gettext("too many arguments\n"));
    645 		goto badusage;
    646 	}
    647 
    648 	if (type == ZFS_TYPE_VOLUME && !noreserve) {
    649 		zpool_handle_t *zpool_handle;
    650 		uint64_t spa_version;
    651 		char *p;
    652 		zfs_prop_t resv_prop;
    653 		char *strval;
    654 
    655 		if (p = strchr(argv[0], '/'))
    656 			*p = '\0';
    657 		zpool_handle = zpool_open(g_zfs, argv[0]);
    658 		if (p != NULL)
    659 			*p = '/';
    660 		if (zpool_handle == NULL)
    661 			goto error;
    662 		spa_version = zpool_get_prop_int(zpool_handle,
    663 		    ZPOOL_PROP_VERSION, NULL);
    664 		zpool_close(zpool_handle);
    665 		if (spa_version >= SPA_VERSION_REFRESERVATION)
    666 			resv_prop = ZFS_PROP_REFRESERVATION;
    667 		else
    668 			resv_prop = ZFS_PROP_RESERVATION;
    669 
    670 		if (nvlist_lookup_string(props, zfs_prop_to_name(resv_prop),
    671 		    &strval) != 0) {
    672 			if (nvlist_add_uint64(props,
    673 			    zfs_prop_to_name(resv_prop), volsize) != 0) {
    674 				(void) fprintf(stderr, gettext("internal "
    675 				    "error: out of memory\n"));
    676 				nvlist_free(props);
    677 				return (1);
    678 			}
    679 		}
    680 	}
    681 
    682 	if (parents && zfs_name_valid(argv[0], type)) {
    683 		/*
    684 		 * Now create the ancestors of target dataset.  If the target
    685 		 * already exists and '-p' option was used we should not
    686 		 * complain.
    687 		 */
    688 		if (zfs_dataset_exists(g_zfs, argv[0], type)) {
    689 			ret = 0;
    690 			goto error;
    691 		}
    692 		if (zfs_create_ancestors(g_zfs, argv[0]) != 0)
    693 			goto error;
    694 	}
    695 
    696 	/* pass to libzfs */
    697 	if (zfs_create(g_zfs, argv[0], type, props) != 0)
    698 		goto error;
    699 
    700 	if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
    701 		goto error;
    702 	/*
    703 	 * if the user doesn't want the dataset automatically mounted,
    704 	 * then skip the mount/share step
    705 	 */
    706 
    707 	canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
    708 
    709 	/*
    710 	 * Mount and/or share the new filesystem as appropriate.  We provide a
    711 	 * verbose error message to let the user know that their filesystem was
    712 	 * in fact created, even if we failed to mount or share it.
    713 	 */
    714 	ret = 0;
    715 	if (canmount == ZFS_CANMOUNT_ON) {
    716 		if (zfs_mount(zhp, NULL, 0) != 0) {
    717 			(void) fprintf(stderr, gettext("filesystem "
    718 			    "successfully created, but not mounted\n"));
    719 			ret = 1;
    720 		} else if (zfs_share(zhp) != 0) {
    721 			(void) fprintf(stderr, gettext("filesystem "
    722 			    "successfully created, but not shared\n"));
    723 			ret = 1;
    724 		}
    725 	}
    726 
    727 error:
    728 	if (zhp)
    729 		zfs_close(zhp);
    730 	nvlist_free(props);
    731 	return (ret);
    732 badusage:
    733 	nvlist_free(props);
    734 	usage(B_FALSE);
    735 	return (2);
    736 }
    737 
    738 /*
    739  * zfs destroy [-rf] <fs, snap, vol>
    740  *
    741  * 	-r	Recursively destroy all children
    742  * 	-R	Recursively destroy all dependents, including clones
    743  * 	-f	Force unmounting of any dependents
    744  *
    745  * Destroys the given dataset.  By default, it will unmount any filesystems,
    746  * and refuse to destroy a dataset that has any dependents.  A dependent can
    747  * either be a child, or a clone of a child.
    748  */
    749 typedef struct destroy_cbdata {
    750 	boolean_t	cb_first;
    751 	int		cb_force;
    752 	int		cb_recurse;
    753 	int		cb_error;
    754 	int		cb_needforce;
    755 	int		cb_doclones;
    756 	boolean_t	cb_closezhp;
    757 	zfs_handle_t	*cb_target;
    758 	char		*cb_snapname;
    759 } destroy_cbdata_t;
    760 
    761 /*
    762  * Check for any dependents based on the '-r' or '-R' flags.
    763  */
    764 static int
    765 destroy_check_dependent(zfs_handle_t *zhp, void *data)
    766 {
    767 	destroy_cbdata_t *cbp = data;
    768 	const char *tname = zfs_get_name(cbp->cb_target);
    769 	const char *name = zfs_get_name(zhp);
    770 
    771 	if (strncmp(tname, name, strlen(tname)) == 0 &&
    772 	    (name[strlen(tname)] == '/' || name[strlen(tname)] == '@')) {
    773 		/*
    774 		 * This is a direct descendant, not a clone somewhere else in
    775 		 * the hierarchy.
    776 		 */
    777 		if (cbp->cb_recurse)
    778 			goto out;
    779 
    780 		if (cbp->cb_first) {
    781 			(void) fprintf(stderr, gettext("cannot destroy '%s': "
    782 			    "%s has children\n"),
    783 			    zfs_get_name(cbp->cb_target),
    784 			    zfs_type_to_name(zfs_get_type(cbp->cb_target)));
    785 			(void) fprintf(stderr, gettext("use '-r' to destroy "
    786 			    "the following datasets:\n"));
    787 			cbp->cb_first = B_FALSE;
    788 			cbp->cb_error = 1;
    789 		}
    790 
    791 		(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
    792 	} else {
    793 		/*
    794 		 * This is a clone.  We only want to report this if the '-r'
    795 		 * wasn't specified, or the target is a snapshot.
    796 		 */
    797 		if (!cbp->cb_recurse &&
    798 		    zfs_get_type(cbp->cb_target) != ZFS_TYPE_SNAPSHOT)
    799 			goto out;
    800 
    801 		if (cbp->cb_first) {
    802 			(void) fprintf(stderr, gettext("cannot destroy '%s': "
    803 			    "%s has dependent clones\n"),
    804 			    zfs_get_name(cbp->cb_target),
    805 			    zfs_type_to_name(zfs_get_type(cbp->cb_target)));
    806 			(void) fprintf(stderr, gettext("use '-R' to destroy "
    807 			    "the following datasets:\n"));
    808 			cbp->cb_first = B_FALSE;
    809 			cbp->cb_error = 1;
    810 		}
    811 
    812 		(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
    813 	}
    814 
    815 out:
    816 	zfs_close(zhp);
    817 	return (0);
    818 }
    819 
    820 static int
    821 destroy_callback(zfs_handle_t *zhp, void *data)
    822 {
    823 	destroy_cbdata_t *cbp = data;
    824 
    825 	/*
    826 	 * Ignore pools (which we've already flagged as an error before getting
    827 	 * here.
    828 	 */
    829 	if (strchr(zfs_get_name(zhp), '/') == NULL &&
    830 	    zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
    831 		zfs_close(zhp);
    832 		return (0);
    833 	}
    834 
    835 	/*
    836 	 * Bail out on the first error.
    837 	 */
    838 	if (zfs_unmount(zhp, NULL, cbp->cb_force ? MS_FORCE : 0) != 0 ||
    839 	    zfs_destroy(zhp) != 0) {
    840 		zfs_close(zhp);
    841 		return (-1);
    842 	}
    843 
    844 	zfs_close(zhp);
    845 	return (0);
    846 }
    847 
    848 static int
    849 destroy_snap_clones(zfs_handle_t *zhp, void *arg)
    850 {
    851 	destroy_cbdata_t *cbp = arg;
    852 	char thissnap[MAXPATHLEN];
    853 	zfs_handle_t *szhp;
    854 	boolean_t closezhp = cbp->cb_closezhp;
    855 	int rv;
    856 
    857 	(void) snprintf(thissnap, sizeof (thissnap),
    858 	    "%s@%s", zfs_get_name(zhp), cbp->cb_snapname);
    859 
    860 	libzfs_print_on_error(g_zfs, B_FALSE);
    861 	szhp = zfs_open(g_zfs, thissnap, ZFS_TYPE_SNAPSHOT);
    862 	libzfs_print_on_error(g_zfs, B_TRUE);
    863 	if (szhp) {
    864 		/*
    865 		 * Destroy any clones of this snapshot
    866 		 */
    867 		if (zfs_iter_dependents(szhp, B_FALSE, destroy_callback,
    868 		    cbp) != 0) {
    869 			zfs_close(szhp);
    870 			if (closezhp)
    871 				zfs_close(zhp);
    872 			return (-1);
    873 		}
    874 		zfs_close(szhp);
    875 	}
    876 
    877 	cbp->cb_closezhp = B_TRUE;
    878 	rv = zfs_iter_filesystems(zhp, destroy_snap_clones, arg);
    879 	if (closezhp)
    880 		zfs_close(zhp);
    881 	return (rv);
    882 }
    883 
    884 static int
    885 zfs_do_destroy(int argc, char **argv)
    886 {
    887 	destroy_cbdata_t cb = { 0 };
    888 	int c;
    889 	zfs_handle_t *zhp;
    890 	char *cp;
    891 
    892 	/* check options */
    893 	while ((c = getopt(argc, argv, "frR")) != -1) {
    894 		switch (c) {
    895 		case 'f':
    896 			cb.cb_force = 1;
    897 			break;
    898 		case 'r':
    899 			cb.cb_recurse = 1;
    900 			break;
    901 		case 'R':
    902 			cb.cb_recurse = 1;
    903 			cb.cb_doclones = 1;
    904 			break;
    905 		case '?':
    906 		default:
    907 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
    908 			    optopt);
    909 			usage(B_FALSE);
    910 		}
    911 	}
    912 
    913 	argc -= optind;
    914 	argv += optind;
    915 
    916 	/* check number of arguments */
    917 	if (argc == 0) {
    918 		(void) fprintf(stderr, gettext("missing path argument\n"));
    919 		usage(B_FALSE);
    920 	}
    921 	if (argc > 1) {
    922 		(void) fprintf(stderr, gettext("too many arguments\n"));
    923 		usage(B_FALSE);
    924 	}
    925 
    926 	/*
    927 	 * If we are doing recursive destroy of a snapshot, then the
    928 	 * named snapshot may not exist.  Go straight to libzfs.
    929 	 */
    930 	if (cb.cb_recurse && (cp = strchr(argv[0], '@'))) {
    931 		int ret;
    932 
    933 		*cp = '\0';
    934 		if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
    935 			return (1);
    936 		*cp = '@';
    937 		cp++;
    938 
    939 		if (cb.cb_doclones) {
    940 			cb.cb_snapname = cp;
    941 			if (destroy_snap_clones(zhp, &cb) != 0) {
    942 				zfs_close(zhp);
    943 				return (1);
    944 			}
    945 		}
    946 
    947 		ret = zfs_destroy_snaps(zhp, cp);
    948 		zfs_close(zhp);
    949 		if (ret) {
    950 			(void) fprintf(stderr,
    951 			    gettext("no snapshots destroyed\n"));
    952 		}
    953 		return (ret != 0);
    954 	}
    955 
    956 
    957 	/* Open the given dataset */
    958 	if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
    959 		return (1);
    960 
    961 	cb.cb_target = zhp;
    962 
    963 	/*
    964 	 * Perform an explicit check for pools before going any further.
    965 	 */
    966 	if (!cb.cb_recurse && strchr(zfs_get_name(zhp), '/') == NULL &&
    967 	    zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
    968 		(void) fprintf(stderr, gettext("cannot destroy '%s': "
    969 		    "operation does not apply to pools\n"),
    970 		    zfs_get_name(zhp));
    971 		(void) fprintf(stderr, gettext("use 'zfs destroy -r "
    972 		    "%s' to destroy all datasets in the pool\n"),
    973 		    zfs_get_name(zhp));
    974 		(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
    975 		    "to destroy the pool itself\n"), zfs_get_name(zhp));
    976 		zfs_close(zhp);
    977 		return (1);
    978 	}
    979 
    980 	/*
    981 	 * Check for any dependents and/or clones.
    982 	 */
    983 	cb.cb_first = B_TRUE;
    984 	if (!cb.cb_doclones &&
    985 	    zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
    986 	    &cb) != 0) {
    987 		zfs_close(zhp);
    988 		return (1);
    989 	}
    990 
    991 	if (cb.cb_error ||
    992 	    zfs_iter_dependents(zhp, B_FALSE, destroy_callback, &cb) != 0) {
    993 		zfs_close(zhp);
    994 		return (1);
    995 	}
    996 
    997 	/*
    998 	 * Do the real thing.  The callback will close the handle regardless of
    999 	 * whether it succeeds or not.
   1000 	 */
   1001 
   1002 	if (destroy_callback(zhp, &cb) != 0)
   1003 		return (1);
   1004 
   1005 
   1006 	return (0);
   1007 }
   1008 
   1009 /*
   1010  * zfs get [-rHp] [-o field[,field]...] [-s source[,source]...]
   1011  * 	< all | property[,property]... > < fs | snap | vol > ...
   1012  *
   1013  *	-r	recurse over any child datasets
   1014  *	-H	scripted mode.  Headers are stripped, and fields are separated
   1015  *		by tabs instead of spaces.
   1016  *	-o	Set of fields to display.  One of "name,property,value,source".
   1017  *		Default is all four.
   1018  *	-s	Set of sources to allow.  One of
   1019  *		"local,default,inherited,temporary,none".  Default is all
   1020  *		five.
   1021  *	-p	Display values in parsable (literal) format.
   1022  *
   1023  *  Prints properties for the given datasets.  The user can control which
   1024  *  columns to display as well as which property types to allow.
   1025  */
   1026 
   1027 /*
   1028  * Invoked to display the properties for a single dataset.
   1029  */
   1030 static int
   1031 get_callback(zfs_handle_t *zhp, void *data)
   1032 {
   1033 	char buf[ZFS_MAXPROPLEN];
   1034 	zprop_source_t sourcetype;
   1035 	char source[ZFS_MAXNAMELEN];
   1036 	zprop_get_cbdata_t *cbp = data;
   1037 	nvlist_t *userprop = zfs_get_user_props(zhp);
   1038 	zprop_list_t *pl = cbp->cb_proplist;
   1039 	nvlist_t *propval;
   1040 	char *strval;
   1041 	char *sourceval;
   1042 
   1043 	for (; pl != NULL; pl = pl->pl_next) {
   1044 		/*
   1045 		 * Skip the special fake placeholder.  This will also skip over
   1046 		 * the name property when 'all' is specified.
   1047 		 */
   1048 		if (pl->pl_prop == ZFS_PROP_NAME &&
   1049 		    pl == cbp->cb_proplist)
   1050 			continue;
   1051 
   1052 		if (pl->pl_prop != ZPROP_INVAL) {
   1053 			if (zfs_prop_get(zhp, pl->pl_prop, buf,
   1054 			    sizeof (buf), &sourcetype, source,
   1055 			    sizeof (source),
   1056 			    cbp->cb_literal) != 0) {
   1057 				if (pl->pl_all)
   1058 					continue;
   1059 				if (!zfs_prop_valid_for_type(pl->pl_prop,
   1060 				    ZFS_TYPE_DATASET)) {
   1061 					(void) fprintf(stderr,
   1062 					    gettext("No such property '%s'\n"),
   1063 					    zfs_prop_to_name(pl->pl_prop));
   1064 					continue;
   1065 				}
   1066 				sourcetype = ZPROP_SRC_NONE;
   1067 				(void) strlcpy(buf, "-", sizeof (buf));
   1068 			}
   1069 
   1070 			zprop_print_one_property(zfs_get_name(zhp), cbp,
   1071 			    zfs_prop_to_name(pl->pl_prop),
   1072 			    buf, sourcetype, source);
   1073 		} else {
   1074 			if (nvlist_lookup_nvlist(userprop,
   1075 			    pl->pl_user_prop, &propval) != 0) {
   1076 				if (pl->pl_all)
   1077 					continue;
   1078 				sourcetype = ZPROP_SRC_NONE;
   1079 				strval = "-";
   1080 			} else {
   1081 				verify(nvlist_lookup_string(propval,
   1082 				    ZPROP_VALUE, &strval) == 0);
   1083 				verify(nvlist_lookup_string(propval,
   1084 				    ZPROP_SOURCE, &sourceval) == 0);
   1085 
   1086 				if (strcmp(sourceval,
   1087 				    zfs_get_name(zhp)) == 0) {
   1088 					sourcetype = ZPROP_SRC_LOCAL;
   1089 				} else {
   1090 					sourcetype = ZPROP_SRC_INHERITED;
   1091 					(void) strlcpy(source,
   1092 					    sourceval, sizeof (source));
   1093 				}
   1094 			}
   1095 
   1096 			zprop_print_one_property(zfs_get_name(zhp), cbp,
   1097 			    pl->pl_user_prop, strval, sourcetype,
   1098 			    source);
   1099 		}
   1100 	}
   1101 
   1102 	return (0);
   1103 }
   1104 
   1105 static int
   1106 zfs_do_get(int argc, char **argv)
   1107 {
   1108 	zprop_get_cbdata_t cb = { 0 };
   1109 	boolean_t recurse =