[Libosinfo] [libosinfo PATCH v3 06/12] os: Make os aware of Guest Features

Fabiano Fidêncio fidencio at redhat.com
Fri Jan 18 12:30:41 UTC 2019


This commit adds the whole machinery needed for dealing with Guest
Features for an Os object.

Signed-off-by: Fabiano Fidêncio <fidencio at redhat.com>
---
 osinfo/libosinfo.syms |   2 +
 osinfo/osinfo_os.c    | 140 ++++++++++++++++++++++++++++++++++++++++++
 osinfo/osinfo_os.h    |   4 ++
 3 files changed, 146 insertions(+)

diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 30bab43..99a7843 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -562,9 +562,11 @@ LIBOSINFO_1.3.0 {
 
 	osinfo_media_supports_installer_script;
 
+	osinfo_os_add_feature;
 	osinfo_os_add_image;
 	osinfo_os_add_maximum_resources;
 	osinfo_os_get_all_device_links;
+	osinfo_os_get_feature_list;
 	osinfo_os_get_image_list;
 	osinfo_os_get_maximum_resources;
 
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index 01d2e01..c29ffd2 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -29,6 +29,7 @@
 #include "osinfo/osinfo_product_private.h"
 #include "osinfo/osinfo_os_private.h"
 #include "osinfo/osinfo_resources_private.h"
+#include "osinfo/osinfo_feature_private.h"
 #include <glib/gi18n-lib.h>
 
 G_DEFINE_TYPE(OsinfoOs, osinfo_os, OSINFO_TYPE_PRODUCT);
@@ -59,6 +60,7 @@ struct _OsinfoOsPrivate
     OsinfoResourcesList *minimum;
     OsinfoResourcesList *recommended;
     OsinfoResourcesList *maximum;
+    OsinfoFeatureList *features;
 
     OsinfoInstallScriptList *scripts;
 
@@ -119,6 +121,7 @@ osinfo_os_finalize(GObject *object)
     g_object_unref(os->priv->minimum);
     g_object_unref(os->priv->recommended);
     g_object_unref(os->priv->maximum);
+    g_object_unref(os->priv->features);
 
     g_object_unref(os->priv->scripts);
 
@@ -186,6 +189,7 @@ osinfo_os_init(OsinfoOs *os)
     os->priv->minimum = osinfo_resourceslist_new();
     os->priv->recommended = osinfo_resourceslist_new();
     os->priv->maximum = osinfo_resourceslist_new();
+    os->priv->features = osinfo_featurelist_new();
     os->priv->scripts = osinfo_install_scriptlist_new();
     os->priv->device_drivers = osinfo_device_driverlist_new();
 }
@@ -553,6 +557,142 @@ OsinfoDeviceLink *osinfo_os_add_device(OsinfoOs *os, OsinfoDevice *dev)
     return devlink;
 }
 
+static gboolean feature_exists_in_list(const gchar *name,
+                                       OsinfoList *list)
+{
+    gssize len, i;
+
+    if (list == NULL)
+        return FALSE;
+
+    len = osinfo_list_get_length(list);
+    for (i = 0; i < len; i++) {
+        OsinfoFeature *f;
+
+        f = OSINFO_FEATURE(osinfo_list_get_nth(list, i));
+
+        if (g_str_equal(name, osinfo_feature_get_name(f)))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+struct GetAllFeaturesData {
+    OsinfoOs *os;
+    OsinfoFilter *filter;
+    OsinfoFeatureList *feature_list;
+    OsinfoFeatureList *unsupported_list;
+};
+
+static void get_all_features_cb(OsinfoProduct *product, gpointer user_data)
+{
+    OsinfoFeatureList *filtered;
+    OsinfoFeatureList *filtered_arch;
+    OsinfoFeatureList *filtered_all;
+    OsinfoOs *os;
+    OsinfoFilter *filter;
+    struct GetAllFeaturesData *foreach_data = (struct GetAllFeaturesData *)user_data;
+    gsize featurelist_len;
+    gsize i;
+
+    g_return_if_fail(OSINFO_IS_OS(product));
+    os = OSINFO_OS(product);
+
+    filter = osinfo_filter_new();
+    osinfo_filter_add_constraint(filter, OSINFO_FEATURE_PROP_ARCHITECTURE, "all");
+    filtered_all = OSINFO_FEATURELIST(osinfo_list_new_filtered(OSINFO_LIST(os->priv->features),
+                                                               filter));
+    filtered_arch = OSINFO_FEATURELIST(osinfo_list_new_filtered(OSINFO_LIST(os->priv->features),
+                                                                foreach_data->filter));
+
+    filtered = OSINFO_FEATURELIST(osinfo_list_new_union(OSINFO_LIST(filtered_arch),
+                                                        OSINFO_LIST(filtered_all)));
+
+    featurelist_len = osinfo_list_get_length(OSINFO_LIST(filtered));
+
+    for (i = 0; i < featurelist_len; i++) {
+        OsinfoFeature *feature;
+        const gchar *name;
+
+        feature = OSINFO_FEATURE(osinfo_list_get_nth(OSINFO_LIST(filtered), i));
+        name = osinfo_feature_get_name(feature);
+
+        if (!osinfo_feature_get_supported(feature) &&
+            !feature_exists_in_list(name, OSINFO_LIST(foreach_data->unsupported_list)))
+            osinfo_list_add(OSINFO_LIST(foreach_data->unsupported_list), OSINFO_ENTITY(feature));
+    }
+
+    for (i = 0; i < featurelist_len; i++) {
+        OsinfoFeature *feature;
+        const gchar *name;
+
+        feature = OSINFO_FEATURE(osinfo_list_get_nth(OSINFO_LIST(filtered), i));
+        name = osinfo_feature_get_name(feature);
+
+        if (!feature_exists_in_list(name, OSINFO_LIST(foreach_data->unsupported_list)) &&
+            !feature_exists_in_list(name, OSINFO_LIST(foreach_data->feature_list)))
+            osinfo_list_add(OSINFO_LIST(foreach_data->feature_list), OSINFO_ENTITY(feature));
+    }
+
+    g_object_unref(filtered);
+    g_object_unref(filtered_all);
+    g_object_unref(filtered_arch);
+    g_object_unref(filter);
+}
+
+/**
+ * osinfo_os_get_feature_list:
+ * @os: an operating system
+ * @arch: the target architecture
+ *
+ * Get all features matching a given filter and taking into consideration
+ * all features previous set in all OSes from which @os derived and/or cloned.
+ *
+ * Returns: (transfer full): A list of OsinfoFeature
+ */
+OsinfoFeatureList *osinfo_os_get_feature_list(OsinfoOs *os, const gchar *arch)
+{
+    struct GetAllFeaturesData foreach_data = {
+        .os = os,
+        .filter = osinfo_filter_new(),
+        .feature_list = osinfo_featurelist_new(),
+        .unsupported_list = osinfo_featurelist_new(),
+    };
+
+    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
+    g_return_val_if_fail(arch != NULL, NULL);
+
+    osinfo_filter_add_constraint(foreach_data.filter,
+                                 OSINFO_FEATURE_PROP_ARCHITECTURE,
+                                 arch);
+
+    osinfo_product_foreach_related(OSINFO_PRODUCT(os),
+                                   OSINFO_PRODUCT_FOREACH_FLAG_DERIVES_FROM |
+                                   OSINFO_PRODUCT_FOREACH_FLAG_CLONES,
+                                   get_all_features_cb,
+                                   &foreach_data);
+
+    g_object_unref(foreach_data.filter);
+    g_object_unref(foreach_data.unsupported_list);
+
+    return foreach_data.feature_list;
+}
+
+/** osinfo_os_add_feature:
+ * @os: an operating system
+ * @feature: (transfer none): the feature to associate with
+ *
+ * Adds @feature to list of features of operating system @os.
+ */
+void osinfo_os_add_feature(OsinfoOs *os, OsinfoFeature *feature)
+{
+    g_return_if_fail(OSINFO_IS_OS(os));
+    g_return_if_fail(OSINFO_IS_FEATURE(feature));
+
+    osinfo_list_add(OSINFO_LIST(os->priv->features), OSINFO_ENTITY(feature));
+}
+
 /**
  * osinfo_os_get_family:
  * @os: an #OsinfoOs
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
index 4eb4b1b..6ea825d 100644
--- a/osinfo/osinfo_os.h
+++ b/osinfo/osinfo_os.h
@@ -34,6 +34,7 @@
 #include <osinfo/osinfo_tree.h>
 #include <osinfo/osinfo_resources.h>
 #include <osinfo/osinfo_resourceslist.h>
+#include <osinfo/osinfo_feature.h>
 #include <osinfo/osinfo_image.h>
 #include <osinfo/osinfo_imagelist.h>
 
@@ -137,6 +138,9 @@ void osinfo_os_add_install_script(OsinfoOs *os, OsinfoInstallScript *script);
 OsinfoDeviceDriverList *osinfo_os_get_device_drivers(OsinfoOs *os);
 void osinfo_os_add_device_driver(OsinfoOs *os, OsinfoDeviceDriver *driver);
 
+OsinfoFeatureList *osinfo_os_get_feature_list(OsinfoOs *os, const gchar *arch);
+void osinfo_os_add_feature(OsinfoOs *os, OsinfoFeature *feature);
+
 #endif /* __OSINFO_OS_H__ */
 /*
  * Local variables:
-- 
2.19.2




More information about the Libosinfo mailing list