Andrey Shinkevich
2020-Aug-13 04:48 UTC
[Libguestfs] [PATCH v3] appliance: extract UUID from QCOW2 disk image
For the appliance of the QCOW2 format, the function get_root_uuid() fails to get the UUID of the disk image. In this case, let us read the first 256k bytes of the disk image with the 'qemu-img dd' command. Then pass the read block to the 'file' command. Suggested-by: Denis V. Lunev <den@openvz.org> Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> --- v3: 01: The code refactoring was made based on reviewers comments. The e-mail thread Message-Id: <1597246570-901723-1-git-send-email-andrey.shinkevich@virtuozzo.com> lib/appliance-kcmdline.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c index fbeb4f4..e088fc0 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) +get_root_uuid_with_file (guestfs_h *g, const char *appliance) { CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); char *ret = NULL; @@ -96,6 +96,72 @@ 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; + CLEANUP_UNLINK_FREE char *tmpfile = NULL; + + uuid = get_root_uuid_with_file (g, appliance); + if (uuid) { + return uuid; + } + + tmpfile = guestfs_int_make_temp_path (g, "root", "raw"); + if (!tmpfile) { + error (g, "get_root_uuid: failed to make temporary file"); + return NULL; + } + + ret = run_qemu_img_dd (g, appliance, tmpfile); + if (ret < 0) { + return NULL; + } + + uuid = get_root_uuid_with_file (g, tmpfile); + if (!uuid) { + error (g, "Failed to get the appliance UUID"); + } + + 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
Richard W.M. Jones
2020-Aug-13 09:03 UTC
Re: [Libguestfs] [PATCH v3] appliance: extract UUID from QCOW2 disk image
On Thu, Aug 13, 2020 at 07:48:52AM +0300, Andrey Shinkevich wrote:> For the appliance of the QCOW2 format, the function get_root_uuid() > fails to get the UUID of the disk image. > In this case, let us read the first 256k bytes of the disk image with > the 'qemu-img dd' command. Then pass the read block to the 'file' > command. > > Suggested-by: Denis V. Lunev <den@openvz.org> > Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>Thanks, I pushed this with a few minor adjustments to error handling in the get_root_uuid function. Rich.> v3: > 01: The code refactoring was made based on reviewers comments. > The e-mail thread Message-Id: > <1597246570-901723-1-git-send-email-andrey.shinkevich@virtuozzo.com> > > lib/appliance-kcmdline.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 67 insertions(+), 1 deletion(-) > > diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c > index fbeb4f4..e088fc0 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) > +get_root_uuid_with_file (guestfs_h *g, const char *appliance) > { > CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); > char *ret = NULL; > @@ -96,6 +96,72 @@ 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; > + CLEANUP_UNLINK_FREE char *tmpfile = NULL; > + > + uuid = get_root_uuid_with_file (g, appliance); > + if (uuid) { > + return uuid; > + } > + > + tmpfile = guestfs_int_make_temp_path (g, "root", "raw"); > + if (!tmpfile) { > + error (g, "get_root_uuid: failed to make temporary file"); > + return NULL; > + } > + > + ret = run_qemu_img_dd (g, appliance, tmpfile); > + if (ret < 0) { > + return NULL; > + } > + > + uuid = get_root_uuid_with_file (g, tmpfile); > + if (!uuid) { > + error (g, "Failed to get the appliance UUID"); > + } > + > + 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-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
Richard W.M. Jones
2020-Aug-13 09:18 UTC
Re: [Libguestfs] [PATCH v3] appliance: extract UUID from QCOW2 disk image
On Thu, Aug 13, 2020 at 10:03:56AM +0100, Richard W.M. Jones wrote:> On Thu, Aug 13, 2020 at 07:48:52AM +0300, Andrey Shinkevich wrote: > > For the appliance of the QCOW2 format, the function get_root_uuid() > > fails to get the UUID of the disk image. > > In this case, let us read the first 256k bytes of the disk image with > > the 'qemu-img dd' command. Then pass the read block to the 'file' > > command. > > > > Suggested-by: Denis V. Lunev <den@openvz.org> > > Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> > > Thanks, I pushed this with a few minor adjustments to error > handling in the get_root_uuid function.Or at least I thought I pushed the adjustments. I force-pushed the right commit just now. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Possibly Parallel Threads
- [PATCH v2] appliance: extract UUID from QCOW2 disk image
- Re: [PATCH v3] appliance: extract UUID from QCOW2 disk image
- [PATCH] appliance: extract UUID from QCOW2 disk image
- Re: [PATCH] appliance: extract UUID from QCOW2 disk image
- Re: [PATCH] appliance: extract UUID from QCOW2 disk image