[PATCH v4 0/3] Install QEMU-GA from oVirt guest tools ISO on Linux
by Tomáš Golembiovský
changes in v4:
- fix call to install_local
changes in v2:
- moved copy_drivers above copy_files
- renamed copy_files to copy_from_virtio_win
- renamed install to install_local
- use rpm instead of yum
This installs packages with QEMU Guest Agent when converting Linux machine. The
packages should be available on guest tools ISO. The patches work "as-is" but
probably deserve some more attention:
- it is "abusing" Winows_virtio code but renaming/refactoring everything to
remove "windows" from the name and use "guest tools" seems like a lot of
unnecesary work
- support for Debian is missing
I don't know how to install the package only when all it's dependencies are
already installed. dpkg cannot be used to check that (simulate the install).
And attempting to install the package will leave it half-installed (dpkg
cannot roll-back).
Tomáš Golembiovský (3):
v2v: refactor copy_drivers() in Windows_virtio
v2v: linux: install packages
v2v: linux: install QEMU-GA (RHBZ#1619665)
v2v/convert_linux.ml | 2 ++
v2v/linux.ml | 14 ++++++++
v2v/linux.mli | 3 ++
v2v/windows_virtio.ml | 78 +++++++++++++++++++++++++++++++++---------
v2v/windows_virtio.mli | 4 +++
5 files changed, 84 insertions(+), 17 deletions(-)
--
2.19.1
6 years
[nbdkit PATCH] ocaml: Make build VPATH aware
by Eric Blake
The ocaml.opt compiler defaults to building things in the same
directory as its input; we need explicit -o options to build
in a VPATH $(builddir) when $(srcdir) is read-only (as is the
case during 'make distcheck'). We also have to build any side
effect files explicitly in cases where we can't directly use -o
to control those outputs alongside the final product.
Thanks: Richard W.M. Jones
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
I'm working on getting 'make distcheck' happy (in general, it
fails because we aren't set up for VPATH builds yet). I'm pushing
the small and obvious patches when I spot them, but for stuff
where I'm less certain, I'll post to the list as well. This is
what Rich helped me come up with on IRC for the ocaml failures.
plugins/ocaml/Makefile.am | 4 ++--
tests/Makefile.am | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/plugins/ocaml/Makefile.am b/plugins/ocaml/Makefile.am
index 484d041..b95f255 100644
--- a/plugins/ocaml/Makefile.am
+++ b/plugins/ocaml/Makefile.am
@@ -43,10 +43,10 @@ ocamllibdir = $(OCAMLLIB)
ocamllib_DATA = NBDKit.mli NBDKit.cmi NBDKit.cmx NBDKit.o
NBDKit.cmi: NBDKit.mli
- $(OCAMLC) -c $<
+ $(OCAMLC) -c $< -o $@
NBDKit.cmx: NBDKit.ml NBDKit.cmi
- $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $<
+ $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $< -o $@
NBDKit.o: NBDKit.cmx
# NB: libnbdkitocaml is not plugin. It's a library that you have to
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4e16fa9..94f3d43 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -517,7 +517,9 @@ test_ocaml_CFLAGS = \
test_ocaml_LDADD = libtest.la $(LIBGUESTFS_LIBS)
check_SCRIPTS += test-ocaml-plugin.so
-test-ocaml-plugin.so: test_ocaml_plugin.ml ../plugins/ocaml/libnbdkitocaml.la ../plugins/ocaml/NBDKit.cmi ../plugins/ocaml/NBDKit.cmx
+test_ocaml_plugin.cmx: test_ocaml_plugin.ml
+ $(OCAMLOPT) $(OCAMLOPTFLAGS) -I ../plugins/ocaml -c $< -o $@
+test-ocaml-plugin.so: test_ocaml_plugin.cmx ../plugins/ocaml/libnbdkitocaml.la ../plugins/ocaml/NBDKit.cmi ../plugins/ocaml/NBDKit.cmx
$(OCAMLOPT) $(OCAMLOPTFLAGS) -I ../plugins/ocaml \
-output-obj -runtime-variant _pic -o $@ \
NBDKit.cmx $< \
--
2.17.2
6 years
[nbdkit PATCH] connections: Implement NBD_OPT_INFO
by Eric Blake
qemu is about to add 'qemu-nbd --list', which exercises NBD_OPT_LIST
and NBD_OPT_INFO to give the user as much detail as possible about
an export without actually connecting to it. For that to display
more than the export name when nbdkit is the server, we need to
implement NBD_OPT_INFO. Thankfully, the NBD spec intentionally
made the command very similar to NBD_OPT_GO, to the point that
all we really have to do is tweak our debug messages :)
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
This turned out to be so trivial that I'm pushing it right away.
docs/nbdkit-protocol.pod | 7 +++++++
src/protocol.h | 1 +
src/connections.c | 19 +++++++++++--------
3 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/docs/nbdkit-protocol.pod b/docs/nbdkit-protocol.pod
index e3e06a6..ddabb53 100644
--- a/docs/nbdkit-protocol.pod
+++ b/docs/nbdkit-protocol.pod
@@ -109,6 +109,13 @@ Supported in nbdkit E<ge> 1.5.3.
This protocol enhancement allows the server to return errors when
negotiating the export name.
+=item C<NBD_OPT_INFO>
+
+Supported in nbdkit E<ge> 1.9.3.
+
+This protocol enhancement allows a client to inspect details about
+the export without actually connecting.
+
=item Structured Replies
I<Not supported>.
diff --git a/src/protocol.h b/src/protocol.h
index 792a905..088dcab 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -98,6 +98,7 @@ struct fixed_new_option_reply {
#define NBD_OPT_ABORT 2
#define NBD_OPT_LIST 3
#define NBD_OPT_STARTTLS 5
+#define NBD_OPT_INFO 6
#define NBD_OPT_GO 7
#define NBD_REP_ACK 1
diff --git a/src/connections.c b/src/connections.c
index 1b40e46..410a893 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -636,6 +636,7 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
uint32_t optlen;
char data[MAX_OPTION_LENGTH+1];
struct new_handshake_finish handshake_finish;
+ const char *optname;
for (nr_options = 0; nr_options < MAX_NR_OPTIONS; ++nr_options) {
if (conn->recv (conn, &new_option, sizeof new_option) == -1) {
@@ -774,14 +775,16 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
}
break;
+ case NBD_OPT_INFO:
case NBD_OPT_GO:
+ optname = option == NBD_OPT_INFO ? "NBD_OPT_INFO" : "NBD_OPT_GO";
if (conn->recv (conn, data, optlen) == -1) {
nbdkit_error ("read: %m");
return -1;
}
if (optlen < 6) { /* 32 bit export length + 16 bit nr info */
- debug ("newstyle negotiation: NBD_OPT_GO option length < 6");
+ debug ("newstyle negotiation: %s option length < 6", optname);
if (send_newstyle_option_reply (conn, option, NBD_REP_ERR_INVALID)
== -1)
@@ -800,7 +803,7 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
memcpy (&exportnamelen, &data[0], 4);
exportnamelen = be32toh (exportnamelen);
if (exportnamelen > optlen-6 /* NB optlen >= 6, see above */) {
- debug ("newstyle negotiation: NBD_OPT_GO: export name too long");
+ debug ("newstyle negotiation: %s: export name too long", optname);
if (send_newstyle_option_reply (conn, option, NBD_REP_ERR_INVALID)
== -1)
return -1;
@@ -809,8 +812,8 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
memcpy (&nrinfos, &data[exportnamelen+4], 2);
nrinfos = be16toh (nrinfos);
if (optlen != 4 + exportnamelen + 2 + 2*nrinfos) {
- debug ("newstyle negotiation: NBD_OPT_GO: "
- "number of information requests incorrect");
+ debug ("newstyle negotiation: %s: "
+ "number of information requests incorrect", optname);
if (send_newstyle_option_reply (conn, option, NBD_REP_ERR_INVALID)
== -1)
return -1;
@@ -827,9 +830,9 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
}
memcpy (requested_exportname, &data[4], exportnamelen);
requested_exportname[exportnamelen] = '\0';
- debug ("newstyle negotiation: NBD_OPT_GO: "
+ debug ("newstyle negotiation: %s: "
"client requested export '%s' (ignored)",
- requested_exportname);
+ optname, requested_exportname);
/* The spec is confusing, but it is required that we send back
* NBD_INFO_EXPORT, even if the client did not request it!
@@ -855,8 +858,8 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
switch (info) {
case NBD_INFO_EXPORT: /* ignore - reply sent above */ break;
default:
- debug ("newstyle negotiation: NBD_OPT_GO: "
- "ignoring NBD_INFO_* request %u", (unsigned) info);
+ debug ("newstyle negotiation: %s: "
+ "ignoring NBD_INFO_* request %u", optname, (unsigned) info);
break;
}
}
--
2.17.2
6 years
[nbdkit PATCH] connections: Be less noisy when client sends NBD_OPT_ABORT
by Eric Blake
At least 'nbd-client -l localhost' is a good demonstration of a
client that legitimately sends NBD_OPT_ABORT - it exists only
to enumerate the exports advertised by the server, rather than
intending to connect to any of those exports. As such, we should
downgrade the message for a client telling us it is going away
to the same status as our debug message for NBD_CMD_DISC, given
that the two have the same effect at different points in the
protocol. This stops nbdkit from spamming stderr with
nbdkit: file[1]: error: client sent NBD_OPT_ABORT to abort the connection
messages due to a client that doesn't want to connect after all.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Found while implementing a similar 'qemu-nbd --list' that is
nicer than nbd-client's version ;)
src/connections.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/connections.c b/src/connections.c
index e1ffeff..1b40e46 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -705,7 +705,7 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
case NBD_OPT_ABORT:
if (send_newstyle_option_reply (conn, option, NBD_REP_ACK) == -1)
return -1;
- nbdkit_error ("client sent NBD_OPT_ABORT to abort the connection");
+ debug ("client sent NBD_OPT_ABORT to abort the connection");
return -1;
case NBD_OPT_LIST:
--
2.17.2
6 years
[PATCH v2 0/7] RFC: switch v2v to ocaml-libvirt
by Pino Toscano
Hi,
this is a mostly done attempt to switch to ocaml-libvirt, embedding the
latest version of it from git. This way, it is possible to improve the
way v2v connects to libvirt for both input, and output modules, and
interacts with libvirt (e.g. no more virsh calls needed in virt-v2v).
As side effect, virt-v2v now requires libvirt, as keeping it optional
would create too much burden.
I could not test all the libvirt input modes (like VDDK, and Xen), but
VMware and libvirtxml work fine as before.
Changes from v1:
- rebase on master
- update ocaml-libvirt from libvirt-ocaml.git on libvirt.org, and adjust
the code to it
- pass again the URI to input_libvirt_vddk, so an error message is
preserved
Pino Toscano (7):
v2v: require libvirt
common: Bundle the libvirt-ocaml library for use by virt-v2v
v2v: switch to ocaml-libvirt
v2v: -o libvirt: use a Lazy for the connection
v2v: -o libvirt: switch away from virsh
v2v: test-harness: stop using the external ocaml-libvirt
build: stop looking for ocaml-libvirt
.gitignore | 2 +
Makefile.am | 5 +-
common/mllibvirt/Makefile.am | 102 ++
common/mllibvirt/generator.pl | 908 +++++++++++++
common/mllibvirt/libvirt.README | 9 +
common/mllibvirt/libvirt.ml | 1661 ++++++++++++++++++++++++
common/mllibvirt/libvirt.mli | 1626 +++++++++++++++++++++++
common/mllibvirt/libvirt_c_epilogue.c | 462 +++++++
common/mllibvirt/libvirt_c_oneoffs.c | 1698 +++++++++++++++++++++++++
common/mllibvirt/libvirt_c_prologue.c | 134 ++
configure.ac | 1 +
docs/C_SOURCE_FILES | 1 -
m4/guestfs-ocaml.m4 | 4 -
po/POTFILES | 1 -
v2v/Makefile.am | 26 +-
v2v/copy_to_local.ml | 7 +-
v2v/dummy.c | 2 +
v2v/input_libvirt.ml | 20 +-
v2v/input_libvirt_other.ml | 27 +-
v2v/input_libvirt_other.mli | 5 +-
v2v/input_libvirt_vcenter_https.ml | 13 +-
v2v/input_libvirt_vcenter_https.mli | 2 +-
v2v/input_libvirt_vddk.ml | 15 +-
v2v/input_libvirt_vddk.mli | 4 +-
v2v/input_libvirt_xen_ssh.ml | 13 +-
v2v/input_libvirt_xen_ssh.mli | 2 +-
v2v/input_libvirtxml.ml | 3 +-
v2v/libvirt_utils-c.c | 539 --------
v2v/libvirt_utils.ml | 95 +-
v2v/libvirt_utils.mli | 51 +-
v2v/output_libvirt.ml | 56 +-
v2v/parse_libvirt_xml.ml | 14 +-
v2v/parse_libvirt_xml.mli | 11 +-
v2v/test-harness/Makefile.am | 5 +-
v2v/v2v.ml | 12 +-
35 files changed, 6838 insertions(+), 698 deletions(-)
create mode 100644 common/mllibvirt/Makefile.am
create mode 100755 common/mllibvirt/generator.pl
create mode 100644 common/mllibvirt/libvirt.README
create mode 100644 common/mllibvirt/libvirt.ml
create mode 100644 common/mllibvirt/libvirt.mli
create mode 100644 common/mllibvirt/libvirt_c_epilogue.c
create mode 100644 common/mllibvirt/libvirt_c_oneoffs.c
create mode 100644 common/mllibvirt/libvirt_c_prologue.c
create mode 100644 v2v/dummy.c
delete mode 100644 v2v/libvirt_utils-c.c
--
2.17.2
6 years
nbdkit: Could not read L1 table when reading exported qcow2
by Han Han
Hello, I face a problem on the nbdkit server:
Version-Release number of selected component (if applicable):
nbdkit-v1.9.1
qemu-utils-2.12+dfsg-3+b1
How reproducible:
100%
Steps:
1. Create a qcow2 file
# qemu-img create disk 1G -f qcow2
2. Export the qcow2 file then try to read it via nbd url
# nbdkit file file=disk -e raw -v
nbdkit: debug: TLS disabled: could not load TLS certificates
nbdkit: debug: registering plugin
/usr/local/lib/nbdkit/plugins/nbdkit-file-plugin.so
nbdkit: debug: registered plugin
/usr/local/lib/nbdkit/plugins/nbdkit-file-plugin.so (name file)
nbdkit: debug: file: load
nbdkit: debug: file: config key=file, value=/tmp/disk
nbdkit: debug: file: config_complete
nbdkit: debug: bound to IP address <any>:10809 (2 socket(s))
nbdkit: debug: forked into background (new pid = 32524)
3. Try to read the file via nbd:
# qemu-img info
nbd://localhost/raw
qemu-img: Could not open 'nbd://localhost/raw': Could not read L1 table:
Invalid argument
Logs from nbdkit:
nbdkit: debug: file: open readonly=0
nbdkit: file[1]: debug: newstyle negotiation: flags: global 0x3
nbdkit: file[1]: debug: newstyle negotiation: client flags: 0x3
nbdkit: file[1]: debug: newstyle negotiation: NBD_OPT_GO: client requested
export 'raw' (ignored)
nbdkit: file[1]: debug: get_size
nbdkit: file[1]: debug: can_write
nbdkit: file[1]: debug: can_zero
nbdkit: file[1]: debug: can_write
nbdkit: file[1]: debug: can_trim
nbdkit: file[1]: debug: can_fua
nbdkit: file[1]: debug: can_flush
nbdkit: file[1]: debug: is_rotational
nbdkit: file[1]: debug: newstyle negotiation: flags: export 0x6d
nbdkit: file[1]: debug: newstyle negotiation: NBD_OPT_GO: ignoring
NBD_INFO_* request 3
nbdkit: file[1]: debug: handshake complete, processing requests with 16
threads
nbdkit: debug: starting worker thread file.0
nbdkit: debug: starting worker thread file.1
nbdkit: debug: starting worker thread file.3
nbdkit: debug: starting worker thread file.2
nbdkit: debug: starting worker thread file.4
nbdkit: debug: starting worker thread file.5
nbdkit: debug: starting worker thread file.7
nbdkit: debug: starting worker thread file.6
nbdkit: debug: starting worker thread file.8
nbdkit: debug: starting worker thread file.9
nbdkit: debug: starting worker thread file.10
nbdkit: debug: starting worker thread file.11
nbdkit: debug: starting worker thread file.12
nbdkit: debug: starting worker thread file.13
nbdkit: debug: starting worker thread file.14
nbdkit: debug: starting worker thread file.15
nbdkit: file.1: debug: pread count=512 offset=0
nbdkit: file.0: debug: pread count=512 offset=0
nbdkit: file.3: debug: sending error reply: Invalid argument
nbdkit: file.4: debug: client sent disconnect command, closing connection
nbdkit: file.4: debug: exiting worker thread file.4
nbdkit: file.2: debug: exiting worker thread file.2
nbdkit: file.7: debug: exiting worker thread file.7
nbdkit: file.5: debug: exiting worker thread file.5
nbdkit: file.6: debug: exiting worker thread file.6
nbdkit: file.8: debug: exiting worker thread file.8
nbdkit: file.9: debug: exiting worker thread file.9
nbdkit: file.10: debug: exiting worker thread file.10
nbdkit: file.11: debug: exiting worker thread file.11
nbdkit: file.12: debug: exiting worker thread file.12
nbdkit: file.0: debug: exiting worker thread file.0
nbdkit: file.14: debug: exiting worker thread file.14
nbdkit: file.15: debug: exiting worker thread file.15
nbdkit: file.1: debug: exiting worker thread file.1
nbdkit: file.13: debug: exiting worker thread file.13
nbdkit: file.3: debug: exiting worker thread file.3
nbdkit: file[1]: debug: close
Could you please check if it is a bug from nbdkit? Thanks
--
Best regards,
-----------------------------------
Han Han
Quality Engineer
Redhat.
Email: hhan(a)redhat.com
Phone: +861065339333
6 years
Integration with muCommander
by Arik Hadas
Hi All,
In the last few days, I've been working on leveraging a pluggable mechanism
that is going to be introduced for muCommander [1] to provide a front-end
for libguestfs.
I published a video [2] that demonstrates this integration: enabling to
browse/upload-to/download-from virtual disks via a file manager with a
dual-pane interface.
I've followed the guidelines for inspecting the disk's file system(s) I got
on IRC (thanks Richard!). The code is available at [3], mostly in
LibguestfsFile.java.
However, as one can see in the video, it takes a pretty long time to
inspect the disk (in order to find the operating system) and to mount the
file systems. So it takes me back to the filesystem_walk function as I read
in [4] that it allows inspecting the metadata without mounting the disk
partition(s). Unfortunately, I didn't manage to try that function due to
the following error I get when trying to use it (tried on Fedora 28 & 29):
Exception in thread "main" com.redhat.et.libguestfs.LibGuestFSException:
internal_filesystem_walk: feature 'libtsk' is not available in this
build of libguestfs. Read 'AVAILABILITY' in the guestfs(3) man page for
how to check for the availability of features.
at com.redhat.et.libguestfs.GuestFS._filesystem_walk(Native Method)
at com.redhat.et.libguestfs.GuestFS.filesystem_walk(GuestFS.java:6010)
at test.Main.main(Main.java:27)
Is that right that the filesystem_walk doesn't require mounting the disk
partition(s)? If that's true, can we publish a version that supports that
in the Fedora repo?
And another question, the upload/download API requires to provide a remote
file and a file on the hosting file system. I currently use a temporary
local file that is passed as input (in case of upload) or output (in case
of download) for libguestfs. But I've noticed that by specifying "-",
libguestfs reads from stdin/writes to stdout. Do you have any experience in
using this to inject/retrieve data directly from/to a Java application
(that holds an input/output stream at hand) without going through the disk?
[1] http://www.mucommander.com
[2] https://youtu.be/_ykVRSuKFwc
[3]
https://github.com/ahadas/mucommander/tree/osgi/mucommander-libguestfs/sr...
[4] https://www.redhat.com/archives/libguestfs/2016-June/msg00051.html
6 years
[PATCH v2] v2v: Add support for libosinfo metadata
by Martin Kletzander
There's a standardized libosinfo namespace for libvirt domain metadata. For now
it supports the id of the OS only. However that is still a very helpful feature
that is already supported in gnome-boxes and virt-manager (at least).
The discussion happened here:
https://www.redhat.com/archives/libosinfo/2018-September/msg00003.html
So let's add the support to local and libvirt outputs.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
v2:
- Added support for SLED
- Fixed test-v2v-i-ova test output
v2v/create_libvirt_xml.ml | 119 ++++++++++++++++++++++++++++++++++++-
v2v/create_libvirt_xml.mli | 1 +
v2v/output_libvirt.ml | 4 +-
v2v/output_local.ml | 4 +-
v2v/test-v2v-i-ova.xml | 5 ++
5 files changed, 128 insertions(+), 5 deletions(-)
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 55e83e8bc1b9..6b2fb874a5a6 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -34,8 +34,112 @@ let find_target_disk targets { s_disk_id = id } =
try List.find (fun t -> t.target_overlay.ov_source.s_disk_id = id) targets
with Not_found -> assert false
+let get_osinfo_id = function
+ | { i_type = "linux"; i_distro = "rhel";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://redhat.com/rhel/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos";
+ i_major_version = major; i_minor_version = minor } when major < 7 ->
+ Some (sprintf "http://centos.org/centos/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos"; i_major_version = major } ->
+ Some (sprintf "http://centos.org/centos/%d.0" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = 0;
+ i_product_name = product } when String.find product "Desktop" >= 0 ->
+ Some (sprintf "http://suse.com/sled/%d" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = minor;
+ i_product_name = product } when String.find product "Desktop" >= 0 ->
+ Some (sprintf "http://suse.com/sled/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = 0 } ->
+ Some (sprintf "http://suse.com/sles/%d" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://suse.com/sles/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "opensuse";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://opensuse.org/opensuse/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "debian"; i_major_version = major } ->
+ Some (sprintf "http://debian.org/debian/%d" major)
+
+ | { i_type = "linux"; i_distro = "ubuntu";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://ubuntu.com/ubuntu/%d.%02d" major minor)
+
+ | { i_type = "linux"; i_distro = "fedora"; i_major_version = major } ->
+ Some (sprintf "http://fedoraproject.org/fedora/%d" major)
+
+ | { i_type = "windows"; i_major_version = major; i_minor_version = minor }
+ when major < 4 ->
+ Some (sprintf "http://microsoft.com/win/%d.%d" major minor)
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "XP" >= 0 ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "R2" >= 0 ->
+ Some "http://microsoft.com/win/2k3r2"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/2k3"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/vista"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/7"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3 } ->
+ Some "http://microsoft.com/win/8.1"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k16"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/10"
+
+ | { i_type = typ; i_distro = distro;
+ i_major_version = major; i_minor_version = minor; i_arch = arch;
+ i_product_name = product } ->
+ warning (f_"unknown guest operating system: %s %s %d.%d %s (%s)")
+ typ distro major minor arch product;
+ None
+
let create_libvirt_xml ?pool source targets target_buses guestcaps
- target_features target_firmware =
+ target_features target_firmware inspect =
(* The main body of the libvirt XML document. *)
let body = ref [] in
@@ -49,6 +153,19 @@ let create_libvirt_xml ?pool source targets target_buses guestcaps
| Some genid -> List.push_back body (e "genid" [] [PCData genid])
);
+
+ (match get_osinfo_id inspect with
+ | None -> ()
+ | Some osinfo_id ->
+ List.push_back_list body [
+ e "metadata" [] [
+ e "libosinfo:libosinfo" ["xmlns:libosinfo", "http://libosinfo.org/xmlns/libvirt/domain/1.0"] [
+ e "libosinfo:os" ["id", osinfo_id] [];
+ ];
+ ];
+ ];
+ );
+
let memory_k = source.s_memory /^ 1024L in
List.push_back_list body [
e "memory" ["unit", "KiB"] [PCData (Int64.to_string memory_k)];
diff --git a/v2v/create_libvirt_xml.mli b/v2v/create_libvirt_xml.mli
index 3f883c625c8a..9a596208481a 100644
--- a/v2v/create_libvirt_xml.mli
+++ b/v2v/create_libvirt_xml.mli
@@ -22,6 +22,7 @@ val create_libvirt_xml : ?pool:string -> Types.source -> Types.target list ->
Types.target_buses ->
Types.guestcaps -> string list ->
Types.target_firmware ->
+ Types.inspect ->
DOM.doc
(** [create_libvirt_xml ?pool source targets target_buses guestcaps
target_features target_firmware] creates the final libvirt XML
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
index 1271bdc2f5e3..9008b05079cd 100644
--- a/v2v/output_libvirt.ml
+++ b/v2v/output_libvirt.ml
@@ -143,7 +143,7 @@ class output_libvirt oc output_pool = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We copied directly into the final pool directory. However we
* have to tell libvirt.
*)
@@ -172,7 +172,7 @@ class output_libvirt oc output_pool = object
(* Create the metadata. *)
let doc =
create_libvirt_xml ~pool:pool_name source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let tmpfile, chan = Filename.open_temp_file "v2vlibvirt" ".xml" in
DOM.doc_to_chan chan doc;
diff --git a/v2v/output_local.ml b/v2v/output_local.ml
index 2f4b4e6c9cfd..3a00ed58a72d 100644
--- a/v2v/output_local.ml
+++ b/v2v/output_local.ml
@@ -49,7 +49,7 @@ class output_local dir = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We don't know what target features the hypervisor supports, but
* assume a common set that libvirt supports.
*)
@@ -61,7 +61,7 @@ class output_local dir = object
let doc =
create_libvirt_xml source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let name = source.s_name in
let file = dir // name ^ ".xml" in
diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml
index b277193a87ed..7c19828316c8 100644
--- a/v2v/test-v2v-i-ova.xml
+++ b/v2v/test-v2v-i-ova.xml
@@ -2,6 +2,11 @@
<domain type='kvm'>
<!-- generated by -->
<name>TestOva</name>
+ <metadata>
+ <libosinfo:libosinfo xmlns:libosinfo='http://libosinfo.org/xmlns/libvirt/domain/1.0'>
+ <libosinfo:os id='http://microsoft.com/win/7'/>
+ </libosinfo:libosinfo>
+ </metadata>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu>1</vcpu>
--
2.19.2
6 years, 1 month
[PATCH] v2v: Add support for libosinfo metadata
by Martin Kletzander
There's a standardized libosinfo namespace for libvirt domain metadata. For now
it supports the id of the OS only. However that is still a very helpful feature
that is already supported in gnome-boxes and virt-manager (at least).
The discussion happened here:
https://www.redhat.com/archives/libosinfo/2018-September/msg00003.html
So let's add the support to local and libvirt outputs.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
v2v/create_libvirt_xml.ml | 109 ++++++++++++++++++++++++++++++++++++-
v2v/create_libvirt_xml.mli | 1 +
v2v/output_libvirt.ml | 4 +-
v2v/output_local.ml | 4 +-
4 files changed, 113 insertions(+), 5 deletions(-)
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 55e83e8bc1b9..180f3768792b 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -34,8 +34,102 @@ let find_target_disk targets { s_disk_id = id } =
try List.find (fun t -> t.target_overlay.ov_source.s_disk_id = id) targets
with Not_found -> assert false
+let get_osinfo_id = function
+ | { i_type = "linux"; i_distro = "rhel";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://redhat.com/rhel/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos";
+ i_major_version = major; i_minor_version = minor } when major < 7 ->
+ Some (sprintf "http://centos.org/centos/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos"; i_major_version = major } ->
+ Some (sprintf "http://centos.org/centos/%d.0" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = 0 } ->
+ Some (sprintf "http://suse.com/sles/%d" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://suse.com/sles/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "opensuse";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://opensuse.org/opensuse/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "debian"; i_major_version = major } ->
+ Some (sprintf "http://debian.org/debian/%d" major)
+
+ | { i_type = "linux"; i_distro = "ubuntu";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://ubuntu.com/ubuntu/%d.%02d" major minor)
+
+ | { i_type = "linux"; i_distro = "fedora"; i_major_version = major } ->
+ Some (sprintf "http://fedoraproject.org/fedora/%d" major)
+
+ | { i_type = "windows"; i_major_version = major; i_minor_version = minor }
+ when major < 4 ->
+ Some (sprintf "http://microsoft.com/win/%d.%d" major minor)
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "XP" >= 0 ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "R2" >= 0 ->
+ Some "http://microsoft.com/win/2k3r2"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/2k3"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/vista"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/7"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3 } ->
+ Some "http://microsoft.com/win/8.1"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k16"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/10"
+
+ | { i_type = typ; i_distro = distro;
+ i_major_version = major; i_minor_version = minor; i_arch = arch;
+ i_product_name = product } ->
+ warning (f_"unknown guest operating system: %s %s %d.%d %s (%s)")
+ typ distro major minor arch product;
+ None
+
let create_libvirt_xml ?pool source targets target_buses guestcaps
- target_features target_firmware =
+ target_features target_firmware inspect =
(* The main body of the libvirt XML document. *)
let body = ref [] in
@@ -49,6 +143,19 @@ let create_libvirt_xml ?pool source targets target_buses guestcaps
| Some genid -> List.push_back body (e "genid" [] [PCData genid])
);
+
+ (match get_osinfo_id inspect with
+ | None -> ()
+ | Some osinfo_id ->
+ List.push_back_list body [
+ e "metadata" [] [
+ e "libosinfo:libosinfo" ["xmlns:libosinfo", "http://libosinfo.org/xmlns/libvirt/domain/1.0"] [
+ e "libosinfo:os" ["id", osinfo_id] [];
+ ];
+ ];
+ ];
+ );
+
let memory_k = source.s_memory /^ 1024L in
List.push_back_list body [
e "memory" ["unit", "KiB"] [PCData (Int64.to_string memory_k)];
diff --git a/v2v/create_libvirt_xml.mli b/v2v/create_libvirt_xml.mli
index 3f883c625c8a..9a596208481a 100644
--- a/v2v/create_libvirt_xml.mli
+++ b/v2v/create_libvirt_xml.mli
@@ -22,6 +22,7 @@ val create_libvirt_xml : ?pool:string -> Types.source -> Types.target list ->
Types.target_buses ->
Types.guestcaps -> string list ->
Types.target_firmware ->
+ Types.inspect ->
DOM.doc
(** [create_libvirt_xml ?pool source targets target_buses guestcaps
target_features target_firmware] creates the final libvirt XML
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
index 1271bdc2f5e3..9008b05079cd 100644
--- a/v2v/output_libvirt.ml
+++ b/v2v/output_libvirt.ml
@@ -143,7 +143,7 @@ class output_libvirt oc output_pool = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We copied directly into the final pool directory. However we
* have to tell libvirt.
*)
@@ -172,7 +172,7 @@ class output_libvirt oc output_pool = object
(* Create the metadata. *)
let doc =
create_libvirt_xml ~pool:pool_name source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let tmpfile, chan = Filename.open_temp_file "v2vlibvirt" ".xml" in
DOM.doc_to_chan chan doc;
diff --git a/v2v/output_local.ml b/v2v/output_local.ml
index 2f4b4e6c9cfd..3a00ed58a72d 100644
--- a/v2v/output_local.ml
+++ b/v2v/output_local.ml
@@ -49,7 +49,7 @@ class output_local dir = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We don't know what target features the hypervisor supports, but
* assume a common set that libvirt supports.
*)
@@ -61,7 +61,7 @@ class output_local dir = object
let doc =
create_libvirt_xml source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let name = source.s_name in
let file = dir // name ^ ".xml" in
--
2.19.2
6 years, 1 month
[PATCH] Fix include for xattr.h
by Martin Kletzander
The proper file that should be included is `sys/xattr.h` as that comes from
`glibc` and not `attr/xattr.h` which ships with the `attr` utility.
New enough `attr` utility (at least 2.4.48 in my case) even includes a #warning
in `attr/xattr.h` for projects that still have this mistake in the code.
---
daemon/xattr.c | 8 ++------
fuse/test-fuse.c | 4 ----
lib/fuse.c | 2 +-
m4/guestfs-libraries.m4 | 1 -
4 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/daemon/xattr.c b/daemon/xattr.c
index bbe571b3f8bb..b10f6bddf4d0 100644
--- a/daemon/xattr.c
+++ b/daemon/xattr.c
@@ -37,12 +37,8 @@
#ifdef HAVE_LINUX_XATTRS
-# ifdef HAVE_ATTR_XATTR_H
-# include <attr/xattr.h>
-# else
-# ifdef HAVE_SYS_XATTR_H
-# include <sys/xattr.h>
-# endif
+# ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
# endif
int
diff --git a/fuse/test-fuse.c b/fuse/test-fuse.c
index 5ce8322f0d0e..ac0a49348a3a 100644
--- a/fuse/test-fuse.c
+++ b/fuse/test-fuse.c
@@ -41,13 +41,9 @@
#include <acl/libacl.h>
#endif
-#ifdef HAVE_ATTR_XATTR_H
-#include <attr/xattr.h>
-#else
#ifdef HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#endif
-#endif
#include <guestfs.h>
#include "guestfs-utils.h"
diff --git a/lib/fuse.c b/lib/fuse.c
index 1ac42330d3e7..52dc0bd99d11 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -35,7 +35,7 @@
#endif
#if HAVE_FUSE
-/* See <attr/xattr.h> */
+/* See <sys/xattr.h> */
#ifndef ENOATTR
#define ENOATTR ENODATA
#endif
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
index 095dd38bf43b..6b2e8db9456d 100644
--- a/m4/guestfs-libraries.m4
+++ b/m4/guestfs-libraries.m4
@@ -36,7 +36,6 @@ AC_DEFINE_UNQUOTED([host_cpu],["$host_cpu"],[Host architecture.])
dnl Headers.
AC_CHECK_HEADERS([\
- attr/xattr.h \
byteswap.h \
endian.h \
sys/endian.h \
--
2.19.1
6 years, 1 month