Switch from genisoimage to xorriso.

This commit is contained in:
Richard W.M. Jones 2021-03-30 15:35:23 +01:00
parent 9da4883de4
commit 928729ea6e
4 changed files with 797 additions and 5 deletions

View File

@ -0,0 +1,35 @@
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/3] 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

@ -0,0 +1,67 @@
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/3] 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

@ -0,0 +1,684 @@
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/3] 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

@ -42,7 +42,7 @@
# If there are patches which touch autotools files, set this to 1.
%if !0%{?rhel}
%global patches_touch_autotools %{nil}
%global patches_touch_autotools 1
%else
# On RHEL the downstream patches always touch autotools files.
%global patches_touch_autotools 1
@ -61,7 +61,7 @@ Summary: Access and modify virtual machine disk images
Name: libguestfs
Epoch: 1
Version: 1.45.3
Release: 3%{?dist}
Release: 4%{?dist}
License: LGPLv2+
# Build only for architectures that have a kernel
@ -91,6 +91,11 @@ 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
# Downstream (RHEL-only) patches.
%if 0%{?rhel}
Patch9001: 0001-RHEL-Remove-libguestfs-live-RHBZ-798980.patch
@ -118,7 +123,7 @@ BuildRequires: /usr/bin/pod2text
BuildRequires: po4a
BuildRequires: augeas-devel >= 1.7.0
BuildRequires: readline-devel
BuildRequires: genisoimage
BuildRequires: xorriso
BuildRequires: libxml2-devel
BuildRequires: createrepo_c
BuildRequires: glibc-static
@ -234,7 +239,6 @@ BuildRequires: file
BuildRequires: findutils
BuildRequires: gawk
BuildRequires: gdisk
BuildRequires: genisoimage
%if !0%{?rhel}
BuildRequires: gfs2-utils
%endif
@ -297,6 +301,7 @@ BuildRequires: vim-minimal
BuildRequires: which
%endif
BuildRequires: xfsprogs
BuildRequires: xorriso
BuildRequires: xz
BuildRequires: yajl
%if !0%{?rhel}
@ -1119,8 +1124,9 @@ rm ocaml/html/.gitignore
%changelog
* Tue Mar 30 2021 Richard W.M. Jones <rjones@redhat.com> - 1:1.45.3-3
* Tue Mar 30 2021 Richard W.M. Jones <rjones@redhat.com> - 1:1.45.3-4
- Add downstream (RHEL-only) patches (RHBZ#1931724).
- Switch from genisoimage to xorriso.
* Mon Mar 29 2021 Richard W.M. Jones <rjones@redhat.com> - 1:1.45.3-2
- New upstream release 1.45.3.