Re: [Libguestfs] a question about multithreading with libguestfs
by Richard W.M. Jones
On Mon, Jun 26, 2017 at 10:27:54AM +0300, Maxim Kozover wrote:
> I'd like to ask you, please, about multithreading with libguestfs.
> I'm using libguestfs 1.36.4 with Perl front-end.
>
> Should it be possible to have the same libguestfs appliance provide both
> fuse interface and periodically perform some longer APIs like find0?
>
> I mean make one Perl thread do mount_local_run and another thread
> periodically run find0 that executes simultaneously with fuse (hopefully
> not blocking fuse functionality internally until find0 exits)?
Unfortunately not, and as you discovered it will (currently) crash.
> When I'm trying this, the whole thing crashes, so the question is if it
> should be possible, please, and if yes, how could the problem be fixed?
This is really a bug, and something we've been meaning to fix. What
should happen is there is a lock in the handle which every API takes.
It requires some changes to the generator to implement but is not
necessary hard to do. In fact I posted patches for it a while back,
but they did not get upstream:
https://www.redhat.com/archives/libguestfs/2015-June/msg00048.html
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
7 years, 4 months
[PATCH 0/2] support autodetection of appliance image format
by Pavel Butsykin
This feature allows you to use different image formats for the fixed
appliance. The raw format is used by default.
In accordance with the discussion (https://www.redhat.com/archives/libguestfs/2017-June/msg00230.html)
Pavel Butsykin (2):
launch: add support for autodetection of appliance image format
build: add ./configure --enable-appliance-fmt-auto option
lib/create.c | 5 +++--
lib/guestfs-internal.h | 2 ++
lib/launch-direct.c | 2 ++
lib/launch-libvirt.c | 15 +++++++++------
m4/guestfs_appliance.m4 | 11 +++++++++++
5 files changed, 27 insertions(+), 8 deletions(-)
--
2.13.0
7 years, 4 months
IRC question: virt-p2v-make-disk hanging
by Richard W.M. Jones
10:16 < netman1> Hi All. First timer. Running "sudo virt-p2v-make-disk -o image.dd debian-8" where the image is a zeroed out disk file of
16GB. Let is run for over 12 hours, still nothing. It has the deb8 cached. Still waiting on "[ 14.1] Opening the new
disk". What am I doing wrong/could be the cause?
11:02 < netman1> Hum. Running it in DEBUG and TRACE mode (as root as it wants to read my current kernel file /boot/vm*), gets it to complain
about "RTNETLINK answers: File exists /sbin/dhclient-script: 34: /sbin/dhclient-script: cannot open /etc/fstab: No such
file"
I believe this is the following Ubuntu bug:
https://bugs.launchpad.net/ubuntu/+source/libguestfs/+bug/1632405
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine. Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/
7 years, 4 months
Appliance image. Why raw?
by Pavel Butsykin
I noticed that raw is intentionally used as image format for appliance
image. So I would like to ask, is there any reason to use raw as image
format for appliance?
I would suggest that choice is related with the performance, so I did
several test runs (./run utils/boot-benchmark/boot-benchmark)
/appliance/root.raw:
Result: 1342.9ms ±2.9ms
Result: 1370.1ms ±17.3ms
Result: 1365.1ms ±11.0ms
appliance/root.qcow2:
Result: 1353.1ms ±2.4ms
Result: 1350.2ms ±5.3ms
Result: 1374.7ms ±5.4ms
But even theoretically there should not be much difference, because
qcow2 uses a cache to internal tables. Also -drive configured to use the
host cache:
if (has_appliance_drive) {
ADD_CMDLINE ("-drive");
ADD_CMDLINE_PRINTF ("file=%s,snapshot=on,id=appliance,"
"cache=unsafe,if=none,format=raw",
7 years, 4 months
[PATCH v2 1/2] mllib: add new Common_utils.run_commands
by Pino Toscano
Mostly modelled after a snippet implemented in dib, it is an helper
function to run multiple commands in parallel, waiting for all of them
at once, and returning all their exit codes. It is possible to pass
custom descriptors for collecting stdout and stderr of each command.
Common_utils.run_command is adapted to use few helper methods used by
run_commands, so all the existing code using it keeps working; in
addition, it gets labelled parameters for stdout and stderr FDs.
Add a simple unit tests for them.
---
mllib/common_utils.ml | 87 ++++++++++++++++++++++++++++++++++++---------
mllib/common_utils.mli | 21 ++++++++++-
mllib/common_utils_tests.ml | 70 ++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+), 18 deletions(-)
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 6a9b089..60b43a3 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -846,29 +846,82 @@ let external_command ?(echo_cmd = true) cmd =
);
lines
-let run_command ?(echo_cmd = true) args =
- if echo_cmd then
- debug "%s" (stringify_args args);
+let rec run_commands ?(echo_cmd = true) cmds =
+ let res = Array.make (List.length cmds) 0 in
+ let pids =
+ mapi (
+ fun i (args, stdout_chan, stderr_chan) ->
+ let run_res = do_run args ?stdout_chan ?stderr_chan in
+ match run_res with
+ | Either (pid, app, outfd, errfd) ->
+ Some (i, pid, app, outfd, errfd)
+ | Or code ->
+ res.(i) <- code;
+ None
+ ) cmds in
+ let pids = filter_map identity pids in
+ let pids = ref pids in
+ while !pids <> [] do
+ let pid, stat = Unix.waitpid [] 0 in
+ let matching_pair, new_pids =
+ List.partition (
+ fun (_, p, _, _, _) ->
+ pid = p
+ ) !pids in
+ if matching_pair <> [] then (
+ let matching_pair = List.hd matching_pair in
+ let idx, _, app, outfd, errfd = matching_pair in
+ pids := new_pids;
+ res.(idx) <- do_teardown app outfd errfd stat
+ );
+ done;
+ Array.to_list res
+
+and run_command ?(echo_cmd = true) ?stdout_chan ?stderr_chan args =
+ let run_res = do_run args ~echo_cmd ?stdout_chan ?stderr_chan in
+ match run_res with
+ | Either (pid, app, outfd, errfd) ->
+ let _, stat = Unix.waitpid [] pid in
+ do_teardown app outfd errfd stat
+ | Or code ->
+ code
+
+and do_run ?(echo_cmd = true) ?stdout_chan ?stderr_chan args =
let app = List.hd args in
+ let get_fd default = function
+ | None ->
+ default
+ | Some fd ->
+ Unix.set_close_on_exec fd;
+ fd
+ in
try
let app =
if Filename.is_relative app then which app
else (Unix.access app [Unix.X_OK]; app) in
- let pid =
- Unix.create_process app (Array.of_list args) Unix.stdin
- Unix.stdout Unix.stderr in
- let _, stat = Unix.waitpid [] pid in
- match stat with
- | Unix.WEXITED i -> i
- | Unix.WSIGNALED i ->
- error (f_"external command ‘%s’ killed by signal %d")
- (stringify_args args) i
- | Unix.WSTOPPED i ->
- error (f_"external command ‘%s’ stopped by signal %d")
- (stringify_args args) i
+ let outfd = get_fd Unix.stdout stdout_chan in
+ let errfd = get_fd Unix.stderr stderr_chan in
+ if echo_cmd then
+ debug "%s" (stringify_args args);
+ let pid = Unix.create_process app (Array.of_list args) Unix.stdin
+ outfd errfd in
+ Either (pid, app, stdout_chan, stderr_chan)
with
- | Executable_not_found tool -> 127
- | Unix.Unix_error (errcode, _, _) when errcode = Unix.ENOENT -> 127
+ | Executable_not_found _ ->
+ Or 127
+ | Unix.Unix_error (errcode, _, _) when errcode = Unix.ENOENT ->
+ Or 127
+
+and do_teardown app outfd errfd exitstat =
+ may Unix.close outfd;
+ may Unix.close errfd;
+ match exitstat with
+ | Unix.WEXITED i ->
+ i
+ | Unix.WSIGNALED i ->
+ error (f_"external command ‘%s’ killed by signal %d") app i
+ | Unix.WSTOPPED i ->
+ error (f_"external command ‘%s’ stopped by signal %d") app i
let shell_command ?(echo_cmd = true) cmd =
if echo_cmd then
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index c088f84..ee8c2e6 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -374,7 +374,26 @@ val external_command : ?echo_cmd:bool -> string -> string list
[echo_cmd] specifies whether to output the full command on verbose
mode, and it's on by default. *)
-val run_command : ?echo_cmd:bool -> string list -> int
+val run_commands : ?echo_cmd:bool -> (string list * Unix.file_descr option * Unix.file_descr option) list -> int list
+(** Run external commands in parallel without using a shell,
+ and return a list with their exit codes.
+
+ The list of commands is composed as tuples:
+ - the first element is a list of command and its arguments
+ - the second element is an optional [Unix.file_descr] descriptor
+ for the stdout of the process; if not specified, [stdout] is
+ used
+ - the third element is an optional [Unix.file_descr] descriptor
+ for the stderr of the process; if not specified, [stderr] is
+ used
+
+ If any descriptor is specified, it is automatically closed at the
+ end of the execution of the command for which it was specified.
+
+ [echo_cmd] specifies whether output the full command on verbose
+ mode, and it's on by default. *)
+
+val run_command : ?echo_cmd:bool -> ?stdout_chan:Unix.file_descr -> ?stderr_chan:Unix.file_descr -> string list -> int
(** Run an external command without using a shell, and return its exit code.
[echo_cmd] specifies whether output the full command on verbose
diff --git a/mllib/common_utils_tests.ml b/mllib/common_utils_tests.ml
index aacc01e..4c9f53f 100644
--- a/mllib/common_utils_tests.ml
+++ b/mllib/common_utils_tests.ml
@@ -26,6 +26,7 @@ let assert_equal_string = assert_equal ~printer:(fun x -> x)
let assert_equal_int = assert_equal ~printer:(fun x -> string_of_int x)
let assert_equal_int64 = assert_equal ~printer:(fun x -> Int64.to_string x)
let assert_equal_stringlist = assert_equal ~printer:(fun x -> "(" ^ (String.escaped (String.concat "," x)) ^ ")")
+let assert_equal_intlist = assert_equal ~printer:(fun x -> "(" ^ (String.concat ";" (List.map string_of_int x)) ^ ")")
let test_subdirectory ctx =
assert_equal_string "" (subdirectory "/foo" "/foo");
@@ -131,6 +132,73 @@ let test_string_lines_split ctx =
assert_equal_stringlist ["A\nB"; ""] (String.lines_split "A\\\nB\n");
assert_equal_stringlist ["A\nB\n"] (String.lines_split "A\\\nB\\\n")
+(* Test Common_utils.run_command. *)
+let test_run_command ctx =
+ assert_equal_int 0 (run_command ["true"]);
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_command ["echo"; "this is a test"] ~stdout_chan:(Unix.descr_of_out_channel chan) in
+ assert_equal_int 0 res;
+ let content = read_whole_file tmpfile in
+ assert_equal_string "this is a test\n" content
+ end;
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_command ["ls"; "/this-directory-is-unlikely-to-exist"] ~stderr_chan:(Unix.descr_of_out_channel chan) in
+ assert_equal_int 2 res;
+ let content = read_whole_file tmpfile in
+ assert_bool "test_run_commands/not-existing/content" (String.length content > 0)
+ end;
+ ()
+
+(* Test Common_utils.run_commands. *)
+let test_run_commands ctx =
+ begin
+ let res = run_commands [] in
+ assert_equal_intlist [] res
+ end;
+ begin
+ let res = run_commands [(["true"], None, None)] in
+ assert_equal_intlist [0] res
+ end;
+ begin
+ let res = run_commands [(["true"], None, None); (["false"], None, None)] in
+ assert_equal_intlist [0; 1] res
+ end;
+ begin
+ let res = run_commands [(["this-command-does-not-really-exist"], None, None)] in
+ assert_equal_intlist [127] res
+ end;
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_commands [(["echo"; "this is a test"], Some (Unix.descr_of_out_channel chan), None)] in
+ assert_equal_intlist [0] res;
+ let content = read_whole_file tmpfile in
+ assert_equal_string "this is a test\n" content
+ end;
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_commands [(["ls"; "/this-directory-is-unlikely-to-exist"], None, Some (Unix.descr_of_out_channel chan))] in
+ assert_equal_intlist [2] res;
+ let content = read_whole_file tmpfile in
+ assert_bool "test_run_commands/not-existing/content" (String.length content > 0)
+ end;
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_commands [(["echo"; "this is a test"], Some (Unix.descr_of_out_channel chan), None); (["false"], None, None)] in
+ assert_equal_intlist [0; 1] res;
+ let content = read_whole_file tmpfile in
+ assert_equal_string "this is a test\n" content
+ end;
+ begin
+ let tmpfile, chan = bracket_tmpfile ctx in
+ let res = run_commands [(["this-command-does-not-really-exist"], None, None); (["echo"; "this is a test"], Some (Unix.descr_of_out_channel chan), None)] in
+ assert_equal_intlist [127; 0] res;
+ let content = read_whole_file tmpfile in
+ assert_equal_string "this is a test\n" content
+ end;
+ ()
+
(* Suites declaration. *)
let suite =
"mllib Common_utils" >:::
@@ -143,6 +211,8 @@ let suite =
"strings.is_suffix" >:: test_string_is_suffix;
"strings.find" >:: test_string_find;
"strings.lines_split" >:: test_string_lines_split;
+ "run_command" >:: test_run_command;
+ "run_commands" >:: test_run_commands;
]
let () =
--
2.9.4
7 years, 4 months
[PATCH] inspection: Deprecate APIs and remove support for inspecting installer CDs.
by Richard W.M. Jones
This just duplicated libosinfo information, and because it was never
tested it didn't work most of the time.
---
docs/C_SOURCE_FILES | 2 -
generator/actions_inspection.ml | 67 ---
generator/actions_inspection_deprecated.ml | 61 +++
inspector/Makefile.am | 11 +-
inspector/example-debian-netinst-cd.xml | 23 -
inspector/example-debian.xml | 1 -
inspector/example-fedora-dvd.xml | 23 -
inspector/example-fedora-netinst-cd.xml | 21 -
inspector/example-fedora.xml | 1 -
inspector/example-rhel-6-dvd.xml | 23 -
inspector/example-rhel-6-netinst-cd.xml | 21 -
inspector/example-rhel-6.xml | 1 -
inspector/example-ubuntu-live-cd.xml | 23 -
inspector/example-ubuntu.xml | 1 -
inspector/example-windows-2003-x64-cd.xml | 24 --
inspector/example-windows-2003-x86-cd.xml | 24 --
inspector/example-windows-xp-cd.xml | 24 --
inspector/example-windows.xml | 1 -
inspector/expected-archlinux.img.xml | 1 -
inspector/expected-coreos.img.xml | 1 -
inspector/expected-debian.img.xml | 1 -
inspector/expected-fedora.img.xml | 1 -
inspector/expected-ubuntu.img.xml | 1 -
inspector/expected-windows.img.xml | 1 -
inspector/inspector.c | 31 +-
inspector/virt-inspector.pod | 22 -
inspector/virt-inspector.rng | 15 -
lib/Makefile.am | 3 -
lib/guestfs-internal.h | 31 --
lib/guestfs.pod | 9 -
lib/inspect-fs-cd.c | 606 --------------------------
lib/inspect-fs.c | 40 --
lib/osinfo.c | 655 -----------------------------
33 files changed, 63 insertions(+), 1707 deletions(-)
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index 15abec124..dc8c052dd 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -296,7 +296,6 @@ lib/guid.c
lib/handle.c
lib/info.c
lib/inspect-apps.c
-lib/inspect-fs-cd.c
lib/inspect-fs-unix.c
lib/inspect-fs-windows.c
lib/inspect-fs.c
@@ -315,7 +314,6 @@ lib/listfs.c
lib/lpj.c
lib/match.c
lib/mountable.c
-lib/osinfo.c
lib/private-data.c
lib/proto.c
lib/qemu.c
diff --git a/generator/actions_inspection.ml b/generator/actions_inspection.ml
index b7ea5a4de..cd8b9da18 100644
--- a/generator/actions_inspection.ml
+++ b/generator/actions_inspection.ml
@@ -566,73 +566,6 @@ string C<unknown> is returned.
Please read L<guestfs(3)/INSPECTION> for more details." };
{ defaults with
- name = "inspect_get_format"; added = (1, 9, 4);
- style = RString (RPlainString, "format"), [String (Mountable, "root")], [];
- shortdesc = "get format of inspected operating system";
- longdesc = "\
-This returns the format of the inspected operating system. You
-can use it to detect install images, live CDs and similar.
-
-Currently defined formats are:
-
-=over 4
-
-=item \"installed\"
-
-This is an installed operating system.
-
-=item \"installer\"
-
-The disk image being inspected is not an installed operating system,
-but a I<bootable> install disk, live CD, or similar.
-
-=item \"unknown\"
-
-The format of this disk image is not known.
-
-=back
-
-Future versions of libguestfs may return other strings here.
-The caller should be prepared to handle any string.
-
-Please read L<guestfs(3)/INSPECTION> for more details." };
-
- { defaults with
- name = "inspect_is_live"; added = (1, 9, 4);
- style = RBool "live", [String (Mountable, "root")], [];
- shortdesc = "get live flag for install disk";
- longdesc = "\
-If C<guestfs_inspect_get_format> returns C<installer> (this
-is an install disk), then this returns true if a live image
-was detected on the disk.
-
-Please read L<guestfs(3)/INSPECTION> for more details." };
-
- { defaults with
- name = "inspect_is_netinst"; added = (1, 9, 4);
- style = RBool "netinst", [String (Mountable, "root")], [];
- shortdesc = "get netinst (network installer) flag for install disk";
- longdesc = "\
-If C<guestfs_inspect_get_format> returns C<installer> (this
-is an install disk), then this returns true if the disk is
-a network installer, ie. not a self-contained install CD but
-one which is likely to require network access to complete
-the install.
-
-Please read L<guestfs(3)/INSPECTION> for more details." };
-
- { defaults with
- name = "inspect_is_multipart"; added = (1, 9, 4);
- style = RBool "multipart", [String (Mountable, "root")], [];
- shortdesc = "get multipart flag for install disk";
- longdesc = "\
-If C<guestfs_inspect_get_format> returns C<installer> (this
-is an install disk), then this returns true if the disk is
-part of a set.
-
-Please read L<guestfs(3)/INSPECTION> for more details." };
-
- { defaults with
name = "inspect_get_product_variant"; added = (1, 9, 13);
style = RString (RPlainString, "variant"), [String (Mountable, "root")], [];
shortdesc = "get product variant of inspected operating system";
diff --git a/generator/actions_inspection_deprecated.ml b/generator/actions_inspection_deprecated.ml
index 342b0c8cd..7c34cb1a8 100644
--- a/generator/actions_inspection_deprecated.ml
+++ b/generator/actions_inspection_deprecated.ml
@@ -121,4 +121,65 @@ If unavailable this is returned as an empty string C<\"\">.
Please read L<guestfs(3)/INSPECTION> for more details." };
+ { defaults with
+ name = "inspect_get_format"; added = (1, 9, 4);
+ style = RString (RPlainString, "format"), [String (Mountable, "root")], [];
+ deprecated_by = Deprecated_no_replacement;
+ shortdesc = "get format of inspected operating system";
+ longdesc = "\
+Before libguestfs 1.38, there was some unreliable support for detecting
+installer CDs. This API would return:
+
+=over 4
+
+=item \"installed\"
+
+This is an installed operating system.
+
+=item \"installer\"
+
+The disk image being inspected is not an installed operating system,
+but a I<bootable> install disk, live CD, or similar.
+
+=item \"unknown\"
+
+The format of this disk image is not known.
+
+=back
+
+In libguestfs E<ge> 1.38, this only returns C<installed>.
+Use libosinfo directly to detect installer CDs.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+ { defaults with
+ name = "inspect_is_live"; added = (1, 9, 4);
+ style = RBool "live", [String (Mountable, "root")], [];
+ deprecated_by = Deprecated_no_replacement;
+ shortdesc = "get live flag for install disk";
+ longdesc = "\
+This is deprecated and always returns C<false>.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+ { defaults with
+ name = "inspect_is_netinst"; added = (1, 9, 4);
+ style = RBool "netinst", [String (Mountable, "root")], [];
+ deprecated_by = Deprecated_no_replacement;
+ shortdesc = "get netinst (network installer) flag for install disk";
+ longdesc = "\
+This is deprecated and always returns C<false>.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+ { defaults with
+ name = "inspect_is_multipart"; added = (1, 9, 4);
+ style = RBool "multipart", [String (Mountable, "root")], [];
+ deprecated_by = Deprecated_no_replacement;
+ shortdesc = "get multipart flag for install disk";
+ longdesc = "\
+This is deprecated and always returns C<false>.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
]
diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 753e2c93c..92c4e5e50 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -22,16 +22,7 @@ example_xml = \
example-fedora.xml \
example-rhel-6.xml \
example-ubuntu.xml \
- example-windows.xml \
- example-debian-netinst-cd.xml \
- example-fedora-dvd.xml \
- example-fedora-netinst-cd.xml \
- example-rhel-6-dvd.xml \
- example-rhel-6-netinst-cd.xml \
- example-ubuntu-live-cd.xml \
- example-windows-2003-x64-cd.xml \
- example-windows-2003-x86-cd.xml \
- example-windows-xp-cd.xml
+ example-windows.xml
EXTRA_DIST = \
expected-debian.img.xml \
diff --git a/inspector/example-debian-netinst-cd.xml b/inspector/example-debian-netinst-cd.xml
deleted file mode 100644
index 570a5bd66..000000000
--- a/inspector/example-debian-netinst-cd.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <distro>debian</distro>
- <product_name>Debian GNU/Linux 5.0.5 "Lenny" - Official amd64 NETINST Binary-1 20100627-10:37</product_name>
- <major_version>5</major_version>
- <minor_version>0</minor_version>
- <format>installer</format>
- <netinst/>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>Debian 5.0.5 amd64 Bin-1</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-debian.xml b/inspector/example-debian.xml
index eb10d8567..22f391d80 100644
--- a/inspector/example-debian.xml
+++ b/inspector/example-debian.xml
@@ -11,7 +11,6 @@
<package_format>deb</package_format>
<package_management>apt</package_management>
<hostname>debian5x64.home.annexia.org</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/debian5x64.home.annexia.org/root">/</mountpoint>
<mountpoint dev="/dev/debian5x64.home.annexia.org/tmp">/tmp</mountpoint>
diff --git a/inspector/example-fedora-dvd.xml b/inspector/example-fedora-dvd.xml
deleted file mode 100644
index 16a04baa5..000000000
--- a/inspector/example-fedora-dvd.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <arch>x86_64</arch>
- <distro>fedora</distro>
- <major_version>14</major_version>
- <minor_version>0</minor_version>
- <format>installer</format>
- <multipart/>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>Fedora 14 x86_64 DVD</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-fedora-netinst-cd.xml b/inspector/example-fedora-netinst-cd.xml
deleted file mode 100644
index 654fabbe3..000000000
--- a/inspector/example-fedora-netinst-cd.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <distro>fedora</distro>
- <major_version>14</major_version>
- <minor_version>0</minor_version>
- <format>installer</format>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>Fedora</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-fedora.xml b/inspector/example-fedora.xml
index ca8f56b58..32c88adc5 100644
--- a/inspector/example-fedora.xml
+++ b/inspector/example-fedora.xml
@@ -11,7 +11,6 @@
<package_format>rpm</package_format>
<package_management>yum</package_management>
<hostname>f18x64homeannexiaorg</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/fedora/root">/</mountpoint>
<mountpoint dev="/dev/sda1">/boot</mountpoint>
diff --git a/inspector/example-rhel-6-dvd.xml b/inspector/example-rhel-6-dvd.xml
deleted file mode 100644
index 4004d5a73..000000000
--- a/inspector/example-rhel-6-dvd.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <arch>x86_64</arch>
- <distro>rhel</distro>
- <major_version>6</major_version>
- <minor_version>0</minor_version>
- <format>installer</format>
- <multipart/>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>RHEL_6.0 x86_64 Disc 1</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-rhel-6-netinst-cd.xml b/inspector/example-rhel-6-netinst-cd.xml
deleted file mode 100644
index bcdeebe53..000000000
--- a/inspector/example-rhel-6-netinst-cd.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <distro>rhel</distro>
- <major_version>6</major_version>
- <minor_version>0</minor_version>
- <format>installer</format>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>RHEL_6.0 x86_64 boot</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-rhel-6.xml b/inspector/example-rhel-6.xml
index 0d338cef6..f11402a0c 100644
--- a/inspector/example-rhel-6.xml
+++ b/inspector/example-rhel-6.xml
@@ -11,7 +11,6 @@
<package_format>rpm</package_format>
<package_management>yum</package_management>
<hostname>rhel6x32.home.annexia.org</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/vg_rhel6x32/lv_root">/</mountpoint>
<mountpoint dev="/dev/sda1">/boot</mountpoint>
diff --git a/inspector/example-ubuntu-live-cd.xml b/inspector/example-ubuntu-live-cd.xml
deleted file mode 100644
index ff5a1cedb..000000000
--- a/inspector/example-ubuntu-live-cd.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <distro>ubuntu</distro>
- <product_name>Ubuntu 10.10 "Maverick Meerkat" - Release amd64 (20101007)</product_name>
- <major_version>10</major_version>
- <minor_version>10</minor_version>
- <format>installer</format>
- <live/>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>Ubuntu 10.10 amd64</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-ubuntu.xml b/inspector/example-ubuntu.xml
index 0519d3403..a1f78ea78 100644
--- a/inspector/example-ubuntu.xml
+++ b/inspector/example-ubuntu.xml
@@ -11,7 +11,6 @@
<package_format>deb</package_format>
<package_management>apt</package_management>
<hostname>ubuntu1304.home.annexia.org</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda1">/</mountpoint>
</mountpoints>
diff --git a/inspector/example-windows-2003-x64-cd.xml b/inspector/example-windows-2003-x64-cd.xml
deleted file mode 100644
index e74dcf457..000000000
--- a/inspector/example-windows-2003-x64-cd.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>windows</name>
- <arch>x86_64</arch>
- <distro>windows</distro>
- <product_name>Windows Server 2003 Enterprise x64 Edition</product_name>
- <major_version>5</major_version>
- <minor_version>2</minor_version>
- <windows_systemroot>\WINDOWS</windows_systemroot>
- <format>installer</format>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>CRMEXFPP_EN</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-windows-2003-x86-cd.xml b/inspector/example-windows-2003-x86-cd.xml
deleted file mode 100644
index d46859273..000000000
--- a/inspector/example-windows-2003-x86-cd.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>windows</name>
- <arch>i386</arch>
- <distro>windows</distro>
- <product_name>Windows Server 2003, Enterprise</product_name>
- <major_version>5</major_version>
- <minor_version>2</minor_version>
- <windows_systemroot>\WINDOWS</windows_systemroot>
- <format>installer</format>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>CRMEFPP_EN</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-windows-xp-cd.xml b/inspector/example-windows-xp-cd.xml
deleted file mode 100644
index 57ea235fb..000000000
--- a/inspector/example-windows-xp-cd.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0"?>
-<operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>windows</name>
- <arch>i386</arch>
- <distro>windows</distro>
- <product_name>Windows XP Professional</product_name>
- <major_version>5</major_version>
- <minor_version>1</minor_version>
- <windows_systemroot>\WINDOWS</windows_systemroot>
- <format>installer</format>
- <mountpoints>
- <mountpoint dev="/dev/sda">/</mountpoint>
- </mountpoints>
- <filesystems>
- <filesystem dev="/dev/sda">
- <type>iso9660</type>
- <label>GRTMPFPP_EN</label>
- </filesystem>
- </filesystems>
- <applications/>
- </operatingsystem>
-</operatingsystems>
diff --git a/inspector/example-windows.xml b/inspector/example-windows.xml
index 776026a76..f269affaf 100644
--- a/inspector/example-windows.xml
+++ b/inspector/example-windows.xml
@@ -12,7 +12,6 @@
<windows_systemroot>/Windows</windows_systemroot>
<windows_current_control_set>ControlSet001</windows_current_control_set>
<hostname>WIN-6AOV5N85H2F</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda2">/</mountpoint>
</mountpoints>
diff --git a/inspector/expected-archlinux.img.xml b/inspector/expected-archlinux.img.xml
index 665ac30da..b6c3b9c92 100644
--- a/inspector/expected-archlinux.img.xml
+++ b/inspector/expected-archlinux.img.xml
@@ -10,7 +10,6 @@
<package_format>pacman</package_format>
<package_management>pacman</package_management>
<hostname>archlinux.test</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda1">/</mountpoint>
</mountpoints>
diff --git a/inspector/expected-coreos.img.xml b/inspector/expected-coreos.img.xml
index c819a0521..e4a5d1134 100644
--- a/inspector/expected-coreos.img.xml
+++ b/inspector/expected-coreos.img.xml
@@ -8,7 +8,6 @@
<major_version>899</major_version>
<minor_version>13</minor_version>
<hostname>coreos.invalid</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda5">/</mountpoint>
<mountpoint dev="/dev/sda3">/usr</mountpoint>
diff --git a/inspector/expected-debian.img.xml b/inspector/expected-debian.img.xml
index 6f1d9dfa0..37ecfa049 100644
--- a/inspector/expected-debian.img.xml
+++ b/inspector/expected-debian.img.xml
@@ -11,7 +11,6 @@
<package_format>deb</package_format>
<package_management>apt</package_management>
<hostname>debian.invalid</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/debian/root">/</mountpoint>
<mountpoint dev="/dev/debian/usr">/usr</mountpoint>
diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml
index 5b6f1af6e..8d40e8cb7 100644
--- a/inspector/expected-fedora.img.xml
+++ b/inspector/expected-fedora.img.xml
@@ -11,7 +11,6 @@
<package_format>rpm</package_format>
<package_management>yum</package_management>
<hostname>fedora.invalid</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/VG/Root">/</mountpoint>
<mountpoint dev="/dev/sda1">/boot</mountpoint>
diff --git a/inspector/expected-ubuntu.img.xml b/inspector/expected-ubuntu.img.xml
index ff9d62226..c19c14cd5 100644
--- a/inspector/expected-ubuntu.img.xml
+++ b/inspector/expected-ubuntu.img.xml
@@ -11,7 +11,6 @@
<package_format>deb</package_format>
<package_management>apt</package_management>
<hostname>ubuntu.invalid</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda2">/</mountpoint>
<mountpoint dev="/dev/sda1">/boot</mountpoint>
diff --git a/inspector/expected-windows.img.xml b/inspector/expected-windows.img.xml
index ff787f188..26aab3261 100644
--- a/inspector/expected-windows.img.xml
+++ b/inspector/expected-windows.img.xml
@@ -12,7 +12,6 @@
<windows_systemroot>/Windows</windows_systemroot>
<windows_current_control_set>ControlSet001</windows_current_control_set>
<hostname>windows.invalid</hostname>
- <format>installed</format>
<mountpoints>
<mountpoint dev="/dev/sda2">/</mountpoint>
</mountpoints>
diff --git a/inspector/inspector.c b/inspector/inspector.c
index b00c85208..8c531871e 100644
--- a/inspector/inspector.c
+++ b/inspector/inspector.c
@@ -342,7 +342,7 @@ static void
output_root (xmlTextWriterPtr xo, char *root)
{
char *str;
- int i, r;
+ int i;
char buf[32];
char *canonical_root;
size_t size;
@@ -442,35 +442,6 @@ output_root (xmlTextWriterPtr xo, char *root)
BAD_CAST str));
free (str);
- str = guestfs_inspect_get_format (g, root);
- if (!str) exit (EXIT_FAILURE);
- if (STRNEQ (str, "unknown"))
- XMLERROR (-1,
- xmlTextWriterWriteElement (xo, BAD_CAST "format",
- BAD_CAST str));
- free (str);
-
- r = guestfs_inspect_is_live (g, root);
- if (r > 0) {
- XMLERROR (-1,
- xmlTextWriterStartElement (xo, BAD_CAST "live"));
- XMLERROR (-1, xmlTextWriterEndElement (xo));
- }
-
- r = guestfs_inspect_is_netinst (g, root);
- if (r > 0) {
- XMLERROR (-1,
- xmlTextWriterStartElement (xo, BAD_CAST "netinst"));
- XMLERROR (-1, xmlTextWriterEndElement (xo));
- }
-
- r = guestfs_inspect_is_multipart (g, root);
- if (r > 0) {
- XMLERROR (-1,
- xmlTextWriterStartElement (xo, BAD_CAST "multipart"));
- XMLERROR (-1, xmlTextWriterEndElement (xo));
- }
-
output_mountpoints (xo, root);
output_filesystems (xo, root);
diff --git a/inspector/virt-inspector.pod b/inspector/virt-inspector.pod
index 9d6fbda7c..1cea542c7 100644
--- a/inspector/virt-inspector.pod
+++ b/inspector/virt-inspector.pod
@@ -202,7 +202,6 @@ describe the operating system, its architecture, the descriptive
<major_version>6</major_version>
<minor_version>1</minor_version>
<windows_systemroot>/Windows</windows_systemroot>
- <format>installed</format>
In brief, E<lt>nameE<gt> is the class of operating system (something
like C<linux> or C<windows>), E<lt>distroE<gt> is the distribution
@@ -330,27 +329,6 @@ the conversion back to a PNG file:
base64 -i -d < icon.data > icon.png
-=head2 INSPECTING INSTALL DISKS, LIVE CDs
-
-Virt-inspector can detect some operating system installers on
-install disks, live CDs, bootable USB keys and more.
-
-In this case the E<lt>formatE<gt> tag will contain C<installer>
-and other fields may be present to indicate a live CD, network
-installer, or one part of a multipart CD. For example:
-
- <operatingsystems>
- <operatingsystem>
- <root>/dev/sda</root>
- <name>linux</name>
- <arch>i386</arch>
- <distro>ubuntu</distro>
- <product_name>Ubuntu 10.10 "Maverick Meerkat"</product_name>
- <major_version>10</major_version>
- <minor_version>10</minor_version>
- <format>installer</format>
- <live/>
-
=head1 XPATH QUERIES
Virt-inspector includes built in support for running XPath queries.
diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng
index dff46c53f..857a02766 100644
--- a/inspector/virt-inspector.rng
+++ b/inspector/virt-inspector.rng
@@ -38,10 +38,6 @@
<optional><ref name="ospackageformat"/></optional>
<optional><ref name="ospackagemanagement"/></optional>
<optional><element name="hostname"><text/></element></optional>
- <optional><ref name="osformat"/></optional>
- <optional><element name="live"><empty/></element></optional>
- <optional><element name="netinst"><empty/></element></optional>
- <optional><element name="multipart"><empty/></element></optional>
<ref name="mountpoints"/>
<ref name="filesystems"/>
@@ -152,17 +148,6 @@
</element>
</define>
- <!-- the operating system format -->
- <define name="osformat">
- <element name="format">
- <choice>
- <value>installed</value>
- <value>installer</value>
- <!-- "unknown" is intentionally left out -->
- </choice>
- </element>
- </define>
-
<!-- how filesystems are mounted on mount points -->
<define name="mountpoints">
<element name="mountpoints">
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 360ce9c92..18a912d74 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -97,7 +97,6 @@ libguestfs_la_SOURCES = \
inspect.c \
inspect-apps.c \
inspect-fs.c \
- inspect-fs-cd.c \
inspect-fs-unix.c \
inspect-fs-windows.c \
inspect-icon.c \
@@ -113,7 +112,6 @@ libguestfs_la_SOURCES = \
lpj.c \
match.c \
mountable.c \
- osinfo.c \
private-data.c \
proto.c \
qemu.c \
@@ -134,7 +132,6 @@ libguestfs_la_SOURCES = \
libguestfs_la_CPPFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-DGUESTFS_PRIVATE=1 \
- -DLIBOSINFO_DB_PATH='"$(datadir)/libosinfo/db"' \
-I$(top_srcdir)/common/errnostring -I$(top_builddir)/common/errnostring \
-I$(top_srcdir)/common/protocol -I$(top_builddir)/common/protocol \
-I$(top_srcdir)/common/qemuopts -I$(top_builddir)/common/qemuopts \
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index ec70336e2..2c7767a43 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -890,10 +890,6 @@ extern char *guestfs_int_case_sensitive_path_silently (guestfs_h *g, const char
extern char * guestfs_int_get_windows_systemroot (guestfs_h *g);
extern int guestfs_int_check_windows_root (guestfs_h *g, struct inspect_fs *fs, char *windows_systemroot);
-/* inspect-fs-cd.c */
-extern int guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs);
-extern int guestfs_int_check_installer_iso (guestfs_h *g, struct inspect_fs *fs, const char *device);
-
/* dbdump.c */
typedef int (*guestfs_int_db_dump_callback) (guestfs_h *g, const unsigned char *key, size_t keylen, const unsigned char *value, size_t valuelen, void *opaque);
extern int guestfs_int_read_db_dump (guestfs_h *g, const char *dumpfile, void *opaque, guestfs_int_db_dump_callback callback);
@@ -911,33 +907,6 @@ extern void guestfs_int_free_fuse (guestfs_h *g);
extern virConnectPtr guestfs_int_open_libvirt_connection (guestfs_h *g, const char *uri, unsigned int flags);
#endif
-/* osinfo.c */
-struct osinfo {
- /* Data provided by libosinfo database. */
- enum inspect_os_type type;
- enum inspect_os_distro distro;
- char *product_name;
- int major_version;
- int minor_version;
- char *arch;
- int is_live_disk;
- bool is_installer;
-
-#if 0
- /* Not yet available in libosinfo database. */
- char *product_variant;
- int is_netinst_disk;
- int is_multipart_disk;
-#endif
-
- /* The regular expressions used to match ISOs. */
- pcre *re_system_id;
- pcre *re_volume_id;
- pcre *re_publisher_id;
- pcre *re_application_id;
-};
-extern int guestfs_int_osinfo_map (guestfs_h *g, const struct guestfs_isoinfo *isoinfo, const struct osinfo **osinfo_ret);
-
/* command.c */
struct command;
typedef void (*cmd_stdout_callback) (guestfs_h *g, void *data, const char *line, size_t len);
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
index f2a54a1fd..cd57cc337 100644
--- a/lib/guestfs.pod
+++ b/lib/guestfs.pod
@@ -939,20 +939,11 @@ documentation for that function for details).
Libguestfs (since 1.9.4) can detect some install disks, install
CDs, live CDs and more.
-Call L</guestfs_inspect_get_format> to return the format of the
-operating system, which currently can be C<installed> (a regular
-operating system) or C<installer> (some sort of install disk).
-
Further information is available about the operating system that can
be installed using the regular inspection APIs like
L</guestfs_inspect_get_product_name>,
L</guestfs_inspect_get_major_version> etc.
-Some additional information specific to installer disks is also
-available from the L</guestfs_inspect_is_live>,
-L</guestfs_inspect_is_netinst> and L</guestfs_inspect_is_multipart>
-calls.
-
=head2 SPECIAL CONSIDERATIONS FOR WINDOWS GUESTS
Libguestfs can mount NTFS partitions. It does this using the
diff --git a/lib/inspect-fs-cd.c b/lib/inspect-fs-cd.c
deleted file mode 100644
index 1cff5606b..000000000
--- a/lib/inspect-fs-cd.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/* libguestfs
- * Copyright (C) 2010-2012 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; 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 <string.h>
-#include <libintl.h>
-#include <inttypes.h>
-
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#endif
-
-#include "c-ctype.h"
-
-#include "guestfs.h"
-#include "guestfs-internal.h"
-
-/* Debian/Ubuntu install disks are easy ...
- *
- * These files are added by the debian-cd program, and it is worth
- * looking at the source code to determine exact values, in
- * particular '/usr/share/debian-cd/tools/start_new_disc'
- *
- * XXX Architecture? We could parse it out of the product name
- * string, but that seems quite hairy. We could look for the names
- * of packages. Also note that some Debian install disks are
- * multiarch.
- */
-static int
-check_debian_installer_root (guestfs_h *g, struct inspect_fs *fs)
-{
- fs->product_name = guestfs_int_first_line_of_file (g, "/.disk/info");
- if (!fs->product_name)
- return -1;
-
- fs->type = OS_TYPE_LINUX;
- if (STRPREFIX (fs->product_name, "Ubuntu"))
- fs->distro = OS_DISTRO_UBUNTU;
- else if (STRPREFIX (fs->product_name, "Debian"))
- fs->distro = OS_DISTRO_DEBIAN;
-
- (void) guestfs_int_parse_major_minor (g, fs);
-
- if (guestfs_is_file (g, "/.disk/cd_type") > 0) {
- CLEANUP_FREE char *cd_type =
- guestfs_int_first_line_of_file (g, "/.disk/cd_type");
- if (!cd_type)
- return -1;
-
- if (STRPREFIX (cd_type, "dvd/single") ||
- STRPREFIX (cd_type, "full_cd/single")) {
- fs->is_multipart_disk = 0;
- fs->is_netinst_disk = 0;
- }
- else if (STRPREFIX (cd_type, "dvd") ||
- STRPREFIX (cd_type, "full_cd")) {
- fs->is_multipart_disk = 1;
- fs->is_netinst_disk = 0;
- }
- else if (STRPREFIX (cd_type, "not_complete")) {
- fs->is_multipart_disk = 0;
- fs->is_netinst_disk = 1;
- }
- }
-
- return 0;
-}
-
-/* Take string which must look like "key = value" and find the value.
- * There may or may not be spaces before and after the equals sign.
- * This function is used by both check_fedora_installer_root and
- * check_w2k3_installer_root.
- */
-static const char *
-find_value (const char *kv)
-{
- const char *p;
-
- p = strchr (kv, '=');
- if (!p)
- abort ();
-
- do {
- ++p;
- } while (c_isspace (*p));
-
- return p;
-}
-
-/* RHEL 5 has a DVD.iso and several CD-sized -discX-ftp.iso alternatives.
- *
- * The DVD.iso contains:
- * /.treeinfo:
- * [general]
- * family = Red Hat Enterprise Linux Server
- * timestamp = 1328200566.61
- * totaldiscs = 1
- * version = 5.8
- * discnum = 1
- * packagedir = Server
- * arch = x86_64
- * [...]
- *
- * /.discinfo:
- * 1328205744.315196
- * Red Hat Enterprise Linux Server 5.8 # product name
- * x86_64 # arch
- * 1 # disk number
- * Server/base
- * Server/RPMS
- * Server/pixmaps
- *
- * The alternative CD-sized ISOs contain:
- *
- * disc1:
- * /.treeinfo:
- * [general]
- * family = Red Hat Enterprise Linux Server
- * timestamp = 1328200566.61
- * totaldiscs = 1
- * version = 5.8
- * discnum = 1
- * packagedir = Server
- * arch = x86_64
- * [...]
- *
- * /.discinfo:
- * 1328205744.315196
- * Red Hat Enterprise Linux Server 5.8 # product name
- * x86_64 # arch
- * 1 # disk number
- * Server/base
- * Server/RPMS
- * Server/pixmaps
- *
- * discN (N > 1):
- * /.discinfo:
- * 1328205744.315196
- * Red Hat Enterprise Linux Server 5.8 # product name
- * x86_64 # arch
- * 2 # disk number
- * Server/base
- * Server/RPMS
- * Server/pixmaps
- */
-
-/* Fedora CDs and DVD (not netinst). The /.treeinfo file contains
- * an initial section somewhat like this:
- *
- * [general]
- * version = 14
- * arch = x86_64
- * family = Fedora
- * variant = Fedora
- * discnum = 1
- * totaldiscs = 1
- */
-static int
-check_fedora_installer_root (guestfs_h *g, struct inspect_fs *fs)
-{
- char *str;
- const char *v;
- int r;
- int discnum = 0, totaldiscs = 0;
-
- fs->type = OS_TYPE_LINUX;
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^family = Fedora$", 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_FEDORA;
- free (str);
- }
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^family = Red Hat Enterprise Linux$",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_RHEL;
- free (str);
- }
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^family = Oracle Linux Server$",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_ORACLE_LINUX;
- free (str);
- }
-
- /* XXX should do major.minor before this */
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^version = [[:digit:]]+", 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- v = find_value (str);
- fs->version.v_major = guestfs_int_parse_unsigned_int_ignore_trailing (g, v);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^arch = [-_[:alnum:]]+$", 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- v = find_value (str);
- fs->arch = safe_strdup (g, v);
- free (str);
- }
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^discnum = [[:digit:]]+$", 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- v = find_value (str);
- discnum = guestfs_int_parse_unsigned_int (g, v);
- free (str);
- if (discnum == -1)
- return -1;
- }
-
- r = guestfs_int_first_egrep_of_file (g, "/.treeinfo",
- "^totaldiscs = [[:digit:]]+$", 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- v = find_value (str);
- totaldiscs = guestfs_int_parse_unsigned_int (g, v);
- free (str);
- if (totaldiscs == -1)
- return -1;
- }
-
- fs->is_multipart_disk = totaldiscs > 1;
- /* and what about discnum? */
-
- return 0;
-}
-
-/* Linux with /isolinux/isolinux.cfg.
- *
- * This file is not easily parsable so we have to do our best.
- * Look for the "menu title" line which contains:
- * menu title Welcome to Fedora 14! # since at least Fedora 10
- * menu title Welcome to Red Hat Enterprise Linux 6.0!
- * menu title Welcome to RHEL6.2-20111117.0-Workstation-x!
- */
-static int
-check_isolinux_installer_root (guestfs_h *g, struct inspect_fs *fs)
-{
- char *str;
- int r;
-
- fs->type = OS_TYPE_LINUX;
-
- r = guestfs_int_first_egrep_of_file (g, "/isolinux/isolinux.cfg",
- "^menu title Welcome to Fedora [[:digit:]]+",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_FEDORA;
- fs->version.v_major =
- guestfs_int_parse_unsigned_int_ignore_trailing (g, &str[29]);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- /* XXX parse major.minor */
- r = guestfs_int_first_egrep_of_file (g, "/isolinux/isolinux.cfg",
- "^menu title Welcome to Red Hat Enterprise Linux [[:digit:]]+",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_RHEL;
- fs->version.v_major =
- guestfs_int_parse_unsigned_int_ignore_trailing (g, &str[47]);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- /* XXX parse major.minor */
- r = guestfs_int_first_egrep_of_file (g, "/isolinux/isolinux.cfg",
- "^menu title Welcome to RHEL[[:digit:]]+",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_RHEL;
- fs->version.v_major =
- guestfs_int_parse_unsigned_int_ignore_trailing (g, &str[26]);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- /* XXX parse major.minor */
- r = guestfs_int_first_egrep_of_file (g, "/isolinux/isolinux.cfg",
- "^menu title Welcome to Oracle Linux Server [[:digit:]]+",
- 0, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- fs->distro = OS_DISTRO_ORACLE_LINUX;
- fs->version.v_major =
- guestfs_int_parse_unsigned_int_ignore_trailing (g, &str[42]);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- return 0;
-}
-
-/* Windows 2003 and similar versions.
- *
- * NB: txtsetup file contains Windows \r\n line endings, which guestfs_grep
- * does not remove. We have to remove them by hand here.
- */
-static void
-trim_cr (char *str)
-{
- const size_t n = strlen (str);
- if (n > 0 && str[n-1] == '\r')
- str[n-1] = '\0';
-}
-
-static void
-trim_quot (char *str)
-{
- const size_t n = strlen (str);
- if (n > 0 && str[n-1] == '"')
- str[n-1] = '\0';
-}
-
-static int
-check_w2k3_installer_root (guestfs_h *g, struct inspect_fs *fs,
- const char *txtsetup)
-{
- char *str;
- const char *v;
- int r;
-
- fs->type = OS_TYPE_WINDOWS;
- fs->distro = OS_DISTRO_WINDOWS;
-
- r = guestfs_int_first_egrep_of_file (g, txtsetup,
- "^productname[[:space:]]*=[[:space:]]*\"", 1, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- trim_cr (str);
- trim_quot (str);
- v = find_value (str);
- fs->product_name = safe_strdup (g, v+1);
- free (str);
- }
-
- r = guestfs_int_first_egrep_of_file (g, txtsetup,
- "^majorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
- 1, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- trim_cr (str);
- v = find_value (str);
- fs->version.v_major = guestfs_int_parse_unsigned_int_ignore_trailing (g, v);
- free (str);
- if (fs->version.v_major == -1)
- return -1;
- }
-
- r = guestfs_int_first_egrep_of_file (g, txtsetup,
- "^minorversion[[:space:]]*=[[:space:]]*[[:digit:]]+",
- 1, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- trim_cr (str);
- v = find_value (str);
- fs->version.v_minor = guestfs_int_parse_unsigned_int_ignore_trailing (g, v);
- free (str);
- if (fs->version.v_minor == -1)
- return -1;
- }
-
- /* This is the windows systemroot that would be chosen on
- * installation by default, although not necessarily the one that
- * the user will finally choose.
- */
- r = guestfs_int_first_egrep_of_file (g, txtsetup,
- "^defaultpath[[:space:]]*=[[:space:]]*",
- 1, &str);
- if (r == -1)
- return -1;
- if (r > 0) {
- trim_cr (str);
- v = find_value (str);
- fs->windows_systemroot = safe_strdup (g, v);
- free (str);
- }
-
- return 0;
-}
-
-/* Read the data from a product.id-like file.
- *
- * This is an old file, mostly used in Mandriva-based systems (still including
- * Mageia). A very minimal documentation for it is:
- * - https://wiki.mageia.org/en/Product_id
- * - http://wiki.mandriva.com/en/Product_id (old URL, defunct)
- */
-static int
-check_product_id_installer_root (guestfs_h *g, struct inspect_fs *fs,
- const char *filename)
-{
- CLEANUP_FREE char *line = NULL;
- const char *elem;
- char *saveptr;
-
- fs->type = OS_TYPE_LINUX;
-
- line = guestfs_int_first_line_of_file (g, filename);
- if (line == NULL)
- return -1;
-
- elem = strtok_r (line, ",", &saveptr);
- while (elem) {
- const char *equal = strchr (elem, '=');
- if (equal == NULL || equal == elem)
- return -1;
-
- const char *value = equal + 1;
-
- if (STRPREFIX (elem, "distribution=")) {
- if (STREQ (value, "Mageia"))
- fs->distro = OS_DISTRO_MAGEIA;
- } else if (STRPREFIX (elem, "version=")) {
- if (guestfs_int_version_from_x_y_or_x (g, &fs->version, value) == -1)
- return -1;
- } else if (STRPREFIX (elem, "arch=")) {
- fs->arch = safe_strdup (g, value);
- }
-
- elem = strtok_r (NULL, ",", &saveptr);
- }
-
- /* Not found. */
- return 0;
-}
-
-/* The currently mounted device is very likely to be an installer. */
-int
-guestfs_int_check_installer_root (guestfs_h *g, struct inspect_fs *fs)
-{
- CLEANUP_FREE_STRING_LIST char **paths = NULL;
-
- /* The presence of certain files indicates a live CD.
- *
- * XXX Fedora netinst contains a ~120MB squashfs called
- * /images/install.img. However this is not a live CD (unlike the
- * Fedora live CDs which contain the same, but larger file). We
- * need to unpack this and look inside to tell the difference.
- */
- if (guestfs_is_file (g, "/casper/filesystem.squashfs") > 0 ||
- guestfs_is_file (g, "/live/filesystem.squashfs") > 0 ||
- guestfs_is_file (g, "/mfsroot.gz") > 0)
- fs->is_live_disk = 1;
-
- /* Debian/Ubuntu. */
- if (guestfs_is_file (g, "/.disk/info") > 0) {
- if (check_debian_installer_root (g, fs) == -1)
- return -1;
- }
-
- /* Fedora CDs and DVD (not netinst). */
- else if (guestfs_is_file (g, "/.treeinfo") > 0) {
- if (check_fedora_installer_root (g, fs) == -1)
- return -1;
- }
-
- /* FreeDOS install CD. */
- else if (guestfs_is_file (g, "/freedos/freedos.ico") > 0 &&
- guestfs_is_file (g, "/setup.bat") > 0) {
- fs->type = OS_TYPE_DOS;
- fs->distro = OS_DISTRO_FREEDOS;
- fs->arch = safe_strdup (g, "i386");
- }
-
- /* Linux with /isolinux/isolinux.cfg (note that non-Linux can use
- * ISOLINUX too, eg. FreeDOS).
- */
- else if (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0) {
- if (check_isolinux_installer_root (g, fs) == -1)
- return -1;
- }
-
- /* FreeBSD with /boot/loader.rc. */
- else if (guestfs_is_file (g, "/boot/loader.rc") > 0) {
- fs->type = OS_TYPE_FREEBSD;
- }
-
- /* Windows 2003 64 bit */
- else if (guestfs_is_file (g, "/amd64/txtsetup.sif") > 0) {
- fs->arch = safe_strdup (g, "x86_64");
- if (check_w2k3_installer_root (g, fs, "/amd64/txtsetup.sif") == -1)
- return -1;
- }
-
- /* Windows 2003 32 bit */
- else if (guestfs_is_file (g, "/i386/txtsetup.sif") > 0) {
- fs->arch = safe_strdup (g, "i386");
- if (check_w2k3_installer_root (g, fs, "/i386/txtsetup.sif") == -1)
- return -1;
- }
-
- /* Linux with /{i586,x86_64,etc}/product.id (typically found in Mandriva
- * and Mageia). Usually there should be just one around, so we use the
- * first one found.
- */
- paths = guestfs_glob_expand (g, "/*/product.id");
- if (paths == NULL)
- return -1;
- if (paths[0] != NULL) {
- if (check_product_id_installer_root (g, fs, paths[0]) == -1)
- return -1;
- }
-
- return 0;
-}
-
-/* This is called for whole block devices. See if the device is an
- * ISO and we are able to read the ISO info from it. In that case,
- * try using libosinfo to map from the volume ID and other strings
- * directly to the operating system type.
- */
-int
-guestfs_int_check_installer_iso (guestfs_h *g, struct inspect_fs *fs,
- const char *device)
-{
- CLEANUP_FREE_ISOINFO struct guestfs_isoinfo *isoinfo = NULL;
- const struct osinfo *osinfo;
- int r;
-
- guestfs_push_error_handler (g, NULL, NULL);
- isoinfo = guestfs_isoinfo_device (g, device);
- guestfs_pop_error_handler (g);
- if (!isoinfo)
- return 0;
-
- r = guestfs_int_osinfo_map (g, isoinfo, &osinfo);
- if (r == -1) /* Fatal error. */
- return -1;
- if (r == 0) /* Could not locate any matching ISO. */
- return 0;
-
- /* Otherwise we matched an ISO, so fill in the fs fields. */
- fs->mountable = safe_strdup (g, device);
- fs->role = OS_ROLE_ROOT;
- if (osinfo->is_installer)
- fs->format = OS_FORMAT_INSTALLER;
- fs->type = osinfo->type;
- fs->distro = osinfo->distro;
- fs->product_name =
- osinfo->product_name ? safe_strdup (g, osinfo->product_name) : NULL;
- guestfs_int_version_from_values (&fs->version, osinfo->major_version,
- osinfo->minor_version, 0);
- fs->arch = osinfo->arch ? safe_strdup (g, osinfo->arch) : NULL;
- fs->is_live_disk = osinfo->is_live_disk;
-
- guestfs_int_check_package_format (g, fs);
- guestfs_int_check_package_management (g, fs);
-
- return 1;
-}
diff --git a/lib/inspect-fs.c b/lib/inspect-fs.c
index 9f7630bcf..655b1fb8e 100644
--- a/lib/inspect-fs.c
+++ b/lib/inspect-fs.c
@@ -86,22 +86,6 @@ guestfs_int_check_for_filesystem_on (guestfs_h *g, const char *mountable)
}
}
- if (whole_device) {
- extend_fses (g);
- fs = &g->fses[g->nr_fses-1];
-
- r = guestfs_int_check_installer_iso (g, fs, m->im_device);
- if (r == -1) { /* Fatal error. */
- g->nr_fses--;
- return -1;
- }
- if (r > 0) /* Found something. */
- return 0;
-
- /* Didn't find anything. Fall through ... */
- g->nr_fses--;
- }
-
/* Try mounting the device. As above, ignore errors. */
guestfs_push_error_handler (g, NULL, NULL);
if (vfs_type && STREQ (vfs_type, "ufs")) { /* Hack for the *BSDs. */
@@ -289,30 +273,6 @@ check_filesystem (guestfs_h *g, const char *mountable,
*/
fs->arch = safe_strdup (g, "i386");
}
- /* Install CD/disk?
- *
- * Note that we checked (above) for an install ISO, but there are
- * other types of install image (eg. USB keys) which that check
- * wouldn't have picked up.
- *
- * Skip these checks if it's not a whole device (eg. CD) or the
- * first partition (eg. bootable USB key).
- */
- else if ((whole_device || (partnum == 1 && nr_partitions == 1)) &&
- (guestfs_is_file (g, "/isolinux/isolinux.cfg") > 0 ||
- guestfs_is_dir (g, "/EFI/BOOT") > 0 ||
- guestfs_is_file (g, "/images/install.img") > 0 ||
- guestfs_is_dir (g, "/.disk") > 0 ||
- guestfs_is_file (g, "/.discinfo") > 0 ||
- guestfs_is_file (g, "/i386/txtsetup.sif") > 0 ||
- guestfs_is_file (g, "/amd64/txtsetup.sif") > 0 ||
- guestfs_is_file (g, "/freedos/freedos.ico") > 0 ||
- guestfs_is_file (g, "/boot/loader.rc") > 0)) {
- fs->role = OS_ROLE_ROOT;
- fs->format = OS_FORMAT_INSTALLER;
- if (guestfs_int_check_installer_root (g, fs) == -1)
- return -1;
- }
/* The above code should have set fs->type and fs->distro fields, so
* we can now guess the package management system.
diff --git a/lib/osinfo.c b/lib/osinfo.c
deleted file mode 100644
index ea2a7659a..000000000
--- a/lib/osinfo.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/* libguestfs
- * Copyright (C) 2012 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Read libosinfo XML files to parse out just the
- * os/media/iso/system-id and os/media/iso/volume-id fields, which we
- * can then use to map install media to operating systems.
- *
- * Note some assumptions here:
- *
- * (1) Ignore the libosinfo library itself, since we don't care
- * for GObject nonsense. The XML database contains all we need.
- *
- * (2) Ignore os/upgrades and os/derives-from fields. This is
- * safe(-ish) since the media identifiers always change for every
- * release of an OS. We can easily add support for this if it becomes
- * necessary.
- *
- * (3) We have to do some translation of the distro names and versions
- * stored in the libosinfo files and the standard names returned by
- * libguestfs.
- *
- * (4) Media detection is only part of the story. We may still need
- * to inspect inside the image.
- *
- * (5) We only read the XML database files (at most) once per process,
- * and keep them cached. They are only read at all if someone tries
- * to inspect a CD/DVD/ISO.
- *
- * XXX Currently the database is not freed when the program exits /
- * library is unloaded, although we should probably do that.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <libintl.h>
-#include <sys/stat.h>
-
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-
-#include "ignore-value.h"
-#include "glthread/lock.h"
-#include "c-ctype.h"
-
-#include "guestfs.h"
-#include "guestfs-internal.h"
-
-gl_lock_define_initialized (static, osinfo_db_lock);
-static ssize_t osinfo_db_size = 0; /* 0 = unread, -1 = error, >= 1 = #records */
-static struct osinfo *osinfo_db = NULL;
-
-static int read_osinfo_db (guestfs_h *g);
-static void free_osinfo_db_entry (struct osinfo *);
-
-#define XMLSTREQ(a,b) (xmlStrEqual((a),(b)) == 1)
-
-/* Given one or more fields from the header of a CD/DVD/ISO, look up
- * the media in the libosinfo database and return our best guess for
- * the operating system.
- *
- * This returns:
- * -1 => a fatal error ('error' has been called, caller must not ignore it)
- * 0 => could not locate the OS
- * 1 => matching OS found, the osinfo_ret pointer has been filled in
- */
-int
-guestfs_int_osinfo_map (guestfs_h *g, const struct guestfs_isoinfo *isoinfo,
- const struct osinfo **osinfo_ret)
-{
- size_t i;
-
- /* We only need to lock the database when reading it for the first time. */
- gl_lock_lock (osinfo_db_lock);
- if (osinfo_db_size == 0) {
- if (read_osinfo_db (g) == -1) {
- gl_lock_unlock (osinfo_db_lock);
- return -1;
- }
- }
- gl_lock_unlock (osinfo_db_lock);
-
- if (osinfo_db_size <= 0)
- return 0;
-
- /* Look in the database to see if we can find a match. */
- for (i = 0; i < (size_t) osinfo_db_size; ++i) {
- if (osinfo_db[i].re_system_id) {
- if (!isoinfo->iso_system_id ||
- !match (g, isoinfo->iso_system_id, osinfo_db[i].re_system_id))
- continue;
- }
-
- if (osinfo_db[i].re_volume_id) {
- if (!isoinfo->iso_volume_id ||
- !match (g, isoinfo->iso_volume_id, osinfo_db[i].re_volume_id))
- continue;
- }
-
- if (osinfo_db[i].re_publisher_id) {
- if (!isoinfo->iso_publisher_id ||
- !match (g, isoinfo->iso_publisher_id, osinfo_db[i].re_publisher_id))
- continue;
- }
-
- if (osinfo_db[i].re_application_id) {
- if (!isoinfo->iso_application_id ||
- !match (g, isoinfo->iso_application_id, osinfo_db[i].re_application_id))
- continue;
- }
-
- debug (g, "osinfo: mapped disk to database entry %zu", i);
-
- if (osinfo_ret)
- *osinfo_ret = &osinfo_db[i];
- return 1;
- }
-
- debug (g, "osinfo: no mapping found");
-
- return 0;
-}
-
-/* Read the libosinfo XML database files. The lock is held while
- * this is called.
- *
- * Returns:
- * -1 => a fatal error ('error' has been called)
- * 0 => OK
- *
- * Note that failure to find or parse the XML files is *not* a fatal
- * error, since we should fall back silently if these are not
- * available. Although we'll emit some debug if this happens.
- *
- * Try to use the shared osinfo database layout (and location) first:
- * https://gitlab.com/libosinfo/libosinfo/blob/master/docs/database-layout.txt
- */
-static int read_osinfo_db_xml (guestfs_h *g, const char *filename);
-
-static int read_osinfo_db_flat (guestfs_h *g, const char *directory);
-static int read_osinfo_db_three_levels (guestfs_h *g, const char *directory);
-static int read_osinfo_db_directory (guestfs_h *g, const char *directory);
-
-static int
-read_osinfo_db (guestfs_h *g)
-{
- int r;
- size_t i;
-
- assert (osinfo_db_size == 0);
-
- /* (1) Try the shared osinfo directory, using either the
- * $OSINFO_SYSTEM_DIR envvar or its default value.
- */
- {
- const char *path;
- CLEANUP_FREE char *os_path = NULL;
-
- path = getenv ("OSINFO_SYSTEM_DIR");
- if (path == NULL)
- path = "/usr/share/osinfo";
- os_path = safe_asprintf (g, "%s/os", path);
- r = read_osinfo_db_three_levels (g, os_path);
- }
- if (r == -1)
- goto error;
- else if (r == 1)
- return 0;
-
- /* (2) Try the libosinfo directory, using the newer three-directory
- * layout ($LIBOSINFO_DB_PATH / "os" / $group-ID / [file.xml]).
- */
- r = read_osinfo_db_three_levels (g, LIBOSINFO_DB_PATH "/os");
- if (r == -1)
- goto error;
- else if (r == 1)
- return 0;
-
- /* (3) Try the libosinfo directory, using the old flat directory
- * layout ($LIBOSINFO_DB_PATH / "oses" / [file.xml]).
- */
- r = read_osinfo_db_flat (g, LIBOSINFO_DB_PATH "/oses");
- if (r == -1)
- goto error;
- else if (r == 1)
- return 0;
-
- /* Nothing found. */
- return 0;
-
- error:
- /* Fatal error: free any database entries which have been read, and
- * mark the database as having a permanent error.
- */
- if (osinfo_db_size > 0) {
- for (i = 0; i < (size_t) osinfo_db_size; ++i)
- free_osinfo_db_entry (&osinfo_db[i]);
- }
- free (osinfo_db);
- osinfo_db = NULL;
- osinfo_db_size = -1;
-
- return -1;
-}
-
-static int
-read_osinfo_db_flat (guestfs_h *g, const char *directory)
-{
- debug (g, "osinfo: loading flat database from %s", directory);
-
- return read_osinfo_db_directory (g, directory);
-}
-
-static int
-read_osinfo_db_three_levels (guestfs_h *g, const char *directory)
-{
- DIR *dir;
- int r;
-
- dir = opendir (directory);
- if (!dir) {
- debug (g, "osinfo: %s: %s", directory, strerror (errno));
- return 0; /* This is not an error: RHBZ#948324. */
- }
-
- debug (g, "osinfo: loading 3-level-directories database from %s", directory);
-
- for (;;) {
- struct dirent *d;
- CLEANUP_FREE char *pathname = NULL;
- struct stat sb;
-
- errno = 0;
- d = readdir (dir);
- if (!d) break;
-
- pathname = safe_asprintf (g, "%s/%s", directory, d->d_name);
-
- /* Iterate only on directories. */
- if (stat (pathname, &sb) == 0 && S_ISDIR (sb.st_mode)) {
- r = read_osinfo_db_directory (g, pathname);
- if (r == -1)
- goto error;
- }
- }
-
- /* Check for failure in readdir. */
- if (errno != 0) {
- perrorf (g, "readdir: %s", directory);
- goto error;
- }
-
- /* Close the directory handle. */
- r = closedir (dir);
- dir = NULL;
- if (r == -1) {
- perrorf (g, "closedir: %s", directory);
- goto error;
- }
-
- return 1;
-
- error:
- if (dir)
- closedir (dir);
-
- return -1;
-}
-
-static int
-read_osinfo_db_directory (guestfs_h *g, const char *directory)
-{
- DIR *dir;
- int r;
-
- dir = opendir (directory);
- if (!dir) {
- debug (g, "osinfo: %s: %s", directory, strerror (errno));
- return 0; /* This is not an error: RHBZ#948324. */
- }
-
- for (;;) {
- struct dirent *d;
-
- errno = 0;
- d = readdir (dir);
- if (!d) break;
-
- if (STRSUFFIX (d->d_name, ".xml")) {
- CLEANUP_FREE char *pathname = NULL;
-
- pathname = safe_asprintf (g, "%s/%s", directory, d->d_name);
- r = read_osinfo_db_xml (g, pathname);
- if (r == -1)
- goto error;
- }
- }
-
- /* Check for failure in readdir. */
- if (errno != 0) {
- perrorf (g, "readdir: %s", directory);
- goto error;
- }
-
- /* Close the directory handle. */
- r = closedir (dir);
- dir = NULL;
- if (r == -1) {
- perrorf (g, "closedir: %s", directory);
- goto error;
- }
-
- return 1;
-
- error:
- if (dir)
- closedir (dir);
-
- return -1;
-}
-
-static int read_iso_node (guestfs_h *g, xmlNodePtr iso_node, struct osinfo *osinfo);
-static int read_media_node (guestfs_h *g, xmlXPathContextPtr xpathCtx, xmlNodePtr media_node, struct osinfo *osinfo);
-static int read_os_node (guestfs_h *g, xmlXPathContextPtr xpathCtx, xmlNodePtr os_node, struct osinfo *osinfo);
-
-/* Read a single XML file from pathname (which is a full path).
- * Only memory allocation failures are fatal errors here.
- */
-static int
-read_osinfo_db_xml (guestfs_h *g, const char *pathname)
-{
- CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL;
- CLEANUP_XMLXPATHFREECONTEXT xmlXPathContextPtr xpathCtx = NULL;
- CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpathObj = NULL;
- xmlNodeSetPtr nodes;
- xmlNodePtr iso_node, media_node, os_node;
- struct osinfo *osinfo;
- size_t i;
-
- doc = xmlReadFile (pathname, NULL, XML_PARSE_NONET);
- if (doc == NULL) {
- debug (g, "osinfo: unable to parse XML file %s", pathname);
- return 0;
- }
-
- xpathCtx = xmlXPathNewContext (doc);
- if (xpathCtx == NULL) {
- error (g, _("osinfo: unable to create new XPath context"));
- return -1;
- }
-
- /* Get all <iso> nodes at any depth, then use the parent pointers in
- * order to work back up the tree.
- */
- xpathObj = xmlXPathEvalExpression (BAD_CAST "/libosinfo/os/media/iso",
- xpathCtx);
- if (xpathObj == NULL) {
- error (g, _("osinfo: %s: unable to evaluate XPath expression"),
- pathname);
- return -1;
- }
-
- nodes = xpathObj->nodesetval;
-
- if (nodes != NULL) {
- for (i = 0; i < (size_t) nodes->nodeNr; ++i) {
- iso_node = nodes->nodeTab[i];
- assert (iso_node != NULL);
- assert (STREQ ((const char *) iso_node->name, "iso"));
- assert (iso_node->type == XML_ELEMENT_NODE);
-
- media_node = iso_node->parent;
- assert (media_node != NULL);
- assert (STREQ ((const char *) media_node->name, "media"));
- assert (media_node->type == XML_ELEMENT_NODE);
-
- os_node = media_node->parent;
- assert (os_node != NULL);
- assert (STREQ ((const char *) os_node->name, "os"));
- assert (os_node->type == XML_ELEMENT_NODE);
-
- /* Allocate an osinfo record. */
- osinfo_db_size++;
- osinfo_db = safe_realloc (g, osinfo_db,
- sizeof (struct osinfo) * osinfo_db_size);
- osinfo = &osinfo_db[osinfo_db_size-1];
- memset (osinfo, 0, sizeof *osinfo);
-
- /* Read XML fields into the new osinfo record. */
- if (read_iso_node (g, iso_node, osinfo) == -1 ||
- read_media_node (g, xpathCtx, media_node, osinfo) == -1 ||
- read_os_node (g, xpathCtx, os_node, osinfo) == -1) {
- free_osinfo_db_entry (osinfo);
- osinfo_db_size--;
- return -1;
- }
-
-#if 0
- debug (g, "osinfo: %s: %s%s%s%s=> arch %s live %s installer %s product %s type %d distro %d version %d.%d",
- pathname,
- osinfo->re_system_id ? "<system-id/> " : "",
- osinfo->re_volume_id ? "<volume-id/> " : "",
- osinfo->re_publisher_id ? "<publisher-id/> " : "",
- osinfo->re_application_id ? "<application-id/> " : "",
- osinfo->arch ? osinfo->arch : "(none)",
- osinfo->is_live_disk ? "true" : "false",
- osinfo->is_installer ? "true" : "false",
- osinfo->product_name ? osinfo->product_name : "(none)",
- (int) osinfo->type, (int) osinfo->distro,
- osinfo->major_version, osinfo->minor_version);
-#endif
- }
- }
-
- return 0;
-}
-
-static int compile_re (guestfs_h *g, xmlNodePtr child, pcre **re);
-
-/* Read the regular expressions under the <iso> node. libosinfo
- * itself uses the glib function 'g_regex_match_simple'. That appears
- * to implement PCRE, however I have not checked in detail.
- */
-static int
-read_iso_node (guestfs_h *g, xmlNodePtr iso_node, struct osinfo *osinfo)
-{
- xmlNodePtr child;
-
- for (child = iso_node->children; child; child = child->next) {
- if (STREQ ((const char *) child->name, "system-id")) {
- if (compile_re (g, child, &osinfo->re_system_id) == -1)
- return -1;
- }
- else if (STREQ ((const char *) child->name, "volume-id")) {
- if (compile_re (g, child, &osinfo->re_volume_id) == -1)
- return -1;
- }
- else if (STREQ ((const char *) child->name, "publisher-id")) {
- if (compile_re (g, child, &osinfo->re_publisher_id) == -1)
- return -1;
- }
- else if (STREQ ((const char *) child->name, "application-id")) {
- if (compile_re (g, child, &osinfo->re_application_id) == -1)
- return -1;
- }
- }
-
- return 0;
-}
-
-static int
-compile_re (guestfs_h *g, xmlNodePtr node, pcre **re)
-{
- const char *err;
- int offset;
- CLEANUP_FREE char *content = (char *) xmlNodeGetContent (node);
-
- if (content) {
- *re = pcre_compile (content, 0, &err, &offset, NULL);
- if (*re == NULL)
- debug (g, "osinfo: could not parse regular expression '%s': %s (ignored)",
- content, err);
- }
-
- return 0;
-}
-
-/* Read the attributes of the <media/> node. */
-static int
-read_media_node (guestfs_h *g, xmlXPathContextPtr xpathCtx,
- xmlNodePtr media_node, struct osinfo *osinfo)
-{
- osinfo->arch = (char *) xmlGetProp (media_node, BAD_CAST "arch");
-
- osinfo->is_live_disk = 0; /* If no 'live' attr, defaults to false. */
- {
- CLEANUP_XMLFREE xmlChar *content = NULL;
- content = xmlGetProp (media_node, BAD_CAST "live");
- if (content)
- osinfo->is_live_disk = XMLSTREQ (content, BAD_CAST "true");
- }
-
- osinfo->is_installer = true; /* If no 'installer' attr, defaults to true. */
- {
- CLEANUP_XMLFREE xmlChar *content = NULL;
- content = xmlGetProp (media_node, BAD_CAST "installer");
- if (content)
- osinfo->is_installer = XMLSTREQ (content, BAD_CAST "true");
- }
-
- return 0;
-}
-
-static int parse_version (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo);
-static int parse_family (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo);
-static int parse_distro (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo);
-
-/* Read some fields under the <os/> node. */
-static int
-read_os_node (guestfs_h *g, xmlXPathContextPtr xpathCtx,
- xmlNodePtr os_node, struct osinfo *osinfo)
-{
- xmlNodePtr child;
-
- for (child = os_node->children; child; child = child->next) {
- if (STREQ ((const char *) child->name, "name"))
- osinfo->product_name = (char *) xmlNodeGetContent (child);
- else if (STREQ ((const char *) child->name, "version")) {
- if (parse_version (g, child, osinfo) == -1)
- return -1;
- }
- else if (STREQ ((const char *) child->name, "family")) {
- if (parse_family (g, child, osinfo) == -1)
- return -1;
- }
- else if (STREQ ((const char *) child->name, "distro")) {
- if (parse_distro (g, child, osinfo) == -1)
- return -1;
- }
- }
-
- return 0;
-}
-
-static int
-parse_version (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo)
-{
- CLEANUP_FREE char *content = NULL;
-
- content = (char *) xmlNodeGetContent (node);
- /* We parse either "X.Y" or "X" as version strings, so try to parse
- * only if the first character is a digit.
- */
- if (content && c_isdigit (content[0])) {
- struct version version;
- const int res = guestfs_int_version_from_x_y_or_x (g, &version, content);
- if (res < 0)
- return -1;
- else if (res > 0) {
- osinfo->major_version = version.v_major;
- osinfo->minor_version = version.v_minor;
- }
- }
-
- return 0;
-}
-
-static int
-parse_family (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo)
-{
- CLEANUP_FREE char *content = NULL;
-
- osinfo->type = OS_TYPE_UNKNOWN;
-
- content = (char *) xmlNodeGetContent (node);
- if (content) {
- if (STREQ (content, "linux"))
- osinfo->type = OS_TYPE_LINUX;
- else if (STRPREFIX (content, "win"))
- osinfo->type = OS_TYPE_WINDOWS;
- else if (STREQ (content, "freebsd"))
- osinfo->type = OS_TYPE_FREEBSD;
- else if (STREQ (content, "netbsd"))
- osinfo->type = OS_TYPE_NETBSD;
- else if (STREQ (content, "msdos"))
- osinfo->type = OS_TYPE_DOS;
- else if (STREQ (content, "openbsd"))
- osinfo->type = OS_TYPE_OPENBSD;
- else
- debug (g, "osinfo: warning: unknown <family> '%s'", content);
- }
-
- return 0;
-}
-
-static int
-parse_distro (guestfs_h *g, xmlNodePtr node, struct osinfo *osinfo)
-{
- CLEANUP_FREE char *content = NULL;
-
- osinfo->distro = OS_DISTRO_UNKNOWN;
-
- content = (char *) xmlNodeGetContent (node);
- if (content) {
- if (STREQ (content, "altlinux"))
- osinfo->distro = OS_DISTRO_ALTLINUX;
- else if (STREQ (content, "centos"))
- osinfo->distro = OS_DISTRO_CENTOS;
- else if (STREQ (content, "debian"))
- osinfo->distro = OS_DISTRO_DEBIAN;
- else if (STREQ (content, "fedora"))
- osinfo->distro = OS_DISTRO_FEDORA;
- else if (STREQ (content, "freebsd"))
- osinfo->distro = OS_DISTRO_FREEBSD;
- else if (STREQ (content, "mageia"))
- osinfo->distro = OS_DISTRO_MAGEIA;
- else if (STREQ (content, "mandriva"))
- osinfo->distro = OS_DISTRO_MANDRIVA;
- else if (STREQ (content, "netbsd"))
- osinfo->distro = OS_DISTRO_NETBSD;
- else if (STREQ (content, "openbsd"))
- osinfo->distro = OS_DISTRO_OPENBSD;
- else if (STREQ (content, "opensuse"))
- osinfo->distro = OS_DISTRO_OPENSUSE;
- else if (STREQ (content, "rhel"))
- osinfo->distro = OS_DISTRO_RHEL;
- else if (STREQ (content, "sled") || STREQ (content, "sles"))
- osinfo->distro = OS_DISTRO_SLES;
- else if (STREQ (content, "ubuntu"))
- osinfo->distro = OS_DISTRO_UBUNTU;
- else if (STRPREFIX (content, "win"))
- osinfo->distro = OS_DISTRO_WINDOWS;
- else
- debug (g, "osinfo: warning: unknown <distro> '%s'", content);
- }
-
- return 0;
-}
-
-static void
-free_osinfo_db_entry (struct osinfo *osinfo)
-{
- free (osinfo->product_name);
- free (osinfo->arch);
-
- if (osinfo->re_system_id)
- pcre_free (osinfo->re_system_id);
- if (osinfo->re_volume_id)
- pcre_free (osinfo->re_volume_id);
- if (osinfo->re_publisher_id)
- pcre_free (osinfo->re_publisher_id);
- if (osinfo->re_application_id)
- pcre_free (osinfo->re_application_id);
-}
--
2.13.0
7 years, 4 months