|
| 1 | +From 278d0d3226f4bdb7c6586986ca46d0a25c976fe4 Mon Sep 17 00:00:00 2001 |
| 2 | +From: "Richard W.M. Jones" < [email protected]> |
| 3 | +Date: Wed, 31 Mar 2021 13:40:11 +0100 |
| 4 | +Subject: [PATCH] lib/appliance-kcmdline.c: Read UUID directly from appliance. |
| 5 | + |
| 6 | +Instead of using the external file utility, read the UUID directly |
| 7 | +from the extfs filesystem. file 5.40 broke parsing of UUIDs |
| 8 | +(https://bugs.astron.com/view.php?id=253). |
| 9 | + |
| 10 | +Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1945122 |
| 11 | +--- |
| 12 | + lib/appliance-kcmdline.c | 75 +++++++++++++++++++++++++--------------- |
| 13 | + 1 file changed, 48 insertions(+), 27 deletions(-) |
| 14 | + |
| 15 | +diff --git a/lib/appliance-kcmdline.c b/lib/appliance-kcmdline.c |
| 16 | +index 6d0deef867..8b78655eb2 100644 |
| 17 | +--- a/lib/appliance-kcmdline.c |
| 18 | ++++ b/lib/appliance-kcmdline.c |
| 19 | +@@ -27,6 +27,9 @@ |
| 20 | + #include <stdbool.h> |
| 21 | + #include <string.h> |
| 22 | + #include <unistd.h> |
| 23 | ++#include <fcntl.h> |
| 24 | ++#include <libintl.h> |
| 25 | ++#include <sys/types.h> |
| 26 | + |
| 27 | + #include "c-ctype.h" |
| 28 | + #include "ignore-value.h" |
| 29 | +@@ -56,49 +59,67 @@ |
| 30 | + #define EARLYPRINTK "earlyprintk=pl011,0x9000000" |
| 31 | + #endif |
| 32 | + |
| 33 | +-COMPILE_REGEXP (re_uuid, "UUID=([-0-9a-f]+)", 0) |
| 34 | +- |
| 35 | +-static void |
| 36 | +-read_uuid (guestfs_h *g, void *retv, const char *line, size_t len) |
| 37 | +-{ |
| 38 | +- char **ret = retv; |
| 39 | +- |
| 40 | +- *ret = match1 (g, line, re_uuid); |
| 41 | +-} |
| 42 | +- |
| 43 | + /** |
| 44 | + * Given a disk image containing an extX filesystem, return the UUID. |
| 45 | +- * The L<file(1)> command does the hard work. |
| 46 | + */ |
| 47 | + static char * |
| 48 | + get_root_uuid_with_file (guestfs_h *g, const char *appliance) |
| 49 | + { |
| 50 | +- CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g); |
| 51 | +- char *ret = NULL; |
| 52 | +- int r; |
| 53 | ++ unsigned char magic[2], uuid[16]; |
| 54 | ++ char *ret; |
| 55 | ++ int fd; |
| 56 | + |
| 57 | +- guestfs_int_cmd_add_arg (cmd, "file"); |
| 58 | +- guestfs_int_cmd_add_arg (cmd, "--"); |
| 59 | +- guestfs_int_cmd_add_arg (cmd, appliance); |
| 60 | +- guestfs_int_cmd_set_stdout_callback (cmd, read_uuid, &ret, 0); |
| 61 | +- r = guestfs_int_cmd_run (cmd); |
| 62 | +- if (r == -1) { |
| 63 | +- if (ret) free (ret); |
| 64 | ++ fd = open (appliance, O_RDONLY|O_CLOEXEC); |
| 65 | ++ if (fd == -1) { |
| 66 | ++ perrorf (g, _("open: %s"), appliance); |
| 67 | + return NULL; |
| 68 | + } |
| 69 | +- if (!WIFEXITED (r) || WEXITSTATUS (r) != 0) { |
| 70 | +- guestfs_int_external_command_failed (g, r, "file", NULL); |
| 71 | +- if (ret) free (ret); |
| 72 | ++ if (lseek (fd, 0x438, SEEK_SET) != 0x438) { |
| 73 | ++ magic_error: |
| 74 | ++ error (g, _("%s: cannot read extfs magic in superblock"), appliance); |
| 75 | ++ close (fd); |
| 76 | ++ return NULL; |
| 77 | ++ } |
| 78 | ++ if (read (fd, magic, 2) != 2) |
| 79 | ++ goto magic_error; |
| 80 | ++ if (magic[0] != 0x53 || magic[1] != 0xEF) { |
| 81 | ++ error (g, _("%s: appliance is not an extfs filesystem"), appliance); |
| 82 | ++ close (fd); |
| 83 | + return NULL; |
| 84 | + } |
| 85 | ++ if (lseek (fd, 0x468, SEEK_SET) != 0x468) { |
| 86 | ++ super_error: |
| 87 | ++ error (g, _("%s: cannot read UUID in superblock"), appliance); |
| 88 | ++ close (fd); |
| 89 | ++ return NULL; |
| 90 | ++ } |
| 91 | ++ if (read (fd, uuid, 16) != 16) |
| 92 | ++ goto super_error; |
| 93 | ++ close (fd); |
| 94 | + |
| 95 | ++ /* The UUID is a binary blob, but we must return it as a printable |
| 96 | ++ * string. The caller frees this. |
| 97 | ++ */ |
| 98 | ++ ret = safe_asprintf (g, |
| 99 | ++ "%02x%02x%02x%02x" "-" |
| 100 | ++ "%02x%02x" "-" |
| 101 | ++ "%02x%02x" "-" |
| 102 | ++ "%02x%02x" "-" |
| 103 | ++ "%02x%02x%02x%02x%02x%02x", |
| 104 | ++ uuid[0], uuid[1], uuid[2], uuid[3], |
| 105 | ++ uuid[4], uuid[5], |
| 106 | ++ uuid[6], uuid[7], |
| 107 | ++ uuid[8], uuid[9], |
| 108 | ++ uuid[10], uuid[11], uuid[12], uuid[13], |
| 109 | ++ uuid[14], uuid[15]); |
| 110 | + return ret; |
| 111 | + } |
| 112 | + |
| 113 | + /** |
| 114 | +- * Read the first 256k bytes of the in_file with L<qemu-img(1)> command |
| 115 | +- * and write them into the out_file. That may be useful to get UUID of |
| 116 | +- * the QCOW2 disk image with further L<file(1)> command. |
| 117 | ++ * Read the first 256k bytes of the in_file with L<qemu-img(1)> |
| 118 | ++ * command and write them into the out_file. That may be useful to get |
| 119 | ++ * UUID of the QCOW2 disk image with C<get_root_uuid_with_file>. |
| 120 | ++ * |
| 121 | + * The function returns zero if successful, otherwise -1. |
| 122 | + */ |
| 123 | + static int |
0 commit comments