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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
26 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27 * Copyright (c) 2017 Datto Inc.
28 */
29
30 /*
31 * Internal utility routines for the ZFS library.
32 */
33
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <libintl.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <strings.h>
41 #include <unistd.h>
42 #include <ctype.h>
43 #include <math.h>
44 #include <sys/filio.h>
1167 * Given a propname=value nvpair to set, parse any numeric properties
1168 * (index, boolean, etc) if they are specified as strings and add the
1169 * resulting nvpair to the returned nvlist.
1170 *
1171 * At the DSL layer, all properties are either 64-bit numbers or strings.
1172 * We want the user to be able to ignore this fact and specify properties
1173 * as native values (numbers, for example) or as strings (to simplify
1174 * command line utilities). This also handles converting index types
1175 * (compression, checksum, etc) from strings to their on-disk index.
1176 */
1177 int
1178 zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
1179 zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
1180 const char *errbuf)
1181 {
1182 data_type_t datatype = nvpair_type(elem);
1183 zprop_type_t proptype;
1184 const char *propname;
1185 char *value;
1186 boolean_t isnone = B_FALSE;
1187
1188 if (type == ZFS_TYPE_POOL) {
1189 proptype = zpool_prop_get_type(prop);
1190 propname = zpool_prop_to_name(prop);
1191 } else {
1192 proptype = zfs_prop_get_type(prop);
1193 propname = zfs_prop_to_name(prop);
1194 }
1195
1196 /*
1197 * Convert any properties to the internal DSL value types.
1198 */
1199 *svalp = NULL;
1200 *ivalp = 0;
1201
1202 switch (proptype) {
1203 case PROP_TYPE_STRING:
1204 if (datatype != DATA_TYPE_STRING) {
1205 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1206 "'%s' must be a string"), nvpair_name(elem));
1207 goto error;
1208 }
1209 (void) nvpair_value_string(elem, svalp);
1210 if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
1211 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1212 "'%s' is too long"), nvpair_name(elem));
1213 goto error;
1214 }
1215 break;
1216
1217 case PROP_TYPE_NUMBER:
1218 if (datatype == DATA_TYPE_STRING) {
1219 (void) nvpair_value_string(elem, &value);
1220 if (strcmp(value, "none") == 0) {
1221 isnone = B_TRUE;
1222 } else if (zfs_nicestrtonum(hdl, value, ivalp)
1223 != 0) {
1224 goto error;
1225 }
1226 } else if (datatype == DATA_TYPE_UINT64) {
1227 (void) nvpair_value_uint64(elem, ivalp);
1228 } else {
1229 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1230 "'%s' must be a number"), nvpair_name(elem));
1231 goto error;
1232 }
1233
1234 /*
1235 * Quota special: force 'none' and don't allow 0.
1236 */
1237 if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
1238 (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
1239 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1240 "use 'none' to disable quota/refquota"));
1241 goto error;
1242 }
1243
1244 /*
1245 * Special handling for "*_limit=none". In this case it's not
1246 * 0 but UINT64_MAX.
1247 */
1248 if ((type & ZFS_TYPE_DATASET) && isnone &&
1249 (prop == ZFS_PROP_FILESYSTEM_LIMIT ||
1250 prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
1251 *ivalp = UINT64_MAX;
1252 }
1253 break;
1254
1255 case PROP_TYPE_INDEX:
1256 if (datatype != DATA_TYPE_STRING) {
1257 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1258 "'%s' must be a string"), nvpair_name(elem));
1259 goto error;
1260 }
1261
1262 (void) nvpair_value_string(elem, &value);
1263
1264 if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
1265 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1266 "'%s' must be one of '%s'"), propname,
1267 zprop_values(prop, type));
1268 goto error;
1269 }
1270 break;
1271
1272 default:
1273 abort();
1274 }
|
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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2018 Joyent, Inc.
25 * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
26 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
27 * Copyright (c) 2017 Datto Inc.
28 */
29
30 /*
31 * Internal utility routines for the ZFS library.
32 */
33
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <libintl.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <strings.h>
41 #include <unistd.h>
42 #include <ctype.h>
43 #include <math.h>
44 #include <sys/filio.h>
1167 * Given a propname=value nvpair to set, parse any numeric properties
1168 * (index, boolean, etc) if they are specified as strings and add the
1169 * resulting nvpair to the returned nvlist.
1170 *
1171 * At the DSL layer, all properties are either 64-bit numbers or strings.
1172 * We want the user to be able to ignore this fact and specify properties
1173 * as native values (numbers, for example) or as strings (to simplify
1174 * command line utilities). This also handles converting index types
1175 * (compression, checksum, etc) from strings to their on-disk index.
1176 */
1177 int
1178 zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
1179 zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
1180 const char *errbuf)
1181 {
1182 data_type_t datatype = nvpair_type(elem);
1183 zprop_type_t proptype;
1184 const char *propname;
1185 char *value;
1186 boolean_t isnone = B_FALSE;
1187 boolean_t isauto = B_FALSE;
1188
1189 if (type == ZFS_TYPE_POOL) {
1190 proptype = zpool_prop_get_type(prop);
1191 propname = zpool_prop_to_name(prop);
1192 } else {
1193 proptype = zfs_prop_get_type(prop);
1194 propname = zfs_prop_to_name(prop);
1195 }
1196
1197 /*
1198 * Convert any properties to the internal DSL value types.
1199 */
1200 *svalp = NULL;
1201 *ivalp = 0;
1202
1203 switch (proptype) {
1204 case PROP_TYPE_STRING:
1205 if (datatype != DATA_TYPE_STRING) {
1206 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1207 "'%s' must be a string"), nvpair_name(elem));
1208 goto error;
1209 }
1210 (void) nvpair_value_string(elem, svalp);
1211 if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
1212 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1213 "'%s' is too long"), nvpair_name(elem));
1214 goto error;
1215 }
1216 break;
1217
1218 case PROP_TYPE_NUMBER:
1219 if (datatype == DATA_TYPE_STRING) {
1220 (void) nvpair_value_string(elem, &value);
1221 if (strcmp(value, "none") == 0) {
1222 isnone = B_TRUE;
1223 } else if (strcmp(value, "auto") == 0) {
1224 isauto = B_TRUE;
1225 } else if (zfs_nicestrtonum(hdl, value, ivalp) != 0) {
1226 goto error;
1227 }
1228 } else if (datatype == DATA_TYPE_UINT64) {
1229 (void) nvpair_value_uint64(elem, ivalp);
1230 } else {
1231 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1232 "'%s' must be a number"), nvpair_name(elem));
1233 goto error;
1234 }
1235
1236 /*
1237 * Quota special: force 'none' and don't allow 0.
1238 */
1239 if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
1240 (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
1241 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1242 "use 'none' to disable quota/refquota"));
1243 goto error;
1244 }
1245
1246 /*
1247 * Special handling for "*_limit=none". In this case it's not
1248 * 0 but UINT64_MAX.
1249 */
1250 if ((type & ZFS_TYPE_DATASET) && isnone &&
1251 (prop == ZFS_PROP_FILESYSTEM_LIMIT ||
1252 prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
1253 *ivalp = UINT64_MAX;
1254 }
1255
1256 /*
1257 * Special handling for setting 'reservation' and
1258 * 'refreservation' to 'auto'. Use UINT64_MAX to tell the
1259 * caller to use zfs_fix_auto_resv(). 'auto' is only allowed on
1260 * volumes.
1261 */
1262 if (isauto) {
1263 switch (prop) {
1264 case ZFS_PROP_RESERVATION:
1265 case ZFS_PROP_REFRESERVATION:
1266 if ((type & ZFS_TYPE_VOLUME) == 0) {
1267 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1268 "'%s=auto' only allowed on "
1269 "volumes"), nvpair_name(elem));
1270 goto error;
1271 }
1272 *ivalp = UINT64_MAX;
1273 break;
1274 default:
1275 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1276 "'auto' is invalid value for '%s'"),
1277 nvpair_name(elem));
1278 goto error;
1279 }
1280 }
1281
1282 break;
1283
1284 case PROP_TYPE_INDEX:
1285 if (datatype != DATA_TYPE_STRING) {
1286 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1287 "'%s' must be a string"), nvpair_name(elem));
1288 goto error;
1289 }
1290
1291 (void) nvpair_value_string(elem, &value);
1292
1293 if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
1294 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1295 "'%s' must be one of '%s'"), propname,
1296 zprop_values(prop, type));
1297 goto error;
1298 }
1299 break;
1300
1301 default:
1302 abort();
1303 }
|