usr/src/cmd/zfs/zfs_main.c
changeset 2676 5cee47eddab6
parent 2665 7b208a92357b
child 2856 6f4d5ee1906a
equal deleted inserted replaced
2675:54d99ec6d12d 2676:5cee47eddab6
    24  */
    24  */
    25 
    25 
    26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    27 
    27 
    28 #include <assert.h>
    28 #include <assert.h>
       
    29 #include <ctype.h>
    29 #include <errno.h>
    30 #include <errno.h>
    30 #include <libgen.h>
    31 #include <libgen.h>
    31 #include <libintl.h>
    32 #include <libintl.h>
    32 #include <libuutil.h>
    33 #include <libuutil.h>
    33 #include <locale.h>
    34 #include <locale.h>
   159 {
   160 {
   160 	switch (idx) {
   161 	switch (idx) {
   161 	case HELP_CLONE:
   162 	case HELP_CLONE:
   162 		return (gettext("\tclone <snapshot> <filesystem|volume>\n"));
   163 		return (gettext("\tclone <snapshot> <filesystem|volume>\n"));
   163 	case HELP_CREATE:
   164 	case HELP_CREATE:
   164 		return (gettext("\tcreate <filesystem>\n"
   165 		return (gettext("\tcreate [[-o property=value] ... ] "
   165 		    "\tcreate [-s] [-b blocksize] -V <size> <volume>\n"));
   166 		    "<filesystem>\n"
       
   167 		    "\tcreate [-s] [-b blocksize] [[-o property=value] ...]\n"
       
   168 		    "\t    -V <size> <volume>\n"));
   166 	case HELP_DESTROY:
   169 	case HELP_DESTROY:
   167 		return (gettext("\tdestroy [-rRf] "
   170 		return (gettext("\tdestroy [-rRf] "
   168 		    "<filesystem|volume|snapshot>\n"));
   171 		    "<filesystem|volume|snapshot>\n"));
   169 	case HELP_GET:
   172 	case HELP_GET:
   170 		return (gettext("\tget [-rHp] [-o field[,field]...] "
   173 		return (gettext("\tget [-rHp] [-o field[,field]...] "
   171 		    "[-s source[,source]...]\n"
   174 		    "[-s source[,source]...]\n"
   172 		    "\t    <all | property[,property]...> "
   175 		    "\t    <all | property[,property]...> "
   173 		    "<filesystem|volume|snapshot> ...\n"));
   176 		    "[filesystem|volume|snapshot] ...\n"));
   174 	case HELP_INHERIT:
   177 	case HELP_INHERIT:
   175 		return (gettext("\tinherit [-r] <property> "
   178 		return (gettext("\tinherit [-r] <property> "
   176 		    "<filesystem|volume> ...\n"));
   179 		    "<filesystem|volume> ...\n"));
   177 	case HELP_LIST:
   180 	case HELP_LIST:
   178 		return (gettext("\tlist [-rH] [-o property[,property]...] "
   181 		return (gettext("\tlist [-rH] [-o property[,property]...] "
   300 			else
   303 			else
   301 				(void) fprintf(fp, "%s\n", zfs_prop_values(i));
   304 				(void) fprintf(fp, "%s\n", zfs_prop_values(i));
   302 		}
   305 		}
   303 		(void) fprintf(fp, gettext("\nSizes are specified in bytes "
   306 		(void) fprintf(fp, gettext("\nSizes are specified in bytes "
   304 		    "with standard units such as K, M, G, etc.\n"));
   307 		    "with standard units such as K, M, G, etc.\n"));
       
   308 		(void) fprintf(fp, gettext("\n\nUser-defined properties can "
       
   309 		    "be specified by using a name containing a colon (:).\n"));
   305 	} else {
   310 	} else {
   306 		/*
   311 		/*
   307 		 * TRANSLATION NOTE:
   312 		 * TRANSLATION NOTE:
   308 		 * "zfs set|get" must not be localised this is the
   313 		 * "zfs set|get" must not be localised this is the
   309 		 * command name and arguments.
   314 		 * command name and arguments.
   310 		 */
   315 		 */
   311 		(void) fprintf(fp,
   316 		(void) fprintf(fp,
   312 		    gettext("\nFor the property list, run: zfs set|get\n"));
   317 		    gettext("\nFor the property list, run: zfs set|get\n"));
   313 	}
   318 	}
   314 
   319 
       
   320 	/*
       
   321 	 * See comments at end of main().
       
   322 	 */
       
   323 	if (getenv("ZFS_ABORT") != NULL) {
       
   324 		(void) printf("dumping core by request\n");
       
   325 		abort();
       
   326 	}
       
   327 
   315 	exit(requested ? 0 : 2);
   328 	exit(requested ? 0 : 2);
   316 }
   329 }
   317 
   330 
   318 /*
   331 /*
   319  * zfs clone <fs, snap, vol> fs
   332  * zfs clone <fs, snap, vol> fs
   355 	/* open the source dataset */
   368 	/* open the source dataset */
   356 	if ((zhp = zfs_open(g_zfs, argv[1], ZFS_TYPE_SNAPSHOT)) == NULL)
   369 	if ((zhp = zfs_open(g_zfs, argv[1], ZFS_TYPE_SNAPSHOT)) == NULL)
   357 		return (1);
   370 		return (1);
   358 
   371 
   359 	/* pass to libzfs */
   372 	/* pass to libzfs */
   360 	ret = zfs_clone(zhp, argv[2]);
   373 	ret = zfs_clone(zhp, argv[2], NULL);
   361 
   374 
   362 	/* create the mountpoint if necessary */
   375 	/* create the mountpoint if necessary */
   363 	if (ret == 0) {
   376 	if (ret == 0) {
   364 		zfs_handle_t *clone = zfs_open(g_zfs, argv[2], ZFS_TYPE_ANY);
   377 		zfs_handle_t *clone = zfs_open(g_zfs, argv[2], ZFS_TYPE_ANY);
   365 		if (clone != NULL) {
   378 		if (clone != NULL) {
   373 
   386 
   374 	return (ret == 0 ? 0 : 1);
   387 	return (ret == 0 ? 0 : 1);
   375 }
   388 }
   376 
   389 
   377 /*
   390 /*
   378  * zfs create fs
   391  * zfs create [-o prop=value] ... fs
   379  * zfs create [-s] [-b blocksize] -V vol size
   392  * zfs create [-s] [-b blocksize] [-o prop=value] ... -V vol size
   380  *
   393  *
   381  * Create a new dataset.  This command can be used to create filesystems
   394  * Create a new dataset.  This command can be used to create filesystems
   382  * and volumes.  Snapshot creation is handled by 'zfs snapshot'.
   395  * and volumes.  Snapshot creation is handled by 'zfs snapshot'.
   383  * For volumes, the user must specify a size to be used.
   396  * For volumes, the user must specify a size to be used.
   384  *
   397  *
   388  */
   401  */
   389 static int
   402 static int
   390 zfs_do_create(int argc, char **argv)
   403 zfs_do_create(int argc, char **argv)
   391 {
   404 {
   392 	zfs_type_t type = ZFS_TYPE_FILESYSTEM;
   405 	zfs_type_t type = ZFS_TYPE_FILESYSTEM;
   393 	zfs_handle_t *zhp;
   406 	zfs_handle_t *zhp = NULL;
   394 	char *size = NULL;
   407 	uint64_t volsize;
   395 	char *blocksize = NULL;
       
   396 	int c;
   408 	int c;
   397 	boolean_t noreserve = B_FALSE;
   409 	boolean_t noreserve = B_FALSE;
   398 	int ret;
   410 	int ret = 1;
       
   411 	nvlist_t *props = NULL;
       
   412 	uint64_t intval;
       
   413 	char *propname;
       
   414 	char *propval, *strval;
       
   415 
       
   416 	if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) {
       
   417 		(void) fprintf(stderr, gettext("internal error: "
       
   418 		    "out of memory\n"));
       
   419 		return (1);
       
   420 	}
   399 
   421 
   400 	/* check options */
   422 	/* check options */
   401 	while ((c = getopt(argc, argv, ":V:b:s")) != -1) {
   423 	while ((c = getopt(argc, argv, ":V:b:so:")) != -1) {
   402 		switch (c) {
   424 		switch (c) {
   403 		case 'V':
   425 		case 'V':
   404 			type = ZFS_TYPE_VOLUME;
   426 			type = ZFS_TYPE_VOLUME;
   405 			size = optarg;
   427 			if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
       
   428 				(void) fprintf(stderr, gettext("bad volume "
       
   429 				    "size '%s': %s\n"), optarg,
       
   430 				    libzfs_error_description(g_zfs));
       
   431 				goto error;
       
   432 			}
       
   433 
       
   434 			if (nvlist_add_uint64(props,
       
   435 			    zfs_prop_to_name(ZFS_PROP_VOLSIZE),
       
   436 			    intval) != 0) {
       
   437 				(void) fprintf(stderr, gettext("internal "
       
   438 				    "error: out of memory\n"));
       
   439 				goto error;
       
   440 			}
       
   441 			volsize = intval;
   406 			break;
   442 			break;
   407 		case 'b':
   443 		case 'b':
   408 			blocksize = optarg;
   444 			if (zfs_nicestrtonum(g_zfs, optarg, &intval) != 0) {
       
   445 				(void) fprintf(stderr, gettext("bad volume "
       
   446 				    "block size '%s': %s\n"), optarg,
       
   447 				    libzfs_error_description(g_zfs));
       
   448 				goto error;
       
   449 			}
       
   450 
       
   451 			if (nvlist_add_uint64(props,
       
   452 			    zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
       
   453 			    intval) != 0) {
       
   454 				(void) fprintf(stderr, gettext("internal "
       
   455 				    "error: out of memory\n"));
       
   456 				goto error;
       
   457 			}
       
   458 			break;
       
   459 		case 'o':
       
   460 			propname = optarg;
       
   461 			if ((propval = strchr(propname, '=')) == NULL) {
       
   462 				(void) fprintf(stderr, gettext("missing "
       
   463 				    "'=' for -o option\n"));
       
   464 				goto error;
       
   465 			}
       
   466 			*propval = '\0';
       
   467 			propval++;
       
   468 			if (nvlist_lookup_string(props, propname,
       
   469 			    &strval) == 0) {
       
   470 				(void) fprintf(stderr, gettext("property '%s' "
       
   471 				    "specified multiple times\n"), propname);
       
   472 				goto error;
       
   473 			}
       
   474 			if (nvlist_add_string(props, propname, propval) != 0) {
       
   475 				(void) fprintf(stderr, gettext("internal "
       
   476 				    "error: out of memory\n"));
       
   477 				goto error;
       
   478 			}
   409 			break;
   479 			break;
   410 		case 's':
   480 		case 's':
   411 			noreserve = B_TRUE;
   481 			noreserve = B_TRUE;
   412 			break;
   482 			break;
   413 		case ':':
   483 		case ':':
   414 			(void) fprintf(stderr, gettext("missing size "
   484 			(void) fprintf(stderr, gettext("missing size "
   415 			    "argument\n"));
   485 			    "argument\n"));
   416 			usage(B_FALSE);
   486 			goto badusage;
   417 			break;
   487 			break;
   418 		case '?':
   488 		case '?':
   419 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   489 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
   420 			    optopt);
   490 			    optopt);
   421 			usage(B_FALSE);
   491 			goto badusage;
   422 		}
   492 		}
   423 	}
   493 	}
   424 
   494 
   425 	if (noreserve && type != ZFS_TYPE_VOLUME) {
   495 	if (noreserve && type != ZFS_TYPE_VOLUME) {
   426 		(void) fprintf(stderr, gettext("'-s' can only be used when "
   496 		(void) fprintf(stderr, gettext("'-s' can only be used when "
   427 		    "creating a volume\n"));
   497 		    "creating a volume\n"));
   428 		usage(B_FALSE);
   498 		goto badusage;
   429 	}
   499 	}
   430 
   500 
   431 	argc -= optind;
   501 	argc -= optind;
   432 	argv += optind;
   502 	argv += optind;
   433 
   503 
   434 	/* check number of arguments */
   504 	/* check number of arguments */
   435 	if (argc == 0) {
   505 	if (argc == 0) {
   436 		(void) fprintf(stderr, gettext("missing %s argument\n"),
   506 		(void) fprintf(stderr, gettext("missing %s argument\n"),
   437 		    zfs_type_to_name(type));
   507 		    zfs_type_to_name(type));
   438 		usage(B_FALSE);
   508 		goto badusage;
   439 	}
   509 	}
   440 	if (argc > 1) {
   510 	if (argc > 1) {
   441 		(void) fprintf(stderr, gettext("too many arguments\n"));
   511 		(void) fprintf(stderr, gettext("too many arguments\n"));
   442 		usage(B_FALSE);
   512 		goto badusage;
       
   513 	}
       
   514 
       
   515 	if (type == ZFS_TYPE_VOLUME && !noreserve &&
       
   516 	    nvlist_lookup_string(props, zfs_prop_to_name(ZFS_PROP_RESERVATION),
       
   517 	    &strval) != 0) {
       
   518 		if (nvlist_add_uint64(props,
       
   519 		    zfs_prop_to_name(ZFS_PROP_RESERVATION),
       
   520 		    volsize) != 0) {
       
   521 			(void) fprintf(stderr, gettext("internal "
       
   522 			    "error: out of memory\n"));
       
   523 			nvlist_free(props);
       
   524 			return (1);
       
   525 		}
   443 	}
   526 	}
   444 
   527 
   445 	/* pass to libzfs */
   528 	/* pass to libzfs */
   446 	if (zfs_create(g_zfs, argv[0], type, size, blocksize) != 0)
   529 	if (zfs_create(g_zfs, argv[0], type, props) != 0)
   447 		return (1);
   530 		goto error;
   448 
   531 
   449 	if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_ANY)) == NULL)
   532 	if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_ANY)) == NULL)
   450 		return (1);
   533 		goto error;
   451 
       
   452 	/*
       
   453 	 * Volume handling.  By default, we try to create a reservation of equal
       
   454 	 * size for the volume.  If we can't do this, then destroy the dataset
       
   455 	 * and report an error.
       
   456 	 */
       
   457 	if (type == ZFS_TYPE_VOLUME && !noreserve) {
       
   458 		if (zfs_prop_set(zhp, ZFS_PROP_RESERVATION, size) != 0) {
       
   459 			(void) fprintf(stderr, gettext("use '-s' to create a "
       
   460 			    "volume without a matching reservation\n"));
       
   461 			(void) zfs_destroy(zhp);
       
   462 			return (1);
       
   463 		}
       
   464 	}
       
   465 
   534 
   466 	/*
   535 	/*
   467 	 * Mount and/or share the new filesystem as appropriate.  We provide a
   536 	 * Mount and/or share the new filesystem as appropriate.  We provide a
   468 	 * verbose error message to let the user know that their filesystem was
   537 	 * verbose error message to let the user know that their filesystem was
   469 	 * in fact created, even if we failed to mount or share it.
   538 	 * in fact created, even if we failed to mount or share it.
   478 		ret = 1;
   547 		ret = 1;
   479 	} else {
   548 	} else {
   480 		ret = 0;
   549 		ret = 0;
   481 	}
   550 	}
   482 
   551 
   483 	zfs_close(zhp);
   552 error:
       
   553 	if (zhp)
       
   554 		zfs_close(zhp);
       
   555 	nvlist_free(props);
   484 	return (ret);
   556 	return (ret);
       
   557 badusage:
       
   558 	nvlist_free(props);
       
   559 	usage(B_FALSE);
       
   560 	return (2);
   485 }
   561 }
   486 
   562 
   487 /*
   563 /*
   488  * zfs destroy [-rf] <fs, snap, vol>
   564  * zfs destroy [-rf] <fs, snap, vol>
   489  *
   565  *
   763  *  columns to display as well as which property types to allow.
   839  *  columns to display as well as which property types to allow.
   764  */
   840  */
   765 typedef struct get_cbdata {
   841 typedef struct get_cbdata {
   766 	int cb_sources;
   842 	int cb_sources;
   767 	int cb_columns[4];
   843 	int cb_columns[4];
   768 	int cb_nprop;
   844 	int cb_colwidths[5];
   769 	boolean_t cb_scripted;
   845 	boolean_t cb_scripted;
   770 	boolean_t cb_literal;
   846 	boolean_t cb_literal;
   771 	boolean_t cb_isall;
   847 	boolean_t cb_first;
   772 	zfs_prop_t cb_prop[ZFS_NPROP_ALL];
   848 	zfs_proplist_t *cb_proplist;
   773 } get_cbdata_t;
   849 } get_cbdata_t;
   774 
   850 
   775 #define	GET_COL_NAME		1
   851 #define	GET_COL_NAME		1
   776 #define	GET_COL_PROPERTY	2
   852 #define	GET_COL_PROPERTY	2
   777 #define	GET_COL_VALUE		3
   853 #define	GET_COL_VALUE		3
   778 #define	GET_COL_SOURCE		4
   854 #define	GET_COL_SOURCE		4
   779 
   855 
   780 /*
   856 /*
       
   857  * Print the column headers for 'zfs get'.
       
   858  */
       
   859 static void
       
   860 print_get_headers(get_cbdata_t *cbp)
       
   861 {
       
   862 	zfs_proplist_t *pl = cbp->cb_proplist;
       
   863 	int i;
       
   864 	char *title;
       
   865 	size_t len;
       
   866 
       
   867 	cbp->cb_first = B_FALSE;
       
   868 	if (cbp->cb_scripted)
       
   869 		return;
       
   870 
       
   871 	/*
       
   872 	 * Start with the length of the column headers.
       
   873 	 */
       
   874 	cbp->cb_colwidths[GET_COL_NAME] = strlen(gettext("NAME"));
       
   875 	cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(gettext("PROPERTY"));
       
   876 	cbp->cb_colwidths[GET_COL_VALUE] = strlen(gettext("VALUE"));
       
   877 	cbp->cb_colwidths[GET_COL_SOURCE] = strlen(gettext("SOURCE"));
       
   878 
       
   879 	/*
       
   880 	 * Go through and calculate the widths for each column.  For the
       
   881 	 * 'source' column, we kludge it up by taking the worst-case scenario of
       
   882 	 * inheriting from the longest name.  This is acceptable because in the
       
   883 	 * majority of cases 'SOURCE' is the last column displayed, and we don't
       
   884 	 * use the width anyway.  Note that the 'VALUE' column can be oversized,
       
   885 	 * if the name of the property is much longer the any values we find.
       
   886 	 */
       
   887 	for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
       
   888 		/*
       
   889 		 * 'PROPERTY' column
       
   890 		 */
       
   891 		if (pl->pl_prop != ZFS_PROP_INVAL) {
       
   892 			len = strlen(zfs_prop_to_name(pl->pl_prop));
       
   893 			if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
       
   894 				cbp->cb_colwidths[GET_COL_PROPERTY] = len;
       
   895 		} else {
       
   896 			len = strlen(pl->pl_user_prop);
       
   897 			if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
       
   898 				cbp->cb_colwidths[GET_COL_PROPERTY] = len;
       
   899 		}
       
   900 
       
   901 		/*
       
   902 		 * 'VALUE' column
       
   903 		 */
       
   904 		if ((pl->pl_prop != ZFS_PROP_NAME || !pl->pl_all) &&
       
   905 		    pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE])
       
   906 			cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width;
       
   907 
       
   908 		/*
       
   909 		 * 'NAME' and 'SOURCE' columns
       
   910 		 */
       
   911 		if (pl->pl_prop == ZFS_PROP_NAME &&
       
   912 		    pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
       
   913 			cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
       
   914 			cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
       
   915 			    strlen(gettext("inherited from"));
       
   916 		}
       
   917 	}
       
   918 
       
   919 	/*
       
   920 	 * Now go through and print the headers.
       
   921 	 */
       
   922 	for (i = 0; i < 4; i++) {
       
   923 		switch (cbp->cb_columns[i]) {
       
   924 		case GET_COL_NAME:
       
   925 			title = gettext("NAME");
       
   926 			break;
       
   927 		case GET_COL_PROPERTY:
       
   928 			title = gettext("PROPERTY");
       
   929 			break;
       
   930 		case GET_COL_VALUE:
       
   931 			title = gettext("VALUE");
       
   932 			break;
       
   933 		case GET_COL_SOURCE:
       
   934 			title = gettext("SOURCE");
       
   935 			break;
       
   936 		default:
       
   937 			title = NULL;
       
   938 		}
       
   939 
       
   940 		if (title != NULL) {
       
   941 			if (i == 3 || cbp->cb_columns[i + 1] == 0)
       
   942 				(void) printf("%s", title);
       
   943 			else
       
   944 				(void) printf("%-*s  ",
       
   945 				    cbp->cb_colwidths[cbp->cb_columns[i]],
       
   946 				    title);
       
   947 		}
       
   948 	}
       
   949 	(void) printf("\n");
       
   950 }
       
   951 
       
   952 /*
   781  * Display a single line of output, according to the settings in the callback
   953  * Display a single line of output, according to the settings in the callback
   782  * structure.
   954  * structure.
   783  */
   955  */
   784 static void
   956 static void
   785 print_one_property(zfs_handle_t *zhp, get_cbdata_t *cbp, zfs_prop_t prop,
   957 print_one_property(zfs_handle_t *zhp, get_cbdata_t *cbp, const char *propname,
   786     const char *value, zfs_source_t sourcetype, const char *source)
   958     const char *value, zfs_source_t sourcetype, const char *source)
   787 {
   959 {
   788 	int i;
   960 	int i;
   789 	int width;
       
   790 	const char *str;
   961 	const char *str;
   791 	char buf[128];
   962 	char buf[128];
   792 
   963 
   793 	/*
   964 	/*
   794 	 * Ignore those source types that the user has chosen to ignore.
   965 	 * Ignore those source types that the user has chosen to ignore.
   795 	 */
   966 	 */
   796 	if ((sourcetype & cbp->cb_sources) == 0)
   967 	if ((sourcetype & cbp->cb_sources) == 0)
   797 		return;
   968 		return;
   798 
   969 
       
   970 	if (cbp->cb_first)
       
   971 		print_get_headers(cbp);
       
   972 
   799 	for (i = 0; i < 4; i++) {
   973 	for (i = 0; i < 4; i++) {
   800 		switch (cbp->cb_columns[i]) {
   974 		switch (cbp->cb_columns[i]) {
   801 		case GET_COL_NAME:
   975 		case GET_COL_NAME:
   802 			width = 15;
       
   803 			str = zfs_get_name(zhp);
   976 			str = zfs_get_name(zhp);
   804 			break;
   977 			break;
   805 
   978 
   806 		case GET_COL_PROPERTY:
   979 		case GET_COL_PROPERTY:
   807 			width = 13;
   980 			str = propname;
   808 			str = zfs_prop_to_name(prop);
       
   809 			break;
   981 			break;
   810 
   982 
   811 		case GET_COL_VALUE:
   983 		case GET_COL_VALUE:
   812 			width = 25;
       
   813 			str = value;
   984 			str = value;
   814 			break;
   985 			break;
   815 
   986 
   816 		case GET_COL_SOURCE:
   987 		case GET_COL_SOURCE:
   817 			width = 15;
       
   818 			switch (sourcetype) {
   988 			switch (sourcetype) {
   819 			case ZFS_SRC_NONE:
   989 			case ZFS_SRC_NONE:
   820 				str = "-";
   990 				str = "-";
   821 				break;
   991 				break;
   822 
   992 
   847 		if (cbp->cb_columns[i + 1] == 0)
  1017 		if (cbp->cb_columns[i + 1] == 0)
   848 			(void) printf("%s", str);
  1018 			(void) printf("%s", str);
   849 		else if (cbp->cb_scripted)
  1019 		else if (cbp->cb_scripted)
   850 			(void) printf("%s\t", str);
  1020 			(void) printf("%s\t", str);
   851 		else
  1021 		else
   852 			(void) printf("%-*s  ", width, str);
  1022 			(void) printf("%-*s  ",
       
  1023 			    cbp->cb_colwidths[cbp->cb_columns[i]],
       
  1024 			    str);
   853 
  1025 
   854 	}
  1026 	}
   855 
  1027 
   856 	(void) printf("\n");
  1028 	(void) printf("\n");
   857 }
  1029 }
   864 {
  1036 {
   865 	char buf[ZFS_MAXPROPLEN];
  1037 	char buf[ZFS_MAXPROPLEN];
   866 	zfs_source_t sourcetype;
  1038 	zfs_source_t sourcetype;
   867 	char source[ZFS_MAXNAMELEN];
  1039 	char source[ZFS_MAXNAMELEN];
   868 	get_cbdata_t *cbp = data;
  1040 	get_cbdata_t *cbp = data;
   869 	int i;
  1041 	nvlist_t *userprop = zfs_get_user_props(zhp);
   870 
  1042 	zfs_proplist_t *pl = cbp->cb_proplist;
   871 	for (i = 0; i < cbp->cb_nprop; i++) {
  1043 	nvlist_t *propval;
   872 		if (zfs_prop_get(zhp, cbp->cb_prop[i], buf,
  1044 	char *strval;
   873 		    sizeof (buf), &sourcetype, source, sizeof (source),
  1045 	char *sourceval;
   874 		    cbp->cb_literal) != 0) {
  1046 
   875 			if (cbp->cb_isall)
  1047 	for (; pl != NULL; pl = pl->pl_next) {
   876 				continue;
  1048 		/*
   877 			(void) strlcpy(buf, "-", sizeof (buf));
  1049 		 * Skip the special fake placeholder.  This will also skip over
   878 			sourcetype = ZFS_SRC_NONE;
  1050 		 * the name property when 'all' is specified.
   879 		}
  1051 		 */
   880 
  1052 		if (pl->pl_prop == ZFS_PROP_NAME &&
   881 		print_one_property(zhp, cbp, cbp->cb_prop[i],
  1053 		    pl == cbp->cb_proplist)
   882 		    buf, sourcetype, source);
  1054 			continue;
       
  1055 
       
  1056 		if (pl->pl_prop != ZFS_PROP_INVAL) {
       
  1057 			if (zfs_prop_get(zhp, pl->pl_prop, buf,
       
  1058 			    sizeof (buf), &sourcetype, source,
       
  1059 			    sizeof (source),
       
  1060 			    cbp->cb_literal) != 0) {
       
  1061 				if (pl->pl_all)
       
  1062 					continue;
       
  1063 				sourcetype = ZFS_SRC_NONE;
       
  1064 				(void) strlcpy(buf, "-", sizeof (buf));
       
  1065 			}
       
  1066 
       
  1067 			print_one_property(zhp, cbp,
       
  1068 			    zfs_prop_to_name(pl->pl_prop),
       
  1069 			    buf, sourcetype, source);
       
  1070 		} else {
       
  1071 			if (nvlist_lookup_nvlist(userprop,
       
  1072 			    pl->pl_user_prop, &propval) != 0) {
       
  1073 				if (pl->pl_all)
       
  1074 					continue;
       
  1075 				sourcetype = ZFS_SRC_NONE;
       
  1076 				strval = "-";
       
  1077 			} else {
       
  1078 				verify(nvlist_lookup_string(propval,
       
  1079 				    ZFS_PROP_VALUE, &strval) == 0);
       
  1080 				verify(nvlist_lookup_string(propval,
       
  1081 				    ZFS_PROP_SOURCE, &sourceval) == 0);
       
  1082 
       
  1083 				if (strcmp(sourceval,
       
  1084 				    zfs_get_name(zhp)) == 0) {
       
  1085 					sourcetype = ZFS_SRC_LOCAL;
       
  1086 				} else {
       
  1087 					sourcetype = ZFS_SRC_INHERITED;
       
  1088 					(void) strlcpy(source,
       
  1089 					    sourceval, sizeof (source));
       
  1090 				}
       
  1091 			}
       
  1092 
       
  1093 			print_one_property(zhp, cbp,
       
  1094 			    pl->pl_user_prop, strval, sourcetype,
       
  1095 			    source);
       
  1096 		}
   883 	}
  1097 	}
   884 
  1098 
   885 	return (0);
  1099 	return (0);
   886 }
  1100 }
   887 
  1101 
   888 static int
  1102 static int
   889 zfs_do_get(int argc, char **argv)
  1103 zfs_do_get(int argc, char **argv)
   890 {
  1104 {
   891 	get_cbdata_t cb = { 0 };
  1105 	get_cbdata_t cb = { 0 };
   892 	boolean_t recurse = B_FALSE;
  1106 	boolean_t recurse = B_FALSE;
   893 	int c;
  1107 	int i, c;
   894 	char *value, *fields, *badopt;
  1108 	char *value, *fields;
   895 	int i;
       
   896 	int ret;
  1109 	int ret;
       
  1110 	zfs_proplist_t fake_name = { 0 };
   897 
  1111 
   898 	/*
  1112 	/*
   899 	 * Set up default columns and sources.
  1113 	 * Set up default columns and sources.
   900 	 */
  1114 	 */
   901 	cb.cb_sources = ZFS_SRC_ALL;
  1115 	cb.cb_sources = ZFS_SRC_ALL;
  1012 		usage(B_FALSE);
  1226 		usage(B_FALSE);
  1013 	}
  1227 	}
  1014 
  1228 
  1015 	fields = argv[0];
  1229 	fields = argv[0];
  1016 
  1230 
  1017 	/*
  1231 	if (zfs_get_proplist(g_zfs, fields, &cb.cb_proplist) != 0)
  1018 	 * If the user specifies 'all', the behavior of 'zfs get' is slightly
  1232 		usage(B_FALSE);
  1019 	 * different, because we don't show properties which don't apply to the
       
  1020 	 * given dataset.
       
  1021 	 */
       
  1022 	if (strcmp(fields, "all") == 0)
       
  1023 		cb.cb_isall = B_TRUE;
       
  1024 
       
  1025 	if ((ret = zfs_get_proplist(fields, cb.cb_prop, ZFS_NPROP_ALL,
       
  1026 	    &cb.cb_nprop, &badopt)) != 0) {
       
  1027 		if (ret == EINVAL)
       
  1028 			(void) fprintf(stderr, gettext("invalid property "
       
  1029 			    "'%s'\n"), badopt);
       
  1030 		else
       
  1031 			(void) fprintf(stderr, gettext("too many properties "
       
  1032 			    "specified\n"));
       
  1033 		usage(B_FALSE);
       
  1034 	}
       
  1035 
  1233 
  1036 	argc--;
  1234 	argc--;
  1037 	argv++;
  1235 	argv++;
  1038 
  1236 
  1039 	/* check for at least one dataset name */
       
  1040 	if (argc < 1) {
       
  1041 		(void) fprintf(stderr, gettext("missing dataset argument\n"));
       
  1042 		usage(B_FALSE);
       
  1043 	}
       
  1044 
       
  1045 	/*
  1237 	/*
  1046 	 * Print out any headers
  1238 	 * As part of zfs_expand_proplist(), we keep track of the maximum column
       
  1239 	 * width for each property.  For the 'NAME' (and 'SOURCE') columns, we
       
  1240 	 * need to know the maximum name length.  However, the user likely did
       
  1241 	 * not specify 'name' as one of the properties to fetch, so we need to
       
  1242 	 * make sure we always include at least this property for
       
  1243 	 * print_get_headers() to work properly.
  1047 	 */
  1244 	 */
  1048 	if (!cb.cb_scripted) {
  1245 	if (cb.cb_proplist != NULL) {
  1049 		int i;
  1246 		fake_name.pl_prop = ZFS_PROP_NAME;
  1050 		for (i = 0; i < 4; i++) {
  1247 		fake_name.pl_width = strlen(gettext("NAME"));
  1051 			switch (cb.cb_columns[i]) {
  1248 		fake_name.pl_next = cb.cb_proplist;
  1052 			case GET_COL_NAME:
  1249 		cb.cb_proplist = &fake_name;
  1053 				(void) printf("%-15s  ", "NAME");
  1250 	}
  1054 				break;
  1251 
  1055 			case GET_COL_PROPERTY:
  1252 	cb.cb_first = B_TRUE;
  1056 				(void) printf("%-13s  ", "PROPERTY");
       
  1057 				break;
       
  1058 			case GET_COL_VALUE:
       
  1059 				(void) printf("%-25s  ", "VALUE");
       
  1060 				break;
       
  1061 			case GET_COL_SOURCE:
       
  1062 				(void) printf("%s", "SOURCE");
       
  1063 				break;
       
  1064 			}
       
  1065 		}
       
  1066 		(void) printf("\n");
       
  1067 	}
       
  1068 
  1253 
  1069 	/* run for each object */
  1254 	/* run for each object */
  1070 	return (zfs_for_each(argc, argv, recurse, ZFS_TYPE_ANY, NULL,
  1255 	ret = zfs_for_each(argc, argv, recurse, ZFS_TYPE_ANY, NULL,
  1071 	    get_callback, &cb));
  1256 	    &cb.cb_proplist, get_callback, &cb);
  1072 
  1257 
       
  1258 	if (cb.cb_proplist == &fake_name)
       
  1259 		zfs_free_proplist(fake_name.pl_next);
       
  1260 	else
       
  1261 		zfs_free_proplist(cb.cb_proplist);
       
  1262 
       
  1263 	return (ret);
  1073 }
  1264 }
  1074 
  1265 
  1075 /*
  1266 /*
  1076  * inherit [-r] <property> <fs|vol> ...
  1267  * inherit [-r] <property> <fs|vol> ...
  1077  *
  1268  *
  1084  * local modifications for each dataset.
  1275  * local modifications for each dataset.
  1085  */
  1276  */
  1086 static int
  1277 static int
  1087 inherit_callback(zfs_handle_t *zhp, void *data)
  1278 inherit_callback(zfs_handle_t *zhp, void *data)
  1088 {
  1279 {
  1089 	zfs_prop_t prop = (zfs_prop_t)data;
  1280 	return (zfs_prop_inherit(zhp, data) != 0);
  1090 
       
  1091 	return (zfs_prop_inherit(zhp, prop) != 0);
       
  1092 }
  1281 }
  1093 
  1282 
  1094 static int
  1283 static int
  1095 zfs_do_inherit(int argc, char **argv)
  1284 zfs_do_inherit(int argc, char **argv)
  1096 {
  1285 {
  1125 		(void) fprintf(stderr, gettext("missing dataset argument\n"));
  1314 		(void) fprintf(stderr, gettext("missing dataset argument\n"));
  1126 		usage(B_FALSE);
  1315 		usage(B_FALSE);
  1127 	}
  1316 	}
  1128 
  1317 
  1129 	propname = argv[0];
  1318 	propname = argv[0];
  1130 
  1319 	argc--;
  1131 	/*
  1320 	argv++;
  1132 	 * Get and validate the property before iterating over the datasets.  We
  1321 
  1133 	 * do this now so as to avoid printing out an error message for each and
  1322 	if ((prop = zfs_name_to_prop(propname)) != ZFS_PROP_INVAL) {
  1134 	 * every dataset.
  1323 		if (zfs_prop_readonly(prop)) {
  1135 	 */
  1324 			(void) fprintf(stderr, gettext(
  1136 	if ((prop = zfs_name_to_prop(propname)) == ZFS_PROP_INVAL) {
  1325 			    "%s property is read-only\n"),
  1137 		(void) fprintf(stderr, gettext("invalid property '%s'\n"),
  1326 			    propname);
       
  1327 			return (1);
       
  1328 		}
       
  1329 		if (!zfs_prop_inheritable(prop)) {
       
  1330 			(void) fprintf(stderr, gettext("'%s' property cannot "
       
  1331 			    "be inherited\n"), propname);
       
  1332 			if (prop == ZFS_PROP_QUOTA ||
       
  1333 			    prop == ZFS_PROP_RESERVATION)
       
  1334 				(void) fprintf(stderr, gettext("use 'zfs set "
       
  1335 				    "%s=none' to clear\n"), propname);
       
  1336 			return (1);
       
  1337 		}
       
  1338 	} else if (!zfs_prop_user(propname)) {
       
  1339 		(void) fprintf(stderr, gettext(
       
  1340 		    "invalid property '%s'\n"),
  1138 		    propname);
  1341 		    propname);
  1139 		usage(B_FALSE);
  1342 		usage(B_FALSE);
  1140 	}
  1343 	}
  1141 	if (zfs_prop_readonly(prop)) {
  1344 
  1142 		(void) fprintf(stderr, gettext("%s property is read-only\n"),
  1345 	return (zfs_for_each(argc, argv, recurse,
  1143 		    propname);
  1346 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, NULL, NULL,
  1144 		return (1);
  1347 	    inherit_callback, propname));
  1145 	}
       
  1146 	if (!zfs_prop_inheritable(prop)) {
       
  1147 		(void) fprintf(stderr, gettext("%s property cannot be "
       
  1148 		    "inherited\n"), propname);
       
  1149 		(void) fprintf(stderr, gettext("use 'zfs set %s=none' to "
       
  1150 		    "clear\n"), propname);
       
  1151 		return (1);
       
  1152 	}
       
  1153 
       
  1154 	return (zfs_for_each(argc - 1, argv + 1, recurse,
       
  1155 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, NULL,
       
  1156 	    inherit_callback, (void *)prop));
       
  1157 }
  1348 }
  1158 
  1349 
  1159 /*
  1350 /*
  1160  * list [-rH] [-o property[,property]...] [-t type[,type]...]
  1351  * list [-rH] [-o property[,property]...] [-t type[,type]...]
  1161  *      [-s property [-s property]...] [-S property [-S property]...]
  1352  *      [-s property [-s property]...] [-S property [-S property]...]
  1173  * '-r' is specified.
  1364  * '-r' is specified.
  1174  */
  1365  */
  1175 typedef struct list_cbdata {
  1366 typedef struct list_cbdata {
  1176 	boolean_t	cb_first;
  1367 	boolean_t	cb_first;
  1177 	boolean_t	cb_scripted;
  1368 	boolean_t	cb_scripted;
  1178 	zfs_prop_t	cb_fields[ZFS_NPROP_ALL];
  1369 	zfs_proplist_t	*cb_proplist;
  1179 	int		cb_fieldcount;
       
  1180 } list_cbdata_t;
  1370 } list_cbdata_t;
  1181 
  1371 
  1182 /*
  1372 /*
  1183  * Given a list of columns to display, output appropriate headers for each one.
  1373  * Given a list of columns to display, output appropriate headers for each one.
  1184  */
  1374  */
  1185 static void
  1375 static void
  1186 print_header(zfs_prop_t *fields, size_t count)
  1376 print_header(zfs_proplist_t *pl)
  1187 {
  1377 {
       
  1378 	char headerbuf[ZFS_MAXPROPLEN];
       
  1379 	const char *header;
  1188 	int i;
  1380 	int i;
  1189 
  1381 	boolean_t first = B_TRUE;
  1190 	for (i = 0; i < count; i++) {
  1382 	boolean_t right_justify;
  1191 		if (i != 0)
  1383 
       
  1384 	for (; pl != NULL; pl = pl->pl_next) {
       
  1385 		if (!first) {
  1192 			(void) printf("  ");
  1386 			(void) printf("  ");
  1193 		if (i == count - 1)
  1387 		} else {
  1194 			(void) printf("%s", zfs_prop_column_name(fields[i]));
  1388 			first = B_FALSE;
  1195 		else	/* LINTED - format specifier */
  1389 		}
  1196 			(void) printf(zfs_prop_column_format(fields[i]),
  1390 
  1197 			    zfs_prop_column_name(fields[i]));
  1391 		right_justify = B_FALSE;
       
  1392 		if (pl->pl_prop != ZFS_PROP_INVAL) {
       
  1393 			header = zfs_prop_column_name(pl->pl_prop);
       
  1394 			right_justify = zfs_prop_align_right(pl->pl_prop);
       
  1395 		} else {
       
  1396 			for (i = 0; pl->pl_user_prop[i] != '\0'; i++)
       
  1397 				headerbuf[i] = toupper(pl->pl_user_prop[i]);
       
  1398 			headerbuf[i] = '\0';
       
  1399 			header = headerbuf;
       
  1400 		}
       
  1401 
       
  1402 		if (pl->pl_next == NULL && !right_justify)
       
  1403 			(void) printf("%s", header);
       
  1404 		else if (right_justify)
       
  1405 			(void) printf("%*s", pl->pl_width, header);
       
  1406 		else
       
  1407 			(void) printf("%-*s", pl->pl_width, header);
  1198 	}
  1408 	}
  1199 
  1409 
  1200 	(void) printf("\n");
  1410 	(void) printf("\n");
  1201 }
  1411 }
  1202 
  1412 
  1203 /*
  1413 /*
  1204  * Given a dataset and a list of fields, print out all the properties according
  1414  * Given a dataset and a list of fields, print out all the properties according
  1205  * to the described layout.
  1415  * to the described layout.
  1206  */
  1416  */
  1207 static void
  1417 static void
  1208 print_dataset(zfs_handle_t *zhp, zfs_prop_t *fields, size_t count, int scripted)
  1418 print_dataset(zfs_handle_t *zhp, zfs_proplist_t *pl, int scripted)
  1209 {
  1419 {
  1210 	int i;
  1420 	boolean_t first = B_TRUE;
  1211 	char property[ZFS_MAXPROPLEN];
  1421 	char property[ZFS_MAXPROPLEN];
  1212 
  1422 	nvlist_t *userprops = zfs_get_user_props(zhp);
  1213 	for (i = 0; i < count; i++) {
  1423 	nvlist_t *propval;
  1214 		if (i != 0) {
  1424 	char *propstr;
       
  1425 	boolean_t right_justify;
       
  1426 	int width;
       
  1427 
       
  1428 	for (; pl != NULL; pl = pl->pl_next) {
       
  1429 		if (!first) {
  1215 			if (scripted)
  1430 			if (scripted)
  1216 				(void) printf("\t");
  1431 				(void) printf("\t");
  1217 			else
  1432 			else
  1218 				(void) printf("  ");
  1433 				(void) printf("  ");
  1219 		}
  1434 		} else {
  1220 
  1435 			first = B_FALSE;
  1221 		if (zfs_prop_get(zhp, fields[i], property,
  1436 		}
  1222 		    sizeof (property), NULL, NULL, 0, B_FALSE) != 0)
  1437 
  1223 			(void) strlcpy(property, "-", sizeof (property));
  1438 		right_justify = B_FALSE;
       
  1439 		if (pl->pl_prop != ZFS_PROP_INVAL) {
       
  1440 			if (zfs_prop_get(zhp, pl->pl_prop, property,
       
  1441 			    sizeof (property), NULL, NULL, 0, B_FALSE) != 0)
       
  1442 				propstr = "-";
       
  1443 			else
       
  1444 				propstr = property;
       
  1445 
       
  1446 			right_justify = zfs_prop_align_right(pl->pl_prop);
       
  1447 		} else {
       
  1448 			if (nvlist_lookup_nvlist(userprops,
       
  1449 			    pl->pl_user_prop, &propval) != 0)
       
  1450 				propstr = "-";
       
  1451 			else
       
  1452 				verify(nvlist_lookup_string(propval,
       
  1453 				    ZFS_PROP_VALUE, &propstr) == 0);
       
  1454 		}
       
  1455 
       
  1456 		width = pl->pl_width;
  1224 
  1457 
  1225 		/*
  1458 		/*
  1226 		 * If this is being called in scripted mode, or if this is the
  1459 		 * If this is being called in scripted mode, or if this is the
  1227 		 * last column and it is left-justified, don't include a width
  1460 		 * last column and it is left-justified, don't include a width
  1228 		 * format specifier.
  1461 		 * format specifier.
  1229 		 */
  1462 		 */
  1230 		if (scripted || (i == count - 1 &&
  1463 		if (scripted || (pl->pl_next == NULL && !right_justify))
  1231 		    strchr(zfs_prop_column_format(fields[i]), '-') != NULL))
  1464 			(void) printf("%s", propstr);
  1232 			(void) printf("%s", property);
  1465 		else if (right_justify)
  1233 		else	/* LINTED - format specifier */
  1466 			(void) printf("%*s", width, propstr);
  1234 			(void) printf(zfs_prop_column_format(fields[i]),
  1467 		else
  1235 			    property);
  1468 			(void) printf("%-*s", width, propstr);
  1236 	}
  1469 	}
  1237 
  1470 
  1238 	(void) printf("\n");
  1471 	(void) printf("\n");
  1239 }
  1472 }
  1240 
  1473 
  1246 {
  1479 {
  1247 	list_cbdata_t *cbp = data;
  1480 	list_cbdata_t *cbp = data;
  1248 
  1481 
  1249 	if (cbp->cb_first) {
  1482 	if (cbp->cb_first) {
  1250 		if (!cbp->cb_scripted)
  1483 		if (!cbp->cb_scripted)
  1251 			print_header(cbp->cb_fields, cbp->cb_fieldcount);
  1484 			print_header(cbp->cb_proplist);
  1252 		cbp->cb_first = B_FALSE;
  1485 		cbp->cb_first = B_FALSE;
  1253 	}
  1486 	}
  1254 
  1487 
  1255 	print_dataset(zhp, cbp->cb_fields, cbp->cb_fieldcount,
  1488 	print_dataset(zhp, cbp->cb_proplist, cbp->cb_scripted);
  1256 	    cbp->cb_scripted);
       
  1257 
  1489 
  1258 	return (0);
  1490 	return (0);
  1259 }
  1491 }
  1260 
  1492 
  1261 static int
  1493 static int
  1271 	char *basic_fields = default_fields;
  1503 	char *basic_fields = default_fields;
  1272 	list_cbdata_t cb = { 0 };
  1504 	list_cbdata_t cb = { 0 };
  1273 	char *value;
  1505 	char *value;
  1274 	int ret;
  1506 	int ret;
  1275 	char *type_subopts[] = { "filesystem", "volume", "snapshot", NULL };
  1507 	char *type_subopts[] = { "filesystem", "volume", "snapshot", NULL };
  1276 	char *badopt;
       
  1277 	int alloffset;
       
  1278 	zfs_sort_column_t *sortcol = NULL;
  1508 	zfs_sort_column_t *sortcol = NULL;
  1279 
  1509 
  1280 	/* check options */
  1510 	/* check options */
  1281 	while ((c = getopt(argc, argv, ":o:rt:Hs:S:")) != -1) {
  1511 	while ((c = getopt(argc, argv, ":o:rt:Hs:S:")) != -1) {
  1282 		zfs_prop_t	prop;
       
  1283 
       
  1284 		switch (c) {
  1512 		switch (c) {
  1285 		case 'o':
  1513 		case 'o':
  1286 			fields = optarg;
  1514 			fields = optarg;
  1287 			break;
  1515 			break;
  1288 		case 'r':
  1516 		case 'r':
  1290 			break;
  1518 			break;
  1291 		case 'H':
  1519 		case 'H':
  1292 			scripted = B_TRUE;
  1520 			scripted = B_TRUE;
  1293 			break;
  1521 			break;
  1294 		case 's':
  1522 		case 's':
  1295 			if ((prop = zfs_name_to_prop(optarg)) ==
  1523 			if (zfs_add_sort_column(&sortcol, optarg,
  1296 			    ZFS_PROP_INVAL) {
  1524 			    B_FALSE) != 0) {
  1297 				(void) fprintf(stderr,
  1525 				(void) fprintf(stderr,
  1298 				    gettext("invalid property '%s'\n"), optarg);
  1526 				    gettext("invalid property '%s'\n"), optarg);
  1299 				usage(B_FALSE);
  1527 				usage(B_FALSE);
  1300 			}
  1528 			}
  1301 			zfs_add_sort_column(&sortcol, prop, B_FALSE);
       
  1302 			break;
  1529 			break;
  1303 		case 'S':
  1530 		case 'S':
  1304 			if ((prop = zfs_name_to_prop(optarg)) ==
  1531 			if (zfs_add_sort_column(&sortcol, optarg,
  1305 			    ZFS_PROP_INVAL) {
  1532 			    B_TRUE) != 0) {
  1306 				(void) fprintf(stderr,
  1533 				(void) fprintf(stderr,
  1307 				    gettext("invalid property '%s'\n"), optarg);
  1534 				    gettext("invalid property '%s'\n"), optarg);
  1308 				usage(B_FALSE);
  1535 				usage(B_FALSE);
  1309 			}
  1536 			}
  1310 			zfs_add_sort_column(&sortcol, prop, B_TRUE);
       
  1311 			break;
  1537 			break;
  1312 		case 't':
  1538 		case 't':
  1313 			types = 0;
  1539 			types = 0;
  1314 			while (*optarg != '\0') {
  1540 			while (*optarg != '\0') {
  1315 				switch (getsubopt(&optarg, type_subopts,
  1541 				switch (getsubopt(&optarg, type_subopts,
  1352 	/*
  1578 	/*
  1353 	 * If the user specifies '-o all', the zfs_get_proplist() doesn't
  1579 	 * If the user specifies '-o all', the zfs_get_proplist() doesn't
  1354 	 * normally include the name of the dataset.  For 'zfs list', we always
  1580 	 * normally include the name of the dataset.  For 'zfs list', we always
  1355 	 * want this property to be first.
  1581 	 * want this property to be first.
  1356 	 */
  1582 	 */
  1357 	if (strcmp(fields, "all") == 0) {
  1583 	if (zfs_get_proplist(g_zfs, fields, &cb.cb_proplist) != 0)
  1358 		cb.cb_fields[0] = ZFS_PROP_NAME;
  1584 		usage(B_FALSE);
  1359 		alloffset = 1;
  1585 
  1360 	} else {
       
  1361 		alloffset = 0;
       
  1362 	}
       
  1363 
       
  1364 	if ((ret = zfs_get_proplist(fields, cb.cb_fields + alloffset,
       
  1365 	    ZFS_NPROP_ALL - alloffset, &cb.cb_fieldcount, &badopt)) != 0) {
       
  1366 		if (ret == EINVAL)
       
  1367 			(void) fprintf(stderr, gettext("invalid property "
       
  1368 			    "'%s'\n"), badopt);
       
  1369 		else
       
  1370 			(void) fprintf(stderr, gettext("too many properties "
       
  1371 			    "specified\n"));
       
  1372 		usage(B_FALSE);
       
  1373 	}
       
  1374 
       
  1375 	cb.cb_fieldcount += alloffset;
       
  1376 	cb.cb_scripted = scripted;
  1586 	cb.cb_scripted = scripted;
  1377 	cb.cb_first = B_TRUE;
  1587 	cb.cb_first = B_TRUE;
  1378 
  1588 
  1379 	ret = zfs_for_each(argc, argv, recurse, types, sortcol,
  1589 	ret = zfs_for_each(argc, argv, recurse, types, sortcol, &cb.cb_proplist,
  1380 	    list_callback, &cb);
  1590 	    list_callback, &cb);
  1381 
  1591 
       
  1592 	zfs_free_proplist(cb.cb_proplist);
  1382 	zfs_free_sort_columns(sortcol);
  1593 	zfs_free_sort_columns(sortcol);
  1383 
  1594 
  1384 	if (ret == 0 && cb.cb_first)
  1595 	if (ret == 0 && cb.cb_first)
  1385 		(void) printf(gettext("no datasets available\n"));
  1596 		(void) printf(gettext("no datasets available\n"));
  1386 
  1597 
  1650  * Sets the given property for all datasets specified on the command line.
  1861  * Sets the given property for all datasets specified on the command line.
  1651  */
  1862  */
  1652 typedef struct set_cbdata {
  1863 typedef struct set_cbdata {
  1653 	char		*cb_propname;
  1864 	char		*cb_propname;
  1654 	char		*cb_value;
  1865 	char		*cb_value;
  1655 	zfs_prop_t	cb_prop;
       
  1656 } set_cbdata_t;
  1866 } set_cbdata_t;
  1657 
  1867 
  1658 static int
  1868 static int
  1659 set_callback(zfs_handle_t *zhp, void *data)
  1869 set_callback(zfs_handle_t *zhp, void *data)
  1660 {
  1870 {
  1661 	set_cbdata_t *cbp = data;
  1871 	set_cbdata_t *cbp = data;
  1662 	int ret = 1;
  1872 	int ret = 1;
  1663 
  1873 
  1664 	/* don't allow setting of properties for snapshots */
  1874 	if (zfs_prop_set(zhp, cbp->cb_propname, cbp->cb_value) != 0) {
  1665 	if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
       
  1666 		(void) fprintf(stderr, gettext("cannot set %s property for "
       
  1667 		    "'%s': snapshot properties cannot be modified\n"),
       
  1668 		    cbp->cb_propname, zfs_get_name(zhp));
       
  1669 		return (1);
       
  1670 	}
       
  1671 
       
  1672 	/*
       
  1673 	 * If we're changing the volsize, make sure the value is appropriate,
       
  1674 	 * and set the reservation if this is a non-sparse volume.
       
  1675 	 */
       
  1676 	if (cbp->cb_prop == ZFS_PROP_VOLSIZE &&
       
  1677 	    zfs_get_type(zhp) == ZFS_TYPE_VOLUME) {
       
  1678 		uint64_t volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
       
  1679 		uint64_t avail = zfs_prop_get_int(zhp, ZFS_PROP_AVAILABLE);
       
  1680 		uint64_t reservation = zfs_prop_get_int(zhp,
       
  1681 		    ZFS_PROP_RESERVATION);
       
  1682 		uint64_t blocksize = zfs_prop_get_int(zhp,
       
  1683 		    ZFS_PROP_VOLBLOCKSIZE);
       
  1684 		uint64_t value;
       
  1685 
       
  1686 		verify(zfs_nicestrtonum(cbp->cb_value, &value) == 0);
       
  1687 
       
  1688 		if (value % blocksize != 0) {
       
  1689 			char buf[64];
       
  1690 
       
  1691 			zfs_nicenum(blocksize, buf, sizeof (buf));
       
  1692 			(void) fprintf(stderr, gettext("cannot set %s for "
       
  1693 			    "'%s': must be a multiple of volume block size "
       
  1694 			    "(%s)\n"), cbp->cb_propname, zfs_get_name(zhp),
       
  1695 			    buf);
       
  1696 			return (1);
       
  1697 		}
       
  1698 
       
  1699 		if (value == 0) {
       
  1700 			(void) fprintf(stderr, gettext("cannot set %s for "
       
  1701 			    "'%s': cannot be zero\n"), cbp->cb_propname,
       
  1702 			    zfs_get_name(zhp));
       
  1703 			return (1);
       
  1704 		}
       
  1705 
       
  1706 		if (volsize == reservation) {
       
  1707 			if (value > volsize && (value - volsize) > avail) {
       
  1708 				(void) fprintf(stderr, gettext("cannot set "
       
  1709 				    "%s property for '%s': volume size exceeds "
       
  1710 				    "amount of available space\n"),
       
  1711 				    cbp->cb_propname, zfs_get_name(zhp));
       
  1712 				return (1);
       
  1713 			}
       
  1714 
       
  1715 			if (zfs_prop_set(zhp, ZFS_PROP_RESERVATION,
       
  1716 			    cbp->cb_value) != 0) {
       
  1717 				(void) fprintf(stderr, gettext("volsize and "
       
  1718 				    "reservation must remain equal\n"));
       
  1719 				return (1);
       
  1720 			}
       
  1721 		}
       
  1722 	}
       
  1723 
       
  1724 	/*
       
  1725 	 * Do not allow the reservation to be set above the volume size. We do
       
  1726 	 * this here instead of inside libzfs because libzfs violates this rule
       
  1727 	 * internally.
       
  1728 	 */
       
  1729 	if (cbp->cb_prop == ZFS_PROP_RESERVATION &&
       
  1730 	    zfs_get_type(zhp) == ZFS_TYPE_VOLUME) {
       
  1731 		uint64_t value;
       
  1732 		uint64_t volsize;
       
  1733 
       
  1734 		volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
       
  1735 		if (strcmp(cbp->cb_value, "none") == 0)
       
  1736 			value = 0;
       
  1737 		else
       
  1738 			verify(zfs_nicestrtonum(cbp->cb_value, &value) == 0);
       
  1739 
       
  1740 		if (value > volsize) {
       
  1741 			(void) fprintf(stderr, gettext("cannot set %s "
       
  1742 			    "for '%s': size is greater than current "
       
  1743 			    "volume size\n"), cbp->cb_propname,
       
  1744 			    zfs_get_name(zhp));
       
  1745 			return (-1);
       
  1746 		}
       
  1747 	}
       
  1748 
       
  1749 	if (zfs_prop_set(zhp, cbp->cb_prop, cbp->cb_value) != 0) {
       
  1750 		switch (libzfs_errno(g_zfs)) {
  1875 		switch (libzfs_errno(g_zfs)) {
  1751 		case EZFS_MOUNTFAILED:
  1876 		case EZFS_MOUNTFAILED:
  1752 			(void) fprintf(stderr, gettext("property may be set "
  1877 			(void) fprintf(stderr, gettext("property may be set "
  1753 			    "but unable to remount filesystem\n"));
  1878 			    "but unable to remount filesystem\n"));
  1754 			break;
  1879 			break;
  1801 	if (*cb.cb_propname == '\0') {
  1926 	if (*cb.cb_propname == '\0') {
  1802 		(void) fprintf(stderr,
  1927 		(void) fprintf(stderr,
  1803 		    gettext("missing property in property=value argument\n"));
  1928 		    gettext("missing property in property=value argument\n"));
  1804 		usage(B_FALSE);
  1929 		usage(B_FALSE);
  1805 	}
  1930 	}
  1806 	if (*cb.cb_value == '\0') {
       
  1807 		(void) fprintf(stderr,
       
  1808 		    gettext("missing value in property=value argument\n"));
       
  1809 		usage(B_FALSE);
       
  1810 	}
       
  1811 
       
  1812 	/* get the property type */
       
  1813 	if ((cb.cb_prop = zfs_name_to_prop(cb.cb_propname)) ==
       
  1814 	    ZFS_PROP_INVAL) {
       
  1815 		(void) fprintf(stderr,
       
  1816 		    gettext("invalid property '%s'\n"), cb.cb_propname);
       
  1817 		usage(B_FALSE);
       
  1818 	}
       
  1819 
       
  1820 	/*
       
  1821 	 * Validate that the value is appropriate for this property.  We do this
       
  1822 	 * once now so we don't generate multiple errors each time we try to
       
  1823 	 * apply it to a dataset.
       
  1824 	 */
       
  1825 	if (zfs_prop_validate(g_zfs, cb.cb_prop, cb.cb_value, NULL) != 0)
       
  1826 		return (1);
       
  1827 
  1931 
  1828 	return (zfs_for_each(argc - 2, argv + 2, B_FALSE,
  1932 	return (zfs_for_each(argc - 2, argv + 2, B_FALSE,
  1829 	    ZFS_TYPE_ANY, NULL, set_callback, &cb));
  1933 	    ZFS_TYPE_ANY, NULL, NULL, set_callback, &cb));
  1830 }
  1934 }
  1831 
  1935 
  1832 /*
  1936 /*
  1833  * zfs snapshot [-r] <fs@snap>
  1937  * zfs snapshot [-r] <fs@snap>
  1834  *
  1938  *
  2123 	char mountpoint[ZFS_MAXPROPLEN];
  2227 	char mountpoint[ZFS_MAXPROPLEN];
  2124 	char shareopts[ZFS_MAXPROPLEN];
  2228 	char shareopts[ZFS_MAXPROPLEN];
  2125 	share_mount_cbdata_t *cbp = data;
  2229 	share_mount_cbdata_t *cbp = data;
  2126 	const char *cmdname = cbp->cb_type == OP_SHARE ? "share" : "mount";
  2230 	const char *cmdname = cbp->cb_type == OP_SHARE ? "share" : "mount";
  2127 	struct mnttab mnt;
  2231 	struct mnttab mnt;
  2128 	uint64_t zoned;
  2232 	uint64_t zoned, canmount;
  2129 
  2233 
  2130 	if (cbp->cb_options == NULL)
  2234 	if (cbp->cb_options == NULL)
  2131 		mnt.mnt_mntopts = "";
  2235 		mnt.mnt_mntopts = "";
  2132 	else
  2236 	else
  2133 		mnt.mnt_mntopts = (char *)cbp->cb_options;
  2237 		mnt.mnt_mntopts = (char *)cbp->cb_options;
  2163 	 */
  2267 	 */
  2164 	verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
  2268 	verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
  2165 	    sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
  2269 	    sizeof (mountpoint), NULL, NULL, 0, B_FALSE) == 0);
  2166 	verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
  2270 	verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts,
  2167 	    sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
  2271 	    sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
       
  2272 	canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
  2168 
  2273 
  2169 	if (cbp->cb_type == OP_SHARE) {
  2274 	if (cbp->cb_type == OP_SHARE) {
  2170 		if (strcmp(shareopts, "off") == 0) {
  2275 		if (strcmp(shareopts, "off") == 0) {
  2171 			if (!cbp->cb_explicit)
  2276 			if (!cbp->cb_explicit)
  2172 				return (0);
  2277 				return (0);
  2200 		if (!cbp->cb_explicit)
  2305 		if (!cbp->cb_explicit)
  2201 			return (0);
  2306 			return (0);
  2202 
  2307 
  2203 		(void) fprintf(stderr, gettext("cannot %s '%s': no "
  2308 		(void) fprintf(stderr, gettext("cannot %s '%s': no "
  2204 		    "mountpoint set\n"), cmdname, zfs_get_name(zhp));
  2309 		    "mountpoint set\n"), cmdname, zfs_get_name(zhp));
       
  2310 		return (1);
       
  2311 	}
       
  2312 
       
  2313 	if (!canmount) {
       
  2314 		if (!cbp->cb_explicit)
       
  2315 			return (0);
       
  2316 
       
  2317 		(void) fprintf(stderr, gettext("cannot %s '%s': 'canmount' "
       
  2318 		    "property is set to 'off'\n"), cmdname, zfs_get_name(zhp));
  2205 		return (1);
  2319 		return (1);
  2206 	}
  2320 	}
  2207 
  2321 
  2208 	/*
  2322 	/*
  2209 	 * At this point, we have verified that the mountpoint and/or shareopts
  2323 	 * At this point, we have verified that the mountpoint and/or shareopts