Subject: session ID changes
To: None <tech-kern@NetBSD.ORG>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 02/12/1998 23:16:50
Folks...

The following change-request was made to FreeBSD recently, and the
person who submitted the change, Tom Proett <proett@nas.nasa.gov>
also sent it to me.  It is equally applicable to NetBSD, and is
somewhat necessary in order to support the batch processing system
we use here at the NAS facility.  We have a desire to use this batch
processing software on NetBSD systems.

The description of the problem is as follows:

-=-=-=-=-=-=-=-=-=-=-

I am working with a batch system that uses the POSIX session to keep track
of which processes comprise a "job".  Under FreeBSD, I use kvm_getprocs()
to get information for all the proceses then use kvm_read() to read
the session structure for each process (pointed to by kp_eproc.e_sess).
It turns out that the s_leader field in the session structure becomes
NULL if the session leader exits.

-=-=-=-=-=-=-=-=-=-=-

The following patch, written by Tom, and integrated into NetBSD-current
by me, creates a "session ID", which is the PID of the session leader.
This value sticks around even when the the session leader exits so that
the session can still be uniquely identified.  The PID in use as the SID
will not be recycled until that session disappears.

Comments?

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-5                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 415 428 6939


Index: sys/kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.115
diff -c -r1.115 init_main.c
*** init_main.c	1998/02/10 14:09:22	1.115
--- init_main.c	1998/02/13 07:18:01
***************
*** 224,229 ****
--- 224,230 ----
  
  	pgrp0.pg_session = &session0;
  	session0.s_count = 1;
+ 	session0.s_sid = p->p_pid;
  	session0.s_leader = p;
  
  	p->p_flag = P_INMEM | P_SYSTEM;
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.38
diff -c -r1.38 kern_fork.c
*** kern_fork.c	1998/02/10 14:09:30	1.38
--- kern_fork.c	1998/02/13 07:18:01
***************
*** 175,190 ****
  again:
  		for (; p2 != 0; p2 = p2->p_list.le_next) {
  			while (p2->p_pid == nextpid ||
! 			    p2->p_pgrp->pg_id == nextpid) {
  				nextpid++;
  				if (nextpid >= pidchecked)
  					goto retry;
  			}
  			if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
  				pidchecked = p2->p_pid;
  			if (p2->p_pgrp->pg_id > nextpid && 
  			    pidchecked > p2->p_pgrp->pg_id)
  				pidchecked = p2->p_pgrp->pg_id;
  		}
  		if (!doingzomb) {
  			doingzomb = 1;
--- 175,196 ----
  again:
  		for (; p2 != 0; p2 = p2->p_list.le_next) {
  			while (p2->p_pid == nextpid ||
! 			    p2->p_pgrp->pg_id == nextpid ||
! 			    p2->p_pgrp->pg_session->s_sid == nextpid) {
  				nextpid++;
  				if (nextpid >= pidchecked)
  					goto retry;
  			}
  			if (p2->p_pid > nextpid && pidchecked > p2->p_pid)
  				pidchecked = p2->p_pid;
+ 
  			if (p2->p_pgrp->pg_id > nextpid && 
  			    pidchecked > p2->p_pgrp->pg_id)
  				pidchecked = p2->p_pgrp->pg_id;
+ 
+ 			if (p2->p_pgrp->pg_session->s_sid > nextpid &&
+ 			    pidchecked > p2->p_pgrp->pg_session->s_sid)
+ 				pidchecked = p2->p_pgrp->pg_session->s_sid;
  		}
  		if (!doingzomb) {
  			doingzomb = 1;
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.20
diff -c -r1.20 kern_proc.c
*** kern_proc.c	1998/02/07 02:44:46	1.20
--- kern_proc.c	1998/02/13 07:18:01
***************
*** 214,219 ****
--- 214,220 ----
  			 */
  			MALLOC(sess, struct session *, sizeof(struct session),
  			    M_SESSION, M_WAITOK);
+ 			sess->s_sid = p->p_pid;
  			sess->s_leader = p;
  			sess->s_count = 1;
  			sess->s_ttyvp = NULL;
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.32
diff -c -r1.32 kern_sysctl.c
*** kern_sysctl.c	1998/02/10 14:09:46	1.32
--- kern_sysctl.c	1998/02/13 07:18:01
***************
*** 783,788 ****
--- 783,789 ----
  	else
  		ep->e_ppid = 0;
  	ep->e_pgid = p->p_pgrp->pg_id;
+ 	ep->e_sid = ep->e_sess->s_sid;
  	ep->e_jobc = p->p_pgrp->pg_jobc;
  	if ((p->p_flag & P_CONTROLT) &&
  	     (tp = ep->e_sess->s_ttyp)) {
Index: sys/miscfs/procfs/procfs_status.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_status.c,v
retrieving revision 1.13
diff -c -r1.13 procfs_status.c
*** procfs_status.c	1996/10/13 02:21:38	1.13
--- procfs_status.c	1998/02/13 07:18:21
***************
*** 76,82 ****
  	ppid = p->p_pptr ? p->p_pptr->p_pid : 0,
  	pgid = p->p_pgrp->pg_id;
  	sess = p->p_pgrp->pg_session;
! 	sid = sess->s_leader ? sess->s_leader->p_pid : 0;
  
  /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid gid groups ... */
  
--- 76,82 ----
  	ppid = p->p_pptr ? p->p_pptr->p_pid : 0,
  	pgid = p->p_pgrp->pg_id;
  	sess = p->p_pgrp->pg_session;
! 	sid = sess->s_sid;
  
  /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid gid groups ... */
  
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.57
diff -c -r1.57 proc.h
*** proc.h	1998/02/10 14:08:48	1.57
--- proc.h	1998/02/13 07:18:37
***************
*** 55,60 ****
--- 55,61 ----
   */
  struct	session {
  	int	s_count;		/* Ref cnt; pgrps in session. */
+ 	pid_t	s_sid;			/* pid of session leader */
  	struct	proc *s_leader;		/* Session leader. */
  	struct	vnode *s_ttyvp;		/* Vnode of controlling terminal. */
  	struct	tty *s_ttyp;		/* Controlling terminal. */
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.24
diff -c -r1.24 sysctl.h
*** sysctl.h	1997/09/19 14:05:53	1.24
--- sysctl.h	1998/02/13 07:18:37
***************
*** 202,207 ****
--- 202,208 ----
  		struct	vmspace e_vm;		/* address space */
  		pid_t	e_ppid;			/* parent process id */
  		pid_t	e_pgid;			/* process group id */
+ 		pid_t	e_sid;			/* session id */
  		short	e_jobc;			/* job control counter */
  		dev_t	e_tdev;			/* controlling tty dev */
  		pid_t	e_tpgid;		/* tty process group id */
Index: bin/ps/keyword.c
===================================================================
RCS file: /cvsroot/src/bin/ps/keyword.c,v
retrieving revision 1.16
diff -c -r1.16 keyword.c
*** keyword.c	1998/02/06 04:47:32	1.16
--- keyword.c	1998/02/13 07:20:12
***************
*** 150,155 ****
--- 150,156 ----
  	UID("ruid", "RUID", evar, EOFF(e_pcred.p_ruid)),
  	{"ruser", "RUSER", NULL, LJUST, runame, USERLEN},
  	{"sess", "SESS", NULL, 0, evar, 6, EOFF(e_sess), KPTR, "x"},
+ 	PID("sid", "SID", evar, EOFF(e_sid)),
  	{"sig", "PENDING", NULL, 0, pvar, 8, POFF(p_siglist), INT, "x"},
  	{"sigcatch", "CAUGHT", NULL, 0, pvar, 8, POFF(p_sigcatch), UINT, "x"},
  	{"sigignore", "IGNORED",