X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fparted.c;h=b1750a512db7c840e1f568b3cffc6db552eeb6c1;hp=2b0df4419cfc03855f99b4b6b5dde17d0a41470f;hb=cb9350019cc6382a35c98f522c9c4d221c92b605;hpb=3833ddc6566f92783dc5a8894383c304e3d2c0b4 diff --git a/daemon/parted.c b/daemon/parted.c index 2b0df44..b1750a5 100644 --- a/daemon/parted.c +++ b/daemon/parted.c @@ -46,7 +46,7 @@ recover_blkrrpart (const char *device, const char *err) "Error informing the kernel about modifications to partition")) return -1; - r = command (NULL, NULL, "/sbin/blockdev", "--rereadpt", device, NULL); + r = command (NULL, NULL, "blockdev", "--rereadpt", device, NULL); if (r == -1) return -1; @@ -55,18 +55,18 @@ recover_blkrrpart (const char *device, const char *err) return 0; } -#define RUN_PARTED(device,...) \ +#define RUN_PARTED(error,device,...) \ do { \ int r; \ char *err; \ \ r = commandf (NULL, &err, COMMAND_FLAG_FOLD_STDOUT_ON_STDERR, \ - "/sbin/parted", "-s", "--", (device), __VA_ARGS__); \ + "parted", "-s", "--", (device), __VA_ARGS__); \ if (r == -1) { \ if (recover_blkrrpart ((device), err) == -1) { \ reply_with_error ("%s: parted: %s: %s", __func__, (device), err); \ free (err); \ - return -1; \ + error; \ } \ } \ \ @@ -103,11 +103,11 @@ do_part_init (const char *device, const char *parttype) { parttype = check_parttype (parttype); if (!parttype) { - reply_with_error ("part-init: unknown partition type: common choices are \"gpt\" and \"msdos\""); + reply_with_error ("unknown partition type: common choices are \"gpt\" and \"msdos\""); return -1; } - RUN_PARTED (device, "mklabel", parttype, NULL); + RUN_PARTED (return -1, device, "mklabel", parttype, NULL); udev_settle (); @@ -133,12 +133,12 @@ do_part_add (const char *device, const char *prlogex, else if (STREQ (prlogex, "e")) prlogex = "extended"; else { - reply_with_error ("part-add: unknown partition type: %s: this should be \"primary\", \"logical\" or \"extended\"", prlogex); + reply_with_error ("unknown partition type: %s: this should be \"primary\", \"logical\" or \"extended\"", prlogex); return -1; } if (startsect < 0) { - reply_with_error ("part-add: startsect cannot be negative"); + reply_with_error ("startsect cannot be negative"); return -1; } /* but endsect can be negative */ @@ -151,7 +151,7 @@ do_part_add (const char *device, const char *prlogex, * name_ to prlogex, eg. "primary". I would essentially describe * this as a bug in the parted mkpart command. */ - RUN_PARTED (device, "mkpart", prlogex, startstr, endstr, NULL); + RUN_PARTED (return -1, device, "mkpart", prlogex, startstr, endstr, NULL); udev_settle (); @@ -166,7 +166,7 @@ do_part_disk (const char *device, const char *parttype) parttype = check_parttype (parttype); if (!parttype) { - reply_with_error ("part-disk: unknown partition type: common choices are \"gpt\" and \"msdos\""); + reply_with_error ("unknown partition type: common choices are \"gpt\" and \"msdos\""); return -1; } @@ -183,7 +183,8 @@ do_part_disk (const char *device, const char *parttype) endstr = "-1s"; } - RUN_PARTED (device, + RUN_PARTED (return -1, + device, "mklabel", parttype, /* See comment about about the parted mkpart command. */ "mkpart", STREQ (parttype, "gpt") ? "p1" : "primary", @@ -201,7 +202,8 @@ do_part_set_bootable (const char *device, int partnum, int bootable) snprintf (partstr, sizeof partstr, "%d", partnum); - RUN_PARTED (device, "set", partstr, "boot", bootable ? "on" : "off", NULL); + RUN_PARTED (return -1, + device, "set", partstr, "boot", bootable ? "on" : "off", NULL); udev_settle (); @@ -215,13 +217,43 @@ do_part_set_name (const char *device, int partnum, const char *name) snprintf (partstr, sizeof partstr, "%d", partnum); - RUN_PARTED (device, "name", partstr, name, NULL); + RUN_PARTED (return -1, device, "name", partstr, name, NULL); udev_settle (); return 0; } +/* Return the nth field from a string of ':'/';'-delimited strings. + * Useful for parsing the return value from print_partition_table + * function below. + */ +static char * +get_table_field (const char *line, int n) +{ + const char *p = line; + + while (*p && n > 0) { + p += strcspn (p, ":;") + 1; + n--; + } + + if (n > 0) { + reply_with_error ("not enough fields in output of parted print command: %s", + line); + return NULL; + } + + size_t len = strcspn (p, ":;"); + char *q = strndup (p, len); + if (q == NULL) { + reply_with_perror ("strndup"); + return NULL; + } + + return q; +} + static char ** print_partition_table (const char *device) { @@ -229,7 +261,7 @@ print_partition_table (const char *device) int r; char **lines; - r = command (&out, &err, "/sbin/parted", "-m", "--", device, + r = command (&out, &err, "parted", "-m", "--", device, "unit", "b", "print", NULL); if (r == -1) { @@ -249,14 +281,14 @@ print_partition_table (const char *device) return NULL; if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) { - reply_with_error ("parted print: unknown signature, expected \"BYT;\" as first line of the output: %s", + reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s", lines[0] ? lines[0] : "(signature was null)"); free_strings (lines); return NULL; } if (lines[1] == NULL) { - reply_with_error ("parted print: parted didn't return a line describing the device"); + reply_with_error ("parted didn't return a line describing the device"); free_strings (lines); return NULL; } @@ -267,31 +299,15 @@ print_partition_table (const char *device) char * do_part_get_parttype (const char *device) { - char **lines; - char *r; - - lines = print_partition_table (device); + char **lines = print_partition_table (device); if (!lines) return NULL; /* lines[1] is something like: * "/dev/sda:1953525168s:scsi:512:512:msdos:ATA Hitachi HDT72101;" */ - if (strtok (lines[1], ":") == NULL /* device */ - || strtok (NULL, ":") == NULL /* size */ - || strtok (NULL, ":") == NULL /* transport */ - || strtok (NULL, ":") == NULL /* sector size */ - || strtok (NULL, ":") == NULL /* physical sector size */ - || (r = strtok (NULL, ":")) == NULL /* return value */ - ) { - reply_with_error ("part_get_parttype: too few fields in output from parted print command: %s", lines[1]); - free_strings (lines); - return NULL; - } - - r = strdup (r); - if (!r) { - reply_with_perror ("strdup"); + char *r = get_table_field (lines[1], 5); + if (r == NULL) { free_strings (lines); return NULL; } @@ -339,7 +355,7 @@ do_part_list (const char *device) &r->guestfs_int_partition_list_val[i].part_start, &r->guestfs_int_partition_list_val[i].part_end, &r->guestfs_int_partition_list_val[i].part_size) != 4) { - reply_with_error ("part_list: could not parse row from output of parted print command: %s", lines[row]); + reply_with_error ("could not parse row from output of parted print command: %s", lines[row]); goto error3; } }