tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Enhance ptyfs to handle multiple instances.



DONE.
:)

If seriously, it's first working prototype for comments and objections.

It's working as follow:

Mount first ptyfs instance in /dev/pts(or other path) you can get access to 
master side
through ptm{x} device.

Mount second ptyfs instance inside chroot(Example: /var/chroot/test/dev/pts), 
create ptm{x}
device inside chroot(Ex. /var/chroot/test/dev/ptm{x}). 
Chroot: chroot /var/chroot/test /rescue/sh,
now you can see only second instance in /dev/pts.

 ptyfs_vfsops.c |   47 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

I'm leaving for the weekend till Monday.
Best regards.
Ilya.

Index: fs/ptyfs/ptyfs_vfsops.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_vfsops.c,v
retrieving revision 1.9
diff -u -r1.9 ptyfs_vfsops.c
--- fs/ptyfs/ptyfs_vfsops.c     19 Mar 2014 21:00:16 -0000      1.9
+++ fs/ptyfs/ptyfs_vfsops.c     21 Mar 2014 17:55:54 -0000
@@ -83,6 +83,8 @@
  */
 struct ptm_pty *ptyfs_save_ptm;
 static int ptyfs_count;
+#define PTYFS_MINSTANCE 16
+static struct mount *ptyfs_mp[PTYFS_MINSTANCE] = { NULL };
 
 struct ptm_pty ptm_ptyfspty = {
        ptyfs__allocvp,
@@ -124,13 +126,25 @@
        return rv;
 }
 
+static struct mount *
+ptyfs__mpget(struct lwp *l) {
+       int i;
+       for (i = 0; i < PTYFS_MINSTANCE; i++)
+               if (ptyfs_mp[i] != NULL &&
+                       ptyfs__getpath(l, ptyfs_mp[i]) != NULL)
+                       return ptyfs_mp[i];
+       return NULL;
+}
+
 static int
 ptyfs__makename(struct ptm_pty *pt, struct lwp *l, char *tbuf, size_t bufsiz,
     dev_t dev, char ms)
 {
-       struct mount *mp = pt->arg;
        size_t len;
        const char *np;
+       struct mount *mp = ptyfs__mpget(l);
+       if (mp == NULL)
+               return EOPNOTSUPP;
 
        switch (ms) {
        case 'p':
@@ -157,8 +171,10 @@
 ptyfs__allocvp(struct ptm_pty *pt, struct lwp *l, struct vnode **vpp,
     dev_t dev, char ms)
 {
-       struct mount *mp = pt->arg;
        ptyfstype type;
+       struct mount *mp = ptyfs__mpget(l);
+       if (mp == NULL)
+               return EOPNOTSUPP;
 
        switch (ms) {
        case 'p':
@@ -178,7 +194,7 @@
 static void
 ptyfs__getvattr(struct ptm_pty *pt, struct lwp *l, struct vattr *vattr)
 {
-       struct mount *mp = pt->arg;
+       struct mount *mp = ptyfs__mpget(l);
        struct ptyfsmount *pmnt = VFSTOPTY(mp);
        vattr_null(vattr);
        /* get real uid */
@@ -220,7 +236,7 @@
 ptyfs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
 {
        struct lwp *l = curlwp;
-       int error = 0;
+       int i, error = 0;
        struct ptyfsmount *pmnt;
        struct ptyfs_args *args = data;
 
@@ -247,11 +263,9 @@
                return 0;
        }
 
-#if 0
-       /* Don't allow more than one mount */
-       if (ptyfs_count)
+       /* Don't allow more than PTYFS_MINSTANCE mount */
+       if (PTYFS_MINSTANCE <= ptyfs_count)
                return EBUSY;
-#endif
 
        if (mp->mnt_flag & MNT_UPDATE)
                return EOPNOTSUPP;
@@ -278,10 +292,13 @@
        }
 
        /* Point pty access to us */
-       if (ptyfs_count == 0) {
-               ptm_ptyfspty.arg = mp;
+       if (ptyfs_count == 0)
                ptyfs_save_ptm = pty_sethandler(&ptm_ptyfspty);
-       }
+       for (i = 0; i < PTYFS_MINSTANCE; i++)
+               if (ptyfs_mp[i] == NULL) {
+                       ptyfs_mp[i] = mp;
+                       break;
+               }
        ptyfs_count++;
        return 0;
 }
@@ -297,7 +314,7 @@
 int
 ptyfs_unmount(struct mount *mp, int mntflags)
 {
-       int error;
+       int error, i;
        int flags = 0;
 
        if (mntflags & MNT_FORCE)
@@ -306,6 +323,12 @@
        if ((error = vflush(mp, 0, flags)) != 0)
                return error;
 
+       for (i = 0; i < PTYFS_MINSTANCE; i++)
+               if (ptyfs_mp[i] == mp) {
+                       ptyfs_mp[i] = NULL;
+                       break;
+               }
+
        ptyfs_count--;
        if (ptyfs_count == 0) {
                /* Restore where pty access was pointing */


Home | Main Index | Thread Index | Old Index