summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/session.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys/session.h')
-rw-r--r--usr/src/uts/common/sys/session.h115
1 files changed, 78 insertions, 37 deletions
diff --git a/usr/src/uts/common/sys/session.h b/usr/src/uts/common/sys/session.h
index 639d6bf69d..8db8a8a5bb 100644
--- a/usr/src/uts/common/sys/session.h
+++ b/usr/src/uts/common/sys/session.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,54 +36,96 @@
extern "C" {
#endif
+/*
+ * Session structure overview.
+ *
+ * Currently, the only structure in the kernel which has a pointer to a
+ * session structures is the proc_t via the p_sessp pointer. To
+ * access a session proc_t->p_sessp pointer a caller must hold either
+ * pidlock or p_splock. These locks only protect the p_sessp pointer
+ * itself and do not protect any of the contents of the session structure.
+ * To prevent the contents of a the session structure from changing the
+ * caller must grab s_lock.
+ *
+ * No callers should ever update the contents of the session structure
+ * directly. Only the session management code should ever modify the
+ * contents of the session structure. When the session code attempts
+ * to modify the contents of a session structure it must hold multiple
+ * locks. The locking order for all the locks that may need to be
+ * acquired is:
+ * sd_lock -> pidlock -> p_splock -> s_lock
+ *
+ * If a caller requires access to a session structure for long
+ * periods of time or across operations that may block it should
+ * use the tty_hold() and sess_hold() interfaces.
+ *
+ * sess_hold() returns a pointer to a session structure associated
+ * with the proc_t that was passed in. It also increments the reference
+ * count associated with that session structure to ensure that it
+ * can't be freed until after the caller is done with it and calls
+ * sess_rele(). This hold doesn't actually protect any of the
+ * contents of the session structure.
+ *
+ * tty_hold() returns a pointer to a session structure associated
+ * with the curproc. It also "locks" the contents of the session
+ * structure. This hold should be used when the caller will be
+ * doing operations on a controlling tty associated with the session.
+ * This operation doesn an implicit sess_hold() so that the session
+ * structure can't be free'd until after the caller is done with it
+ * and invokes tty_rele().
+ *
+ * NOTE: Neither of these functions (sess_hold() or tty_hold())
+ * prevent a process from changing its session. Once these functions
+ * return a session pointer, that session pointer may no longer be
+ * associated with the current process. If a caller wants to prevent
+ * a process from changing its session then it must hold pidlock or
+ * p_splock.
+ */
+
typedef struct sess {
- uint_t s_ref; /* reference count */
- dev_t s_dev; /* tty's device number */
- struct vnode *s_vp; /* tty's vnode */
- struct pid *s_sidp; /* session ID info */
- struct cred *s_cred; /* allocation credentials */
- kmutex_t s_lock; /* sync s_vp use with freectty */
- kcondvar_t s_wait_cv; /* Condvar for sleeping */
- int s_cnt; /* # of active users of this session */
- int s_flag; /* session state flag see below */
-} sess_t;
+ struct pid *s_sidp; /* session ID info, never changes */
-#define SESS_CLOSE 1 /* session about to close */
-#define s_sid s_sidp->pid_id
+ kmutex_t s_lock; /* protects everything below */
+ uint_t s_ref; /* reference count */
+ boolean_t s_sighuped; /* ctty had sighup sent to it */
-#if defined(_KERNEL)
+ boolean_t s_exit; /* sesion leader is exiting */
+ kcondvar_t s_exit_cv; /* Condvar for s_exit */
-extern sess_t session0;
+ int s_cnt; /* active users of this ctty */
+ kcondvar_t s_cnt_cv; /* Condvar for s_cnt */
-#define SESS_HOLD(sp) (++(sp)->s_ref)
-#define SESS_RELE(sp) sess_rele(sp)
+ /*
+ * The following fields can only be updated while s_lock is held
+ * and s_cnt is 0. (ie, no one has a tty_hold() on this session.)
+ */
+ dev_t s_dev; /* tty's device number */
+ struct vnode *s_vp; /* tty's vnode */
+ struct cred *s_cred; /* allocation credentials */
+} sess_t;
-/*
- * Used to synchronize session vnode users with freectty()
- */
+#define s_sid s_sidp->pid_id
-#define TTY_HOLD(sp) { \
- mutex_enter(&(sp)->s_lock); \
- (++(sp)->s_cnt); \
- mutex_exit(&(sp)->s_lock); \
-}
+#if defined(_KERNEL)
-#define TTY_RELE(sp) { \
- mutex_enter(&(sp)->s_lock); \
- if ((--(sp)->s_cnt) == 0) \
- cv_signal(&(sp)->s_wait_cv); \
- mutex_exit(&(sp)->s_lock); \
-}
+extern sess_t session0;
/* forward referenced structure tags */
struct vnode;
struct proc;
+struct stdata;
+
+extern void sess_hold(proc_t *p);
+extern void sess_rele(sess_t *, boolean_t);
+extern sess_t *tty_hold(void);
+extern void tty_rele(sess_t *sp);
+
-extern void sess_rele(sess_t *);
extern void sess_create(void);
-extern void freectty(sess_t *);
-extern void alloctty(struct proc *, struct vnode *);
+extern int strctty(struct stdata *);
+extern int freectty(boolean_t);
extern dev_t cttydev(struct proc *);
+extern void ctty_clear_sighuped(void);
#endif /* defined(_KERNEL) */