New upstream version 1.45.4.

This commit is contained in:
Richard W.M. Jones 2021-04-03 12:36:41 +01:00
parent a6a11a65c9
commit 6ab119c488
7 changed files with 8 additions and 1331 deletions

View File

@ -1,35 +0,0 @@
From 49b8b69cb8e10e5476bbe86a708ee1babfe330e8 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 30 Mar 2021 12:56:06 +0100
Subject: [PATCH 1/5] daemon/xfs.c: Fix error message.
Fixes: commit 87206e4e9e3b0ca813a4ff7b5fac0eccc07a484a
---
daemon/xfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemon/xfs.c b/daemon/xfs.c
index 3707f56d9..aa056ddff 100644
--- a/daemon/xfs.c
+++ b/daemon/xfs.c
@@ -62,7 +62,7 @@ parse_uint32 (uint32_t *ret, const char *str)
uint32_t r;
if (sscanf (str, "%" SCNu32, &r) != 1) {
- reply_with_error ("cannot parse numeric field from isoinfo: %s", str);
+ reply_with_error ("cannot parse numeric field from xfs_info: %s", str);
return -1;
}
@@ -76,7 +76,7 @@ parse_uint64 (uint64_t *ret, const char *str)
uint64_t r;
if (sscanf (str, "%" SCNu64, &r) != 1) {
- reply_with_error ("cannot parse numeric field from isoinfo: %s", str);
+ reply_with_error ("cannot parse numeric field from xfs_info: %s", str);
return -1;
}
--
2.29.0.rc2

View File

@ -1,67 +0,0 @@
From 2216ab2e328457ef172d6bfa534272edf2f81a3a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 30 Mar 2021 12:41:58 +0100
Subject: [PATCH 2/5] tests: Prefer xorriso over genisoimage to generate
test.iso
This Debian page explains the upstream situation:
https://wiki.debian.org/genisoimage
On Fedora, xorriso provides a compatibility program called "mkisofs".
However this is not present in Debian. Hence the choice to look for
the program called "xorrisofs".
---
docs/guestfs-building.pod | 4 ++--
m4/guestfs-progs.m4 | 6 +++---
test-data/Makefile.am | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
index 8fb2361b2..4d0e943cb 100644
--- a/docs/guestfs-building.pod
+++ b/docs/guestfs-building.pod
@@ -152,9 +152,9 @@ I<Required>.
I<Required>.
-=item genisoimage
+=item xorriso, genisoimage or mkisofs
-I<Required>.
+One of these is I<Required>.
=item libxml2
diff --git a/m4/guestfs-progs.m4 b/m4/guestfs-progs.m4
index 4819df627..cd8662e86 100644
--- a/m4/guestfs-progs.m4
+++ b/m4/guestfs-progs.m4
@@ -49,10 +49,10 @@ AC_CHECK_PROG([GPERF],[gperf],[gperf],[no])
test "x$GPERF" = "xno" &&
AC_MSG_ERROR([gperf must be installed])
-dnl Check for genisoimage/mkisofs
-AC_PATH_PROGS([GENISOIMAGE],[genisoimage mkisofs],[no],
+dnl Check for xorriso/genisoimage/mkisofs.
+AC_PATH_PROGS([MKISOFS],[xorrisofs genisoimage mkisofs],[no],
[$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR/sbin])
-test "x$GENISOIMAGE" = "xno" && AC_MSG_ERROR([genisoimage must be installed])
+test "x$MKISOFS" = "xno" && AC_MSG_ERROR([xorriso or genisoimage or mkisofs must be installed])
dnl Check for optional xmllint.
AC_CHECK_PROG([XMLLINT],[xmllint],[xmllint],[no])
diff --git a/test-data/Makefile.am b/test-data/Makefile.am
index 8a832c94c..b603311a1 100644
--- a/test-data/Makefile.am
+++ b/test-data/Makefile.am
@@ -98,6 +98,6 @@ test.iso: $(images_files)
cp $(image_files) d/
mkdir -p d/directory
cd d && ln -sf /10klines abssymlink
- cd d && $(GENISOIMAGE) -J -r -o ../$@-t .
+ cd d && $(MKISOFS) -J -r -o ../$@-t .
rm -rf d
mv $@-t $@
--
2.29.0.rc2

View File

@ -1,684 +0,0 @@
From efb8a766cac4ba8e413594946136bf91e176bb8c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 30 Mar 2021 13:54:22 +0100
Subject: [PATCH 3/5] daemon: Allow xorriso as an alternative to isoinfo.
Currently the guestfs_isoinfo and guestfs_isoinfo_device APIs run
isoinfo inside the appliance to extract the information.
isoinfo is part of genisoimage which is somewhat dead upstream.
xorriso is supposedly the new thing. (For a summary of the situation
see: https://wiki.debian.org/genisoimage).
This commit rewrites the parsing from C to OCaml to make it easier to
deal with, and allows you to use either isoinfo or xorriso.
Mostly the same fields are available from either tool, but xorriso is
a bit more awkward to parse.
---
.gitignore | 1 +
appliance/packagelist.in | 2 +
daemon/Makefile.am | 4 +-
daemon/isoinfo.c | 279 --------------------------------------
daemon/isoinfo.ml | 248 +++++++++++++++++++++++++++++++++
docs/C_SOURCE_FILES | 1 -
generator/actions_core.ml | 2 +
po/POTFILES | 1 -
8 files changed, 256 insertions(+), 282 deletions(-)
delete mode 100644 daemon/isoinfo.c
create mode 100644 daemon/isoinfo.ml
diff --git a/.gitignore b/.gitignore
index f9b95a6c5..de4abff58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -92,6 +92,7 @@ Makefile.in
/daemon/guestfsd.exe
/daemon/inspect.mli
/daemon/is.mli
+/daemon/isoinfo.mli
/daemon/ldm.mli
/daemon/link.mli
/daemon/listfs.mli
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 2f75a1c17..f4ad50b79 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -45,6 +45,7 @@ ifelse(REDHAT,1,
syslinux-extlinux
systemd dnl for /sbin/reboot and udevd
vim-minimal
+ xorriso dnl alternative for genisoimage
xz
zfs-fuse
)
@@ -84,6 +85,7 @@ dnl iproute has been renamed to iproute2
systemd dnl alternative for /sbin/reboot
ufsutils
vim-tiny
+ xorriso dnl alternative for genisoimage
xz-utils
zfs-fuse
uuid-runtime
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 216029b7c..6f13bd43c 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -46,6 +46,7 @@ generator_built = \
findfs.mli \
inspect.mli \
is.mli \
+ isoinfo.mli \
ldm.mli \
link.mli \
listfs.mli \
@@ -142,7 +143,6 @@ guestfsd_SOURCES = \
inotify.c \
internal.c \
is.c \
- isoinfo.c \
journal.c \
labels.c \
ldm.c \
@@ -291,6 +291,7 @@ SOURCES_MLI = \
inspect_types.mli \
inspect_utils.mli \
is.mli \
+ isoinfo.mli \
ldm.mli \
link.mli \
listfs.mli \
@@ -324,6 +325,7 @@ SOURCES_ML = \
devsparts.ml \
file.ml \
filearch.ml \
+ isoinfo.ml \
is.ml \
ldm.ml \
link.ml \
diff --git a/daemon/isoinfo.c b/daemon/isoinfo.c
deleted file mode 100644
index e616df82f..000000000
--- a/daemon/isoinfo.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/* libguestfs - the guestfsd daemon
- * Copyright (C) 2012 Red Hat Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "guestfs_protocol.h"
-#include "daemon.h"
-#include "actions.h"
-
-static int
-parse_uint32 (uint32_t *ret, const char *str)
-{
- uint32_t r;
-
- if (sscanf (str, "%" SCNu32, &r) != 1) {
- reply_with_error ("cannot parse numeric field from isoinfo: %s", str);
- return -1;
- }
-
- *ret = r;
- return 0;
-}
-
-/* This is always in a fixed format:
- * "2012 03 16 11:05:46.00"
- * or if the field is not present, then:
- * "0000 00 00 00:00:00.00"
- */
-static int
-parse_time_t (int64_t *ret, const char *str)
-{
- struct tm tm;
- time_t r;
-
- if (STREQ (str, "0000 00 00 00:00:00.00") ||
- STREQ (str, " : : . ")) {
- *ret = -1;
- return 0;
- }
-
- if (sscanf (str, "%04d %02d %02d %02d:%02d:%02d",
- &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
- &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
- reply_with_error ("cannot parse date from isoinfo: %s", str);
- return -1;
- }
-
- /* Adjust fields. */
- tm.tm_year -= 1900;
- tm.tm_mon--;
- tm.tm_isdst = -1;
-
- /* Convert to time_t. */
- r = timegm (&tm);
- if (r == -1) {
- reply_with_error ("invalid date or time: %s", str);
- return -1;
- }
-
- *ret = r;
- return 0;
-}
-
-static guestfs_int_isoinfo *
-parse_isoinfo (char **lines)
-{
- guestfs_int_isoinfo *ret;
- size_t i;
-
- ret = calloc (1, sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("calloc");
- return NULL;
- }
-
- /* Default each int field in the struct to -1. */
- ret->iso_volume_space_size = (uint32_t) -1;
- ret->iso_volume_set_size = (uint32_t) -1;
- ret->iso_volume_sequence_number = (uint32_t) -1;
- ret->iso_logical_block_size = (uint32_t) -1;
- ret->iso_volume_creation_t = -1;
- ret->iso_volume_modification_t = -1;
- ret->iso_volume_expiration_t = -1;
- ret->iso_volume_effective_t = -1;
-
- for (i = 0; lines[i] != NULL; ++i) {
- if (STRPREFIX (lines[i], "System id: ")) {
- ret->iso_system_id = strdup (&lines[i][11]);
- if (ret->iso_system_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Volume id: ")) {
- ret->iso_volume_id = strdup (&lines[i][11]);
- if (ret->iso_volume_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Volume set id: ")) {
- ret->iso_volume_set_id = strdup (&lines[i][15]);
- if (ret->iso_volume_set_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Publisher id: ")) {
- ret->iso_publisher_id = strdup (&lines[i][14]);
- if (ret->iso_publisher_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Data preparer id: ")) {
- ret->iso_data_preparer_id = strdup (&lines[i][18]);
- if (ret->iso_data_preparer_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Application id: ")) {
- ret->iso_application_id = strdup (&lines[i][16]);
- if (ret->iso_application_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Copyright File id: ")) {
- ret->iso_copyright_file_id = strdup (&lines[i][19]);
- if (ret->iso_copyright_file_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Abstract File id: ")) {
- ret->iso_abstract_file_id = strdup (&lines[i][18]);
- if (ret->iso_abstract_file_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Bibliographic File id: ")) {
- ret->iso_bibliographic_file_id = strdup (&lines[i][23]);
- if (ret->iso_bibliographic_file_id == NULL) goto error;
- }
- else if (STRPREFIX (lines[i], "Volume size is: ")) {
- if (parse_uint32 (&ret->iso_volume_space_size, &lines[i][16]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Volume set size is: ")) {
- if (parse_uint32 (&ret->iso_volume_set_size, &lines[i][20]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Volume set sequence number is: ")) {
- if (parse_uint32 (&ret->iso_volume_sequence_number, &lines[i][31]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Logical block size is: ")) {
- if (parse_uint32 (&ret->iso_logical_block_size, &lines[i][23]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Creation Date: ")) {
- if (parse_time_t (&ret->iso_volume_creation_t, &lines[i][19]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Modification Date: ")) {
- if (parse_time_t (&ret->iso_volume_modification_t, &lines[i][19]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Expiration Date: ")) {
- if (parse_time_t (&ret->iso_volume_expiration_t, &lines[i][19]) == -1)
- goto error;
- }
- else if (STRPREFIX (lines[i], "Effective Date: ")) {
- if (parse_time_t (&ret->iso_volume_effective_t, &lines[i][19]) == -1)
- goto error;
- }
- }
-
- /* Any string fields which were not set above will be NULL. However
- * we cannot return NULL fields in structs, so we convert these to
- * empty strings here.
- */
- if (ret->iso_system_id == NULL) {
- ret->iso_system_id = strdup ("");
- if (ret->iso_system_id == NULL) goto error;
- }
- if (ret->iso_volume_id == NULL) {
- ret->iso_volume_id = strdup ("");
- if (ret->iso_volume_id == NULL) goto error;
- }
- if (ret->iso_volume_set_id == NULL) {
- ret->iso_volume_set_id = strdup ("");
- if (ret->iso_volume_set_id == NULL) goto error;
- }
- if (ret->iso_publisher_id == NULL) {
- ret->iso_publisher_id = strdup ("");
- if (ret->iso_publisher_id == NULL) goto error;
- }
- if (ret->iso_data_preparer_id == NULL) {
- ret->iso_data_preparer_id = strdup ("");
- if (ret->iso_data_preparer_id == NULL) goto error;
- }
- if (ret->iso_application_id == NULL) {
- ret->iso_application_id = strdup ("");
- if (ret->iso_application_id == NULL) goto error;
- }
- if (ret->iso_copyright_file_id == NULL) {
- ret->iso_copyright_file_id = strdup ("");
- if (ret->iso_copyright_file_id == NULL) goto error;
- }
- if (ret->iso_abstract_file_id == NULL) {
- ret->iso_abstract_file_id = strdup ("");
- if (ret->iso_abstract_file_id == NULL) goto error;
- }
- if (ret->iso_bibliographic_file_id == NULL) {
- ret->iso_bibliographic_file_id = strdup ("");
- if (ret->iso_bibliographic_file_id == NULL) goto error;
- }
-
- return ret;
-
- error:
- free (ret->iso_system_id);
- free (ret->iso_volume_id);
- free (ret->iso_volume_set_id);
- free (ret->iso_publisher_id);
- free (ret->iso_data_preparer_id);
- free (ret->iso_application_id);
- free (ret->iso_copyright_file_id);
- free (ret->iso_abstract_file_id);
- free (ret->iso_bibliographic_file_id);
- free (ret);
- return NULL;
-}
-
-static guestfs_int_isoinfo *
-isoinfo (const char *path)
-{
- int r;
- CLEANUP_FREE char *out = NULL, *err = NULL;
- CLEANUP_FREE_STRING_LIST char **lines = NULL;
-
- /* --debug is necessary to get additional fields, in particular
- * the date & time fields.
- */
- r = command (&out, &err, "isoinfo", "--debug", "-d", "-i", path, NULL);
- if (r == -1) {
- reply_with_error ("%s", err);
- return NULL;
- }
-
- lines = split_lines (out);
- if (lines == NULL)
- return NULL;
-
- return parse_isoinfo (lines);
-}
-
-guestfs_int_isoinfo *
-do_isoinfo_device (const char *device)
-{
- return isoinfo (device);
-}
-
-guestfs_int_isoinfo *
-do_isoinfo (const char *path)
-{
- guestfs_int_isoinfo *ret;
- CLEANUP_FREE char *buf = sysroot_path (path);
- if (!buf) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- ret = isoinfo (buf);
-
- return ret;
-}
diff --git a/daemon/isoinfo.ml b/daemon/isoinfo.ml
new file mode 100644
index 000000000..b7fe0af7e
--- /dev/null
+++ b/daemon/isoinfo.ml
@@ -0,0 +1,248 @@
+(* Parse isoinfo or xorriso output.
+ * Copyright (C) 2009-2021 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Printf
+open Scanf
+open Unix
+
+open Std_utils
+open Unix_utils
+
+open Mountable
+open Utils
+
+include Structs
+
+type tool = Isoinfo | Xorriso
+let tool = ref None
+
+let get_tool () =
+ match !tool with
+ | Some t -> t
+ | None ->
+ (* Prefer isoinfo because we've been using that tool for longer. *)
+ if Sys.command "isoinfo -version" = 0 then (
+ tool := Some Isoinfo;
+ Isoinfo
+ )
+ else if Sys.command "xorriso -version" = 0 then (
+ tool := Some Xorriso;
+ Xorriso
+ )
+ else
+ failwith "isoinfo or xorriso not available"
+
+(* Default each int field in the struct to -1 and each string to "". *)
+let default_iso = {
+ iso_system_id = "";
+ iso_volume_id = "";
+ iso_volume_space_size = -1_l;
+ iso_volume_set_size = -1_l;
+ iso_volume_sequence_number = -1_l;
+ (* This is almost always true for CDs because of the media itself,
+ * and is not available from xorriso.
+ *)
+ iso_logical_block_size = 2048_l;
+ iso_volume_set_id = "";
+ iso_publisher_id = "";
+ iso_data_preparer_id = "";
+ iso_application_id = "";
+ iso_copyright_file_id = "";
+ iso_abstract_file_id = "";
+ iso_bibliographic_file_id = "";
+ iso_volume_creation_t = -1_L;
+ iso_volume_modification_t = -1_L;
+ iso_volume_expiration_t = -1_L;
+ iso_volume_effective_t = -1_L;
+}
+
+(* This is always in a fixed format:
+ * "2012 03 16 11:05:46.00"
+ * or if the field is not present, then:
+ * "0000 00 00 00:00:00.00"
+ *)
+let parse_isoinfo_date str =
+ if str = "0000 00 00 00:00:00.00" ||
+ str = " : : . " then
+ -1_L
+ else (
+ sscanf str "%04d %02d %02d %02d:%02d:%02d"
+ (fun tm_year tm_mon tm_mday tm_hour tm_min tm_sec ->
+ (* Adjust fields. *)
+ let tm_year = tm_year - 1900 in
+ let tm_mon = tm_mon - 1 in
+
+ (* Convert to time_t *)
+ let tm = { tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year;
+ tm_wday = -1; tm_yday = -1; tm_isdst = false } in
+ Int64.of_float (fst (Unix.mktime tm))
+ )
+ )
+
+let do_isoinfo dev =
+ (* --debug is necessary to get additional fields, in particular
+ * the date & time fields.
+ *)
+ let lines = command "isoinfo" ["--debug"; "-d"; "-i"; dev] in
+ let lines = String.nsplit "\n" lines in
+
+ let ret = ref default_iso in
+ List.iter (
+ fun line ->
+ let n = String.length line in
+ if String.is_prefix line "System id: " then
+ ret := { !ret with iso_system_id = String.sub line 11 (n-11) }
+ else if String.is_prefix line "Volume id: " then
+ ret := { !ret with iso_volume_id = String.sub line 11 (n-11) }
+ else if String.is_prefix line "Volume set id: " then
+ ret := { !ret with iso_volume_set_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Publisher id: " then
+ ret := { !ret with iso_publisher_id = String.sub line 14 (n-14) }
+ else if String.is_prefix line "Data preparer id: " then
+ ret := { !ret with iso_data_preparer_id = String.sub line 18 (n-18) }
+ else if String.is_prefix line "Application id: " then
+ ret := { !ret with iso_application_id = String.sub line 16 (n-16) }
+ else if String.is_prefix line "Copyright File id: " then
+ ret := { !ret with iso_copyright_file_id = String.sub line 19 (n-19) }
+ else if String.is_prefix line "Abstract File id: " then
+ ret := { !ret with iso_abstract_file_id = String.sub line 18 (n-18) }
+ else if String.is_prefix line "Bibliographic File id: " then
+ ret := { !ret with
+ iso_bibliographic_file_id = String.sub line 23 (n-23) }
+ else if String.is_prefix line "Volume size is: " then (
+ let i = Int32.of_string (String.sub line 16 (n-16)) in
+ ret := { !ret with iso_volume_space_size = i }
+ )
+ else if String.is_prefix line "Volume set size is: " then (
+ let i = Int32.of_string (String.sub line 20 (n-20)) in
+ ret := { !ret with iso_volume_set_size = i }
+ )
+ else if String.is_prefix line "Volume set sequence number is: " then (
+ let i = Int32.of_string (String.sub line 31 (n-31)) in
+ ret := { !ret with iso_volume_sequence_number = i }
+ )
+ else if String.is_prefix line "Logical block size is: " then (
+ let i = Int32.of_string (String.sub line 23 (n-23)) in
+ ret := { !ret with iso_logical_block_size = i }
+ )
+ else if String.is_prefix line "Creation Date: " then (
+ let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
+ ret := { !ret with iso_volume_creation_t = t }
+ )
+ else if String.is_prefix line "Modification Date: " then (
+ let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
+ ret := { !ret with iso_volume_modification_t = t }
+ )
+ else if String.is_prefix line "Expiration Date: " then (
+ let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
+ ret := { !ret with iso_volume_expiration_t = t }
+ )
+ else if String.is_prefix line "Effective Date: " then (
+ let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
+ ret := { !ret with iso_volume_effective_t = t }
+ )
+ ) lines;
+ !ret
+
+(* This is always in a fixed format:
+ * "2021033012313200"
+ * or if the field is not present, then:
+ * "0000000000000000"
+ * XXX Parse the time zone fields too.
+ *)
+let parse_xorriso_date str =
+ if str = "0000000000000000" then -1_L
+ else if String.length str <> 16 then -1_L
+ else (
+ let tm_year = int_of_string (String.sub str 0 4) in
+ let tm_mon = int_of_string (String.sub str 4 2) in
+ let tm_mday = int_of_string (String.sub str 6 2) in
+ let tm_hour = int_of_string (String.sub str 8 2) in
+ let tm_min = int_of_string (String.sub str 10 2) in
+ let tm_sec = int_of_string (String.sub str 12 2) in
+
+ (* Adjust fields. *)
+ let tm_year = tm_year - 1900 in
+ let tm_mon = tm_mon - 1 in
+
+ (* Convert to time_t *)
+ let tm = { tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year;
+ tm_wday = -1; tm_yday = -1; tm_isdst = false } in
+ Int64.of_float (fst (Unix.mktime tm))
+ )
+
+let do_xorriso dev =
+ (* stdio: prefix is to work around a stupidity of xorriso. *)
+ let lines = command "xorriso" ["-indev"; "stdio:" ^ dev; "-pvd_info"] in
+ let lines = String.nsplit "\n" lines in
+
+ let ret = ref default_iso in
+ List.iter (
+ fun line ->
+ let n = String.length line in
+ if String.is_prefix line "System Id : " then
+ ret := { !ret with iso_system_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Volume Id : " then
+ ret := { !ret with iso_volume_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Volume Set Id: " then
+ ret := { !ret with iso_volume_set_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Publisher Id : " then
+ ret := { !ret with iso_publisher_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "App Id : " then
+ ret := { !ret with iso_application_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "CopyrightFile: " then
+ ret := { !ret with iso_copyright_file_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Abstract File: " then
+ ret := { !ret with iso_abstract_file_id = String.sub line 15 (n-15) }
+ else if String.is_prefix line "Biblio File : " then
+ ret := { !ret with
+ iso_bibliographic_file_id = String.sub line 15 (n-15) }
+ (* XXX The following fields don't appear to be available
+ * with xorriso:
+ * - iso_volume_space_size (only available on stderr)
+ * - iso_volume_sequence_number
+ * - iso_logical_block_size
+ *)
+ (* XXX xorriso provides a timezone for these fields, but
+ * we don't use it here.
+ *)
+ else if String.is_prefix line "Creation Time: " then (
+ let t = parse_xorriso_date (String.sub line 15 (n-15)) in
+ ret := { !ret with iso_volume_creation_t = t }
+ )
+ else if String.is_prefix line "Modif. Time : " then (
+ let t = parse_xorriso_date (String.sub line 15 (n-15)) in
+ ret := { !ret with iso_volume_modification_t = t }
+ )
+ else if String.is_prefix line "Expir. Time : " then (
+ let t = parse_xorriso_date (String.sub line 15 (n-15)) in
+ ret := { !ret with iso_volume_expiration_t = t }
+ )
+ else if String.is_prefix line "Eff. Time : " then (
+ let t = parse_xorriso_date (String.sub line 15 (n-15)) in
+ ret := { !ret with iso_volume_effective_t = t }
+ )
+ ) lines;
+ !ret
+
+let isoinfo dev =
+ match get_tool () with
+ | Isoinfo -> do_isoinfo dev
+ | Xorriso -> do_xorriso dev
+
+let isoinfo_device = isoinfo
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index 060be051b..e65c2f9d9 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -103,7 +103,6 @@ daemon/initrd.c
daemon/inotify.c
daemon/internal.c
daemon/is.c
-daemon/isoinfo.c
daemon/journal.c
daemon/labels.c
daemon/ldm.c
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index bb92ef2ca..40505d8b5 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -6878,6 +6878,7 @@ this will create the largest possible LV." };
{ defaults with
name = "isoinfo_device"; added = (1, 17, 19);
style = RStruct ("isodata", "isoinfo"), [String (Device, "device")], [];
+ impl = OCaml "Isoinfo.isoinfo_device";
tests = [
InitNone, Always, TestResult (
[["isoinfo_device"; "/dev/sdd"]],
@@ -6904,6 +6905,7 @@ L<https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor>" };
{ defaults with
name = "isoinfo"; added = (1, 17, 19);
style = RStruct ("isodata", "isoinfo"), [String (Pathname, "isofile")], [];
+ impl = OCaml "Isoinfo.isoinfo";
shortdesc = "get ISO information from primary volume descriptor of ISO file";
longdesc = "\
This is the same as C<guestfs_isoinfo_device> except that it
diff --git a/po/POTFILES b/po/POTFILES
index c5f4e6aa7..717579d56 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -82,7 +82,6 @@ daemon/initrd.c
daemon/inotify.c
daemon/internal.c
daemon/is.c
-daemon/isoinfo.c
daemon/journal.c
daemon/labels.c
daemon/ldm.c
--
2.29.0.rc2

View File

@ -1,405 +0,0 @@
From 2f587bbaec718e414e46c7e6f2a3e2662c3a1c2a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 31 Mar 2021 10:32:52 +0100
Subject: [PATCH 4/5] daemon: Read ISO9660 Primary Volume Descriptor directly.
It turns out we can read the information we need for the isoinfo API
directly from the ISO9660 PVD. We don't need to use either isoinfo or
xorriso. This also has the advantages of reducing by 1 the number of
dependencies in the appliance, and reducing potential vulnerability to
a crafted ISO file.
This also fixes timezone calculation for the datetime fields.
Thanks: Thomas Schmitt
Updates: commit efb8a766cac4ba8e413594946136bf91e176bb8c
---
appliance/packagelist.in | 10 --
daemon/isoinfo.ml | 282 ++++++++++++---------------------------
2 files changed, 82 insertions(+), 210 deletions(-)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index f4ad50b79..cede0ac0b 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -26,7 +26,6 @@ ifelse(REDHAT,1,
cryptsetup
cryptsetup-luks dnl old name used before Fedora 17
dhclient
- genisoimage
gfs-utils
gfs2-utils
grub
@@ -45,7 +44,6 @@ ifelse(REDHAT,1,
syslinux-extlinux
systemd dnl for /sbin/reboot and udevd
vim-minimal
- xorriso dnl alternative for genisoimage
xz
zfs-fuse
)
@@ -57,7 +55,6 @@ dnl old name used in Jessie and earlier
cryptsetup
dash
extlinux
- genisoimage
dnl gfs-tools, gfs2-tools have been renamed to gfs2-utils
gfs-tools
gfs2-tools
@@ -85,7 +82,6 @@ dnl iproute has been renamed to iproute2
systemd dnl alternative for /sbin/reboot
ufsutils
vim-tiny
- xorriso dnl alternative for genisoimage
xz-utils
zfs-fuse
uuid-runtime
@@ -124,13 +120,11 @@ ifelse(SUSE,1,
cryptsetup
dhcpcd
dhcp-client
- genisoimage
glibc-locale
gptfdisk
initviocons
iproute2
iputils
- mkisofs
ntfsprogs
ntfs-3g
reiserfs
@@ -164,8 +158,6 @@ ifelse(FRUGALWARE,1,
ifelse(MAGEIA,1,
cryptsetup
chkconfig /* for /etc/init.d */
- cdrkit-genisoimage
- cdrkit-isotools
dhcp-client
extlinux
gfs2-utils
@@ -190,8 +182,6 @@ ifelse(MAGEIA,1,
ifelse(OPENMANDRIVA,1,
cryptsetup
chkconfig /* for /etc/init.d */
- cdrkit-genisoimage
- cdrkit-isotools
dhcp-client
extlinux
grub2
diff --git a/daemon/isoinfo.ml b/daemon/isoinfo.ml
index b7fe0af7e..448563365 100644
--- a/daemon/isoinfo.ml
+++ b/daemon/isoinfo.ml
@@ -17,157 +17,32 @@
*)
open Printf
-open Scanf
open Unix
open Std_utils
-open Unix_utils
-
-open Mountable
-open Utils
include Structs
-type tool = Isoinfo | Xorriso
-let tool = ref None
-
-let get_tool () =
- match !tool with
- | Some t -> t
- | None ->
- (* Prefer isoinfo because we've been using that tool for longer. *)
- if Sys.command "isoinfo -version" = 0 then (
- tool := Some Isoinfo;
- Isoinfo
- )
- else if Sys.command "xorriso -version" = 0 then (
- tool := Some Xorriso;
- Xorriso
- )
- else
- failwith "isoinfo or xorriso not available"
-
-(* Default each int field in the struct to -1 and each string to "". *)
-let default_iso = {
- iso_system_id = "";
- iso_volume_id = "";
- iso_volume_space_size = -1_l;
- iso_volume_set_size = -1_l;
- iso_volume_sequence_number = -1_l;
- (* This is almost always true for CDs because of the media itself,
- * and is not available from xorriso.
- *)
- iso_logical_block_size = 2048_l;
- iso_volume_set_id = "";
- iso_publisher_id = "";
- iso_data_preparer_id = "";
- iso_application_id = "";
- iso_copyright_file_id = "";
- iso_abstract_file_id = "";
- iso_bibliographic_file_id = "";
- iso_volume_creation_t = -1_L;
- iso_volume_modification_t = -1_L;
- iso_volume_expiration_t = -1_L;
- iso_volume_effective_t = -1_L;
-}
-
-(* This is always in a fixed format:
- * "2012 03 16 11:05:46.00"
- * or if the field is not present, then:
- * "0000 00 00 00:00:00.00"
+(* We treat ISO "strA" and "strD" formats the same way, simply
+ * discarding any trailing spaces.
*)
-let parse_isoinfo_date str =
- if str = "0000 00 00 00:00:00.00" ||
- str = " : : . " then
- -1_L
- else (
- sscanf str "%04d %02d %02d %02d:%02d:%02d"
- (fun tm_year tm_mon tm_mday tm_hour tm_min tm_sec ->
- (* Adjust fields. *)
- let tm_year = tm_year - 1900 in
- let tm_mon = tm_mon - 1 in
+let iso_parse_strA str =
+ let len = String.length str in
+ let rec loop len =
+ if len > 0 && str.[len-1] = ' ' then loop (len-1) else len
+ in
+ let len = loop len in
+ String.sub str 0 len
- (* Convert to time_t *)
- let tm = { tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year;
- tm_wday = -1; tm_yday = -1; tm_isdst = false } in
- Int64.of_float (fst (Unix.mktime tm))
- )
- )
+let iso_parse_strD = iso_parse_strA
-let do_isoinfo dev =
- (* --debug is necessary to get additional fields, in particular
- * the date & time fields.
- *)
- let lines = command "isoinfo" ["--debug"; "-d"; "-i"; dev] in
- let lines = String.nsplit "\n" lines in
+(* These always parse the intX_LSB (little endian) version. *)
+let iso_parse_int16 s = s |> int_of_le16 |> Int64.to_int32
+let iso_parse_int32 s = s |> int_of_le32 |> Int64.to_int32
- let ret = ref default_iso in
- List.iter (
- fun line ->
- let n = String.length line in
- if String.is_prefix line "System id: " then
- ret := { !ret with iso_system_id = String.sub line 11 (n-11) }
- else if String.is_prefix line "Volume id: " then
- ret := { !ret with iso_volume_id = String.sub line 11 (n-11) }
- else if String.is_prefix line "Volume set id: " then
- ret := { !ret with iso_volume_set_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Publisher id: " then
- ret := { !ret with iso_publisher_id = String.sub line 14 (n-14) }
- else if String.is_prefix line "Data preparer id: " then
- ret := { !ret with iso_data_preparer_id = String.sub line 18 (n-18) }
- else if String.is_prefix line "Application id: " then
- ret := { !ret with iso_application_id = String.sub line 16 (n-16) }
- else if String.is_prefix line "Copyright File id: " then
- ret := { !ret with iso_copyright_file_id = String.sub line 19 (n-19) }
- else if String.is_prefix line "Abstract File id: " then
- ret := { !ret with iso_abstract_file_id = String.sub line 18 (n-18) }
- else if String.is_prefix line "Bibliographic File id: " then
- ret := { !ret with
- iso_bibliographic_file_id = String.sub line 23 (n-23) }
- else if String.is_prefix line "Volume size is: " then (
- let i = Int32.of_string (String.sub line 16 (n-16)) in
- ret := { !ret with iso_volume_space_size = i }
- )
- else if String.is_prefix line "Volume set size is: " then (
- let i = Int32.of_string (String.sub line 20 (n-20)) in
- ret := { !ret with iso_volume_set_size = i }
- )
- else if String.is_prefix line "Volume set sequence number is: " then (
- let i = Int32.of_string (String.sub line 31 (n-31)) in
- ret := { !ret with iso_volume_sequence_number = i }
- )
- else if String.is_prefix line "Logical block size is: " then (
- let i = Int32.of_string (String.sub line 23 (n-23)) in
- ret := { !ret with iso_logical_block_size = i }
- )
- else if String.is_prefix line "Creation Date: " then (
- let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
- ret := { !ret with iso_volume_creation_t = t }
- )
- else if String.is_prefix line "Modification Date: " then (
- let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
- ret := { !ret with iso_volume_modification_t = t }
- )
- else if String.is_prefix line "Expiration Date: " then (
- let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
- ret := { !ret with iso_volume_expiration_t = t }
- )
- else if String.is_prefix line "Effective Date: " then (
- let t = parse_isoinfo_date (String.sub line 19 (n-19)) in
- ret := { !ret with iso_volume_effective_t = t }
- )
- ) lines;
- !ret
-
-(* This is always in a fixed format:
- * "2021033012313200"
- * or if the field is not present, then:
- * "0000000000000000"
- * XXX Parse the time zone fields too.
- *)
-let parse_xorriso_date str =
- if str = "0000000000000000" then -1_L
- else if String.length str <> 16 then -1_L
+(* Parse ISO dec-datetime to a Unix time_t. *)
+let iso_parse_datetime str =
+ if String.sub str 0 16 = "0000000000000000" then -1_L
else (
let tm_year = int_of_string (String.sub str 0 4) in
let tm_mon = int_of_string (String.sub str 4 2) in
@@ -180,69 +55,76 @@ let parse_xorriso_date str =
let tm_year = tm_year - 1900 in
let tm_mon = tm_mon - 1 in
- (* Convert to time_t *)
+ (* Convert to time_t in UTC timezone. *)
let tm = { tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year;
tm_wday = -1; tm_yday = -1; tm_isdst = false } in
- Int64.of_float (fst (Unix.mktime tm))
+ let old_TZ = try Some (getenv "TZ") with Not_found -> None in
+ putenv "TZ" "UTC";
+ let r = Int64.of_float (fst (mktime tm)) in
+ Option.may (putenv "TZ") old_TZ;
+
+ (* The final byte is a time zone offset from GMT.
+ *
+ * The documentation of this at
+ * https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor
+ * is wrong. See the ECMA 119 documentation for a correct
+ * description.
+ *
+ * For a disk image which we know was created
+ * in BST (GMT+1), this contains 0x4, ie. 4 * 15 mins ahead.
+ * We have to subtract this from the gmtime above.
+ *)
+ let tz = Char.code str.[16] in
+ let tz = if tz >= 128 then tz - 256 else tz in
+ r -^ (Int64.of_int (tz * 15 * 60))
)
-let do_xorriso dev =
- (* stdio: prefix is to work around a stupidity of xorriso. *)
- let lines = command "xorriso" ["-indev"; "stdio:" ^ dev; "-pvd_info"] in
- let lines = String.nsplit "\n" lines in
-
- let ret = ref default_iso in
- List.iter (
- fun line ->
- let n = String.length line in
- if String.is_prefix line "System Id : " then
- ret := { !ret with iso_system_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Volume Id : " then
- ret := { !ret with iso_volume_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Volume Set Id: " then
- ret := { !ret with iso_volume_set_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Publisher Id : " then
- ret := { !ret with iso_publisher_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "App Id : " then
- ret := { !ret with iso_application_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "CopyrightFile: " then
- ret := { !ret with iso_copyright_file_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Abstract File: " then
- ret := { !ret with iso_abstract_file_id = String.sub line 15 (n-15) }
- else if String.is_prefix line "Biblio File : " then
- ret := { !ret with
- iso_bibliographic_file_id = String.sub line 15 (n-15) }
- (* XXX The following fields don't appear to be available
- * with xorriso:
- * - iso_volume_space_size (only available on stderr)
- * - iso_volume_sequence_number
- * - iso_logical_block_size
- *)
- (* XXX xorriso provides a timezone for these fields, but
- * we don't use it here.
- *)
- else if String.is_prefix line "Creation Time: " then (
- let t = parse_xorriso_date (String.sub line 15 (n-15)) in
- ret := { !ret with iso_volume_creation_t = t }
- )
- else if String.is_prefix line "Modif. Time : " then (
- let t = parse_xorriso_date (String.sub line 15 (n-15)) in
- ret := { !ret with iso_volume_modification_t = t }
- )
- else if String.is_prefix line "Expir. Time : " then (
- let t = parse_xorriso_date (String.sub line 15 (n-15)) in
- ret := { !ret with iso_volume_expiration_t = t }
- )
- else if String.is_prefix line "Eff. Time : " then (
- let t = parse_xorriso_date (String.sub line 15 (n-15)) in
- ret := { !ret with iso_volume_effective_t = t }
- )
- ) lines;
- !ret
-
let isoinfo dev =
- match get_tool () with
- | Isoinfo -> do_isoinfo dev
- | Xorriso -> do_xorriso dev
+ let r, pvd =
+ with_openfile dev [O_RDONLY] 0 (
+ fun fd ->
+ ignore (lseek fd 32768 SEEK_SET);
+ let pvd = Bytes.create 2048 in
+ let r = read fd pvd 0 2048 in
+ r, Bytes.to_string pvd
+ ) in
+
+ let sub = String.sub pvd in
+
+ (* Check that it looks like an ISO9660 Primary Volume Descriptor.
+ * https://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor
+ *)
+ if r <> 2048 || pvd.[0] <> '\001' || sub 1 5 <> "CD001" then
+ failwithf "%s: not an ISO file or CD-ROM" dev;
+
+ (* Parse out the PVD fields. *)
+ let iso_system_id = sub 8 32 |> iso_parse_strA in
+ let iso_volume_id = sub 40 32 |> iso_parse_strA in
+ let iso_volume_space_size = sub 80 4 |> iso_parse_int32 in
+ let iso_volume_set_size = sub 120 2 |> iso_parse_int16 in
+ let iso_volume_sequence_number = sub 124 2 |> iso_parse_int16 in
+ let iso_logical_block_size = sub 128 2 |> iso_parse_int16 in
+ let iso_volume_set_id = sub 190 128 |> iso_parse_strD in
+ let iso_publisher_id = sub 318 128 |> iso_parse_strA in
+ let iso_data_preparer_id = sub 446 128 |> iso_parse_strA in
+ let iso_application_id = sub 574 128 |> iso_parse_strA in
+ let iso_copyright_file_id = sub 702 38 |> iso_parse_strD in
+ let iso_abstract_file_id = sub 740 36 |> iso_parse_strD in
+ let iso_bibliographic_file_id = sub 776 37 |> iso_parse_strD in
+ let iso_volume_creation_t = sub 813 17 |> iso_parse_datetime in
+ let iso_volume_modification_t = sub 830 17 |> iso_parse_datetime in
+ let iso_volume_expiration_t = sub 847 17 |> iso_parse_datetime in
+ let iso_volume_effective_t = sub 864 17 |> iso_parse_datetime in
+
+ (* Return the struct. *)
+ {
+ iso_system_id; iso_volume_id; iso_volume_space_size;
+ iso_volume_set_size; iso_volume_sequence_number;
+ iso_logical_block_size; iso_volume_set_id; iso_publisher_id;
+ iso_data_preparer_id; iso_application_id; iso_copyright_file_id;
+ iso_abstract_file_id; iso_bibliographic_file_id;
+ iso_volume_creation_t; iso_volume_modification_t;
+ iso_volume_expiration_t; iso_volume_effective_t;
+ }
let isoinfo_device = isoinfo
--
2.29.0.rc2

View File

@ -1,127 +0,0 @@
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

View File

@ -42,7 +42,7 @@
# If there are patches which touch autotools files, set this to 1.
%if !0%{?rhel}
%global patches_touch_autotools 1
%global patches_touch_autotools %{nil}
%else
# On RHEL the downstream patches always touch autotools files.
%global patches_touch_autotools 1
@ -60,8 +60,8 @@
Summary: Access and modify virtual machine disk images
Name: libguestfs
Epoch: 1
Version: 1.45.3
Release: 6%{?dist}
Version: 1.45.4
Release: 1%{?dist}
License: LGPLv2+
# Build only for architectures that have a kernel
@ -91,14 +91,6 @@ Source7: libguestfs.keyring
# Maintainer script which helps with handling patches.
Source8: copy-patches.sh
# Upstream patches since 1.45.3.
Patch0001: 0001-daemon-xfs.c-Fix-error-message.patch
Patch0002: 0002-tests-Prefer-xorriso-over-genisoimage-to-generate-te.patch
Patch0003: 0003-daemon-Allow-xorriso-as-an-alternative-to-isoinfo.patch
Patch0004: 0004-daemon-Read-ISO9660-Primary-Volume-Descriptor-direct.patch
# Workaround for file 5.40 which is broken in Fedora Rawhide.
Patch0005: 0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch
# Downstream (RHEL-only) patches.
%if 0%{?rhel}
Patch9001: 0001-RHEL-Remove-libguestfs-live-RHBZ-798980.patch
@ -1126,6 +1118,9 @@ rm ocaml/html/.gitignore
%changelog
* Sat Apr 03 2021 Richard W.M. Jones <rjones@redhat.com> - 1:1.45.4-1
- New upstream version 1.45.4.
* Wed Mar 31 2021 Richard W.M. Jones <rjones@redhat.com> - 1:1.45.3-6
- Don't require genisoimage or xorriso for the appliance.
- Add workaround for broken "file" utility in Rawhide (RHBZ#1945122).

View File

@ -1,2 +1,2 @@
SHA512 (libguestfs-1.45.3.tar.gz) = b8f3dc9ffa49b50769f8f11d65cf3c8e645b35ee05ea2563b19daa8bc743e7f3386754cb5ffd2447f55ade4b57e9c4f98e483ecffc548652659e1260bf2e6e0b
SHA512 (libguestfs-1.45.3.tar.gz.sig) = bce2ed6fd987baf82ebdd7d97cf1b1a07f62991e07de45d4f22d20c5180120c5b443b690c1db6c00a71cb14fb66b5a950de227d9c7fea2c9ca32afba33818216
SHA512 (libguestfs-1.45.4.tar.gz) = 5e4960a0a0a182f1736a9707a84fd11f28b530a31d6a1ac2fca35d284e63bb07f20d2344355f4a626866dfb006e09c3f4a60754512a10b6462d4587e8cdc075e
SHA512 (libguestfs-1.45.4.tar.gz.sig) = 860529aa6febf552ba5495f5b56f61daa27bd117fa0bc9a965511646022ee8f8f27f34a9ab1605cb7dea71d66bff2ab9da72d189f559f07ced57dc982929200c