On 07/31/2018 09:55 AM, Daniel P. Berrangé wrote:
The jansson and json-glib libraries both export symbols with a json_
name prefix and json_object_iter_next() clashes between them.
Unfortunately json_glib is linked in by GTK, so any app using GTK and
libvirt will get a clash, resulting in SEGV. This also affects the NSS
module provided by libvirt
Instead of directly linking to jansson, use dlopen() with the RTLD_LOCAL
flag which allows us to hide the symbols from the application that loads
libvirt or the NSS module.
Some preprocessor black magic and wrapper functions are used to redirect
calls into the dlopen resolved symbols.
Would using dlmopen() instead of dlopen() make this task any easier?
Otherwise, this looks reasonable to me, and is preferable to Jan's
proposal to revert jansson support.
+++ b/src/util/virjsoncompat.c
+
+static int virJSONJanssonOnceInit(void)
+{
+ void *handle = dlopen("libjansson.so.4",
RTLD_LAZY|RTLD_LOCAL|RTLD_DEEPBIND|RTLD_NODELETE);
RTLD_DEEPBIND might be specific to glibc; is this going to cause any
compilation issues on BSD machines?
+
+VIR_ONCE_GLOBAL_INIT(virJSONJansson);
+
+int virJSONInitialize(void) {
+ return virJSONJanssonInitialize();
+}
+
+json_t *json_array_impl(void)
+{
+ return json_array_ptr();
+}
+
+
+int json_array_append_new_impl(json_t *array, json_t *value)
+{
+ return json_array_append_new_ptr(array, value);
+}
Would it be possible with __typeof__ to write a macro to make this
forwarding more compact (one line per stem, instead of open-coding each
renamed function)? Looking something like:
#define FORWARD(name, params, args) \
__typeof__(name # _impl) name # _impl params { \
return name # _ptr args; \
}
FORWARD(json_array, (void), ())
FORWARD(json_array_append_new, (json_t * array, json_t *value),
(array, value))
(hmm, that's still a bit verbose; I'm not sure if the preprocessor could
be cajoled into even less repetition of parameter names)
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org