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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"@(#)zfs_prop.c	1.30	07/11/16 SMI"
     27 
     28 #include <sys/zio.h>
     29 #include <sys/spa.h>
     30 #include <sys/u8_textprep.h>
     31 #include <sys/zfs_acl.h>
     32 #include <sys/zfs_ioctl.h>
     33 #include <sys/zfs_znode.h>
     34 
     35 #include "zfs_prop.h"
     36 #include "zfs_deleg.h"
     37 
     38 #if defined(_KERNEL)
     39 #include <sys/systm.h>
     40 #else
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <ctype.h>
     44 #endif
     45 
     46 static zprop_desc_t zfs_prop_table[ZFS_NUM_PROPS];
     47 
     48 zprop_desc_t *
     49 zfs_prop_get_table(void)
     50 {
     51 	return (zfs_prop_table);
     52 }
     53 
     54 void
     55 zfs_prop_init(void)
     56 {
     57 	static zprop_index_t checksum_table[] = {
     58 		{ "on",		ZIO_CHECKSUM_ON },
     59 		{ "off",	ZIO_CHECKSUM_OFF },
     60 		{ "fletcher2",	ZIO_CHECKSUM_FLETCHER_2 },
     61 		{ "fletcher4",	ZIO_CHECKSUM_FLETCHER_4 },
     62 		{ "sha256",	ZIO_CHECKSUM_SHA256 },
     63 		{ NULL }
     64 	};
     65 
     66 	static zprop_index_t compress_table[] = {
     67 		{ "on",		ZIO_COMPRESS_ON },
     68 		{ "off",	ZIO_COMPRESS_OFF },
     69 		{ "lzjb",	ZIO_COMPRESS_LZJB },
     70 		{ "gzip",	ZIO_COMPRESS_GZIP_6 },	/* gzip default */
     71 		{ "gzip-1",	ZIO_COMPRESS_GZIP_1 },
     72 		{ "gzip-2",	ZIO_COMPRESS_GZIP_2 },
     73 		{ "gzip-3",	ZIO_COMPRESS_GZIP_3 },
     74 		{ "gzip-4",	ZIO_COMPRESS_GZIP_4 },
     75 		{ "gzip-5",	ZIO_COMPRESS_GZIP_5 },
     76 		{ "gzip-6",	ZIO_COMPRESS_GZIP_6 },
     77 		{ "gzip-7",	ZIO_COMPRESS_GZIP_7 },
     78 		{ "gzip-8",	ZIO_COMPRESS_GZIP_8 },
     79 		{ "gzip-9",	ZIO_COMPRESS_GZIP_9 },
     80 		{ NULL }
     81 	};
     82 
     83 	static zprop_index_t snapdir_table[] = {
     84 		{ "hidden",	ZFS_SNAPDIR_HIDDEN },
     85 		{ "visible",	ZFS_SNAPDIR_VISIBLE },
     86 		{ NULL }
     87 	};
     88 
     89 	static zprop_index_t acl_mode_table[] = {
     90 		{ "discard",	ZFS_ACL_DISCARD },
     91 		{ "groupmask",	ZFS_ACL_GROUPMASK },
     92 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
     93 		{ NULL }
     94 	};
     95 
     96 	static zprop_index_t acl_inherit_table[] = {
     97 		{ "discard",	ZFS_ACL_DISCARD },
     98 		{ "noallow",	ZFS_ACL_NOALLOW },
     99 		{ "secure",	ZFS_ACL_SECURE },
    100 		{ "passthrough", ZFS_ACL_PASSTHROUGH },
    101 		{ NULL }
    102 	};
    103 
    104 	static zprop_index_t case_table[] = {
    105 		{ "sensitive",		ZFS_CASE_SENSITIVE },
    106 		{ "insensitive",	ZFS_CASE_INSENSITIVE },
    107 		{ "mixed",		ZFS_CASE_MIXED },
    108 		{ NULL }
    109 	};
    110 
    111 	static zprop_index_t copies_table[] = {
    112 		{ "1",		1 },
    113 		{ "2",		2 },
    114 		{ "3",		3 },
    115 		{ NULL }
    116 	};
    117 
    118 	/*
    119 	 * Use the unique flags we have to send to u8_strcmp() and/or
    120 	 * u8_textprep() to represent the various normalization property
    121 	 * values.
    122 	 */
    123 	static zprop_index_t normalize_table[] = {
    124 		{ "none",	0 },
    125 		{ "formD",	U8_TEXTPREP_NFD },
    126 		{ "formKC",	U8_TEXTPREP_NFKC },
    127 		{ "formC",	U8_TEXTPREP_NFC },
    128 		{ "formKD",	U8_TEXTPREP_NFKD },
    129 		{ NULL }
    130 	};
    131 
    132 	static zprop_index_t version_table[] = {
    133 		{ "1",		1 },
    134 		{ "2",		2 },
    135 		{ "3",		3 },
    136 		{ "current",	ZPL_VERSION },
    137 		{ NULL }
    138 	};
    139 
    140 	static zprop_index_t boolean_table[] = {
    141 		{ "off",	0 },
    142 		{ "on",		1 },
    143 		{ NULL }
    144 	};
    145 
    146 	/* inherit index properties */
    147 	register_index(ZFS_PROP_CHECKSUM, "checksum", ZIO_CHECKSUM_DEFAULT,
    148 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    149 	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM",
    150 	    checksum_table);
    151 	register_index(ZFS_PROP_COMPRESSION, "compression",
    152 	    ZIO_COMPRESS_DEFAULT, PROP_INHERIT,
    153 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    154 	    "on | off | lzjb | gzip | gzip-[1-9]", "COMPRESS", compress_table);
    155 	register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
    156 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    157 	    "hidden | visible", "SNAPDIR", snapdir_table);
    158 	register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK,
    159 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    160 	    "discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
    161 	register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_SECURE,
    162 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
    163 	    "discard | noallow | secure | passthrough", "ACLINHERIT",
    164 	    acl_inherit_table);
    165 	register_index(ZFS_PROP_COPIES, "copies", 1,
    166 	    PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    167 	    "1 | 2 | 3", "COPIES", copies_table);
    168 
    169 	/* inherit index (boolean) properties */
    170 	register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
    171 	    ZFS_TYPE_FILESYSTEM, "on | off", "ATIME", boolean_table);
    172 	register_index(ZFS_PROP_DEVICES, "devices", 1, PROP_INHERIT,
    173 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "DEVICES",
    174 	    boolean_table);
    175 	register_index(ZFS_PROP_EXEC, "exec", 1, PROP_INHERIT,
    176 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "EXEC",
    177 	    boolean_table);
    178 	register_index(ZFS_PROP_SETUID, "setuid", 1, PROP_INHERIT,
    179 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
    180 	    boolean_table);
    181 	register_index(ZFS_PROP_READONLY, "readonly", 0, PROP_INHERIT,
    182 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off", "RDONLY",
    183 	    boolean_table);
    184 	register_index(ZFS_PROP_ZONED, "zoned", 0, PROP_INHERIT,
    185 	    ZFS_TYPE_FILESYSTEM, "on | off", "ZONED", boolean_table);
    186 	register_index(ZFS_PROP_XATTR, "xattr", 1, PROP_INHERIT,
    187 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "XATTR",
    188 	    boolean_table);
    189 	register_index(ZFS_PROP_VSCAN, "vscan", 0, PROP_INHERIT,
    190 	    ZFS_TYPE_FILESYSTEM, "on | off", "VSCAN",
    191 	    boolean_table);
    192 	register_index(ZFS_PROP_NBMAND, "nbmand", 0, PROP_INHERIT,
    193 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "NBMAND",
    194 	    boolean_table);
    195 
    196 	/* default index properties */
    197 	register_index(ZFS_PROP_VERSION, "version", 0, PROP_DEFAULT,
    198 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    199 	    "1 | 2 | 3 | current", "VERSION", version_table);
    200 
    201 	/* default index (boolean) properties */
    202 	register_index(ZFS_PROP_CANMOUNT, "canmount", 1, PROP_DEFAULT,
    203 	    ZFS_TYPE_FILESYSTEM, "on | off", "CANMOUNT", boolean_table);
    204 
    205 	/* readonly index (boolean) properties */
    206 	register_index(ZFS_PROP_MOUNTED, "mounted", 0, PROP_READONLY,
    207 	    ZFS_TYPE_FILESYSTEM, "yes | no", "MOUNTED", boolean_table);
    208 
    209 	/* set once index properties */
    210 	register_index(ZFS_PROP_NORMALIZE, "normalization", 0,
    211 	    PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    212 	    "none | formC | formD | formKC | formKD", "NORMALIZATION",
    213 	    normalize_table);
    214 	register_index(ZFS_PROP_CASE, "casesensitivity", ZFS_CASE_SENSITIVE,
    215 	    PROP_ONETIME, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    216 	    "sensitive | insensitive | mixed", "CASE", case_table);
    217 
    218 	/* set once index (boolean) properties */
    219 	register_index(ZFS_PROP_UTF8ONLY, "utf8only", 0, PROP_ONETIME,
    220 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
    221 	    "on | off", "UTF8ONLY", boolean_table);
    222 
    223 	/* string properties */
    224 	register_string(ZFS_PROP_ORIGIN, "origin", NULL, PROP_READONLY,
    225 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN");
    226 	register_string(ZFS_PROP_MOUNTPOINT, "mountpoint", "/", PROP_INHERIT,
    227 	    ZFS_TYPE_FILESYSTEM, "<path> | legacy | none", "MOUNTPOINT");
    228 	register_string(ZFS_PROP_SHARENFS, "sharenfs", "off", PROP_INHERIT,
    229 	    ZFS_TYPE_FILESYSTEM, "on | off | share(1M) options", "SHARENFS");
    230 	register_string(ZFS_PROP_SHAREISCSI, "shareiscsi", "off", PROP_INHERIT,
    231 	    ZFS_TYPE_DATASET, "on | off | type=<type>", "SHAREISCSI");
    232 	register_string(ZFS_PROP_TYPE, "type", NULL, PROP_READONLY,
    233 	    ZFS_TYPE_DATASET, "filesystem | volume | snapshot", "TYPE");
    234 	register_string(ZFS_PROP_SHARESMB, "sharesmb", "off", PROP_INHERIT,
    235 	    ZFS_TYPE_FILESYSTEM, "on | off | sharemgr(1M) options", "SHARESMB");
    236 
    237 	/* readonly number properties */
    238 	register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
    239 	    ZFS_TYPE_DATASET, "<size>", "USED");
    240 	register_number(ZFS_PROP_AVAILABLE, "available", 0, PROP_READONLY,
    241 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL");
    242 	register_number(ZFS_PROP_REFERENCED, "referenced", 0, PROP_READONLY,
    243 	    ZFS_TYPE_DATASET, "<size>", "REFER");
    244 	register_number(ZFS_PROP_COMPRESSRATIO, "compressratio", 0,
    245 	    PROP_READONLY, ZFS_TYPE_DATASET,
    246 	    "<1.00x or higher if compressed>", "RATIO");
    247 	register_number(ZFS_PROP_VOLBLOCKSIZE, "volblocksize", 8192,
    248 	    PROP_ONETIME,
    249 	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK");
    250 
    251 	/* default number properties */
    252 	register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,
    253 	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA");
    254 	register_number(ZFS_PROP_RESERVATION, "reservation", 0, PROP_DEFAULT,
    255 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size> | none", "RESERV");
    256 	register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
    257 	    ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
    258 	register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
    259 	    ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
    260 	register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
    261 	    PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
    262 	    "<size> | none", "REFRESERV");
    263 
    264 	/* inherit number properties */
    265 	register_number(ZFS_PROP_RECORDSIZE, "recordsize", SPA_MAXBLOCKSIZE,
    266 	    PROP_INHERIT,
    267 	    ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE");
    268 
    269 	/* hidden properties */
    270 	register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER,
    271 	    PROP_READONLY, ZFS_TYPE_DATASET, NULL);
    272 	register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER,
    273 	    PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL);
    274 	register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING,
    275 	    PROP_READONLY, ZFS_TYPE_DATASET, "NAME");
    276 	register_hidden(ZFS_PROP_ISCSIOPTIONS, "iscsioptions", PROP_TYPE_STRING,
    277 	    PROP_INHERIT, ZFS_TYPE_VOLUME, "ISCSIOPTIONS");
    278 
    279 	/* oddball properties */
    280 	register_impl(ZFS_PROP_CREATION, "creation", PROP_TYPE_NUMBER, 0, NULL,
    281 	    PROP_READONLY, ZFS_TYPE_DATASET,
    282 	    "<date>", "CREATION", B_FALSE, B_TRUE, NULL);
    283 }
    284 
    285 boolean_t
    286 zfs_prop_delegatable(zfs_prop_t prop)
    287 {
    288 	zprop_desc_t *pd = &zfs_prop_table[prop];
    289 	return (pd->pd_attr != PROP_READONLY);
    290 }
    291 
    292 /*
    293  * Given a zfs dataset property name, returns the corresponding property ID.
    294  */
    295 zfs_prop_t
    296 zfs_name_to_prop(const char *propname)
    297 {
    298 	return (zprop_name_to_prop(propname, ZFS_TYPE_DATASET));
    299 }
    300 
    301 
    302 /*
    303  * For user property names, we allow all lowercase alphanumeric characters, plus
    304  * a few useful punctuation characters.
    305  */
    306 static int
    307 valid_char(char c)
    308 {
    309 	return ((c >= 'a' && c <= 'z') ||
    310 	    (c >= '0' && c <= '9') ||
    311 	    c == '-' || c == '_' || c == '.' || c == ':');
    312 }
    313 
    314 /*
    315  * Returns true if this is a valid user-defined property (one with a ':').
    316  */
    317 boolean_t
    318 zfs_prop_user(const char *name)
    319 {
    320 	int i;
    321 	char c;
    322 	boolean_t foundsep = B_FALSE;
    323 
    324 	for (i = 0; i < strlen(name); i++) {
    325 		c = name[i];
    326 		if (!valid_char(c))
    327 			return (B_FALSE);
    328 		if (c == ':')
    329 			foundsep = B_TRUE;
    330 	}
    331 
    332 	if (!foundsep)
    333 		return (B_FALSE);
    334 
    335 	return (B_TRUE);
    336 }
    337 
    338 /*
    339  * Tables of index types, plus functions to convert between the user view
    340  * (strings) and internal representation (uint64_t).
    341  */
    342 int
    343 zfs_prop_string_to_index(zfs_prop_t prop, const char *string, uint64_t *index)
    344 {
    345 	return (zprop_string_to_index(prop, string, index, ZFS_TYPE_DATASET));
    346 }
    347 
    348 int
    349 zfs_prop_index_to_string(zfs_prop_t prop, uint64_t index, const char **string)
    350 {
    351 	return (zprop_index_to_string(prop, index, string, ZFS_TYPE_DATASET));
    352 }
    353 
    354 /*
    355  * Returns TRUE if the property applies to any of the given dataset types.
    356  */
    357 int
    358 zfs_prop_valid_for_type(int prop, zfs_type_t types)
    359 {
    360 	return (zprop_valid_for_type(prop, types));
    361 }
    362 
    363 zprop_type_t
    364 zfs_prop_get_type(zfs_prop_t prop)
    365 {
    366 	return (zfs_prop_table[prop].pd_proptype);
    367 }
    368 
    369 /*
    370  * Returns TRUE if the property is readonly.
    371  */
    372 boolean_t
    373 zfs_prop_readonly(zfs_prop_t prop)
    374 {
    375 	return (zfs_prop_table[prop].pd_attr == PROP_READONLY ||
    376 	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    377 }
    378 
    379 /*
    380  * Returns TRUE if the property is only allowed to be set once.
    381  */
    382 boolean_t
    383 zfs_prop_setonce(zfs_prop_t prop)
    384 {
    385 	return (zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    386 }
    387 
    388 const char *
    389 zfs_prop_default_string(zfs_prop_t prop)
    390 {
    391 	return (zfs_prop_table[prop].pd_strdefault);
    392 }
    393 
    394 uint64_t
    395 zfs_prop_default_numeric(zfs_prop_t prop)
    396 {
    397 	return (zfs_prop_table[prop].pd_numdefault);
    398 }
    399 
    400 /*
    401  * Given a dataset property ID, returns the corresponding name.
    402  * Assuming the zfs dataset property ID is valid.
    403  */
    404 const char *
    405 zfs_prop_to_name(zfs_prop_t prop)
    406 {
    407 	return (zfs_prop_table[prop].pd_name);
    408 }
    409 
    410 /*
    411  * Returns TRUE if the property is inheritable.
    412  */
    413 boolean_t
    414 zfs_prop_inheritable(zfs_prop_t prop)
    415 {
    416 	return (zfs_prop_table[prop].pd_attr == PROP_INHERIT ||
    417 	    zfs_prop_table[prop].pd_attr == PROP_ONETIME);
    418 }
    419 
    420 #ifndef _KERNEL
    421 
    422 /*
    423  * Returns a string describing the set of acceptable values for the given
    424  * zfs property, or NULL if it cannot be set.
    425  */
    426 const char *
    427 zfs_prop_values(zfs_prop_t prop)
    428 {
    429 	return (zfs_prop_table[prop].pd_values);
    430 }
    431 
    432 /*
    433  * Returns TRUE if this property is a string type.  Note that index types
    434  * (compression, checksum) are treated as strings in userland, even though they
    435  * are stored numerically on disk.
    436  */
    437 int
    438 zfs_prop_is_string(zfs_prop_t prop)
    439 {
    440 	return (zfs_prop_table[prop].pd_proptype == PROP_TYPE_STRING ||
    441 	    zfs_prop_table[prop].pd_proptype == PROP_TYPE_INDEX);
    442 }
    443 
    444 /*
    445  * Returns the column header for the given property.  Used only in
    446  * 'zfs list -o', but centralized here with the other property information.
    447  */
    448 const char *
    449 zfs_prop_column_name(zfs_prop_t prop)
    450 {
    451 	return (zfs_prop_table[prop].pd_colname);
    452 }
    453 
    454 /*
    455  * Returns whether the given property should be displayed right-justified for
    456  * 'zfs list'.
    457  */
    458 boolean_t
    459 zfs_prop_align_right(zfs_prop_t prop)
    460 {
    461 	return (zfs_prop_table[prop].pd_rightalign);
    462 }
    463 
    464 #endif
    465