Andrey Shinkevich
2020-Aug-12 12:39 UTC
[Libguestfs] [PATCH] appliance: extract UUID from QCOW2 disk image
For the appliance of the QCOW2 format, get the UUID of the disk by reading the first 256k bytes with 'qemu-img dd' command. Then pass the read block to the 'file' command. In case of failure, run the 'file' command again directly. Suggested-by: Denis V. Lunev <den@openvz.org> Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> --- lib/appliance-kcmdline.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c index 211cc46..3bb8bcd 100644 --- a/lib/appliance-kcmdline.c +++ b/lib/appliance-kcmdline.c @@ -71,7 +71,7 @@ read_uuid (guestfs_h *g, void *retv, const char *line, size_t len) * The L<file(1)> command does the hard work. */ static char * -get_root_uuid (guestfs_h *g, const char *appliance) +do_get_root_uuid (guestfs_h *g, const char *appliance) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); char *ret = NULL; @@ -96,6 +96,74 @@ get_root_uuid (guestfs_h *g, const char *appliance) } /** + * Read the first 256k bytes of the in_file with L<qemu-img(1)> command + * and write them into the out_file. That may be useful to get UUID of + * the QCOW2 disk image with further L<file(1)> command. + * The function returns zero if successful, otherwise -1. + */ +static int +run_qemu_img_dd (guestfs_h *g, const char *in_file, char *out_file) +{ + CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); + int r; + + guestfs_int_cmd_add_arg (cmd, "qemu-img"); + guestfs_int_cmd_add_arg (cmd, "dd"); + guestfs_int_cmd_add_arg_format (cmd, "if=%s", in_file); + guestfs_int_cmd_add_arg_format (cmd, "of=%s", out_file); + guestfs_int_cmd_add_arg (cmd, "bs=256k"); + guestfs_int_cmd_add_arg (cmd, "count=1"); + + r = guestfs_int_cmd_run (cmd); + if (r == -1) { + error (g, "Failed to run qemu-img"); + return -1; + } + if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { + guestfs_int_external_command_failed (g, r, "qemu-img dd", NULL); + return -1; + } + + return 0; +} + +/** + * Get the UUID from the appliance disk image. + */ +static char * +get_root_uuid (guestfs_h *g, const char *appliance) +{ + char *UUID = NULL; + int ret; + char tmp_file[] = "/tmp/libguestfsXXXXXX"; + + if (!mktemp (tmp_file)) { + error (g, "get_root_uuid: mktemp failed"); + return NULL; + } + + ret = run_qemu_img_dd (g, appliance, tmp_file); + if (ret == 0) { + UUID = do_get_root_uuid (g, tmp_file); + if (UUID) { + goto out; + } + } + + /* We get here in case of failure to extract a UUID from the temporary file. + * Let us try to get the UUID from the appliance directly. + */ + UUID = do_get_root_uuid (g, appliance); + if (!UUID) { + error (g, "Failed to get the appliance UUID"); + } + +out: + unlink (tmp_file); + return UUID; +} + +/** * Construct the Linux command line passed to the appliance. This is * used by the C<direct> and C<libvirt> backends, and is simply * located in this file because it's a convenient place for this -- 1.8.3.1
Reasonably Related Threads
- Re: [PATCH] appliance: extract UUID from QCOW2 disk image
- Re: [PATCH] appliance: extract UUID from QCOW2 disk image
- [PATCH v2] appliance: extract UUID from QCOW2 disk image
- Re: [PATCH v3] appliance: extract UUID from QCOW2 disk image
- [PATCH v3] appliance: extract UUID from QCOW2 disk image