summaryrefslogtreecommitdiff
path: root/tools/lvmcmdline.c
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2014-10-30 14:52:37 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2014-10-30 23:58:49 +0100
commit464f3b8abd03633ff5dd2c5fe5585d921af8931f (patch)
tree14dcb9045ae47dd94864a0b3ca255ce8eb37699e /tools/lvmcmdline.c
parent519fbe71e46c747a254bc200ea93396591e1a1a3 (diff)
downloadlvm2-464f3b8abd03633ff5dd2c5fe5585d921af8931f.tar.gz
lvmcmdline: support size_mb_arg_with_percent
New size_mb_arg_with_percent is able to read size_mb_arg but also it's able to read % values. Percent parsing is share with int_arg_with_sign_and_percent.
Diffstat (limited to 'tools/lvmcmdline.c')
-rw-r--r--tools/lvmcmdline.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 33c0045b0..1d3e993ad 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -384,8 +384,32 @@ static int _get_int_arg(struct arg_values *av, char **ptr)
return 1;
}
+static int _get_percent_arg(struct arg_values *av, const char *ptr)
+{
+ if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
+ av->percent = PERCENT_VG;
+ else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
+ av->percent = PERCENT_LV;
+ else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
+ !strcasecmp(ptr, "PVS"))
+ av->percent = PERCENT_PVS;
+ else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
+ !strcasecmp(ptr, "FREE"))
+ av->percent = PERCENT_FREE;
+ else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") ||
+ !strcasecmp(ptr, "ORIGIN"))
+ av->percent = PERCENT_ORIGIN;
+ else {
+ log_error("Specified %%%s is unknown.", ptr);
+ return 0;
+ }
+
+ return 1;
+}
+
/* Size stored in sectors */
-static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av, int factor)
+static int _size_arg(struct cmd_context *cmd __attribute__((unused)),
+ struct arg_values *av, int factor, int percent)
{
char *ptr;
int i;
@@ -429,7 +453,14 @@ static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg
if (ptr == val)
return 0;
- if (*ptr) {
+ if (percent && *ptr == '%') {
+ if (!_get_percent_arg(av, ++ptr))
+ return_0;
+ if ((uint64_t) v >= UINT32_MAX) {
+ log_error("Percentage is too big (>=%d%%).", UINT32_MAX);
+ return 0;
+ }
+ } else if (*ptr) {
for (i = strlen(suffixes) - 1; i >= 0; i--)
if (suffixes[i] == tolower((int) *ptr))
break;
@@ -474,12 +505,17 @@ static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg
int size_kb_arg(struct cmd_context *cmd, struct arg_values *av)
{
- return _size_arg(cmd, av, 2);
+ return _size_arg(cmd, av, 2, 0);
}
int size_mb_arg(struct cmd_context *cmd, struct arg_values *av)
{
- return _size_arg(cmd, av, 2048);
+ return _size_arg(cmd, av, 2048, 0);
+}
+
+int size_mb_arg_with_percent(struct cmd_context *cmd, struct arg_values *av)
+{
+ return _size_arg(cmd, av, 2048, 1);
}
int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
@@ -516,21 +552,13 @@ int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute__((unused)
if (*ptr++ != '%')
return 0;
- if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
- av->percent = PERCENT_VG;
- else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
- av->percent = PERCENT_LV;
- else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
- !strcasecmp(ptr, "PVS"))
- av->percent = PERCENT_PVS;
- else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
- !strcasecmp(ptr, "FREE"))
- av->percent = PERCENT_FREE;
- else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") ||
- !strcasecmp(ptr, "ORIGIN"))
- av->percent = PERCENT_ORIGIN;
- else
+ if (!_get_percent_arg(av, ptr))
+ return_0;
+
+ if (av->ui64_value >= UINT32_MAX) {
+ log_error("Percentage is too big (>=%d%%).", UINT32_MAX);
return 0;
+ }
return 1;
}
@@ -613,7 +641,7 @@ int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_va
return 1;
}
- if (!_size_arg(cmd, av, 1))
+ if (!_size_arg(cmd, av, 1, 0))
return 0;
if (av->sign == SIGN_MINUS)