Date: Wed, 18 Dec 2013 12:50:44 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r259549 - in head/sys: kern sys Message-ID: <201312181250.rBICoi48091807@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Wed Dec 18 12:50:43 2013 New Revision: 259549 URL: http://svnweb.freebsd.org/changeset/base/259549 Log: - Rename tty_makedev() into tty_makedevf() and make it capable to fail and return error. - Use make_dev_p() in tty_makedevf() instead of make_dev_cred(). - Always pass MAKEDEV_CHECKNAME flag. - Optionally pass MAKEDEV_REF flag. - Provide macro for compatibility with old API. This fixes races with simultaneous creation and desctruction of ttys, and makes it possible to call tty_makedevf() from device cloners. A race in tty_watermarks() still exist, since the latter drops lock for M_WAITOK allocation. This will be addressed in separate commit. Reviewed by: kib Sponsored by: Nginx, Inc. Modified: head/sys/kern/tty.c head/sys/sys/tty.h Modified: head/sys/kern/tty.c ============================================================================== --- head/sys/kern/tty.c Wed Dec 18 12:18:17 2013 (r259548) +++ head/sys/kern/tty.c Wed Dec 18 12:50:43 2013 (r259549) @@ -289,7 +289,7 @@ ttydev_open(struct cdev *dev, int oflags goto done; ttydisc_open(tp); - tty_watermarks(tp); + tty_watermarks(tp); /* XXXGL: drops lock */ } /* Wait for Carrier Detect. */ @@ -1174,16 +1174,18 @@ SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTY * the user. */ -void -tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...) +int +tty_makedevf(struct tty *tp, struct ucred *cred, int flags, + const char *fmt, ...) { va_list ap; - struct cdev *dev; + struct cdev *dev, *init, *lock, *cua, *cinit, *clock; const char *prefix = "tty"; char name[SPECNAMELEN - 3]; /* for "tty" and "cua". */ uid_t uid; gid_t gid; mode_t mode; + int error; /* Remove "tty" prefix from devices like PTY's. */ if (tp->t_flags & TF_NOPREFIX) @@ -1205,57 +1207,92 @@ tty_makedev(struct tty *tp, struct ucred mode = S_IRUSR|S_IWUSR|S_IWGRP; } + flags = flags & TTYMK_CLONING ? MAKEDEV_REF : 0; + flags |= MAKEDEV_CHECKNAME; + /* Master call-in device. */ - dev = make_dev_cred(&ttydev_cdevsw, 0, cred, - uid, gid, mode, "%s%s", prefix, name); + error = make_dev_p(flags, &dev, &ttydev_cdevsw, cred, uid, gid, mode, + "%s%s", prefix, name); + if (error) + return (error); dev->si_drv1 = tp; wakeup(&dev->si_drv1); tp->t_dev = dev; + init = lock = cua = cinit = clock = NULL; + /* Slave call-in devices. */ if (tp->t_flags & TF_INITLOCK) { - dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_INIT, cred, - uid, gid, mode, "%s%s.init", prefix, name); - dev_depends(tp->t_dev, dev); - dev->si_drv1 = tp; - wakeup(&dev->si_drv1); - dev->si_drv2 = &tp->t_termios_init_in; - - dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_LOCK, cred, - uid, gid, mode, "%s%s.lock", prefix, name); - dev_depends(tp->t_dev, dev); - dev->si_drv1 = tp; - wakeup(&dev->si_drv1); - dev->si_drv2 = &tp->t_termios_lock_in; + error = make_dev_p(flags, &init, &ttyil_cdevsw, cred, uid, + gid, mode, "%s%s.init", prefix, name); + if (error) + goto fail; + dev_depends(dev, init); + dev2unit(init) = TTYUNIT_INIT; + init->si_drv1 = tp; + wakeup(&init->si_drv1); + init->si_drv2 = &tp->t_termios_init_in; + + error = make_dev_p(flags, &lock, &ttyil_cdevsw, cred, uid, + gid, mode, "%s%s.lock", prefix, name); + if (error) + goto fail; + dev_depends(dev, lock); + dev2unit(lock) = TTYUNIT_LOCK; + lock->si_drv1 = tp; + wakeup(&lock->si_drv1); + lock->si_drv2 = &tp->t_termios_lock_in; } /* Call-out devices. */ if (tp->t_flags & TF_CALLOUT) { - dev = make_dev_cred(&ttydev_cdevsw, TTYUNIT_CALLOUT, cred, + error = make_dev_p(flags, &cua, &ttydev_cdevsw, cred, UID_UUCP, GID_DIALER, 0660, "cua%s", name); - dev_depends(tp->t_dev, dev); - dev->si_drv1 = tp; - wakeup(&dev->si_drv1); + if (error) + goto fail; + dev_depends(dev, cua); + dev2unit(cua) = TTYUNIT_CALLOUT; + cua->si_drv1 = tp; + wakeup(&cua->si_drv1); /* Slave call-out devices. */ if (tp->t_flags & TF_INITLOCK) { - dev = make_dev_cred(&ttyil_cdevsw, - TTYUNIT_CALLOUT | TTYUNIT_INIT, cred, + error = make_dev_p(flags, &cinit, &ttyil_cdevsw, cred, UID_UUCP, GID_DIALER, 0660, "cua%s.init", name); - dev_depends(tp->t_dev, dev); - dev->si_drv1 = tp; - wakeup(&dev->si_drv1); - dev->si_drv2 = &tp->t_termios_init_out; + if (error) + goto fail; + dev_depends(dev, cinit); + dev2unit(cinit) = TTYUNIT_CALLOUT | TTYUNIT_INIT; + cinit->si_drv1 = tp; + wakeup(&cinit->si_drv1); + cinit->si_drv2 = &tp->t_termios_init_out; - dev = make_dev_cred(&ttyil_cdevsw, - TTYUNIT_CALLOUT | TTYUNIT_LOCK, cred, + error = make_dev_p(flags, &clock, &ttyil_cdevsw, cred, UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name); - dev_depends(tp->t_dev, dev); - dev->si_drv1 = tp; - wakeup(&dev->si_drv1); - dev->si_drv2 = &tp->t_termios_lock_out; + if (error) + goto fail; + dev_depends(dev, clock); + dev2unit(clock) = TTYUNIT_CALLOUT | TTYUNIT_LOCK; + clock->si_drv1 = tp; + wakeup(&clock->si_drv1); + clock->si_drv2 = &tp->t_termios_lock_out; } } + + return (0); + +fail: + destroy_dev(dev); + if (init) + destroy_dev(init); + if (lock) + destroy_dev(lock); + if (cinit) + destroy_dev(cinit); + if (clock) + destroy_dev(clock); + + return (error); } /* Modified: head/sys/sys/tty.h ============================================================================== --- head/sys/sys/tty.h Wed Dec 18 12:18:17 2013 (r259548) +++ head/sys/sys/tty.h Wed Dec 18 12:50:43 2013 (r259549) @@ -171,8 +171,11 @@ void tty_rel_gone(struct tty *tp); #define tty_getlock(tp) ((tp)->t_mtx) /* Device node creation. */ -void tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...) - __printflike(3, 4); +int tty_makedevf(struct tty *tp, struct ucred *cred, int flags, + const char *fmt, ...) __printflike(4, 5); +#define TTYMK_CLONING 0x1 +#define tty_makedev(tp, cred, fmt, ...) \ + (void )tty_makedevf((tp), (cred), 0, (fmt), ## __VA_ARGS__) #define tty_makealias(tp,fmt,...) \ make_dev_alias((tp)->t_dev, fmt, ## __VA_ARGS__)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312181250.rBICoi48091807>