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(a)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(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
--
best regards
eli