提交 3563c51d 编写于 作者: D Daniel P. Berrange

Avoid async signal safety problem in glibc's setxid

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: NDaniel P. Berrange <berrange@redhat.com>
上级 8c41794a
...@@ -1982,6 +1982,12 @@ virLXCControllerSetupFuse(virLXCControllerPtr ctrl) ...@@ -1982,6 +1982,12 @@ virLXCControllerSetupFuse(virLXCControllerPtr ctrl)
return lxcSetupFuse(&ctrl->fuse, ctrl->def); return lxcSetupFuse(&ctrl->fuse, ctrl->def);
} }
static int
virLXCControllerStartFuse(virLXCControllerPtr ctrl)
{
return lxcStartFuse(ctrl->fuse);
}
static int static int
virLXCControllerSetupConsoles(virLXCControllerPtr ctrl, virLXCControllerSetupConsoles(virLXCControllerPtr ctrl,
char **containerTTYPaths) char **containerTTYPaths)
...@@ -2187,6 +2193,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl) ...@@ -2187,6 +2193,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
if (virLXCControllerMoveInterfaces(ctrl) < 0) if (virLXCControllerMoveInterfaces(ctrl) < 0)
goto cleanup; goto cleanup;
if (virLXCControllerStartFuse(ctrl) < 0)
goto cleanup;
if (lxcContainerSendContinue(control[0]) < 0) { if (lxcContainerSendContinue(control[0]) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Unable to send container continue message")); _("Unable to send container continue message"));
...@@ -2199,8 +2208,6 @@ virLXCControllerRun(virLXCControllerPtr ctrl) ...@@ -2199,8 +2208,6 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
goto cleanup; goto cleanup;
} }
/* Now the container is fully setup... */
/* ...and reduce our privileges */ /* ...and reduce our privileges */
if (lxcControllerClearCapabilities() < 0) if (lxcControllerClearCapabilities() < 0)
goto cleanup; goto cleanup;
......
...@@ -322,12 +322,6 @@ int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def) ...@@ -322,12 +322,6 @@ int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def)
goto cleanup1; goto cleanup1;
} }
if (virThreadCreate(&fuse->thread, false, lxcFuseRun,
(void *)fuse) < 0) {
lxcFuseDestroy(fuse);
goto cleanup1;
}
ret = 0; ret = 0;
cleanup: cleanup:
fuse_opt_free_args(&args); fuse_opt_free_args(&args);
...@@ -341,6 +335,17 @@ cleanup2: ...@@ -341,6 +335,17 @@ cleanup2:
goto cleanup; 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) void lxcFreeFuse(virLXCFusePtr *f)
{ {
virLXCFusePtr fuse = *f; virLXCFusePtr fuse = *f;
...@@ -364,6 +369,10 @@ int lxcSetupFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED, ...@@ -364,6 +369,10 @@ int lxcSetupFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED,
return 0; return 0;
} }
int lxcStartFuse(virLXCFusePtr f ATTRIBUTE_UNUSED)
{
}
void lxcFreeFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED) void lxcFreeFuse(virLXCFusePtr *f ATTRIBUTE_UNUSED)
{ {
} }
......
...@@ -58,6 +58,7 @@ struct virLXCFuse { ...@@ -58,6 +58,7 @@ struct virLXCFuse {
typedef struct virLXCFuse *virLXCFusePtr; typedef struct virLXCFuse *virLXCFusePtr;
extern int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def); extern int lxcSetupFuse(virLXCFusePtr *f, virDomainDefPtr def);
extern int lxcStartFuse(virLXCFusePtr f);
extern void lxcFreeFuse(virLXCFusePtr *f); extern void lxcFreeFuse(virLXCFusePtr *f);
#endif /* LXC_FUSE_H */ #endif /* LXC_FUSE_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册