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

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

 



This looks fine, one comment below.

On Thu, 12 Aug 2010, Martin Sivak wrote:

---
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));

Since you are using other glib functions on 'value' including g_free(), you
need to use g_malloc0() or another glib memory management function.  You
cannot mix glib and glibc memory management functions safely:

    http://library.gnome.org/devel/glib/stable/glib-Memory-Allocation.html

+
+    /* 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


--
David Cantrell <dcantrell@xxxxxxxxxx>
Red Hat / Honolulu, HI

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux