mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
lxc: use hand-rolled code in place of unlockpt and grantpt
The glibc ones (intentionally) cannot handle ptys opened in a devpts not mounted at /dev/pts. Drop the (un-exported, unused) virFileOpenTtyAt. Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
99e2505210
commit
80710c69fe
@ -41,6 +41,8 @@
|
||||
#include <locale.h>
|
||||
#include <linux/loop.h>
|
||||
#include <dirent.h>
|
||||
#include <grp.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if HAVE_CAPNG
|
||||
# include <cap-ng.h>
|
||||
@ -780,6 +782,50 @@ static int lxcSetPersonality(virDomainDefPtr def)
|
||||
# define MS_SLAVE (1<<19)
|
||||
#endif
|
||||
|
||||
/* Create a private tty using the private devpts at PTMX, returning
|
||||
* the master in *TTYMASTER and the name of the slave, _from the
|
||||
* perspective of the guest after remounting file systems_, in
|
||||
* *TTYNAME. Heavily borrowed from glibc, but doesn't require that
|
||||
* devpts == "/dev/pts" */
|
||||
static int
|
||||
lxcCreateTty(char *ptmx, int *ttymaster, char **ttyName)
|
||||
{
|
||||
int ret = -1;
|
||||
int ptyno;
|
||||
int unlock = 0;
|
||||
|
||||
if ((*ttymaster = open(ptmx, O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (ioctl(*ttymaster, TIOCSPTLCK, &unlock) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (ioctl(*ttymaster, TIOCGPTN, &ptyno) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* If mount() succeeded at honoring newinstance, then the kernel
|
||||
* was new enough to also honor the mode=0620,gid=5 options, which
|
||||
* guarantee that the new pty already has correct permissions; so
|
||||
* while glibc has to fstat(), fchmod(), and fchown() for older
|
||||
* kernels, we can skip those steps. ptyno shouldn't currently be
|
||||
* anything other than 0, but let's play it safe. */
|
||||
if (virAsprintf(ttyName, "/dev/pts/%d", ptyno) < 0) {
|
||||
virReportOOMError();
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (ret != 0) {
|
||||
VIR_FORCE_CLOSE(*ttymaster);
|
||||
VIR_FREE(*ttyName);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
lxcControllerRun(virDomainDefPtr def,
|
||||
unsigned int nveths,
|
||||
@ -877,6 +923,8 @@ lxcControllerRun(virDomainDefPtr def,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* XXX should we support gid=X for X!=5 for distros which use
|
||||
* a different gid for tty? */
|
||||
VIR_DEBUG("Mounting 'devpts' on %s", devpts);
|
||||
if (mount("devpts", devpts, "devpts", 0,
|
||||
"newinstance,ptmxmode=0666,mode=0620,gid=5") < 0) {
|
||||
@ -894,10 +942,7 @@ lxcControllerRun(virDomainDefPtr def,
|
||||
|
||||
if (devptmx) {
|
||||
VIR_DEBUG("Opening tty on private %s", devptmx);
|
||||
if (virFileOpenTtyAt(devptmx,
|
||||
&containerPty,
|
||||
&containerPtyPath,
|
||||
0) < 0) {
|
||||
if (lxcCreateTty(devptmx, &containerPty, &containerPtyPath) < 0) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Failed to allocate tty"));
|
||||
goto cleanup;
|
||||
|
@ -1103,22 +1103,17 @@ virFileBuildPath(const char *dir, const char *name, const char *ext)
|
||||
int virFileOpenTty(int *ttymaster,
|
||||
char **ttyName,
|
||||
int rawmode)
|
||||
{
|
||||
return virFileOpenTtyAt("/dev/ptmx",
|
||||
ttymaster,
|
||||
ttyName,
|
||||
rawmode);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
int virFileOpenTtyAt(const char *ptmx,
|
||||
int *ttymaster,
|
||||
char **ttyName,
|
||||
int rawmode)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
if ((*ttymaster = open(ptmx, O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
|
||||
#ifdef WIN32
|
||||
/* mingw completely lacks pseudo-terminals, and the gnulib
|
||||
* replacements are not (yet) license compatible. */
|
||||
errno = ENOSYS;
|
||||
|
||||
#else /* !WIN32 */
|
||||
|
||||
if ((*ttymaster = posix_openpt(O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (unlockpt(*ttymaster) < 0)
|
||||
@ -1156,19 +1151,9 @@ cleanup:
|
||||
if (rc != 0)
|
||||
VIR_FORCE_CLOSE(*ttymaster);
|
||||
|
||||
#endif /* !WIN32 */
|
||||
return rc;
|
||||
|
||||
}
|
||||
#else
|
||||
int virFileOpenTtyAt(const char *ptmx ATTRIBUTE_UNUSED,
|
||||
int *ttymaster ATTRIBUTE_UNUSED,
|
||||
char **ttyName ATTRIBUTE_UNUSED,
|
||||
int rawmode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Creates an absolute path for a potentially relative path.
|
||||
|
Loading…
Reference in New Issue
Block a user