summaryrefslogtreecommitdiffstats
path: root/libfdisk/src/script.c
diff options
context:
space:
mode:
authorKarel Zak2015-04-21 14:32:31 +0200
committerKarel Zak2015-04-22 12:21:19 +0200
commit6f163929379ab2eca661e425ddaf5d8238c89379 (patch)
tree2ab7e4217607c538e0d91881e0167278c0b11f62 /libfdisk/src/script.c
parentlibfdisk: don't resize in label drivers (diff)
downloadkernel-qcow2-util-linux-6f163929379ab2eca661e425ddaf5d8238c89379.tar.gz
kernel-qcow2-util-linux-6f163929379ab2eca661e425ddaf5d8238c89379.tar.xz
kernel-qcow2-util-linux-6f163929379ab2eca661e425ddaf5d8238c89379.zip
libfdisk: fix script parser to support resize operations
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libfdisk/src/script.c')
-rw-r--r--libfdisk/src/script.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c
index a7e0d21d8..469c1d4c1 100644
--- a/libfdisk/src/script.c
+++ b/libfdisk/src/script.c
@@ -815,6 +815,9 @@ static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp,
return type ? fdisk_label_parse_parttype(lb, type) : NULL;
}
+#define TK_PLUS 1
+#define TK_MINUS -1
+
/* simple format:
* <start>, <size>, <type>, <bootable>, ...
*/
@@ -840,6 +843,7 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
while (rc == 0 && p && *p) {
uint64_t num;
char *begin;
+ int sign = 0;
p = (char *) skip_blank(p);
item++;
@@ -847,25 +851,38 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
DBG(SCRIPT, ul_debugobj(dp, " parsing item %d ('%s')", item, p));
begin = p;
+ if (item != ITEM_BOOTABLE) {
+ sign = *p == '-' ? TK_MINUS : *p == '+' ? TK_PLUS : 0;
+ if (sign)
+ p++;
+ }
+
switch (item) {
case ITEM_START:
- if (*p == ',' || *p == ';')
+ if (*p == ',' || *p == ';' || (sign && *p == '\0'))
fdisk_partition_start_follow_default(pa, 1);
else {
int pow = 0;
+
rc = next_number(&p, &num, &pow);
if (!rc) {
if (pow) /* specified as <num><suffix> */
num /= dp->cxt->sector_size;
fdisk_partition_set_start(pa, num);
+ pa->movestart = sign == TK_MINUS ? FDISK_MOVE_DOWN :
+ sign == TK_PLUS ? FDISK_MOVE_UP :
+ FDISK_MOVE_NONE;
}
fdisk_partition_start_follow_default(pa, 0);
}
break;
case ITEM_SIZE:
- if (*p == ',' || *p == ';' || *p == '+')
+ if (*p == ',' || *p == ';' || (sign && *p == '\0')) {
fdisk_partition_end_follow_default(pa, 1);
- else {
+ if (sign == TK_PLUS)
+ /* alone '+' means use all possible space, elone '-' means nothing */
+ pa->resize = FDISK_RESIZE_ENLARGE;
+ } else {
int pow = 0;
rc = next_number(&p, &num, &pow);
if (!rc) {
@@ -874,12 +891,15 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
else /* specified as number of sectors */
fdisk_partition_size_explicit(pa, 1);
fdisk_partition_set_size(pa, num);
+ pa->resize = sign == TK_MINUS ? FDISK_RESIZE_REDUCE :
+ sign == TK_PLUS ? FDISK_RESIZE_ENLARGE :
+ FDISK_RESIZE_NONE;
}
fdisk_partition_end_follow_default(pa, 0);
}
break;
case ITEM_TYPE:
- if (*p == ',' || *p == ';')
+ if (*p == ',' || *p == ';' || (sign && *p == '\0'))
break; /* use default type */
rc = next_string(&p, &str);
@@ -908,6 +928,8 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
pa->boot = 1;
else if (tk && *tk == '-' && *(tk + 1) == '\0')
pa->boot = 0;
+ else if (tk && *tk == '+' && *(tk + 1) == '\0')
+ pa->boot = 1;
else
rc = -EINVAL;
}