Print this page
9286 want refreservation=auto


   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         }