Re: dynamic pty driver...

Greg Alexander (galexand@sietch.bloomington.in.us)
Fri, 20 Mar 1998 11:25:56 -0500 (EST)


On Fri, 20 Mar 1998, Alexander Kjeldaas wrote:

> On Thu, Mar 19, 1998 at 02:31:34PM -0500, Greg Alexander wrote:
> > I'm working on a dynamic pty driver. The purpose being to allow the
> > creation of ptys by normal users (no more suid root screen!) and to allow
> > the creation of an almost unlimited number of ptys without wasting a bunch
> > of RAM for huge arrays on small systems or trying to switch to 16-bit minors
> > or anything like that. The ptys would not have associated files/devices and
> > they'd be made using a syscall similar to pipe() (should I make a new
> > syscall or just an ioctl()?). Another possibility would be to add another
> > filetype for mknod(), S_IFPTY that normal users could create, but this
> > doesn't seem reasonable to me and I am unlikely to bother to implement it.
> > It would be trivial to modify rxvt, screen, etc. to use these instead of
> > /dev/pty* and /dev/tty[p-za-e]?.
> >
> > It looks like the best way to do this is to make a different
> > tty_driver struct for every pty. I'm not sure what major/minor to give
> > them...I was thinking I could probably just make all of them 5,0 (/dev/tty),
> > but this would cause ps to see 5,0 as the tty device in /proc/<pid>/stat so
> > it would list all processes on dptys as being run on /dev/tty...not the most
> > useful solution. I was also considering possibly not adding the tty_driver
> > structs to the actual tty_driver linked list. All the tables would be
> > dynamically allocated with the tty_driver struct and would be created with
> > only one entry.
> >
> > I was just wondering if anyone had any comments, suggestions, etc.,
> > before I go implementing (I haven't done much deep kernel hacking in the
> > past and the whole tty layout is just now beginning to somewhat make a
> > little sense).
> >
> > FYI, this idea is not my own but was suggested to me by Alan Cox (I
> > think...it's been a while).
> >
>
> I have a suggestion :-)
>
> If I remember correctly, the /dev/ptmx device is used to allocate a
> new tty without having to try all the pty* devices in succession. The
> semantics of /dev/ptmx doesn't deal with opening the device as
> non-root but it is basically just making things faster for login and
> others.

The way /dev/ptmx is implemented, it does search through all the ptys
internally. :)

> Now, what we want is a /dev/ptmx which normal users can open as
> well. This could be accomplished by setting ownership when opening
> /dev/ptmx if the calling process is not root. This would be a simple
> extension of the current semantics. For programs that used /dev/ptmx
> already (not many on linux I know..) you can start running it as
> non-root. No code needs to be changed.

I got 2.1.90 right after posting my original message and knew that something
ptmx-like was the right answer.. However, "setting ownership" isn't
properly Unixy. It's even more improper than, say, kmod calling
/sbin/modprobe. :) Most of the problem is that converting kdev_t to inode
is quite a bitch and I don't know how proper it is to assume that
/dev/tty[p-za-e]? are named standardly or to enforce such decisions that a
lot of sysads like to keep for themselves (i.e. what do we do with the
groups). I could just add another /proc variable, I guess...but I really
wanted to make this dynamic. FWIW, I did make a userspace daemon that would
chown slave tty's if the caller opened the master. :)
So... A new device (/dev/dpty?) that, on open, appears similar to
/dev/ptmx...it'll allocate a new pty master (and it looks like the code is
setup such that we'd allocate the slave here too) and make the current file
point to that tty structure. Then the code would call ioctl(TIOCGSPTFD) (or
something)...Get Slave Pseudo-Terminal File Descriptor.
Therefore, /dev/ptmx code like:
master=open("/dev/ptmx",...);
ioctl(master,TIOCGPTN,&ptn); /* Get PT number */
sprintf(s,"/dev/tty%s",ptn_to_string(ptn));
slave=open(s,...);
would be replaced with:
master=open("/dev/dpty",...);
ioctl(master,TIOCGSPTFD,&slave);
No chowning or anything else necessary since the slave tty doesn't actually
exist in the filesystem...the master can only be opened once so it doesn't
matter that subsequent /dev/dpty opens get different masters. Only real
problem is that there's no file for the slave pty, meaning that the program
controlling the master (i.e. rxvt) has to be smart enough to use ioctl if it
wants to reopen the slave again for some reason, and the child programs
(i.e. sh) have to use /dev/tty if they want to open the slave pty.
Only one important question left: Should I bother to number these
slave ptys for some purpose or another? If I number them, should I make the
numbering map the slave pty's to real /dev/tty[a-zA-F]? devices (the whole
range would be available because /dev/pty* could be deleted) or maybe even
map them to /proc space? The former is bad because it's not as dynamic
(though there is a lot of kdev_t space and once the traditional pty majors
are used up, it could start allocating majors from the unused portion or
something) and the latter is somewhat limited similarly (/proc has a finite
number of inodes, and this part would probably be allocated a static number
of inodes), but making a /proc/tty/drivers/dpty/ and filling it with ttypX
(X=number) dynamically shouldn't be too difficult, should it?
I can always go back and implement /proc and other interfaces later.
Do any kernels (of any unix flavor) allocate ptys dynamically yet?

Greg Alexander - also <gralexan@indiana.edu> - http://sietch.home.ml.org/
----
"Trashed filesystems are child's play -- if the hardware ain't smoking,
IT'S RUNNING TOO SLOW!"
-- John Kelly, linux-kernel@vger.rutgers.edu contributor

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu