提交 4c87afe0 编写于 作者: D Daniel P. Berrange

Move /dev/pts setup out of virLXCControllerRun

The virLXCControllerRun method is getting a little too large,
and about 50% of its code is related to setting up a /dev/pts
mount. Move the latter out into a dedicated method
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 25aa0532
...@@ -119,6 +119,7 @@ struct _virLXCController { ...@@ -119,6 +119,7 @@ struct _virLXCController {
size_t nconsoles; size_t nconsoles;
virLXCControllerConsolePtr consoles; virLXCControllerConsolePtr consoles;
char *devptmx;
size_t nloopDevs; size_t nloopDevs;
int *loopDevFds; int *loopDevFds;
...@@ -236,6 +237,8 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl) ...@@ -236,6 +237,8 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
VIR_FORCE_CLOSE(ctrl->handshakeFd); VIR_FORCE_CLOSE(ctrl->handshakeFd);
VIR_FREE(ctrl->devptmx);
virDomainDefFree(ctrl->def); virDomainDefFree(ctrl->def);
VIR_FREE(ctrl->name); VIR_FREE(ctrl->name);
...@@ -1546,45 +1549,27 @@ cleanup: ...@@ -1546,45 +1549,27 @@ cleanup:
return ret; return ret;
} }
static int static int
virLXCControllerRun(virLXCControllerPtr ctrl, virLXCControllerSetupDevPTS(virLXCControllerPtr ctrl)
int monitor,
int client)
{ {
int rc = -1; virDomainFSDefPtr root = virDomainGetRootFilesystem(ctrl->def);
int control[2] = { -1, -1};
int containerhandshake[2] = { -1, -1 };
char **containerTTYPaths = NULL;
virDomainFSDefPtr root;
char *devpts = NULL;
char *devptmx = NULL;
size_t i;
char *mount_options = NULL; char *mount_options = NULL;
char *opts;
char *devpts = NULL;
int ret = -1;
if (VIR_ALLOC_N(containerTTYPaths, ctrl->nconsoles) < 0) { if (!root) {
virReportOOMError(); if (ctrl->nconsoles != 1) {
goto cleanup; lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
} _("Expected exactly one console, but got %zu"),
ctrl->nconsoles);
if (socketpair(PF_UNIX, SOCK_STREAM, 0, control) < 0) { return -1;
virReportSystemError(errno, "%s", }
_("sockpair failed")); return 0;
goto cleanup;
}
if (socketpair(PF_UNIX, SOCK_STREAM, 0, containerhandshake) < 0) {
virReportSystemError(errno, "%s",
_("socketpair failed"));
goto cleanup;
} }
if (virLXCControllerSetupLoopDevices(ctrl) < 0) VIR_DEBUG("Setting up private /dev/pts");
goto cleanup;
root = virDomainGetRootFilesystem(ctrl->def);
if (lxcSetContainerResources(ctrl->def) < 0)
goto cleanup;
/* /*
* If doing a chroot style setup, we need to prepare * If doing a chroot style setup, we need to prepare
...@@ -1606,85 +1591,87 @@ virLXCControllerRun(virLXCControllerPtr ctrl, ...@@ -1606,85 +1591,87 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
* into slave mode, just in case it was currently * into slave mode, just in case it was currently
* marked as shared * marked as shared
*/ */
if (root) { mount_options = virSecurityManagerGetMountOptions(ctrl->securityManager,
mount_options = virSecurityManagerGetMountOptions(ctrl->securityManager, ctrl->def);
ctrl->def);
char *opts;
VIR_DEBUG("Setting up private /dev/pts");
if (!virFileExists(root->src)) { if (!virFileExists(root->src)) {
virReportSystemError(errno, virReportSystemError(errno,
_("root source %s does not exist"), _("root source %s does not exist"),
root->src); root->src);
goto cleanup; goto cleanup;
} }
if (unshare(CLONE_NEWNS) < 0) { if (unshare(CLONE_NEWNS) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Cannot unshare mount namespace")); _("Cannot unshare mount namespace"));
goto cleanup; goto cleanup;
} }
if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Failed to switch root mount into slave mode")); _("Failed to switch root mount into slave mode"));
goto cleanup; goto cleanup;
} }
if (virAsprintf(&devpts, "%s/dev/pts", root->src) < 0 || if (virAsprintf(&devpts, "%s/dev/pts", root->src) < 0 ||
virAsprintf(&devptmx, "%s/dev/pts/ptmx", root->src) < 0) { virAsprintf(&ctrl->devptmx, "%s/dev/pts/ptmx", root->src) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
if (virFileMakePath(devpts) < 0) { if (virFileMakePath(devpts) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("Failed to make path %s"), _("Failed to make path %s"),
devpts); devpts);
goto cleanup; goto cleanup;
} }
/* XXX should we support gid=X for X!=5 for distros which use /* XXX should we support gid=X for X!=5 for distros which use
* a different gid for tty? */ * a different gid for tty? */
if (virAsprintf(&opts, "newinstance,ptmxmode=0666,mode=0620,gid=5%s", if (virAsprintf(&opts, "newinstance,ptmxmode=0666,mode=0620,gid=5%s",
(mount_options ? mount_options : "")) < 0) { (mount_options ? mount_options : "")) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
VIR_DEBUG("Mount devpts on %s type=tmpfs flags=%x, opts=%s", VIR_DEBUG("Mount devpts on %s type=tmpfs flags=%x, opts=%s",
devpts, MS_NOSUID, opts); devpts, MS_NOSUID, opts);
if (mount("devpts", devpts, "devpts", MS_NOSUID, opts) < 0) { if (mount("devpts", devpts, "devpts", MS_NOSUID, opts) < 0) {
VIR_FREE(opts); virReportSystemError(errno,
virReportSystemError(errno, _("Failed to mount devpts on %s"),
_("Failed to mount devpts on %s"), devpts);
devpts); goto cleanup;
goto cleanup; }
}
VIR_FREE(opts);
if (access(devptmx, R_OK) < 0) { if (access(ctrl->devptmx, R_OK) < 0) {
VIR_WARN("Kernel does not support private devpts, using shared devpts"); VIR_WARN("Kernel does not support private devpts, using shared devpts");
VIR_FREE(devptmx); VIR_FREE(ctrl->devptmx);
}
} else {
if (ctrl->nconsoles != 1) {
lxcError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Expected exactly one console, but got %zu"),
ctrl->nconsoles);
goto cleanup;
}
} }
ret = 0;
cleanup:
VIR_FREE(opts);
VIR_FREE(devpts);
return ret;
}
static int
virLXCControllerSetupConsoles(virLXCControllerPtr ctrl,
char **containerTTYPaths)
{
size_t i;
for (i = 0 ; i < ctrl->nconsoles ; i++) { for (i = 0 ; i < ctrl->nconsoles ; i++) {
if (devptmx) { if (ctrl->devptmx) {
VIR_DEBUG("Opening tty on private %s", devptmx); VIR_DEBUG("Opening tty on private %s", ctrl->devptmx);
if (lxcCreateTty(devptmx, if (lxcCreateTty(ctrl->devptmx,
&ctrl->consoles[i].contFd, &ctrl->consoles[i].contFd,
&containerTTYPaths[i]) < 0) { &containerTTYPaths[i]) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Failed to allocate tty")); _("Failed to allocate tty"));
goto cleanup; return -1;
} }
} else { } else {
VIR_DEBUG("Opening tty on shared /dev/ptmx"); VIR_DEBUG("Opening tty on shared /dev/ptmx");
...@@ -1693,10 +1680,53 @@ virLXCControllerRun(virLXCControllerPtr ctrl, ...@@ -1693,10 +1680,53 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
0) < 0) { 0) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Failed to allocate tty")); _("Failed to allocate tty"));
goto cleanup; return -1;
} }
} }
} }
return 0;
}
static int
virLXCControllerRun(virLXCControllerPtr ctrl,
int monitor,
int client)
{
int rc = -1;
int control[2] = { -1, -1};
int containerhandshake[2] = { -1, -1 };
char **containerTTYPaths = NULL;
size_t i;
if (VIR_ALLOC_N(containerTTYPaths, ctrl->nconsoles) < 0) {
virReportOOMError();
goto cleanup;
}
if (socketpair(PF_UNIX, SOCK_STREAM, 0, control) < 0) {
virReportSystemError(errno, "%s",
_("sockpair failed"));
goto cleanup;
}
if (socketpair(PF_UNIX, SOCK_STREAM, 0, containerhandshake) < 0) {
virReportSystemError(errno, "%s",
_("socketpair failed"));
goto cleanup;
}
if (virLXCControllerSetupLoopDevices(ctrl) < 0)
goto cleanup;
if (lxcSetContainerResources(ctrl->def) < 0)
goto cleanup;
if (virLXCControllerSetupDevPTS(ctrl) < 0)
goto cleanup;
if (virLXCControllerSetupConsoles(ctrl, containerTTYPaths) < 0)
goto cleanup;
if (lxcSetPersonality(ctrl->def) < 0) if (lxcSetPersonality(ctrl->def) < 0)
goto cleanup; goto cleanup;
...@@ -1755,9 +1785,6 @@ virLXCControllerRun(virLXCControllerPtr ctrl, ...@@ -1755,9 +1785,6 @@ virLXCControllerRun(virLXCControllerPtr ctrl,
monitor = client = -1; monitor = client = -1;
cleanup: cleanup:
VIR_FREE(mount_options);
VIR_FREE(devptmx);
VIR_FREE(devpts);
VIR_FORCE_CLOSE(control[0]); VIR_FORCE_CLOSE(control[0]);
VIR_FORCE_CLOSE(control[1]); VIR_FORCE_CLOSE(control[1]);
VIR_FORCE_CLOSE(containerhandshake[0]); VIR_FORCE_CLOSE(containerhandshake[0]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册