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@xxxxxxxxxx> 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 */ > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list