On Apr 2, 10:36am, net...@izyk.ru (Ilya Zykov) wrote:
-- Subject: Re: Enhance ptyfs to handle multiple instances.
Looks very good. Some changes:
- I don't like the refactoring because it makes ptyfs less optional (brings
in code and headers to the base kernel). I think it is simpler to provide
an entry function to get the mount point instead, and this way all the guts
of ptyfs stay in ptyfs.
- Is it important to append to the list? Then perhaps use a different set
of macros than LIST_. I've changed the code just to prepend.
I hope I did not break it. Comments?
christos
Index: sys/pty.h
===
RCS file: /cvsroot/src/sys/sys/pty.h,v
retrieving revision 1.9
diff -u -p -u -r1.9 pty.h
--- sys/pty.h 27 Mar 2014 17:31:56 - 1.9
+++ sys/pty.h 3 Apr 2014 21:51:03 -
@@ -41,7 +41,7 @@ int pty_grant_slave(struct lwp *, dev_t,
dev_t pty_makedev(char, int);
int pty_vn_open(struct vnode *, struct lwp *);
struct ptm_pty *pty_sethandler(struct ptm_pty *);
-int ptyfs_getmp(struct lwp *, struct mount **);
+int pty_getmp(struct lwp *, struct mount **);
/*
* Ptm_pty is used for switch ptm{x} driver between BSDPTY, PTYFS.
@@ -53,7 +53,7 @@ struct ptm_pty {
char);
int (*makename)(struct mount *, struct lwp *, char *, size_t, dev_t,
char);
void (*getvattr)(struct mount *, struct lwp *, struct vattr *);
- void *arg;
+ int (*getmp)(struct lwp *, struct mount **);
};
#ifdef COMPAT_BSDPTY
Index: fs/ptyfs/ptyfs.h
===
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs.h,v
retrieving revision 1.11
diff -u -p -u -r1.11 ptyfs.h
--- fs/ptyfs/ptyfs.h21 Mar 2014 17:21:53 - 1.11
+++ fs/ptyfs/ptyfs.h3 Apr 2014 21:51:04 -
@@ -106,6 +106,8 @@ struct ptyfsnode {
};
struct ptyfsmount {
+ LIST_ENTRY(ptyfsmount) pmnt_le;
+ struct mount *pmnt_mp;
gid_t pmnt_gid;
mode_t pmnt_mode;
int pmnt_flags;
Index: fs/ptyfs/ptyfs_vfsops.c
===
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vfsops.c,v
retrieving revision 1.48
diff -u -p -u -r1.48 ptyfs_vfsops.c
--- fs/ptyfs/ptyfs_vfsops.c 27 Mar 2014 17:31:56 - 1.48
+++ fs/ptyfs/ptyfs_vfsops.c 3 Apr 2014 21:51:04 -
@@ -77,6 +77,7 @@ static int ptyfs__allocvp(struct mount *
static int ptyfs__makename(struct mount *, struct lwp *, char *, size_t,
dev_t, char);
static void ptyfs__getvattr(struct mount *, struct lwp *, struct vattr *);
+static int ptyfs__getmp(struct lwp *, struct mount **);
/*
* ptm glue: When we mount, we make ptm point to us.
@@ -84,13 +85,37 @@ static void ptyfs__getvattr(struct mount
struct ptm_pty *ptyfs_save_ptm;
static int ptyfs_count;
+static LIST_HEAD(, ptyfsmount) ptyfs_head;
+
struct ptm_pty ptm_ptyfspty = {
ptyfs__allocvp,
ptyfs__makename,
ptyfs__getvattr,
- NULL
+ ptyfs__getmp,
};
+static int
+ptyfs__getmp(struct lwp *l, struct mount **mpp)
+{
+ struct cwdinfo *cwdi = l->l_proc->p_cwdi;
+ struct mount *mp;
+ struct ptyfsmount *pmnt;
+
+ LIST_FOREACH(pmnt, &ptyfs_head, pmnt_le) {
+ mp = pmnt->pmnt_mp;
+ if (cwdi->cwdi_rdir == NULL)
+ goto ok;
+
+ if (vn_isunder(mp->mnt_vnodecovered, cwdi->cwdi_rdir, l))
+ goto ok;
+ }
+ *mpp = NULL;
+ return EOPNOTSUPP;
+ok:
+ *mpp = mp;
+ return 0;
+}
+
static const char *
ptyfs__getpath(struct lwp *l, const struct mount *mp)
{
@@ -137,6 +162,18 @@ ptyfs__makename(struct mount *mp, struct
len = snprintf(tbuf, bufsiz, "/dev/null");
break;
case 't':
+ /*
+* We support traditional ptys, so we can get here,
+* if pty had been opened before PTYFS was mounted,
+* or was opened through /dev/ptyXX devices.
+* Return it only outside chroot for more security :).
+*/
+ if (l->l_proc->p_cwdi->cwdi_rdir == NULL
+ && ptyfs_save_ptm != NULL
+ && ptyfs_used_get(PTYFSptc, minor(dev), mp, 0) == NULL)
+ return (*ptyfs_save_ptm->makename)(mp, l,
+ tbuf, bufsiz, dev, ms);
+
np = ptyfs__getpath(l, mp);
if (np == NULL)
return EOPNOTSUPP;
@@ -189,6 +226,7 @@ void
ptyfs_init(void)
{
+ LIST_INIT(&ptyfs_head);
malloc_type_attach(M_PTYFSMNT);
malloc_type_attach(M_PTYFSTMP);
ptyfs_hashinit();
@@ -274,9 +312,9 @@ ptyfs_mount(struct mount *mp, const char
return error;
}
- /* Point pty access to us */
- if (ptyfs_count == 0) {
- ptm_ptyfspty.arg = mp;
+ LIST_INSERT_HEAD(&ptyfs_head, p