Am 04.04.2013 um 10:35 hat Josh Durgin geschrieben:
> QEMU may be compiled against a newer version of librbd, but run and
> dynamically linked with an older version that does not support these
> functions. Declare them as weak symbols so they can be checked for
> existence at runtime.
> 
> Only rbd_aio_discard, rbd_aio_flush, and rbd_flush were added after
> the initial version of librbd, so only they need to be checked.
> 
> Signed-off-by: Josh Durgin <josh.dur...@inktank.com>
> ---
>  block/rbd.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/block/rbd.c b/block/rbd.c
> index 037d82b..69a339a 100644
> --- a/block/rbd.c
> +++ b/block/rbd.c
> @@ -44,6 +44,15 @@
>   * leading "\".
>   */
>  
> +/*
> + * Treat newer librbd functions as weak symbols so we can detect
> + * whether they're supported at runtime, and disable their use
> + * if they aren't available.
> + */
> +#pragma weak rbd_aio_discard
> +#pragma weak rbd_aio_flush
> +#pragma weak rbd_flush
> +
>  /* rbd_aio_discard added in 0.1.2 */
>  #if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 2)
>  #define LIBRBD_SUPPORTS_DISCARD
> @@ -970,6 +979,7 @@ static BlockDriver bdrv_rbd = {
>      .bdrv_aio_readv         = qemu_rbd_aio_readv,
>      .bdrv_aio_writev        = qemu_rbd_aio_writev,
>  
> +    /* select which of these to use at runtime in bdrv_rbd_init */
>      .bdrv_aio_flush         = qemu_rbd_aio_flush,
>      .bdrv_co_flush_to_disk  = qemu_rbd_co_flush,
>  
> @@ -985,6 +995,15 @@ static BlockDriver bdrv_rbd = {
>  
>  static void bdrv_rbd_init(void)
>  {
> +    if (!rbd_flush || rbd_aio_flush) {
> +        bdrv_rbd.bdrv_co_flush_to_disk = NULL;
> +    }
> +    if (!rbd_aio_flush) {
> +        bdrv_rbd.bdrv_aio_flush = NULL;
> +    }
> +    if (!rbd_aio_discard) {
> +        bdrv_rbd.bdrv_aio_discard = NULL;
> +    }
>      bdrv_register(&bdrv_rbd);
>  }

After searching the net a bit and trying out some things myself, I'm
afraid that this approach doesn't work. It does seem to do the right
thing when build and runtime version are the same, but new build -> old
runtime segfaults (because the symbol doesn't become NULL) and old build
-> new runtime segfaults (because the symbol stays NULL). Unless I
missed some build option that is different in qemu than in my test
program.

So it looks as if you had to use dlsym() instead.

Kevin

Reply via email to