Create a very minimal interface for libosinfo, in particular for
OsinfoDb and OsinfoOs, aimed to get the list of device drivers for an
OS.
---
v2v/Makefile.am | 5 +
v2v/libosinfo-c.c | 237 ++++++++++++++++++++++++++++++++++++++++
v2v/libosinfo.ml | 53 +++++++++
v2v/libosinfo.mli | 48 ++++++++
v2v/libosinfo_utils.ml | 34 ++++++
v2v/libosinfo_utils.mli | 26 +++++
6 files changed, 403 insertions(+)
create mode 100644 v2v/libosinfo-c.c
create mode 100644 v2v/libosinfo.ml
create mode 100644 v2v/libosinfo.mli
create mode 100644 v2v/libosinfo_utils.ml
create mode 100644 v2v/libosinfo_utils.mli
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index aae1ffa2..491238ea 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -63,6 +63,8 @@ SOURCES_MLI = \
input_ova.mli \
input_vmx.mli \
inspect_source.mli \
+ libosinfo.mli \
+ libosinfo_utils.mli \
libvirt_utils.mli \
linux.mli \
linux_bootloaders.mli \
@@ -112,6 +114,8 @@ SOURCES_ML = \
name_from_disk.ml \
nbdkit.ml \
vCenter.ml \
+ libosinfo.ml \
+ libosinfo_utils.ml \
libvirt_utils.ml \
DOM.ml \
changeuid.ml \
@@ -164,6 +168,7 @@ SOURCES_ML = \
v2v.ml
SOURCES_C = \
+ libosinfo-c.c \
qemuopts-c.c
# These files are generated and contain *.py embedded as an OCaml string.
diff --git a/v2v/libosinfo-c.c b/v2v/libosinfo-c.c
new file mode 100644
index 00000000..1f153b3d
--- /dev/null
+++ b/v2v/libosinfo-c.c
@@ -0,0 +1,237 @@
+/* virt-v2v
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * Mini interface to libosinfo.
+ */
+
+#include <config.h>
+
+#include <osinfo/osinfo.h>
+
+#include <caml/alloc.h>
+#include <caml/callback.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+#include <caml/custom.h>
+
+#include <stdio.h>
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
+#define MAKE_VERSION_HEX(maj, min, mic) \
+ (((maj) << 16) | ((min) << 8) | ((mic) << 0))
+#define V2V_LIBOSINFO_VERSION_HEX \
+ MAKE_VERSION_HEX(OSINFO_MAJOR_VERSION, OSINFO_MINOR_VERSION, OSINFO_MICRO_VERSION)
+#define IS_LIBOSINFO_VERSION(maj, min, mic) \
+ V2V_LIBOSINFO_VERSION_HEX >= MAKE_VERSION_HEX(maj, min, mic)
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoFilter, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoLoader, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoList, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OsinfoOsList, g_object_unref)
+
+typedef OsinfoDb *OsinfoDb_t;
+typedef OsinfoOs *OsinfoOs_t;
+
+/* Wrap and unwrap handles, with a finalizer. */
+#define OsinfoDb_t_val(rv) (*(OsinfoDb_t *)Data_custom_val(rv))
+
+#define _OsinfoOs_t_val(rv) (*((OsinfoOs_t *)Data_custom_val(rv)))
+#define OsinfoOs_t_val(rv) _OsinfoOs_t_val(Field((rv),0))
+
+static void
+OsinfoDb_t_finalize (value tv)
+{
+ OsinfoDb_t t = OsinfoDb_t_val (tv);
+ if (t) g_object_unref (t);
+}
+
+static struct custom_operations db_custom_operations = {
+ (char *) "OsinfoDb_t_custom_operations",
+ OsinfoDb_t_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default,
+ custom_compare_ext_default,
+};
+
+static value
+Val_OsinfoDb_t (OsinfoDb_t t)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+
+ rv = caml_alloc_custom (&db_custom_operations,
+ sizeof (OsinfoDb_t), 0, 1);
+ OsinfoDb_t_val(rv) = t;
+
+ CAMLreturn (rv);
+}
+
+static struct custom_operations os_custom_operations = {
+ (char *) "OsinfoDb_t_custom_operations",
+ custom_finalize_default,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default,
+ custom_compare_ext_default,
+};
+
+static value
+Val_OsinfoOs_t (value dbv, OsinfoOs *os)
+{
+ CAMLparam1 (dbv);
+ CAMLlocal2 (rv, v);
+
+ v = caml_alloc_custom (&os_custom_operations,
+ sizeof(OsinfoOs_t), 0, 1);
+ _OsinfoOs_t_val (v) = os;
+ rv = caml_alloc_tuple (2);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, dbv);
+
+ CAMLreturn (rv);
+}
+
+value
+v2v_osinfo_db_load (value unitv)
+{
+ CAMLparam1 (unitv);
+ CAMLlocal1 (rv);
+ g_autoptr(OsinfoLoader) loader = NULL;
+ OsinfoDb *db = NULL;
+ g_autoptr(GError) error = NULL;
+
+ loader = osinfo_loader_new ();
+ osinfo_loader_process_default_path (loader, &error);
+ if (error != NULL)
+ caml_failwith (error->message);
+
+ db = osinfo_loader_get_db (loader);
+ g_object_ref (db);
+
+ rv = Val_OsinfoDb_t (db);
+
+ CAMLreturn (rv);
+}
+
+value
+v2v_osinfo_os_find_os_by_short_id (value dbv, value osv)
+{
+ CAMLparam2 (dbv, osv);
+ CAMLlocal1 (rv);
+ g_autoptr(OsinfoFilter) filter = NULL;
+ g_autoptr(OsinfoOsList) os_list = NULL;
+ g_autoptr(OsinfoList) list = NULL;
+ OsinfoOs *os;
+
+ os_list = osinfo_db_get_os_list (OsinfoDb_t_val (dbv));
+ filter = osinfo_filter_new ();
+ osinfo_filter_add_constraint (filter, OSINFO_PRODUCT_PROP_SHORT_ID, String_val (osv));
+ list = osinfo_list_new_filtered (OSINFO_LIST(os_list), filter);
+
+ if (osinfo_list_get_length (list) == 0)
+ caml_raise_not_found ();
+
+ os = OSINFO_OS(osinfo_list_get_nth (list, 0));
+ rv = Val_OsinfoOs_t (dbv, os);
+
+ CAMLreturn (rv);
+}
+
+value
+v2v_osinfo_os_get_id (value osv)
+{
+ CAMLparam1 (osv);
+ const gchar *id;
+
+ id = osinfo_entity_get_id (OSINFO_ENTITY(OsinfoOs_t_val (osv)));
+ CAMLreturn (caml_copy_string (id));
+}
+
+static value
+glist_to_value_list (GList *list)
+{
+ CAMLparam0 ();
+ CAMLlocal2 (rv, v);
+ GList *l;
+
+ rv = Val_emptylist;
+ for (l = list; l != NULL; l = l->next) {
+ v = caml_alloc (2, 0);
+ Store_field (v, 0, caml_copy_string (l->data));
+ Store_field (v, 1, rv);
+ rv = v;
+ }
+
+ CAMLreturn (rv);
+}
+
+value
+v2v_osinfo_os_get_device_drivers (value osv)
+{
+ CAMLparam1 (osv);
+ CAMLlocal3 (rv, v, vi);
+ OsinfoDeviceDriverList *list;
+ gint i, len;
+
+ list = osinfo_os_get_device_drivers (OsinfoOs_t_val (osv));
+ len = osinfo_list_get_length (OSINFO_LIST(list));
+
+ rv = Val_emptylist;
+ for (i = len - 1; i >= 0; --i) {
+ OsinfoDeviceDriver *driver;
+ const gchar *str;
+ gboolean b;
+ GList *l;
+ gint64 i64;
+
+ driver = OSINFO_DEVICE_DRIVER(osinfo_list_get_nth (OSINFO_LIST(list), i));
+
+ vi = caml_alloc (6, 0);
+ str = osinfo_device_driver_get_architecture (driver);
+ Store_field (vi, 0, caml_copy_string (str));
+ str = osinfo_device_driver_get_location (driver);
+ Store_field (vi, 1, caml_copy_string (str));
+ b = osinfo_device_driver_get_pre_installable (driver);
+ Store_field (vi, 2, Val_bool (b));
+ b = osinfo_device_driver_get_signed (driver);
+ Store_field (vi, 3, Val_bool (b));
+#if IS_LIBOSINFO_VERSION(1, 7, 0)
+ i64 = osinfo_device_driver_get_priority (driver);
+#else
+ /* Same as OSINFO_DEVICE_DRIVER_DEFAULT_PRIORITY in libosinfo 1.7.0+. */
+ i64 = 50;
+#endif
+ Store_field (vi, 4, caml_copy_int64 (i64));
+ l = osinfo_device_driver_get_files (driver);
+ Store_field (vi, 5, glist_to_value_list (l));
+ g_list_free (l);
+
+ v = caml_alloc (2, 0);
+ Store_field (v, 0, vi);
+ Store_field (v, 1, rv);
+ rv = v;
+ }
+
+ CAMLreturn (rv);
+}
diff --git a/v2v/libosinfo.ml b/v2v/libosinfo.ml
new file mode 100644
index 00000000..bd9ca126
--- /dev/null
+++ b/v2v/libosinfo.ml
@@ -0,0 +1,53 @@
+(* virt-v2v
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Std_utils
+open Tools_utils
+open Common_gettext.Gettext
+
+type osinfo_db_t
+type osinfo_os_t
+
+type osinfo_device_driver = {
+ architecture : string;
+ location : string;
+ pre_installable : bool;
+ signed : bool;
+ priority : int64;
+ files : string list;
+}
+
+external osinfo_os_get_id : osinfo_os_t -> string = "v2v_osinfo_os_get_id"
+external osinfo_os_get_device_drivers : osinfo_os_t -> osinfo_device_driver list =
"v2v_osinfo_os_get_device_drivers"
+
+class osinfo_os h =
+ object (self)
+ method get_id () = osinfo_os_get_id h
+ method get_device_drivers () = osinfo_os_get_device_drivers h
+end
+
+external osinfo_db_load : unit -> osinfo_db_t = "v2v_osinfo_db_load"
+external osinfo_db_find_os_by_short_id : osinfo_db_t -> string -> osinfo_os_t =
"v2v_osinfo_os_find_os_by_short_id"
+
+class osinfo_db () =
+ let h = osinfo_db_load () in
+ object (self)
+ method find_os_by_short_id name =
+ let os = osinfo_db_find_os_by_short_id h name in
+ new osinfo_os os
+end
diff --git a/v2v/libosinfo.mli b/v2v/libosinfo.mli
new file mode 100644
index 00000000..0428ef91
--- /dev/null
+++ b/v2v/libosinfo.mli
@@ -0,0 +1,48 @@
+(* virt-v2v
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** This module implements a minimal libosinfo API. *)
+
+type osinfo_os_t
+
+type osinfo_device_driver = {
+ architecture : string;
+ location : string;
+ pre_installable : bool;
+ signed : bool;
+ priority : int64;
+ files : string list;
+}
+
+class osinfo_os : osinfo_os_t -> object
+ method get_id : unit -> string
+ (** Return the ID. *)
+ method get_device_drivers : unit -> osinfo_device_driver list
+ (** Return the list of device drivers. *)
+end
+(** Minimal OsinfoOs wrapper. *)
+
+class osinfo_db : unit -> object
+ method find_os_by_short_id : string -> osinfo_os
+ (** [find_os_by_short_id short-id] get the [osinfo_os] that has the
+ specified [short-id].
+
+ Raise [Not_found] in case there is no matching OS.
+ *)
+end
+(** Minimal OsinfoDb wrapper. *)
diff --git a/v2v/libosinfo_utils.ml b/v2v/libosinfo_utils.ml
new file mode 100644
index 00000000..3c7bce10
--- /dev/null
+++ b/v2v/libosinfo_utils.ml
@@ -0,0 +1,34 @@
+(* virt-v2v
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Std_utils
+open Tools_utils
+open Common_gettext.Gettext
+
+(* Singleton DB, created on the first access. *)
+let db = lazy (new Libosinfo.osinfo_db ())
+(*
+ * Helper function to get the DB -- use it as sole way to get the DB.
+ *)
+let get_db () =
+ Lazy.force db
+
+let get_os_by_short_id os =
+ let os = (get_db ())#find_os_by_short_id os in
+ debug "libosinfo: loaded OS: %s" (os#get_id ());
+ os
diff --git a/v2v/libosinfo_utils.mli b/v2v/libosinfo_utils.mli
new file mode 100644
index 00000000..37485c57
--- /dev/null
+++ b/v2v/libosinfo_utils.mli
@@ -0,0 +1,26 @@
+(* virt-v2v
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** This module implements helper functions based on libosinfo. *)
+
+val get_os_by_short_id : string -> Libosinfo.osinfo_os
+(** [get_os_by_short_id short-id] get the [Libosinfo.osinfo_os]
+ that has the specified [short-id].
+
+ Raise [Not_found] in case there is no matching OS.
+ *)
--
2.24.1