lkml.org 
[lkml]   [2006]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[RFC][PATCH 07/20] tty: Update the tty layer to work with pspaces.
From
Date

Of kernel subsystems that work with pids the tty layer
is probably the largest consumer. But it has the nice
virtue that the association with a session only lasts until
the session leader exits. Which means that no reference
counting is required. Only caching of the pspace,
and a few extra comparisons.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>


---

drivers/char/n_tty.c | 9 ++++---
drivers/char/tty_io.c | 62 ++++++++++++++++++++++++++++++-------------------
include/linux/tty.h | 1 +
3 files changed, 44 insertions(+), 28 deletions(-)

5de29104be4f33d4dca8246e13d2996c1ce745b3
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index ccad7ae..5edfd13 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -580,7 +580,7 @@ static void eraser(unsigned char c, stru
static inline void isig(int sig, struct tty_struct *tty, int flush)
{
if (tty->pgrp > 0)
- kill_pg(tty->pgrp, sig, 1);
+ kill_pg(tty->pspace, tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
n_tty_flush_buffer(tty);
if (tty->driver->flush_buffer)
@@ -1187,11 +1187,12 @@ static int job_control(struct tty_struct
current->signal->tty == tty) {
if (tty->pgrp <= 0)
printk("read_chan: tty->pgrp <= 0!\n");
- else if (process_group(current) != tty->pgrp) {
+ else if ((process_group(current) != tty->pgrp) ||
+ (current->pspace != tty->pspace)) {
if (is_ignored(SIGTTIN) ||
- is_orphaned_pgrp(process_group(current)))
+ is_orphaned_pgrp(current->pspace, process_group(current)))
return -EIO;
- kill_pg(process_group(current), SIGTTIN, 1);
+ kill_pg(current->pspace, process_group(current), SIGTTIN, 1);
return -ERESTARTSYS;
}
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 1d83cd5..b6f3004 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -95,6 +95,7 @@
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/pspace.h>

#include <asm/uaccess.h>
#include <asm/system.h>
@@ -858,13 +859,14 @@ int tty_check_change(struct tty_struct *
printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
return 0;
}
- if (process_group(current) == tty->pgrp)
+ if ((process_group(current) == tty->pgrp) &&
+ (current->pspace == tty->pspace))
return 0;
if (is_ignored(SIGTTOU))
return 0;
- if (is_orphaned_pgrp(process_group(current)))
+ if (is_orphaned_pgrp(current->pspace, process_group(current)))
return -EIO;
- (void) kill_pg(process_group(current), SIGTTOU, 1);
+ (void) kill_pg(current->pspace, process_group(current), SIGTTOU, 1);
return -ERESTARTSYS;
}

@@ -1070,7 +1072,7 @@ static void do_tty_hangup(void *data)

read_lock(&tasklist_lock);
if (tty->session > 0) {
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+ do_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p) {
if (p->signal->tty == tty)
p->signal->tty = NULL;
if (!p->signal->leader)
@@ -1079,11 +1081,12 @@ static void do_tty_hangup(void *data)
group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
if (tty->pgrp > 0)
p->signal->tty_old_pgrp = tty->pgrp;
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
+ } while_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p);
}
read_unlock(&tasklist_lock);

tty->flags = 0;
+ tty->pspace = NULL;
tty->session = 0;
tty->pgrp = -1;
tty->ctrl_status = 0;
@@ -1162,6 +1165,7 @@ void disassociate_ctty(int on_exit)
{
struct tty_struct *tty;
struct task_struct *p;
+ struct pspace *tty_pspace = NULL;
int tty_pgrp = -1;

lock_kernel();
@@ -1170,35 +1174,37 @@ void disassociate_ctty(int on_exit)
tty = current->signal->tty;
if (tty) {
tty_pgrp = tty->pgrp;
+ tty_pspace = tty->pspace;
up(&tty_sem);
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
} else {
if (current->signal->tty_old_pgrp) {
- kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
- kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
+ kill_pg(current->pspace, current->signal->tty_old_pgrp, SIGHUP, on_exit);
+ kill_pg(current->pspace, current->signal->tty_old_pgrp, SIGCONT, on_exit);
}
up(&tty_sem);
unlock_kernel();
return;
}
if (tty_pgrp > 0) {
- kill_pg(tty_pgrp, SIGHUP, on_exit);
+ kill_pg(tty_pspace, tty_pgrp, SIGHUP, on_exit);
if (!on_exit)
- kill_pg(tty_pgrp, SIGCONT, on_exit);
+ kill_pg(tty_pspace, tty_pgrp, SIGCONT, on_exit);
}

/* Must lock changes to tty_old_pgrp */
down(&tty_sem);
current->signal->tty_old_pgrp = 0;
+ tty->pspace = NULL;
tty->session = 0;
tty->pgrp = -1;

/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
- do_each_task_pid(current->signal->session, PIDTYPE_SID, p) {
+ do_each_task_pid(current->pspace, current->signal->session, PIDTYPE_SID, p) {
p->signal->tty = NULL;
- } while_each_task_pid(current->signal->session, PIDTYPE_SID, p);
+ } while_each_task_pid(current->pspace, current->signal->session, PIDTYPE_SID, p);
read_unlock(&tasklist_lock);
up(&tty_sem);
unlock_kernel();
@@ -1905,13 +1911,13 @@ static void release_dev(struct file * fi
struct task_struct *p;

read_lock(&tasklist_lock);
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+ do_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p) {
p->signal->tty = NULL;
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
+ } while_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p);
if (o_tty)
- do_each_task_pid(o_tty->session, PIDTYPE_SID, p) {
+ do_each_task_pid(o_tty->pspace, o_tty->session, PIDTYPE_SID, p) {
p->signal->tty = NULL;
- } while_each_task_pid(o_tty->session, PIDTYPE_SID, p);
+ } while_each_task_pid(o_tty->pspace, o_tty->session, PIDTYPE_SID, p);
read_unlock(&tasklist_lock);
}

@@ -2110,6 +2116,7 @@ got_driver:
current->signal->tty = tty;
task_unlock(current);
current->signal->tty_old_pgrp = 0;
+ tty->pspace = current->pspace;
tty->session = current->signal->session;
tty->pgrp = process_group(current);
}
@@ -2270,9 +2277,9 @@ static int tiocswinsz(struct tty_struct
}
#endif
if (tty->pgrp > 0)
- kill_pg(tty->pgrp, SIGWINCH, 1);
+ kill_pg(tty->pspace, tty->pgrp, SIGWINCH, 1);
if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
- kill_pg(real_tty->pgrp, SIGWINCH, 1);
+ kill_pg(real_tty->pspace, real_tty->pgrp, SIGWINCH, 1);
tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws;
return 0;
@@ -2342,9 +2349,9 @@ static int tiocsctty(struct tty_struct *
*/

read_lock(&tasklist_lock);
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+ do_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p) {
p->signal->tty = NULL;
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
+ } while_each_task_pid(tty->pspace, tty->session, PIDTYPE_SID, p);
read_unlock(&tasklist_lock);
} else
return -EPERM;
@@ -2353,6 +2360,7 @@ static int tiocsctty(struct tty_struct *
current->signal->tty = tty;
task_unlock(current);
current->signal->tty_old_pgrp = 0;
+ tty->pspace = current->pspace;
tty->session = current->signal->session;
tty->pgrp = process_group(current);
return 0;
@@ -2360,17 +2368,22 @@ static int tiocsctty(struct tty_struct *

static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ pid_t pgrp;
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(real_tty->pgrp, p);
+ pgrp = real_tty->pgrp;
+ if (real_tty->pspace != current->pspace)
+ pgrp = -1;
+ return put_user(pgrp, p);
}

static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ struct pspace *pspace = current->pspace;
pid_t pgrp;
int retval = tty_check_change(real_tty);

@@ -2380,13 +2393,14 @@ static int tiocspgrp(struct tty_struct *
return retval;
if (!current->signal->tty ||
(current->signal->tty != real_tty) ||
- (real_tty->session != current->signal->session))
+ (real_tty->session != current->signal->session) ||
+ (real_tty->pspace != pspace))
return -ENOTTY;
if (get_user(pgrp, p))
return -EFAULT;
if (pgrp < 0)
return -EINVAL;
- if (session_of_pgrp(pgrp) != current->signal->session)
+ if (session_of_pgrp(pspace, pgrp) != current->signal->session)
return -EPERM;
real_tty->pgrp = pgrp;
return 0;
@@ -2676,12 +2690,12 @@ static void __do_SAK(void *arg)

read_lock(&tasklist_lock);
/* Kill the entire session */
- do_each_task_pid(session, PIDTYPE_SID, p) {
+ do_each_task_pid(tty->pspace, session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): p->signal->session==tty->session\n",
p->pid, p->comm);
send_sig(SIGKILL, p, 1);
- } while_each_task_pid(session, PIDTYPE_SID, p);
+ } while_each_task_pid(tty->pspace, session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the
* tty open.
*/
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 898d593..bc9e9c4 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -184,6 +184,7 @@ struct tty_struct {
struct semaphore termios_sem;
struct termios *termios, *termios_locked;
char name[64];
+ struct pspace *pspace;
int pgrp;
int session;
unsigned long flags;
--
1.1.5.g3480
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-02-06 20:47    [W:0.103 / U:1.444 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site