From 6ab119c488e3a21511bbd97f4950d1d16fe9d30f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 3 Apr 2021 12:36:41 +0100 Subject: [PATCH] New upstream version 1.45.4. --- 0001-daemon-xfs.c-Fix-error-message.patch | 35 - ...riso-over-genisoimage-to-generate-te.patch | 67 -- ...xorriso-as-an-alternative-to-isoinfo.patch | 684 ------------------ ...660-Primary-Volume-Descriptor-direct.patch | 405 ----------- ...mdline.c-Read-UUID-directly-from-app.patch | 127 ---- libguestfs.spec | 17 +- sources | 4 +- 7 files changed, 8 insertions(+), 1331 deletions(-) delete mode 100644 0001-daemon-xfs.c-Fix-error-message.patch delete mode 100644 0002-tests-Prefer-xorriso-over-genisoimage-to-generate-te.patch delete mode 100644 0003-daemon-Allow-xorriso-as-an-alternative-to-isoinfo.patch delete mode 100644 0004-daemon-Read-ISO9660-Primary-Volume-Descriptor-direct.patch delete mode 100644 0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch diff --git a/0001-daemon-xfs.c-Fix-error-message.patch b/0001-daemon-xfs.c-Fix-error-message.patch deleted file mode 100644 index e45d459..0000000 --- a/0001-daemon-xfs.c-Fix-error-message.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 49b8b69cb8e10e5476bbe86a708ee1babfe330e8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0002-tests-Prefer-xorriso-over-genisoimage-to-generate-te.patch b/0002-tests-Prefer-xorriso-over-genisoimage-to-generate-te.patch deleted file mode 100644 index 4957a95..0000000 --- a/0002-tests-Prefer-xorriso-over-genisoimage-to-generate-te.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2216ab2e328457ef172d6bfa534272edf2f81a3a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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. - - I. - --=item genisoimage -+=item xorriso, genisoimage or mkisofs - --I. -+One of these is I. - - =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 - diff --git a/0003-daemon-Allow-xorriso-as-an-alternative-to-isoinfo.patch b/0003-daemon-Allow-xorriso-as-an-alternative-to-isoinfo.patch deleted file mode 100644 index d8a07a8..0000000 --- a/0003-daemon-Allow-xorriso-as-an-alternative-to-isoinfo.patch +++ /dev/null @@ -1,684 +0,0 @@ -From efb8a766cac4ba8e413594946136bf91e176bb8c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 -- --#include --#include --#include --#include --#include --#include --#include -- --#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" }; - { 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 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 - diff --git a/0004-daemon-Read-ISO9660-Primary-Volume-Descriptor-direct.patch b/0004-daemon-Read-ISO9660-Primary-Volume-Descriptor-direct.patch deleted file mode 100644 index b965807..0000000 --- a/0004-daemon-Read-ISO9660-Primary-Volume-Descriptor-direct.patch +++ /dev/null @@ -1,405 +0,0 @@ -From 2f587bbaec718e414e46c7e6f2a3e2662c3a1c2a Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - diff --git a/0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch b/0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch deleted file mode 100644 index c1b70c0..0000000 --- a/0005-lib-appliance-kcmdline.c-Read-UUID-directly-from-app.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 278d0d3226f4bdb7c6586986ca46d0a25c976fe4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -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 - #include - #include -+#include -+#include -+#include - - #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 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 command -- * and write them into the out_file. That may be useful to get UUID of -- * the QCOW2 disk image with further L command. -+ * Read the first 256k bytes of the in_file with L -+ * command and write them into the out_file. That may be useful to get -+ * UUID of the QCOW2 disk image with C. -+ * - * The function returns zero if successful, otherwise -1. - */ - static int --- -2.29.0.rc2 - diff --git a/libguestfs.spec b/libguestfs.spec index 4899029..a1c558a 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -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 - 1:1.45.4-1 +- New upstream version 1.45.4. + * Wed Mar 31 2021 Richard W.M. Jones - 1:1.45.3-6 - Don't require genisoimage or xorriso for the appliance. - Add workaround for broken "file" utility in Rawhide (RHBZ#1945122). diff --git a/sources b/sources index 4b6006f..0021018 100644 --- a/sources +++ b/sources @@ -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