
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