[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