
hi Serge : I checked the code , only in lxc_controller.c call virFileOpenTtyAt(). I didn't test the path, but my suggestion is that modify the utility function in /src/util/util.c instead of adding a new function.
The glibc ones cannot handle ptys opened in a devpts not mounted at /dev/pts.
Signed-off-by: Serge Hallyn<serge.hallyn@canonical.com> --- src/lxc/lxc_controller.c | 82 +++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 89ce7f5..d79f5ba 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -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> @@ -781,6 +783,81 @@ static int lxcSetPersonality(virDomainDefPtr def) #endif
static int +lxcGetTtyGid(void) { + char *grtmpbuf; + struct group grbuf; + size_t grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); + struct group *p; + int ret; + gid_t tty_gid = -1; + + /* Get the group ID of the special `tty' group. */ + if (grbuflen == (size_t) -1L) + /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX. + Try a moderate value. */ + grbuflen = 1024; + + grtmpbuf = (char *) alloca (grbuflen); use this macro VIR_ALLOC_N(ptr, count) to allocate memory and you should also check if it is valid. + ret = getgrnam_r("tty",&grbuf, grtmpbuf, grbuflen,&p); + if (ret || p != NULL) + tty_gid = p->gr_gid; + + return tty_gid == -1 ? getgid() : tty_gid; +} + +#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) /* 0777 */ + +/* heavily borrowed from glibc, but don't assume devpts == "/dev/pts" */ +static int +lxcCreateTty(char *ptmx, int *ttymaster, char **ttyName) +{ + int rc = -1; + int ret; + int ptyno; + uid_t uid; + gid_t gid; + struct stat st; + int unlock = 0; + + if ((*ttymaster = open(ptmx, O_RDWR|O_NOCTTY|O_NONBLOCK))< 0) + goto cleanup; + + if (ioctl(*ttymaster, TIOCSPTLCK,&unlock)< 0) + goto cleanup; + + ret = ioctl(*ttymaster, TIOCGPTN,&ptyno); + if (ret< 0) + goto cleanup; if (ioctl(*ttymaster, TIOCGPTN, &ptyno) < 0) goto clearup; + + ret = fstat(*ttymaster,&st); + + uid = getuid(); + gid = lxcGetTtyGid(); + if (st.st_uid != uid || st.st_gid != gid) + if (fchown(*ttymaster, uid, gid)< 0) + goto cleanup; + + if ((st.st_mode& ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP)) + if (fchmod(*ttymaster, S_IRUSR|S_IWUSR|S_IWGRP)< 0) + goto cleanup; + + if (VIR_ALLOC_N(*ttyName, PATH_MAX)< 0) { + errno = ENOMEM; + goto cleanup; + } + + snprintf(*ttyName, PATH_MAX, "/dev/pts/%d", ptyno); + + rc = 0; + +cleanup: + if (rc != 0) + VIR_FORCE_CLOSE(*ttymaster); + + return rc; +} + +static int lxcControllerRun(virDomainDefPtr def, unsigned int nveths, char **veths, @@ -894,10 +971,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; -- 1.7.5.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- best regards eli