[Libguestfs] [PATCH] appliance: extract UUID from QCOW2 disk image

Vladimir Sementsov-Ogievskiy vsementsov at virtuozzo.com
Wed Aug 12 13:12:28 UTC 2020


12.08.2020 15:52, Vladimir Sementsov-Ogievskiy wrote:
> 12.08.2020 15:39, Andrey Shinkevich wrote:
>> 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 at openvz.org>
>> Signed-off-by: Andrey Shinkevich <andrey.shinkevich at 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;
> 
> Generally, don't use uppercase for local variables, I'd rename it s/UUID/uuid/
> 
>> +  int ret;
>> +  char tmp_file[] = "/tmp/libguestfsXXXXXX";
>> +
>> +  if (!mktemp (tmp_file)) {
>> +    error (g, "get_root_uuid: mktemp failed");
>> +    return NULL;
> 
> Hmm, if failed to create temp file, we still can try call do_get_root_uuid on original appliance image.
> 

Another thought: with this patch, in case of raw appliance, we will do copying for nothing. Probably better try file command on original image first, and if failed, try with qemu-img dd.

>> +  }
>> +
>> +  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
>>
> 
> 


-- 
Best regards,
Vladimir





More information about the Libguestfs mailing list