libguestfs/0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch

128 lines
3.9 KiB
Diff

From 278d0d3226f4bdb7c6586986ca46d0a25c976fe4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 31 Mar 2021 13:40:11 +0100
Subject: [PATCH 5/5] lib/appliance-kcmdline.c: Read UUID directly from
appliance.
Instead of using the external file utility, read the UUID directly
from the extfs filesystem. file 5.40 broke parsing of UUIDs
(https://bugs.astron.com/view.php?id=253).
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1945122
---
lib/appliance-kcmdline.c | 75 +++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 27 deletions(-)
diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c
index 6d0deef86..8b78655eb 100644
--- a/lib/appliance-kcmdline.c
+++ b/lib/appliance-kcmdline.c
@@ -27,6 +27,9 @@
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <libintl.h>
+#include <sys/types.h>
#include "c-ctype.h"
#include "ignore-value.h"
@@ -56,49 +59,67 @@
#define EARLYPRINTK "earlyprintk=pl011,0x9000000"
#endif
-COMPILE_REGEXP (re_uuid, "UUID=([-0-9a-f]+)", 0)
-
-static void
-read_uuid (guestfs_h *g, void *retv, const char *line, size_t len)
-{
- char **ret = retv;
-
- *ret = match1 (g, line, re_uuid);
-}
-
/**
* Given a disk image containing an extX filesystem, return the UUID.
- * The L<file(1)> command does the hard work.
*/
static char *
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;
- int r;
+ unsigned char magic[2], uuid[16];
+ char *ret;
+ int fd;
- guestfs_int_cmd_add_arg (cmd, "file");
- guestfs_int_cmd_add_arg (cmd, "--");
- guestfs_int_cmd_add_arg (cmd, appliance);
- guestfs_int_cmd_set_stdout_callback (cmd, read_uuid, &ret, 0);
- r = guestfs_int_cmd_run (cmd);
- if (r == -1) {
- if (ret) free (ret);
+ fd = open (appliance, O_RDONLY|O_CLOEXEC);
+ if (fd == -1) {
+ perrorf (g, _("open: %s"), appliance);
return NULL;
}
- if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) {
- guestfs_int_external_command_failed (g, r, "file", NULL);
- if (ret) free (ret);
+ if (lseek (fd, 0x438, SEEK_SET) != 0x438) {
+ magic_error:
+ error (g, _("%s: cannot read extfs magic in superblock"), appliance);
+ close (fd);
return NULL;
}
+ if (read (fd, magic, 2) != 2)
+ goto magic_error;
+ if (magic[0] != 0x53 || magic[1] != 0xEF) {
+ error (g, _("%s: appliance is not an extfs filesystem"), appliance);
+ close (fd);
+ return NULL;
+ }
+ if (lseek (fd, 0x468, SEEK_SET) != 0x468) {
+ super_error:
+ error (g, _("%s: cannot read UUID in superblock"), appliance);
+ close (fd);
+ return NULL;
+ }
+ if (read (fd, uuid, 16) != 16)
+ goto super_error;
+ close (fd);
+ /* The UUID is a binary blob, but we must return it as a printable
+ * string. The caller frees this.
+ */
+ ret = safe_asprintf (g,
+ "%02x%02x%02x%02x" "-"
+ "%02x%02x" "-"
+ "%02x%02x" "-"
+ "%02x%02x" "-"
+ "%02x%02x%02x%02x%02x%02x",
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5],
+ uuid[6], uuid[7],
+ uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13],
+ uuid[14], uuid[15]);
return ret;
}
/**
- * 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.
+ * 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 C<get_root_uuid_with_file>.
+ *
* The function returns zero if successful, otherwise -1.
*/
static int
--
2.29.0.rc2