[libvirt] [PATCH] Avoid async signal safety problem in glibc's setxid

Gao feng gaofeng at cn.fujitsu.com
Mon Nov 18 00:32:44 UTC 2013


On 11/16/2013 12:20 AM, Daniel P. Berrange wrote:
> The glibc setxid is supposed to be async signal safe, but
> libc developers confirm that it is not. This causes a problem
> when libvirt_lxc starts the FUSE thread and then runs clone()
> to start the container. If the clone() was done before the
> FUSE thread has completely started up, then the container
> will hang in setxid after clone().
> 
> The fix is to avoid creating any threads until after the
> container has been clone()'d. By avoiding any threads in
> the parent, the child is no longer required to run in an
> async signal safe context, and we thus avoid the glibc
> bug.
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>

AC
thanks

> ---
>  src/lxc/lxc_controller.c | 11 +++++++++--
>  src/lxc/lxc_fuse.c       | 21 +++++++++++++++------
>  src/lxc/lxc_fuse.h       |  1 +
>  3 files changed, 25 insertions(+), 8 deletions(-)
> 
> diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
> index 232af54..c013147 100644
> --- a/src/lxc/lxc_controller.c
> +++ b/src/lxc/lxc_controller.c
> @@ -1983,6 +1983,12 @@ virLXCControllerSetupFuse(virLXCControllerPtr ctrl)
>  }
>  
>  static int
> +virLXCControllerStartFuse(virLXCControllerPtr ctrl)
> +{
> +    return lxcStartFuse(ctrl->fuse);
> +}
> +
> +static int
>  virLXCControllerSetupConsoles(virLXCControllerPtr ctrl,
>                                char **containerTTYPaths)
>  {
> @@ -2187,6 +2193,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
>      if (virLXCControllerMoveInterfaces(ctrl) < 0)
>          goto cleanup;
>  
> +    if (virLXCControllerStartFuse(ctrl) < 0)
> +        goto cleanup;
> +
>      if (lxcContainerSendContinue(control[0]) < 0) {
>          virReportSystemError(errno, "%s",
>                               _("Unable to send container continue message"));
> @@ -2199,8 +2208,6 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
>          goto cleanup;
>      }
>  
> -    /* Now the container is fully setup... */
> -
>      /* ...and reduce our privileges */
>      if (lxcControllerClearCapabilities() < 0)
>          goto cleanup;
> diff --git a/src/lxc/lxc_fuse.c b/src/lxc/lxc_fuse.c
> index 9d12832..88e122e 100644
> --- a/src/lxc/lxc_fuse.c
> +++ b/src/lxc/lxc_fuse.c
> @@ -322,12 +322,6 @@ int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def)
>          goto cleanup1;
>      }
>  
> -    if (virThreadCreate(&fuse->thread, false, lxcFuseRun,
> -                        (void *)fuse) < 0) {
> -        lxcFuseDestroy(fuse);
> -        goto cleanup1;
> -    }
> -
>      ret = 0;
>  cleanup:
>      fuse_opt_free_args(&args);
> @@ -341,6 +335,17 @@ cleanup2:
>      goto cleanup;
>  }
>  
> +int lxcStartFuse(virLXCFusePtr fuse)
> +{
> +    if (virThreadCreate(&fuse->thread, false, lxcFuseRun,
> +                        (void *)fuse) < 0) {
> +        lxcFuseDestroy(fuse);
> +        return -1;
> +    }
> +
> +    return 0;
> +}
> +
>  void lxcFreeFuse(virLXCFusePtr *f)
>  {
>      virLXCFusePtr fuse = *f;
> @@ -364,6 +369,10 @@ int lxcSetupFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED,
>      return 0;
>  }
>  
> +int lxcStartFuse(virLXCFusePtr f ATTRIBUTE_UNUSED)
> +{
> +}
> +
>  void lxcFreeFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED)
>  {
>  }
> diff --git a/src/lxc/lxc_fuse.h b/src/lxc/lxc_fuse.h
> index b3713af..d60492b 100644
> --- a/src/lxc/lxc_fuse.h
> +++ b/src/lxc/lxc_fuse.h
> @@ -58,6 +58,7 @@ struct virLXCFuse {
>  typedef struct virLXCFuse *virLXCFusePtr;
>  
>  extern int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def);
> +extern int lxcStartFuse(virLXCFusePtr f);
>  extern void lxcFreeFuse(virLXCFusePtr *f);
>  
>  #endif /* LXC_FUSE_H */
> 




More information about the libvir-list mailing list