summaryrefslogtreecommitdiffstats
path: root/loader/modules.c
diff options
context:
space:
mode:
authorMartin Sivak <msivak@redhat.com>2010-08-12 13:13:33 +0200
committerMartin Sivak <msivak@redhat.com>2010-08-12 16:16:53 +0200
commitf7a5edcc2868b34ec4e2490e1043bcc76b788d60 (patch)
treea5ea2abeaa9614b2f80faeae6fc1a9259653373d /loader/modules.c
parentc71ddf006048a7e870307f26a75ddb66e9f3eaeb (diff)
downloadanaconda-f7a5edcc2868b34ec4e2490e1043bcc76b788d60.tar.gz
anaconda-f7a5edcc2868b34ec4e2490e1043bcc76b788d60.tar.xz
anaconda-f7a5edcc2868b34ec4e2490e1043bcc76b788d60.zip
Proper detection of successful module update (#618862)
Diffstat (limited to 'loader/modules.c')
-rw-r--r--loader/modules.c98
1 files changed, 93 insertions, 5 deletions
diff --git a/loader/modules.c b/loader/modules.c
index 8fc07dfde..ef101d259 100644
--- a/loader/modules.c
+++ b/loader/modules.c
@@ -348,7 +348,8 @@ inline gint gcmp(gconstpointer a, gconstpointer b, gpointer userptr)
return g_strcmp0(a, b);
}
-int processModuleLines(GTree *data, int (*f)(gchar**, GTree*)){
+int processModuleLines(int (*f)(gchar**, void*), void *data)
+{
char *line = NULL;
size_t linesize = 0;
gchar** lineparts = NULL;
@@ -382,8 +383,9 @@ int processModuleLines(GTree *data, int (*f)(gchar**, GTree*)){
return count;
}
-inline int cb_savestate(gchar** parts, GTree *data)
+inline int cb_savestate(gchar** parts, void *data0)
{
+ GTree *data = data0;
logMessage(DEBUGLVL, "Saving module %s", parts[0]);
g_tree_insert(data, g_strdup(parts[0]), (gchar*)1);
return 1;
@@ -397,13 +399,14 @@ GTree* mlSaveModuleState()
if(!state)
return NULL;
- processModuleLines(state, cb_savestate);
+ processModuleLines(cb_savestate, state);
return state;
}
-inline int cb_restorestate(gchar** parts, GTree *data)
+inline int cb_restorestate(gchar** parts, void *data0)
{
+ GTree *data = data0;
pid_t pid;
int status;
@@ -449,7 +452,7 @@ void mlRestoreModuleState(GTree *state)
logMessage(INFO, "Restoring module state...");
/* repeat until we can't remove anything else */
- while (processModuleLines(state, cb_restorestate) > 0)
+ while (processModuleLines(cb_restorestate, state) > 0)
/* noop */;
}
@@ -460,3 +463,88 @@ void mlFreeModuleState(GTree *state)
g_tree_destroy(state);
}
+
+inline int cb_saveversions(gchar** parts, void *data0)
+{
+ GHashTable *ht = data0;
+ gchar *module = g_strdup(parts[0]);
+ char *versionfilename;
+ char *srcversionfilename;
+ gchar *version;
+ gchar *srcversion;
+ gchar *value, *value2;
+
+ checked_asprintf(&versionfilename, "/sys/module/%s/version", module);
+ checked_asprintf(&srcversionfilename, "/sys/module/%s/srcversion", module);
+
+ /* emty string */
+ value = g_new0(gchar, 1);
+
+ /* get possible version file */
+ if (g_file_get_contents(versionfilename, &version, NULL, NULL)) {
+ value2 = g_strconcat(value, version, "/", NULL);
+ g_free(value);
+ g_free(version);
+ value = value2;
+ }
+
+ /* get possible src version file */
+ if (g_file_get_contents(srcversionfilename, &srcversion, NULL, NULL)) {
+ value2 = g_strconcat(value, srcversion, NULL);
+ g_free(value);
+ g_free(srcversion);
+ value = value2;
+ }
+
+ free(versionfilename);
+ free(srcversionfilename);
+
+ g_hash_table_insert(ht, module, value);
+
+ return 1;
+}
+
+VersionState mlVersions()
+{
+ GHashTable *ht = NULL;
+
+ ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ if(!ht) return NULL;
+
+ /* read version info about all modules */
+ processModuleLines(cb_saveversions, ht);
+
+ return (VersionState)ht;
+}
+
+void mlFreeVersions(VersionState ht)
+{
+ g_hash_table_destroy((GHashTable*)ht);
+}
+
+int mlDetectUpdate(VersionState a, VersionState b)
+{
+ int rc = 0;
+
+ if(!a && !b) return 0;
+ if(!a) return 1;
+ if(!b) return 1;
+
+ GList *modules = g_hash_table_get_keys(b);
+ if(!modules) return 0;
+
+ GList *iter = modules;
+ while (iter && !rc) {
+ gchar *va = g_hash_table_lookup(a, iter->data);
+ gchar *vb = g_hash_table_lookup(b, iter->data);
+
+ if (!va) rc = 1; // new module
+ else rc = strcmp(va, vb); // check versions for match
+
+ iter = iter->next;
+ }
+
+ g_list_free(modules);
+
+ return abs(rc);
+}