Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125135
b: refs/heads/master
c: 80618fa
h: refs/heads/master
i:
  125133: a51d690
  125131: 8ff74cd
  125127: 327328e
  125119: 437cb9f
v: v3
  • Loading branch information
Linus Torvalds committed Jan 2, 2009
1 parent 3bd6cdd commit 871db53
Show file tree
Hide file tree
Showing 72 changed files with 3,575 additions and 2,632 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b21a207141d83a06abc5f492b80204602e02ca44
refs/heads/master: 80618fa83a34a26199fa99cfd06476a81ddf57df
132 changes: 132 additions & 0 deletions trunk/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.
12 changes: 9 additions & 3 deletions trunk/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 Expand Up @@ -2635,13 +2641,13 @@ W: http://www.hansenpartnership.com/voyager
S: Maintained

LINUX FOR POWERPC (32-BIT AND 64-BIT)
P: Paul Mackerras
M: paulus@samba.org
P: Benjamin Herrenschmidt
M: benh@kernel.crashing.org
P: Paul Mackerras
M: paulus@samba.org
W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
T: git kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc.git
T: git kernel.org:/pub/scm/linux/kernel/git/benh/powerpc.git
S: Supported

LINUX FOR POWER MACINTOSH
Expand Down
8 changes: 6 additions & 2 deletions trunk/arch/x86/mm/init_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,12 @@ static void __init set_highmem_pages_init(void)
#endif /* !CONFIG_NUMA */

#else
# define permanent_kmaps_init(pgd_base) do { } while (0)
# define set_highmem_pages_init() do { } while (0)
static inline void permanent_kmaps_init(pgd_t *pgd_base)
{
}
static inline void set_highmem_pages_init(void)
{
}
#endif /* CONFIG_HIGHMEM */

void __init native_pagetable_setup_start(pgd_t *base)
Expand Down
13 changes: 12 additions & 1 deletion trunk/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 trunk/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 trunk/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 871db53

Please sign in to comment.