summaryrefslogtreecommitdiff
path: root/util/module.c
diff options
context:
space:
mode:
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>2020-03-10 15:58:06 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2020-03-16 23:02:22 +0100
commitbd83c861c0628a64997b7bd95c3bcc2e916baf2e (patch)
tree1d0596f9e89538d3a6284f43556fd1fcbf43ef11 /util/module.c
parent5b42bc5ce9ab4a3171819feea5042931817211fd (diff)
modules: load modules from versioned /var/run dir
On upgrades the old .so files usually are replaced. But on the other hand since a qemu process represents a guest instance it is usually kept around. That makes late addition of dynamic features e.g. 'hot-attach of a ceph disk' fail by trying to load a new version of e.f. block-rbd.so into an old still running qemu binary. This adds a fallback to also load modules from a versioned directory in the temporary /var/run path. That way qemu is providing a way for packaging to store modules of an upgraded qemu package as needed until the next reboot. An example how that can then be used in packaging can be seen in: https://git.launchpad.net/~paelzer/ubuntu/+source/qemu/log/?h=bug-1847361-miss-old-so-on-upgrade-UBUNTU Fixes: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1847361 Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20200310145806.18335-2-christian.ehrhardt@canonical.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'util/module.c')
-rw-r--r--util/module.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/util/module.c b/util/module.c
index 236a7bb52a..5f7896870a 100644
--- a/util/module.c
+++ b/util/module.c
@@ -19,6 +19,9 @@
#endif
#include "qemu/queue.h"
#include "qemu/module.h"
+#ifdef CONFIG_MODULE_UPGRADES
+#include "qemu-version.h"
+#endif
typedef struct ModuleEntry
{
@@ -170,6 +173,9 @@ bool module_load_one(const char *prefix, const char *lib_name)
#ifdef CONFIG_MODULES
char *fname = NULL;
char *exec_dir;
+#ifdef CONFIG_MODULE_UPGRADES
+ char *version_dir;
+#endif
const char *search_dir;
char *dirs[4];
char *module_name;
@@ -201,6 +207,14 @@ bool module_load_one(const char *prefix, const char *lib_name)
dirs[n_dirs++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
dirs[n_dirs++] = g_strdup_printf("%s/..", exec_dir ? : "");
dirs[n_dirs++] = g_strdup_printf("%s", exec_dir ? : "");
+
+#ifdef CONFIG_MODULE_UPGRADES
+ version_dir = g_strcanon(g_strdup(QEMU_PKGVERSION),
+ G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "+-.~",
+ '_');
+ dirs[n_dirs++] = g_strdup_printf("/var/run/qemu/%s", version_dir);
+#endif
+
assert(n_dirs <= ARRAY_SIZE(dirs));
g_free(exec_dir);