Date: Sat, 17 Mar 2001 03:49:49 +0100 (CET) From: Cyrille Lefevre <clefevre@poboxes.com> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/25866: more than 256 ptys, up to 1302 ptys. Message-ID: <200103170249.f2H2nnr03955@gits.dyndns.org>
next in thread | raw e-mail | index | archive | help
>Number: 25866 >Category: kern >Synopsis: more than 256 ptys, up to 1302 ptys. >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Mar 16 18:50:00 PST 2001 >Closed-Date: >Last-Modified: >Originator: Cyrille Lefevre >Release: FreeBSD 4.3-BETA i386 >Organization: ACME >Environment: System: FreeBSD gits 4.3-BETA FreeBSD 4.3-BETA #18: Sat Mar 17 02:17:40 CET 2001 root@:/disk2/4.x-stable/src/sys/compile/CUSTOM i386 >Description: for years, it is not possible to have more than 256 opened ptys at a time. this patch deals w/ minor numbers greater than 255 and allow up to 1302 ptys to be opened using the following pty names : /dev/[pt]ty[p-uw-zP-Z][0-9a-zA-Z] ^^ v cannot be used bcoz it clash w/ the syscons driver. same assertion about xyz (Cronyx/Sigma) and R (Rocketport), but I suggest to move them to something else since their names aren't used internaly by the kernel. something such as efg and h ? >How-To-Repeat: exec sh ptyclassnames=pqrstuwxyzPQRSTUVWXYZ ptyinstancenames=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ nptyclass=${#ptyclassnames} nptyinstance=${#ptyinstancenames} npty=$(($nptyclass*$nptyinstance)) ofiles=$(($npty*3)) cat << \EOF > testpty.c #include <sys/types.h> #include <sys/ioctl.h> #include <termios.h> #include <libutil.h> #include <stdio.h> #include <stdlib.h> int main () { int i, l = 0; int m [npty], s [npty]; char n [npty][11]; for (i = 0; i < npty; i++) if (openpty (&m [i], &s [i], n [i], (struct termios *)0, (struct winsize *)0) < 0) { perror ("openpty"); fprintf (stderr, "last pty = %d\n", l); break; } else printf ("%d = %s\n", l = i, n [i]); for (i = 0; i <= l; i++) close (m [i]), close (s [i]); return (0); } EOF make testpty CFLAGS=-Dnpty=$npty LDFLAGS=-lutil sysctl -w kern.maxfiles=$ofiles sysctl -w kern.maxfilesperproc=$ofiles ulimit -n $ofiles ./testpty > /dev/null # should give the following results less the currently opened ptys. openpty: No such file or directory last pty = 1302 >Fix: Index: etc/MAKEDEV =================================================================== RCS file: /home/ncvs/src/etc/MAKEDEV,v retrieving revision 1.243.2.24 diff -u -r1.243.2.24 MAKEDEV --- etc/MAKEDEV 2001/03/06 01:40:08 1.243.2.24 +++ etc/MAKEDEV 2001/03/17 02:10:07 @@ -231,6 +231,19 @@ echo $(((($1 >> 8) << 16) | ($1 % 256))) } +# Convert pty (class,instance) to minor number +# Handle pty minor numbers greater than 256 +ptyminor() +{ + echo $(( (( ($1 + $2) &~ 255) << 8) | (($1 + $2) & 255) )) +} + +# *MUST* be the same as in sys/kern/tty_pty.c and lib/libutil/pty.c +ptyclassnames=pqrstuwxyzPQRSTUVWXYZ +ptyinstancenames=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ +nptyclass=${#ptyclassnames} +nptyinstance=${#ptyinstancenames} + # Raw partition for disks dkrawpart=2 @@ -707,34 +720,26 @@ done ;; pty*) - class=`expr $i : 'pty\(.*\)'` - case $class in - 0) offset=0 name=p;; - 1) offset=32 name=q;; - 2) offset=64 name=r;; - 3) offset=96 name=s;; -# Note that xterm (at least) only look at p-s. - 4) offset=128 name=P;; - 5) offset=160 name=Q;; - 6) offset=192 name=R;; - 7) offset=224 name=S;; - # This still leaves [tuTU]. - *) echo bad unit for pty in: $i;; - esac umask 0 - case $class in - 0|1|2|3|4|5|6|7) + class=`expr $i : 'pty\(.*\)'` + if [ -n "$class" -a "$class" -lt $nptyclass ]; then + name=$(echo $ptyclassnames | + dd bs=1 skip=$class count=1 2>/dev/null) + offset=$(($class * $nptyintance)) i=0 - while [ $i -lt 32 ]; do + while [ $i -lt $nptyintance ]; do # This was an awk substr() before. - c=$(echo 0123456789abcdefghijklmnopqrstuv | + c=$(echo $ptyinstancenames | dd bs=1 skip=$i count=1 2>/dev/null) - mknod tty$name$c c 5 $(($offset + $i)) - mknod pty$name$c c 6 $(($offset + $i)) + minor=$(ptyminor $offset $i) + rm -f tty$name$c pty$name$c + mknod tty$name$c c 5 $minor + mknod pty$name$c c 6 $minor i=$(($i + 1)) done - ;; - esac + else + echo bad unit for pty in: $i + fi umask 77 ;; Index: lib/libutil/pty.c =================================================================== RCS file: /home/ncvs/src/lib/libutil/pty.c,v retrieving revision 1.10 diff -u -r1.10 pty.c --- lib/libutil/pty.c 1999/08/28 00:05:51 1.10 +++ lib/libutil/pty.c 2001/03/17 02:01:06 @@ -53,6 +53,10 @@ #include <unistd.h> #include <libutil.h> +/* *MUST* be the same as in sys/kern/tty_pty.c and etc/MAKEDEV */ +#define ptyclassnames "pqrstuwxyzPQRSTUVWXYZ" +#define ptyinstancenames "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + int openpty(amaster, aslave, name, termp, winp) int *amaster, *aslave; @@ -70,9 +74,9 @@ else ttygid = -1; - for (cp1 = "pqrsPQRS"; *cp1; cp1++) { + for (cp1 = ptyclassnames; *cp1; cp1++) { line[8] = *cp1; - for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { + for (cp2 = ptyinstancenames; *cp2; cp2++) { line[5] = 'p'; line[9] = *cp2; if ((master = open(line, O_RDWR, 0)) == -1) { Index: share/man/man4/pty.4 =================================================================== RCS file: /home/ncvs/src/share/man/man4/pty.4,v retrieving revision 1.8.2.1 diff -u -r1.8.2.1 pty.4 --- share/man/man4/pty.4 2000/12/08 14:59:07 1.8.2.1 +++ share/man/man4/pty.4 2001/03/17 02:01:16 @@ -191,10 +191,10 @@ is required. .El .Sh FILES -.Bl -tag -width /dev/tty[p-sP-S][0-9a-v]x -compact -.It Pa /dev/pty[p-sP-S][0-9a-v] +.Bl -tag -width /dev/tty[p-uw-zP-Z][0-9a-zA-Z]x -compact +.It Pa /dev/pty[p-uw-zP-Z][0-9a-zA-Z] master pseudo terminals -.It Pa /dev/tty[p-sP-S][0-9a-v] +.It Pa /dev/tty[p-uw-zP-Z][0-9a-zA-Z] slave pseudo terminals .El .Sh DIAGNOSTICS Index: sys/kern/tty_pty.c =================================================================== RCS file: /home/ncvs/src/sys/kern/tty_pty.c,v retrieving revision 1.74.2.1 diff -u -r1.74.2.1 tty_pty.c --- sys/kern/tty_pty.c 2001/02/26 04:23:16 1.74.2.1 +++ sys/kern/tty_pty.c 2001/03/17 02:01:41 @@ -129,33 +129,55 @@ #define PF_NOSTOP 0x40 #define PF_UCNTL 0x80 /* user control mode */ +/* the opposite of lminor() */ +#define ptyminor(x) ((((x) &~ 255) << 8) | ((x) & 255)) +/* *MUST* be the same as in lib/libutil/pty.c and etc/MAKEDEV */ +#define ptyclassnames "pqrstuwxyzPQRSTUVWXYZ" +#define ptyinstancenames "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define nptyclass (sizeof(ptyclassnames)-1) +#define nptyinstance (sizeof(ptyinstancenames)-1) +#define npty (nptyclass*nptyinstance) + /* * This function creates and initializes a pts/ptc pair + * + * pts == /dev/tty[p-uw-zP-Z][0-9a-zA-Z] + * ptc == /dev/pty[p-uw-zP-Z][0-9a-zA-Z] * - * pts == /dev/tty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] - * ptc == /dev/pty[pqrsPQRS][0123456789abcdefghijklmnopqrstuv] + * don't use the "v" master/slave pair bcoz it clash w/ the syscons driver. + * same assertion about the less used Cronyx/Sigma (xyz) and Rocketport (R) + * drivers. * - * XXX: define and add mapping of upper minor bits to allow more - * than 256 ptys. */ static void ptyinit(n) int n; { dev_t devs, devc; - char *names = "pqrsPQRS"; + char *classes = ptyclassnames; + char *instances = ptyinstancenames; struct pt_ioctl *pt; - /* For now we only map the lower 8 bits of the minor */ - if (n & ~0xff) +#ifdef notdef + if (bootverbose) + printf ("ptyinit: n(%d) <= %d\n", n, npty); +#endif + /* be safe */ + if (n >= npty) return; - +#ifdef notdef + if (bootverbose) + printf ("ptyinit: makedev([tp]ty%c%c)\n", + classes[n / nptyinstance], instances[n % nptyinstance]); +#endif pt = malloc(sizeof(*pt), M_PTY, M_WAITOK); bzero(pt, sizeof(*pt)); - pt->devs = devs = make_dev(&pts_cdevsw, n, - 0, 0, 0666, "tty%c%r", names[n / 32], n % 32); - pt->devc = devc = make_dev(&ptc_cdevsw, n, - 0, 0, 0666, "pty%c%r", names[n / 32], n % 32); + pt->devs = devs = make_dev(&pts_cdevsw, ptyminor(n), + 0, 0, 0666, "tty%c%c", + classes[n / nptyinstance], instances[n % nptyinstance]); + pt->devc = devc = make_dev(&ptc_cdevsw, ptyminor(n), + 0, 0, 0666, "pty%c%c", + classes[n / nptyinstance], instances[n % nptyinstance]); devs->si_drv1 = devc->si_drv1 = pt; devs->si_tty = devc->si_tty = &pt->pt_tty; @@ -171,7 +193,7 @@ { register struct tty *tp; int error; - int minr; + int minr, nextminr; dev_t nextdev; struct pt_ioctl *pti; @@ -181,14 +203,19 @@ * next one too, so people can open it. */ minr = lminor(dev); - if (minr < 255) { - nextdev = makedev(major(dev), minr + 1); - if (!nextdev->si_drv1) { - ptyinit(minr + 1); - } + nextminr = minr+1; + if (nextminr < npty) { + nextdev = makedev(major(dev), ptyminor(nextminr)); + if (!nextdev->si_drv1) + ptyinit(nextminr); } if (!dev->si_drv1) - ptyinit(minor(dev)); + ptyinit(minr); +#ifdef notdef + if (bootverbose) + printf ("ptyopen: makedev(%d:%#x)\n", + major(dev), ptyminor(minr)); +#endif if (!dev->si_drv1) return(ENXIO); pti = dev->si_drv1; @@ -351,9 +378,9 @@ struct pt_ioctl *pti; if (!dev->si_drv1) - ptyinit(minor(dev)); + ptyinit(lminor(dev)); if (!dev->si_drv1) - return(ENXIO); + return(ENXIO); tp = dev->si_tty; if (tp->t_oproc) return (EIO); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103170249.f2H2nnr03955>