Skip to content

Commit

Permalink
Merge branch 'tty-updates' from Alan
Browse files Browse the repository at this point in the history
* tty-updates: (75 commits)
  serial_8250: support for Sealevel Systems Model 7803 COMM+8
  hso maintainers update patch
  hso modem detect fix patch against Alan Cox'es tty tree
  tty: Fix an ircomm warning and note another bug
  drivers/char/cyclades.c: cy_pci_probe: fix error path
  Serial: UART driver changes for Cavium OCTEON.
  Serial: Allow port type to be specified when calling serial8250_register_port.
  8250: Serial driver changes to support future Cavium OCTEON serial patches.
  8250: Don't clobber spinlocks.
  fix for tty-serial-move-port
  tty: We want the port object to be persistent
  __FUNCTION__ is gcc-specific, use __func__
  serial: RS485 ioctl structure uses __u32 include linux/types.h
  tty: Drop the lock_kernel in the private ioctl hook
  synclink_cs: Convert to tty_port
  tty: use port methods for the rocket driver
  tty: kref the rocket driver
  tty: make rocketport use standard port->flags
  tty: Redo the rocket driver locking
  tty: Make epca use the port helpers
  ...
  • Loading branch information
Linus Torvalds committed Jan 2, 2009
2 parents 609e5b7 + e65f0f8 commit d2fde28
Show file tree
Hide file tree
Showing 64 changed files with 3,538 additions and 2,604 deletions.
132 changes: 132 additions & 0 deletions Documentation/filesystems/devpts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@

To support containers, we now allow multiple instances of devpts filesystem,
such that indices of ptys allocated in one instance are independent of indices
allocated in other instances of devpts.

To preserve backward compatibility, this support for multiple instances is
enabled only if:

- CONFIG_DEVPTS_MULTIPLE_INSTANCES=y, and
- '-o newinstance' mount option is specified while mounting devpts

IOW, devpts now supports both single-instance and multi-instance semantics.

If CONFIG_DEVPTS_MULTIPLE_INSTANCES=n, there is no change in behavior and
this referred to as the "legacy" mode. In this mode, the new mount options
(-o newinstance and -o ptmxmode) will be ignored with a 'bogus option' message
on console.

If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and devpts is mounted without the
'newinstance' option (as in current start-up scripts) the new mount binds
to the initial kernel mount of devpts. This mode is referred to as the
'single-instance' mode and the current, single-instance semantics are
preserved, i.e PTYs are common across the system.

The only difference between this single-instance mode and the legacy mode
is the presence of new, '/dev/pts/ptmx' node with permissions 0000, which
can safely be ignored.

If CONFIG_DEVPTS_MULTIPLE_INSTANCES=y and 'newinstance' option is specified,
the mount is considered to be in the multi-instance mode and a new instance
of the devpts fs is created. Any ptys created in this instance are independent
of ptys in other instances of devpts. Like in the single-instance mode, the
/dev/pts/ptmx node is present. To effectively use the multi-instance mode,
open of /dev/ptmx must be a redirected to '/dev/pts/ptmx' using a symlink or
bind-mount.

Eg: A container startup script could do the following:

$ chmod 0666 /dev/pts/ptmx
$ rm /dev/ptmx
$ ln -s pts/ptmx /dev/ptmx
$ ns_exec -cm /bin/bash

# We are now in new container

$ umount /dev/pts
$ mount -t devpts -o newinstance lxcpts /dev/pts
$ sshd -p 1234

where 'ns_exec -cm /bin/bash' calls clone() with CLONE_NEWNS flag and execs
/bin/bash in the child process. A pty created by the sshd is not visible in
the original mount of /dev/pts.

User-space changes
------------------

In multi-instance mode (i.e '-o newinstance' mount option is specified at least
once), following user-space issues should be noted.

1. If -o newinstance mount option is never used, /dev/pts/ptmx can be ignored
and no change is needed to system-startup scripts.

2. To effectively use multi-instance mode (i.e -o newinstance is specified)
administrators or startup scripts should "redirect" open of /dev/ptmx to
/dev/pts/ptmx using either a bind mount or symlink.

$ mount -t devpts -o newinstance devpts /dev/pts

followed by either

$ rm /dev/ptmx
$ ln -s pts/ptmx /dev/ptmx
$ chmod 666 /dev/pts/ptmx
or
$ mount -o bind /dev/pts/ptmx /dev/ptmx

3. The '/dev/ptmx -> pts/ptmx' symlink is the preferred method since it
enables better error-reporting and treats both single-instance and
multi-instance mounts similarly.

But this method requires that system-startup scripts set the mode of
/dev/pts/ptmx correctly (default mode is 0000). The scripts can set the
mode by, either

- adding ptmxmode mount option to devpts entry in /etc/fstab, or
- using 'chmod 0666 /dev/pts/ptmx'

4. If multi-instance mode mount is needed for containers, but the system
startup scripts have not yet been updated, container-startup scripts
should bind mount /dev/ptmx to /dev/pts/ptmx to avoid breaking single-
instance mounts.

Or, in general, container-startup scripts should use:

mount -t devpts -o newinstance -o ptmxmode=0666 devpts /dev/pts
if [ ! -L /dev/ptmx ]; then
mount -o bind /dev/pts/ptmx /dev/ptmx
fi

When all devpts mounts are multi-instance, /dev/ptmx can permanently be
a symlink to pts/ptmx and the bind mount can be ignored.

5. A multi-instance mount that is not accompanied by the /dev/ptmx to
/dev/pts/ptmx redirection would result in an unusable/unreachable pty.

mount -t devpts -o newinstance lxcpts /dev/pts

immediately followed by:

open("/dev/ptmx")

would create a pty, say /dev/pts/7, in the initial kernel mount.
But /dev/pts/7 would be invisible in the new mount.

6. The permissions for /dev/pts/ptmx node should be specified when mounting
/dev/pts, using the '-o ptmxmode=%o' mount option (default is 0000).

mount -t devpts -o newinstance -o ptmxmode=0644 devpts /dev/pts

The permissions can be later be changed as usual with 'chmod'.

chmod 666 /dev/pts/ptmx

7. A mount of devpts without the 'newinstance' option results in binding to
initial kernel mount. This behavior while preserving legacy semantics,
does not provide strict isolation in a container environment. i.e by
mounting devpts without the 'newinstance' option, a container could
get visibility into the 'host' or root container's devpts.

To workaround this and have strict isolation, all mounts of devpts,
including the mount in the root container, should use the newinstance
option.
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2049,6 +2049,12 @@ M: mikulas@artax.karlin.mff.cuni.cz
W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
S: Maintained

HSO 3G Modem Driver (hso.c)
P: Denis Joseph Barrow
M: d.barow@option.com
W: http://www.pharscape.org
S: Maintained

HTCPEN TOUCHSCREEN DRIVER
P: Pau Oliva Fora
M: pof@eslack.org
Expand Down
13 changes: 12 additions & 1 deletion drivers/char/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ config DIGIEPCA

config ESPSERIAL
tristate "Hayes ESP serial port support"
depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API
depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN
help
This is a driver which supports Hayes ESP serial ports. Both single
port cards and multiport cards are supported. Make sure to read
Expand Down Expand Up @@ -443,6 +443,17 @@ config UNIX98_PTYS
All modern Linux systems use the Unix98 ptys. Say Y unless
you're on an embedded system and want to conserve memory.

config DEVPTS_MULTIPLE_INSTANCES
bool "Support multiple instances of devpts"
depends on UNIX98_PTYS
default n
---help---
Enable support for multiple instances of devpts filesystem.
If you want to have isolated PTY namespaces (eg: in containers),
say Y here. Otherwise, say N. If enabled, each mount of devpts
filesystem with the '-o newinstance' option will create an
independent PTY namespace.

config LEGACY_PTYS
bool "Legacy (BSD) PTY support"
default y
Expand Down
34 changes: 17 additions & 17 deletions drivers/char/amiserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ static __inline__ void rtsdtr_ctrl(int bits)
*/
static void rs_stop(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_stop"))
Expand All @@ -190,7 +190,7 @@ static void rs_stop(struct tty_struct *tty)

static void rs_start(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_start"))
Expand Down Expand Up @@ -861,7 +861,7 @@ static int rs_put_char(struct tty_struct *tty, unsigned char ch)

static void rs_flush_chars(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
Expand Down Expand Up @@ -934,7 +934,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count

static int rs_write_room(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;

if (serial_paranoia_check(info, tty->name, "rs_write_room"))
return 0;
Expand All @@ -943,7 +943,7 @@ static int rs_write_room(struct tty_struct *tty)

static int rs_chars_in_buffer(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;

if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
return 0;
Expand All @@ -952,7 +952,7 @@ static int rs_chars_in_buffer(struct tty_struct *tty)

static void rs_flush_buffer(struct tty_struct *tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
Expand All @@ -969,7 +969,7 @@ static void rs_flush_buffer(struct tty_struct *tty)
*/
static void rs_send_xchar(struct tty_struct *tty, char ch)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_send_char"))
Expand Down Expand Up @@ -1004,7 +1004,7 @@ static void rs_send_xchar(struct tty_struct *tty, char ch)
*/
static void rs_throttle(struct tty_struct * tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
Expand All @@ -1029,7 +1029,7 @@ static void rs_throttle(struct tty_struct * tty)

static void rs_unthrottle(struct tty_struct * tty)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;
#ifdef SERIAL_DEBUG_THROTTLE
char buf[64];
Expand Down Expand Up @@ -1194,7 +1194,7 @@ static int get_lsr_info(struct async_struct * info, unsigned int __user *value)

static int rs_tiocmget(struct tty_struct *tty, struct file *file)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
unsigned char control, status;
unsigned long flags;

Expand All @@ -1217,7 +1217,7 @@ static int rs_tiocmget(struct tty_struct *tty, struct file *file)
static int rs_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
Expand All @@ -1244,7 +1244,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
*/
static int rs_break(struct tty_struct *tty, int break_state)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
unsigned long flags;

if (serial_paranoia_check(info, tty->name, "rs_break"))
Expand All @@ -1264,7 +1264,7 @@ static int rs_break(struct tty_struct *tty, int break_state)
static int rs_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
struct async_icount cprev, cnow; /* kernel counter temps */
struct serial_icounter_struct icount;
void __user *argp = (void __user *)arg;
Expand Down Expand Up @@ -1368,7 +1368,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,

static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
struct async_struct *info = (struct async_struct *)tty->driver_data;
struct async_struct *info = tty->driver_data;
unsigned long flags;
unsigned int cflag = tty->termios->c_cflag;

Expand Down Expand Up @@ -1428,7 +1428,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
*/
static void rs_close(struct tty_struct *tty, struct file * filp)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
struct serial_state *state;
unsigned long flags;

Expand Down Expand Up @@ -1523,7 +1523,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
*/
static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
unsigned long orig_jiffies, char_time;
int lsr;

Expand Down Expand Up @@ -1587,7 +1587,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
*/
static void rs_hangup(struct tty_struct *tty)
{
struct async_struct * info = (struct async_struct *)tty->driver_data;
struct async_struct * info = tty->driver_data;
struct serial_state *state = info->state;

if (serial_paranoia_check(info, tty->name, "rs_hangup"))
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/cyclades.c
Original file line number Diff line number Diff line change
Expand Up @@ -5010,7 +5010,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
if (nchan == 0) {
dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
"Serial-Modules\n");
return -EIO;
goto err_unmap;
}
} else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
struct RUNTIME_9060 __iomem *ctl_addr;
Expand Down
Loading

0 comments on commit d2fde28

Please sign in to comment.