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

[PATCH] Proper detection of successful module update (#618862)



---
 loader/driverdisk.c |   18 ++++++---
 loader/modules.c    |   98 ++++++++++++++++++++++++++++++++++++++++++++++++---
 loader/modules.h    |    5 +++
 3 files changed, 110 insertions(+), 11 deletions(-)

diff --git a/loader/driverdisk.c b/loader/driverdisk.c
index b0cd179..eb369cb 100644
--- a/loader/driverdisk.c
+++ b/loader/driverdisk.c
@@ -381,6 +381,7 @@ int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
     int rc, num = 0;
     int dir = 1;
     int found = 0, before = 0;
+    VersionState preDDstate, postDDstate;
 
     while (stage != DEV_DONE) {
         switch(stage) {
@@ -583,8 +584,6 @@ int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
         }
 
         case DEV_PROBE: {
-            struct device ** devices;
-
             /* if they didn't specify that we should probe, then we should
              * just fall out */
             if (noprobe) {
@@ -592,16 +591,23 @@ int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
                 break;
             }
 
+            /* Get info about modules before the update */
+            preDDstate = mlVersions();
+
             /* Unload all devices and load them again to use the updated modules */
             logMessage(INFO, "Trying to refresh loaded drivers");
             mlRestoreModuleState(moduleState);
             busProbe(0);
 
-            devices = getDevices(class);
-            if (devices)
-                for(; devices[found]; found++);
+            /* Get info about modules after the update */
+            postDDstate = mlVersions();
+            found = mlDetectUpdate(preDDstate, postDDstate);
+            logMessage(DEBUGLVL, "mlDetectUpdate returned %d", found);
+
+            mlFreeVersions(postDDstate);
+            mlFreeVersions(preDDstate);
 
-            if (found > before) {
+            if (found) {
                 stage = DEV_DONE;
                 break;
             }
diff --git a/loader/modules.c b/loader/modules.c
index 2e3e429..96c7df5 100644
--- a/loader/modules.c
+++ b/loader/modules.c
@@ -415,7 +415,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;
@@ -449,8 +450,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;
@@ -464,13 +466,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;
 
@@ -516,7 +519,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 */;
 }
 
@@ -527,3 +530,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 = (gchar*) calloc(1, sizeof(char));
+
+    /* 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);
+}
diff --git a/loader/modules.h b/loader/modules.h
index 605d01e..675dffc 100644
--- a/loader/modules.h
+++ b/loader/modules.h
@@ -44,4 +44,9 @@ GTree* mlSaveModuleState();
 void mlRestoreModuleState(GTree *state);
 void mlFreeModuleState(GTree *state);
 
+typedef GHashTable* VersionState;
+VersionState mlVersions();
+int mlDetectUpdate(VersionState a, VersionState b);
+void mlFreeVersions();
+
 #endif
-- 
1.6.6.1


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