[PATCH] loader: process files in alphabetical order

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently when loading DB files we process them in whatever order
readdir() returns them in, which is often inode order. This makes the
order of loading files non-deterministic across installs, and if there
are ambiguities in the data, we can in turn get different results.
eg ISO images match different OS entries depending on load order.

Alphabetically sorting the files doesn't remove any ambiguity that
may exist, but at least gives us consistent results on every host.

Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx>
---
 osinfo/osinfo_loader.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index dca23f1..b2635df 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -1975,6 +1975,15 @@ static void osinfo_loader_entity_files_add_path(GHashTable *entries,
     g_free(basepath);
 }
 
+static gint osinfo_sort_files(gconstpointer a, gconstpointer b)
+{
+    GFileInfo *ai = (GFileInfo *)a;
+    GFileInfo *bi = (GFileInfo *)b;
+    const gchar *an = g_file_info_get_name(ai);
+    const gchar *bn = g_file_info_get_name(bi);
+
+    return strcmp(an, bn);
+}
 
 static void osinfo_loader_find_files(OsinfoLoader *loader,
                                      GFile *base,
@@ -2007,6 +2016,7 @@ static void osinfo_loader_find_files(OsinfoLoader *loader,
         osinfo_loader_entity_files_add_path(entries, NULL, file);
     } else if (type == G_FILE_TYPE_DIRECTORY) {
         GFileEnumerator *ents;
+        GList *children = NULL, *tmp;
         ents = g_file_enumerate_children(file,
                                          "standard::*",
                                          G_FILE_QUERY_INFO_NONE,
@@ -2022,6 +2032,13 @@ static void osinfo_loader_find_files(OsinfoLoader *loader,
         }
 
         while ((info = g_file_enumerator_next_file(ents, NULL, err)) != NULL) {
+            children = g_list_append(children, info);
+        }
+
+        children = g_list_sort(children, osinfo_sort_files);
+        tmp = children;
+        while (tmp) {
+            info = tmp->data;
             const gchar *name = g_file_info_get_name(info);
             GFile *ent = g_file_get_child(file, name);
             type = g_file_info_get_attribute_uint32(info,
@@ -2039,8 +2056,11 @@ static void osinfo_loader_find_files(OsinfoLoader *loader,
                 g_propagate_error(err, error);
                 break;
             }
+
+            tmp = tmp->next;
         }
         g_object_unref(ents);
+        g_list_free(tmp);
     } else {
         OSINFO_ERROR(&error, "Unexpected file type");
         g_propagate_error(err, error);
-- 
2.14.3

_______________________________________________
Libosinfo mailing list
Libosinfo@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libosinfo




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Fedora Users]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]

  Powered by Linux