Index: lib/libc/shlib_version
===================================================================
RCS file: /cvs/OpenBSD/src/lib/libc/shlib_version,v
retrieving revision 1.112
retrieving revision 1.112.4.2
diff -u -r1.112 -r1.112.4.2
--- lib/libc/shlib_version	24 Jul 2008 09:31:06 -0000	1.112
+++ lib/libc/shlib_version	13 Feb 2009 09:08:58 -0000	1.112.4.2
@@ -1,4 +1,4 @@
 major=48
-minor=0
+minor=3
 # note: If changes were made to include/thread_private.h or if system
 # calls were added/changed then libpthread must also be updated.
Index: lib/libc/gen/errlist.c
===================================================================
RCS file: /cvs/OpenBSD/src/lib/libc/gen/errlist.c,v
retrieving revision 1.12
retrieving revision 1.12.6.2
diff -u -r1.12 -r1.12.6.2
--- lib/libc/gen/errlist.c	3 Sep 2007 14:37:52 -0000	1.12
+++ lib/libc/gen/errlist.c	13 Feb 2009 09:08:58 -0000	1.12.6.2
@@ -144,5 +144,7 @@
 	"Operation canceled",			/* 88 - ECANCELED */
 	"Identifier removed",			/* 89 - EIDRM */
 	"No message of desired type",		/* 90 - ENOMSG */
+	"No such instance",			/* 91 - EINSTSRCH */
+	"Instance exists",			/* 92 - EINSTEXIT */
 };
 int _sys_nerr = { sizeof _sys_errlist/sizeof _sys_errlist[0] };
Index: lib/libc/gen/sysctl.3
===================================================================
RCS file: /cvs/OpenBSD/src/lib/libc/gen/sysctl.3,v
retrieving revision 1.181
retrieving revision 1.181.4.2
diff -u -r1.181 -r1.181.4.2
--- lib/libc/gen/sysctl.3	30 May 2008 19:09:42 -0000	1.181
+++ lib/libc/gen/sysctl.3	31 Jan 2009 19:14:52 -0000	1.181.4.2
@@ -402,6 +402,7 @@
 .It Dv KERN_FSYNC No "	integer	no"
 .It Dv KERN_HOSTID No "	integer	yes"
 .It Dv KERN_HOSTNAME No "	string	yes"
+.It Dv KERN_INST No "	struct kinfo_inst	no"
 .It Dv KERN_INTRCNT No "	node	not applicable"
 .It Dv KERN_JOB_CONTROL No "	integer	no"
 .It Dv KERN_MALLOCSTATS No "	node	no"
@@ -427,6 +428,7 @@
 .It Dv KERN_POSIX1 No "	integer	no"
 .It Dv KERN_PROC No "	struct kinfo_proc	no"
 .It Dv KERN_PROC2 No "	struct kinfo_proc2	no"
+.It Dv KERN_INSTPROC2 No "	struct kinfo_proc2	no"
 .It Dv KERN_PROC_ARGS No "	node	not applicable"
 .It Dv KERN_PROF No "	node	not applicable"
 .It Dv KERN_RAWPARTITION No "	integer	no"
@@ -552,6 +554,22 @@
 Get or set the host ID.
 .It Dv KERN_HOSTNAME
 Get or set the hostname.
+.It Dv KERN_INST
+Like
+.Dv KERN_PROC2
+but an array of
+.Li struct kinfo_inst
+structures is returned.
+The fifth level name is the size of the
+.Li struct kinfo_inst
+and the sixth level name is the number of structures to return.  The
+third and fourth level names are as follows:
+.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent
+.It Sy Third level name	Fourth level is:
+.It Dv KERN_INST_ALL No "	None"
+.It Dv KERN_INST_INSTID No "	An instance ID"
+.El
+.Pp
 .It Dv KERN_JOB_CONTROL
 Return 1 if job control is available on this system, otherwise 0.
 .It Dv KERN_MALLOCSTATS
@@ -698,6 +716,13 @@
 returns the argv array and
 .Dv KERN_PROC_ENV
 returns the environ array.
+.It Dv KERN_INSTPROC2
+Exactly like
+.Dv KERN_PROC2
+but accepting a third-level argument of the instance ID.  The remaining
+arguments are as those of
+.Dv KERN_PROC2
+from the third-level downward.
 .It Dv KERN_PROF
 Return profiling information about the kernel.
 If the kernel is not compiled for profiling,
@@ -2192,7 +2217,8 @@
 An attempt to change a value protected by the current kernel security
 level is made.
 .It Bq Er ESRCH
-No process could be found which corresponds to the given process ID.
+No process could be found which corresponds to the given process ID, or
+no instance could be found corresponding to a given instance ID.
 .El
 .Sh SEE ALSO
 .Xr pathconf 2 ,
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvs/OpenBSD/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.85
retrieving revision 1.85.4.2
diff -u -r1.85 -r1.85.4.2
--- lib/libc/sys/Makefile.inc	22 Mar 2008 19:18:42 -0000	1.85
+++ lib/libc/sys/Makefile.inc	13 Feb 2009 09:08:58 -0000	1.85.4.2
@@ -38,15 +38,16 @@
 	chown.o chroot.o clock_gettime.o clock_settime.o clock_getres.o \
 	close.o closefrom.o connect.o dup.o dup2.o execve.o fchdir.o \
 	fchflags.o fchmod.o fchown.o fcntl.o fhopen.o fhstat.o fhstatfs.o \
-	flock.o fpathconf.o fstat.o \
+	flock.o forkinst.o fpathconf.o fstat.o \
 	fstatfs.o fsync.o futimes.o getdirentries.o getegid.o geteuid.o \
-	getfh.o getfsstat.o getgid.o getgroups.o getitimer.o getpeereid.o \
+	getfh.o getfsstat.o getgid.o getgroups.o getinstid.o \
+	getitimer.o getpeereid.o \
 	getpeername.o \
 	getpgid.o \
 	getpgrp.o getpid.o getppid.o getpriority.o getresgid.o getresuid.o \
 	getrlimit.o getrusage.o getsid.o \
 	getsockname.o getsockopt.o gettimeofday.o getuid.o issetugid.o \
-	ioctl.o kill.o kevent.o kqueue.o \
+	ioctl.o kill.o killinst.o kevent.o kqueue.o \
 	ktrace.o lchown.o lfs_bmapv.o lfs_markv.o lfs_segclean.o lfs_segwait.o \
 	link.o listen.o lstat.o madvise.o mincore.o minherit.o mkdir.o \
 	mkfifo.o mknod.o mlock.o mlockall.o \
@@ -213,12 +214,12 @@
 	chflags.2 \
 	chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 closefrom.2 connect.2 \
 	dup.2 execve.2 _exit.2 fcntl.2 fhopen.2 \
-	flock.2 fork.2 fsync.2 getdirentries.2 \
+	flock.2 fork.2 forkinst.2 fsync.2 getdirentries.2 \
 	getfh.2 getfsstat.2 getgid.2 getgroups.2 getitimer.2 getlogin.2 \
 	getpeername.2 getpeereid.2 getpgrp.2 \
 	getpid.2 getpriority.2 getrlimit.2 getrusage.2 getsid.2 getsockname.2 \
 	getsockopt.2 gettimeofday.2 getuid.2 intro.2 issetugid.2 ioctl.2 \
-	kill.2 kqueue.2 ktrace.2 link.2 \
+	kill.2 killinst.2 kqueue.2 ktrace.2 link.2 \
 	listen.2 lseek.2 mkdir.2 mkfifo.2 mknod.2 madvise.2 \
 	mquery.2 mincore.2 minherit.2 mlock.2 mlockall.2 \
 	mmap.2 mount.2 mprotect.2 msync.2 munmap.2 nanosleep.2 \
@@ -254,7 +255,8 @@
 MLINKS+=getitimer.2 timersub.3
 MLINKS+=getlogin.2 getlogin_r.2 getlogin.2 setlogin.2
 MLINKS+=getpgrp.2 getpgid.2
-MLINKS+=getpid.2 getppid.2
+MLINKS+=getpid.2 getppid.2 
+MLINKS+=getpid.2 getinstid.2
 MLINKS+=getpriority.2 setpriority.2
 MLINKS+=getrlimit.2 setrlimit.2
 MLINKS+=getsockopt.2 setsockopt.2
Index: lib/libc/sys/forkinst.2
===================================================================
RCS file: lib/libc/sys/forkinst.2
diff -N lib/libc/sys/forkinst.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libc/sys/forkinst.2	18 Feb 2009 18:20:19 -0000	1.1.2.5
@@ -0,0 +1,157 @@
+.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the
+.\" above copyright notice and this permission notice appear in all
+.\" copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+.\" AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+.\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.Dd $Mdocdate$
+.Dt FORKINST 2
+.Os
+.\" SECTION
+.Sh NAME
+.Nm forkinst
+.Nd create a new instance
+.\" SECTION
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft instid_t
+.Fn forkinst "instid_t id"
+.\" SECTION
+.Sh DESCRIPTION
+The
+.Nm forkinst
+function creates a new instance.  If the function returns zero, the
+executing context is the root process of the new instance.  If the
+function returns \-1 or a positive value, the context is the caller's.
+.\" PARAGRAPH
+.Pp
+If the 
+.Va id
+value is set to
+.Dv INST_NOID ,
+a random instance identifier is chosen.  
+.\" PARAGRAPH
+.Pp
+Life-cycle of an instance:
+.Bl -enum 
+.It 
+Birth:
+.Fn forkinst
+returns.  The new instance contains a single process and cloned
+credentials of the caller.  All caller resources (file descriptors,
+signal masks, limits, etc.) are re-initialised.
+.It 
+Life: the root process creates children, which in turn create more
+children, etc.  Orphaned descendants are reparented to the root process,
+which is 
+.Em strongly encouraged 
+to clean up the mess.
+.It
+Death: the root process exits.  All descendants are killed with
+.Dv SIGKILL .
+The root process won't fully exit until all descendants have exited and
+all descendant resources have been reclaimed.  Once this is satisfied,
+the instance is reclaimed.
+.El
+.\" PARAGRAPH
+.Pp
+The root process has basically the same internal signal-handling rules
+as
+.Xr init 8 :
+it isn't delivered broadcast or process group signals, and it 
+ignores signals instead of following the default handlers.
+.Pp
+If a
+.Dv SIGTERM 
+process is received, the root process should terminate all children with
+.Dv SIGTERM (as in
+.Xr init 8 ) 
+and exit.
+.\" SECTION
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn forkinst
+returns a value of 0 to the new instance and returns the instance ID of
+the new instance to the caller.  Otherwise, a value of \-1 is returned
+to the caller, no instance is created, and the global variable
+.Va errno
+is set to indicate the error.
+.\" SECTION
+.Sh EXAMPLES
+The following is a simple example of starting a new instance containing
+.Xr sshd 8 .  
+Note that 
+.Fl D
+is specified in order to prevent the root process from exiting, as
+.Xr sshd 8
+will daemonise,
+causing the instance to terminate prematurely.  Note also that
+descendant zombies will hang around until the instance dies.
+.Bd -literal
+instid_t id;
+char *p = "/usr/sbin/sshd";
+
+/* Start new instance. */
+
+if (-1 == (id = forkinst(INST_NOID)))
+	err(1, "forkinst");
+else if (0 != id) 
+	return(0);
+
+/* In new instance: assign std{in,out,err}. */
+/* fd will be 0 (if not -1) */
+
+if (-1 == (fd = open(_PATH_DEVNULL, O_RDWR, 0)))
+	_exit(1);
+
+dup2(fd, 1);
+dup2(fd, 2);
+
+execlp(p, p, "-D", (char *)NULL);
+_exit(1);
+.Ed
+.\" SECTION
+.Sh ERRORS
+.Fn fork
+will fail and no child process will be created if:
+.Bl -tag -width [EINSTEXIST]
+.It Bq Er EPERM
+The real uid of the caller isn't 0.
+.It Bq Er ENOMEM
+There is insufficient swap space for the new instance.
+.It Bq Er EINSTEXIST
+If not
+.Dv INST_NOID ,
+instance 
+.Fa id
+already exists; or
+.It Bq Er EINSTEXIST
+the caller does not have permission to start a new instance.
+.El
+.\" SECTION
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr fork 2 ,
+.Xr forkinst1 9
+.\" SECTION
+.Sh STANDARDS
+The
+.Fn forkinst
+function is not a standard function call and should not be used in
+portable sources.
+.\" SECTION
+.Sh CAVEATS
+If the root process doesn't reap re-parented zombies, these will collect
+and waste memory until the instance exits.  Ideally, the instance root
+will behave like
+.Xr init 8 ,
+although this may be overkill.
Index: lib/libc/sys/getpid.2
===================================================================
RCS file: /cvs/OpenBSD/src/lib/libc/sys/getpid.2,v
retrieving revision 1.11
retrieving revision 1.11.8.1
diff -u -r1.11 -r1.11.8.1
--- lib/libc/sys/getpid.2	31 May 2007 19:19:32 -0000	1.11
+++ lib/libc/sys/getpid.2	31 Jan 2009 19:14:53 -0000	1.11.8.1
@@ -35,7 +35,8 @@
 .Os
 .Sh NAME
 .Nm getpid ,
-.Nm getppid
+.Nm getppid ,
+.Nm getinstid
 .Nd get parent or calling process identification
 .Sh SYNOPSIS
 .Fd #include <sys/types.h>
@@ -44,6 +45,8 @@
 .Fn getpid void
 .Ft pid_t
 .Fn getppid void
+.Ft instid_t
+.Fn getinstid void
 .Sh DESCRIPTION
 .Fn getpid
 returns the process ID of the calling process.
@@ -55,6 +58,9 @@
 .Pp
 .Fn getppid
 returns the process ID of the parent of the calling process.
+.Pp
+.Fn getinstid
+returns the instance ID of the calling process.
 .Sh RETURN VALUES
 These functions are always successful, and no return value is
 reserved to indicate an error.
@@ -66,3 +72,5 @@
 .Fn getppid
 conform to
 .St -p1003.1-88 .
+.Fn getinstid
+is not a standard function and shouldn't be used in portable sources.
Index: lib/libc/sys/killinst.2
===================================================================
RCS file: lib/libc/sys/killinst.2
diff -N lib/libc/sys/killinst.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libc/sys/killinst.2	18 Feb 2009 12:44:36 -0000	1.1.2.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the
+.\" above copyright notice and this permission notice appear in all
+.\" copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+.\" AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+.\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.Dd $Mdocdate$
+.Dt KILLINST 2
+.Os
+.\" SECTION
+.Sh NAME
+.Nm killinst
+.Nd send a signal an instance
+.\" SECTION
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft int
+.Fn killinst "instid_t id" "int sig"
+.\" SECTION
+.Sh DESCRIPTION
+The
+.Fn killinst
+function sends the signal given by
+.Fa sig
+to
+.Fa id ,
+which is an instance identifier or
+.Dv INST_NOID ,
+representing all instances except that of the caller and instance 0.
+.Fa sig
+may be one of 
+.Dv SIGINST_TERM
+or
+.Dv SIGINST_KILL ,
+which deliver a 
+.Dv SIGTERM
+or
+.Dv SIGKILL ,
+respectively, to the instance's root process.  See
+.Xr forkinst 2
+for an overview of an instance's life-cycle.
+.\" SECTION
+.Sh RETURN VALUES
+.Rv -std killinst
+.\" SECTION
+.Sh ERRORS
+.Bl -tag -width "EINSTSRCHXXX"
+.It Bq Er EINVAL
+.Fa sig
+is not a valid signal number.
+.It Bq Er EINSTSRCH
+If an instance was specified, it does not exist or may not be signalled by the
+caller.  
+.It Bq Er EINSTSRCH
+If 
+.Dv INST_NOID
+was specified, no other instance exists.
+.El
+.\" PARAGRAPH
+.Pp
+If 
+.Dv INST_NOID
+was specified, permission errors are silently ignored.
+.\" SECTION
+.Sh SEE ALSO
+.Xr getpgrp 2 ,
+.Xr getpid 2 ,
+.Xr sigaction 2 ,
+.Xr killpg 3 ,
+.Xr raise 3
+.Sh STANDARDS
+The
+.Fn killinst
+function is not a standard function call and should not be used in
+portable sources.
+.\" SECTION
+.Sh CAVEATS
+It's up to instances' root process to correctly handle a
+.Dv SIGINST_TERM ,
+which may be ignored, but should gracefully terminate all instance
+processes.  The
+.Dv SIGINST_KILL
+can never be ignored, but I/O-hung processes may caues an instance to
+persist indefinitely.
+.\" PARAGRAPH
+.Pp
+Lastly, instance 0 cannot be killed.  Attempts to kill it will always
+return a
+.Er EINSTSRCH .
Index: sbin/Makefile
===================================================================
RCS file: /cvs/OpenBSD/src/sbin/Makefile,v
retrieving revision 1.88
retrieving revision 1.88.4.4
diff -u -r1.88 -r1.88.4.4
--- sbin/Makefile	9 Jun 2008 22:23:18 -0000	1.88
+++ sbin/Makefile	12 Feb 2009 14:38:06 -0000	1.88.4.4
@@ -2,7 +2,9 @@
 
 SUBDIR=	atactl badsect bioctl brconfig ccdconfig clri dhclient \
 	disklabel dmesg dump dumpfs fdisk fsck fsck_ext2fs fsck_ffs  \
-	fsck_msdos fsdb fsirand growfs ifconfig init iopctl ipsecctl  \
+	fsck_msdos fsdb fsirand growfs ifconfig init \
+	instkill instls instproc instps \
+	iopctl ipsecctl  \
 	isakmpd kbd ldattach lmccontrol mknod modload modunload mount \
 	mount_cd9660 mount_ext2fs mount_ffs mount_msdos \
 	mount_nfs mount_ntfs mount_portal mount_procfs mount_udf \
Index: sbin/instkill/Makefile
===================================================================
RCS file: sbin/instkill/Makefile
diff -N sbin/instkill/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instkill/Makefile	31 Jan 2009 19:14:53 -0000	1.1.2.1
@@ -0,0 +1,6 @@
+#	$OpenBSD: Makefile,v 1.2 1996/06/23 14:32:47 deraadt Exp $
+
+PROG=	instkill
+MAN=	instkill.8
+
+.include <bsd.prog.mk>
Index: sbin/instkill/instkill.8
===================================================================
RCS file: sbin/instkill/instkill.8
diff -N sbin/instkill/instkill.8
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instkill/instkill.8	13 Feb 2009 10:15:54 -0000	1.1.2.3
@@ -0,0 +1,76 @@
+.\"
+.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\" 
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\" 
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" 
+.Dd Jan 31, 2009
+.Dt INSTKILL 8
+.Os
+.\"
+.Sh NAME
+.Nm instkill
+.Nd signal instances
+.\"
+.Sh SYNOPSIS
+.Nm instkill
+.Fl Ar signal_name
+.Ar instid ...
+.\"
+.Sh DESCRIPTION
+The
+.Nm
+utility sends a signal to the instance(s) specified by the
+.Ar instid 
+operand(s) or to all instances (less the current one) if 
+.Ar \-1 .
+If no signal is specified,
+.Dv TERM
+is used.
+.Pp
+The signals available to
+.Fl Ar signal_name 
+follow:
+.Pp
+.Bl -enum -compact -offset indent
+.It 
+TERM (terminate)
+.It 
+KILL (forcibly terminate)
+.El
+.Pp
+The TERM and KILL signals correspond to 
+.Dv SIGINST_TERM
+and
+.Dv SIGINST_KILL ,
+respectively.  See
+.Xr killinst 2 
+for details.
+.\"
+.Sh EXAMPLES
+Forcibly terminate instance ID 1234:
+.Pp
+.Dl # instkill -KILL 1234
+.\"
+.Sh SEE ALSO
+.Xr killinst 2 ,
+.Xr instproc 8
+.\"
+.Sh STANDARDS
+The
+.Nm
+utility should not be used in portable sources.
+.\"
+.Sh AUTHORS
+.Nm
+was written by
+.An Kristaps Dzonsons Aq kristaps@mult.bsd.lv .
Index: sbin/instkill/instkill.c
===================================================================
RCS file: sbin/instkill/instkill.c
diff -N sbin/instkill/instkill.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instkill/instkill.c	19 Feb 2009 10:00:30 -0000	1.1.2.5
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/inst.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdlib.h>
+
+static	int	parse_signum(const char *);
+static	void	usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	int 		 signum;
+	long long	 raw;
+	instid_t	 id;
+
+	signum = 0;
+
+	argc--;
+	argv++;
+
+	signum = SIGINST_TERM;
+	if (argc >= 1 && '-' == *argv[0]) {
+		signum = parse_signum(argv[0]);
+		argc--;
+		argv++;
+	}
+
+	if (0 == argc) {
+		usage();
+		return(0);
+	}
+
+	while (argc) {
+		raw = atoll(argv[0]);
+		id = -1 == raw ? INST_NOID : (instid_t)raw;
+		if (-1 == killinst(id, signum))
+			if (EINSTSRCH != errno)
+				err(1, "killinst");
+
+		argc--;
+		argv++;
+	}
+
+	return(0);
+}
+
+
+static int
+parse_signum(const char *arg)
+{
+	if (0 == strcmp(arg, "-TERM"))
+		return(SIGINST_TERM);
+	else if (0 == strcmp(arg, "-KILL"))
+		return(SIGINST_KILL);
+	
+	errx(1, "bad signal `%s'", arg);
+	/* NOTREACHED */
+}
+
+
+static void
+usage(void)
+{
+	extern char	*__progname;
+
+	(void)printf("usage: %s [-signal_name] instid ...\n", __progname);
+}
Index: sbin/instls/Makefile
===================================================================
RCS file: sbin/instls/Makefile
diff -N sbin/instls/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instls/Makefile	14 Sep 2008 15:35:07 -0000	1.1.2.1
@@ -0,0 +1,6 @@
+#	$OpenBSD: Makefile,v 1.2 1996/06/23 14:32:47 deraadt Exp $
+
+PROG=	instls
+MAN=	instls.8
+
+.include <bsd.prog.mk>
Index: sbin/instls/instls.8
===================================================================
RCS file: sbin/instls/instls.8
diff -N sbin/instls/instls.8
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instls/instls.8	1 Feb 2009 15:37:25 -0000	1.1.2.5
@@ -0,0 +1,49 @@
+.\"
+.\" Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\" 
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\" 
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" 
+.Dd Sep 27, 2008
+.Dt INSTLS 8
+.Os
+.Sh NAME
+.Nm instls
+.Nd list running instances
+.Sh SYNOPSIS
+.Nm instls
+.Op Ar instid ...
+.Sh DESCRIPTION
+.Nm
+lists information on running instances.  If invoked with arguments, only
+the instances matching the instance IDs are displayed; when invoked
+without, all instances are listed.
+.Pp
+If an instance ID passed as an argument does not exist, an error is
+returned.
+.\"
+.Sh EXAMPLES
+To display all running instances:
+.Pp
+.D1 % instls 
+.Pp
+To only display instances 0 and 1:
+.Pp
+.D1 % instls 0 1
+.\"
+.Sh SEE ALSO
+.Xr instproc 8
+.\"
+.Sh AUTHORS
+.Nm
+was written by
+.An Kristaps Dzonsons Aq kristaps@mult.bsd.lv .
Index: sbin/instls/instls.c
===================================================================
RCS file: sbin/instls/instls.c
diff -N sbin/instls/instls.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instls/instls.c	19 Feb 2009 10:00:30 -0000	1.1.2.5
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/param.h>
+#include <sys/inst.h>
+#include <sys/sysctl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static void
+printheader(void)
+{
+	(void)printf(" %-12s %-4s\n", "UUID", "REFS");
+}
+
+
+static void
+printline(const struct kinfo_inst *ki)
+{
+	instid_t	 id;
+
+	id = getinstid();
+
+	(void)printf("%c%-12u %-4u\n", id == ki->inst_id ?
+			'*' : ' ', ki->inst_id, ki->inst_ref);
+}
+
+
+static int
+printselect(int v)
+{
+	int		 name[6];
+	struct kinfo_inst ki;
+	size_t		 oldlen;
+
+	oldlen = sizeof(struct kinfo_inst);
+
+	name[0] = CTL_KERN;
+	name[1] = KERN_INST;
+	name[2] = KERN_INST_INSTID;
+	name[3] = v;
+	name[4] = (int)oldlen;
+	name[5] = 1;
+
+	if (-1 == sysctl(name, 6, &ki, &oldlen, NULL, 0))
+		err(1, "sysctl");
+
+	if (oldlen == 0)
+		errx(1, "instance not found: %u", (unsigned)v);
+	else if ((oldlen % sizeof(struct kinfo_inst)))
+		errx(1, "invalid kinfo_inst size");
+
+	printline(&ki);
+
+	return(1);
+}
+
+
+static int
+printall(void)
+{
+	int		 name[6];
+	struct kinfo_inst *ki;
+	size_t		 oldlen, i;
+
+	name[0] = CTL_KERN;
+	name[1] = KERN_INST;
+	name[2] = KERN_INST_ALL;
+	name[3] = 0;
+	name[4] = sizeof(struct kinfo_inst);
+	name[5] = 0;
+
+	if (-1 == sysctl(name, 6, NULL, &oldlen, NULL, 0))
+		err(1, "sysctl");
+
+	if (oldlen == 0)
+		return(1);
+	else if ((oldlen % sizeof(struct kinfo_inst)))
+		errx(1, "invalid kinfo_inst size");
+
+	if (NULL == (ki = malloc(oldlen)))
+		err(1, "malloc");
+
+	name[4] = sizeof(struct kinfo_inst);
+	name[5] = (int)(oldlen / sizeof(struct kinfo_inst));
+
+	if (-1 == sysctl(name, 6, ki, &oldlen, NULL, 0)) 
+		err(1, "sysctl");
+
+	if (oldlen == 0)
+		return(1);
+
+	else if ((oldlen % sizeof(struct kinfo_inst)))
+		errx(1, "invalid kinfo_inst size");
+
+	oldlen /= sizeof(struct kinfo_inst);
+
+	for (i = 0; i < oldlen; i++)
+		printline(&ki[(int)i]);
+
+	return(1);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	extern char	*__progname;
+
+	if (-1 != getopt(argc, argv, "")) {
+		(void)fprintf(stderr, "usage: %s [instid...]\n", 
+				__progname);
+		return(1);
+	}
+
+	printheader();
+
+	if (1 == argc)
+		return(printall() ? EXIT_SUCCESS : EXIT_FAILURE);
+
+	argv++;
+	while (*argv) 
+		if ( ! printselect(atoi(*argv++)))
+			return (EXIT_FAILURE);
+
+	return(EXIT_SUCCESS);
+}
Index: sbin/instproc/Makefile
===================================================================
RCS file: sbin/instproc/Makefile
diff -N sbin/instproc/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instproc/Makefile	26 Sep 2008 22:24:17 -0000	1.1.2.1
@@ -0,0 +1,6 @@
+#	$OpenBSD: Makefile,v 1.2 1996/06/23 14:32:47 deraadt Exp $
+
+PROG=	instproc
+MAN=	instproc.8
+
+.include <bsd.prog.mk>
Index: sbin/instproc/instproc.8
===================================================================
RCS file: sbin/instproc/instproc.8
diff -N sbin/instproc/instproc.8
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instproc/instproc.8	15 Feb 2009 11:33:07 -0000	1.1.2.7
@@ -0,0 +1,89 @@
+.\"
+.\" Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\" 
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\" 
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" 
+.Dd Sep 27, 2008
+.Dt INSTPROC 8
+.Os
+.Sh NAME
+.Nm instproc
+.Nd create a process jail
+.Sh SYNOPSIS
+.Nm instproc
+.Op Fl i
+.Op Fl I Ar instid
+.Op Fl o Ar file
+.Ar utility
+.Op Ar arguments
+.Sh DESCRIPTION
+The
+.Nm
+tool creates a process jail.  See
+.Xr forkinst 2
+for a description of the instance life-cycle, especially regarding
+zombie processes as reparenting to its instance's root process.  The
+arguments are as follows:
+.Bl -tag -width "-I instid "
+.It Fl i
+Print the new instance's identifier.
+.It Fl I Ar instid
+Use 
+.Ar instid
+as the new instance's identifier.
+.El
+.Pp
+The
+.Ar utility
+and arguments are invoked as the instance's root process.  By default,
+a random instance ID is generated; if one is specified with
+.Fl I ,
+it will be used unless already in use.
+.\"
+.Sh EXAMPLES
+Run 
+.Xr sshd 8
+inside of a jail:
+.Pp
+.Dl # instproc /usr/sbin/sshd -D
+.Pp
+Note that the
+.Fl D
+flag ensures that the daemon does not fork, which terminates the root
+process.  Furthermore, zombied processes will collect under the sshd
+process until the instance exits.
+.Pp
+Run 
+.Xr httpd 8
+inside of a jail:
+.Pp
+.Dl # instproc /usr/sbin/httpd -X
+.Pp
+Note that the
+.Fl X
+ensures, like with the sshd example, that the daemon does not fork.
+.\"
+.Sh SEE ALSO
+.Xr instls 8 ,
+.Xr forkinst 2 ,
+.Xr exec 3
+.\"
+.Sh STANDARDS
+The
+.Nm
+utility should not be used in portable sources.
+.\"
+.Sh AUTHORS
+.Nm
+was written by
+.An Kristaps Dzonsons Aq kristaps@mult.bsd.lv .
Index: sbin/instproc/instproc.c
===================================================================
RCS file: sbin/instproc/instproc.c
diff -N sbin/instproc/instproc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instproc/instproc.c	19 Feb 2009 10:00:30 -0000	1.1.2.8
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/wait.h>
+#include <sys/inst.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <err.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <unistd.h>
+
+static __dead void 	 init(char *[]);
+static void		 usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	instid_t	 req;
+	int		 c, flags, inst;
+#define	ARG_PRINTID	(1 << 0)
+
+	extern int	 optind;
+	extern char	*optarg;
+
+	flags = 0;
+	req = INST_NOID;
+
+	while (-1 != (c = getopt(argc, argv, "iI:")))
+		switch (c) {
+		case ('i'):
+			flags |= ARG_PRINTID;
+			break;
+		case ('I'):
+			req = (instid_t)atoll(optarg);
+			break;
+		default:
+			usage();
+			return(1);
+		}
+
+	argv += optind;
+	if (0 == (argc -= optind)) {
+		usage();
+		return(1);
+	}
+
+	if (-1 == (inst = forkinst(req)))
+		err(1, "forkinst");
+
+	if (0 == inst)
+		init(argv);
+
+	if (flags & ARG_PRINTID)
+		(void)printf("%u\n", (instid_t)inst);
+
+	return(0);
+}
+
+
+static __dead void
+init(char *argv[])
+{
+	int		 fd;
+
+	if (-1 == (fd = open(_PATH_DEVNULL, O_RDWR, 0)))
+		_exit(1);
+
+	assert(0 == fd);
+
+	if (-1 == dup2(fd, 0))
+		_exit(1);
+	if (-1 == dup2(fd, 1))
+		_exit(1);
+	if (-1 == dup2(fd, 2))
+		_exit(1);
+
+	(void)execvp(argv[0], argv);
+	_exit(1);
+	/* NOTREACHED */
+}
+
+
+static void
+usage(void)
+{
+	extern char	*__progname;
+	(void)printf("usage: %s [-i] [-I instid] utility [args ...]\n", 
+			__progname);
+}
+
Index: sbin/instps/Makefile
===================================================================
RCS file: sbin/instps/Makefile
diff -N sbin/instps/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/Makefile	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,10 @@
+#	$OpenBSD: Makefile,v 1.7 2001/06/27 06:16:44 art Exp $
+
+PROG=	instps
+MAN=	instps.8
+SRCS=	fmt.c keyword.c nlist.c print.c ps.c
+DPADD=	${LIBM}
+LDADD=	-lm 
+
+.include <bsd.prog.mk>
+
Index: sbin/instps/extern.h
===================================================================
RCS file: sbin/instps/extern.h
diff -N sbin/instps/extern.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/extern.h	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,84 @@
+/*	$OpenBSD: extern.h,v 1.12 2005/01/07 20:41:13 otto Exp $	*/
+/*	$NetBSD: extern.h,v 1.10 1995/05/21 13:38:27 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.3 (Berkeley) 4/2/94
+ */
+
+struct nlist;
+struct var;
+struct varent;
+
+extern fixpt_t ccpu;
+extern int eval, fscale, nlistread, rawcpu, maxslp;
+extern u_int mempages;
+extern int sumrusage, termwidth, totwidth;
+extern VAR var[];
+extern VARENT *vhead;
+
+__BEGIN_DECLS
+void	 command(const struct kinfo_proc2 *, VARENT *);
+void	 cputime(const struct kinfo_proc2 *, VARENT *);
+int	 donlist(void);
+void	 emulname(const struct kinfo_proc2 *, VARENT *);
+void	 fmt_puts(const char *, int *);
+void	 fmt_putc(int, int *);
+double	 getpcpu(const struct kinfo_proc2 *);
+double	 getpmem(const struct kinfo_proc2 *);
+void	 gname(const struct kinfo_proc2 *, VARENT *);
+void	 logname(const struct kinfo_proc2 *, VARENT *);
+void	 longtname(const struct kinfo_proc2 *, VARENT *);
+void	 lstarted(const struct kinfo_proc2 *, VARENT *);
+void	 maxrss(const struct kinfo_proc2 *, VARENT *);
+void	 p_rssize(const struct kinfo_proc2 *, VARENT *);
+void	 pagein(const struct kinfo_proc2 *, VARENT *);
+void	 parsefmt(char *);
+void	 pcpu(const struct kinfo_proc2 *, VARENT *);
+void	 pmem(const struct kinfo_proc2 *, VARENT *);
+void	 pri(const struct kinfo_proc2 *, VARENT *);
+void	 printheader(void);
+void	 pvar(const struct kinfo_proc2 *kp, VARENT *);
+void	 pnice(const struct kinfo_proc2 *kp, VARENT *);
+void	 rgname(const struct kinfo_proc2 *, VARENT *);
+void	 rssize(const struct kinfo_proc2 *, VARENT *);
+void	 runame(const struct kinfo_proc2 *, VARENT *);
+void	 showkey(void);
+void	 started(const struct kinfo_proc2 *, VARENT *);
+void	 state(const struct kinfo_proc2 *, VARENT *);
+void	 tdev(const struct kinfo_proc2 *, VARENT *);
+void	 tname(const struct kinfo_proc2 *, VARENT *);
+void	 tsize(const struct kinfo_proc2 *, VARENT *);
+void	 dsize(const struct kinfo_proc2 *, VARENT *);
+void	 ssize(const struct kinfo_proc2 *, VARENT *);
+void	 ucomm(const struct kinfo_proc2 *, VARENT *);
+void	 euname(const struct kinfo_proc2 *, VARENT *);
+void	 vsize(const struct kinfo_proc2 *, VARENT *);
+void	 wchan(const struct kinfo_proc2 *, VARENT *);
+__END_DECLS
Index: sbin/instps/fmt.c
===================================================================
RCS file: sbin/instps/fmt.c
diff -N sbin/instps/fmt.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/fmt.c	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,96 @@
+/*	$OpenBSD: fmt.c,v 1.8 2006/04/25 15:41:07 deraadt Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <vis.h>
+#include "ps.h"
+
+void
+fmt_puts(const char *s, int *leftp)
+{
+	static char *v = NULL, *nv;
+	static int maxlen = 0;
+	int len;
+
+	if (*leftp == 0)
+		return;
+	len = strlen(s) * 4 + 1;
+	if (len > maxlen) {
+		size_t newmaxlen = maxlen;
+
+		if (newmaxlen == 0)
+			newmaxlen = getpagesize();
+		while (len > newmaxlen)
+			newmaxlen *= 2;
+		nv = realloc(v, newmaxlen);
+		if (nv == 0) {
+			free(v);
+			v = NULL;
+			maxlen = 0;
+			return;
+		}
+		maxlen = newmaxlen;
+		v = nv;
+	}
+	strvis(v, s, VIS_TAB | VIS_NL | VIS_CSTYLE);
+	if (*leftp != -1) {
+		len = strlen(v);
+		if (len > *leftp) {
+			v[*leftp] = '\0';
+			*leftp = 0;
+		} else
+			*leftp -= len;
+	}
+	printf("%s", v);
+}
+
+void
+fmt_putc(int c, int *leftp)
+{
+
+	if (*leftp == 0)
+		return;
+	if (*leftp != -1)
+		*leftp -= 1;
+	putchar(c);
+}
Index: sbin/instps/instps.8
===================================================================
RCS file: sbin/instps/instps.8
diff -N sbin/instps/instps.8
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/instps.8	15 Feb 2009 11:22:04 -0000	1.1.2.4
@@ -0,0 +1,548 @@
+.\"	$OpenBSD: ps.1,v 1.66 2008/03/17 18:52:00 jmc Exp $
+.\"	$NetBSD: ps.1,v 1.16 1996/03/21 01:36:28 jtc Exp $
+.\"
+.\" Copyright (c) 1980, 1990, 1991, 1993, 1994
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)ps.1	8.3 (Berkeley) 4/18/94
+.\"
+.Dd $Mdocdate: March 17 2008 $
+.Dt INSTPS 1
+.Os
+.Sh NAME
+.Nm instps
+.Nd display instance process status
+.Sh SYNOPSIS
+.Nm instps
+.Sm off
+.Op Fl aChjkLlmrSTuvwx
+.Sm on
+.Op Fl i Ar instid
+.Op Fl O Ar fmt
+.Op Fl o Ar fmt
+.Op Fl p Ar pid
+.Op Fl t Ar tty
+.Op Fl U Ar username
+.Sh DESCRIPTION
+The
+.Nm
+utility displays information about an instance's active processes.  It's
+identical to 
+.Xr ps 1
+except that only the running kernel may be queried and command filename
+and arguments are not displayed.  When given no options,
+.Nm
+prints information about processes of the current user that have a
+controlling terminal.
+.Pp
+The information displayed is selected based on a set of keywords (and for
+even more control, see the
+.Fl L ,
+.Fl O ,
+and
+.Fl o
+options).
+The default output format includes, for each process, the process's ID,
+controlling terminal, CPU time (including both user and system time),
+state, and associated command.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+Display information about other users' processes as well as your own.
+.It Fl C
+Change the way the CPU percentage is calculated by using a
+.Dq raw
+CPU calculation that ignores
+.Dq resident
+time (this normally has
+no effect).
+.It Fl h
+Repeat the information header as often as necessary to guarantee one
+header per page of information.
+.It Fl i Ar instid
+Display processes associated with the specified instance ID.  If the
+instance does not exist or access is prohibited, the request will
+yield no results.
+.It Fl j
+Print information associated with the following keywords:
+user, pid, ppid, pgid, sess, jobc, state, tt, time, and command.
+.It Fl k
+Also display information about kernel threads.
+.It Fl L
+List the set of available keywords.
+This option should not be specified with other options.
+.It Fl l
+Display information associated with the following keywords:
+uid, pid, ppid, cpu, pri, nice, vsz, rss, wchan, state, tt, time,
+and command.
+.It Fl m
+Sort by memory usage, instead of by start time ID.
+.It Fl O Ar fmt
+Add the information associated with the space or comma separated list
+of keywords specified, after the process ID,
+in the default information
+display.
+Keywords may be appended with an equals sign
+.Pq Sq =
+and a string.
+This causes the printed header to use the specified string instead of
+the standard header.
+.It Fl o Ar fmt
+Display information associated with the space or comma separated list
+of keywords specified.
+Keywords may be appended with an equals sign
+.Pq Sq =
+and a string.
+This causes the printed header to use the specified string instead of
+the standard header.
+.It Fl p Ar pid
+Display information associated with the specified process ID.
+.It Fl r
+Sort by current CPU usage, instead of by start time ID.
+.It Fl S
+Change the way the process time is calculated by summing all exited
+children to their parent process.
+.It Fl T
+Display information about processes attached to the device associated
+with the standard input.
+.It Fl t Ar tty
+Display information about processes attached to the specified terminal
+device.
+.It Fl U Ar username
+Display the processes belonging to the specified
+.Ar username .
+.It Fl u
+Display information associated with the following keywords:
+user, pid, %cpu, %mem, vsz, rss, tt, state, start, time, and command.
+The
+.Fl u
+option implies the
+.Fl r
+option.
+.It Fl v
+Display information associated with the following keywords:
+pid, state, time, sl, re, pagein, vsz, rss, lim, tsiz,
+%cpu, %mem, and command.
+The
+.Fl v
+option implies the
+.Fl m
+option.
+.It Fl w
+Use 132 columns to display information, instead of the default, which
+is the window size.
+If the
+.Fl w
+option is specified more than once,
+.Nm
+will use as many columns as necessary without regard for window size.
+.It Fl x
+Display information about processes without controlling terminals.
+.El
+.Pp
+By default, 
+.Nm
+displays the current instance's processes.
+.Pp
+.Ex -std instps
+.Sh KEYWORDS
+The following is a complete list of the available keywords
+and their meanings.
+Several of them have aliases,
+which are also noted.
+.Bl -tag -width "sigignoreXX" -offset 3n
+.It Cm %cpu
+Alias:
+.Cm pcpu .
+The CPU utilization of the process; this is a decaying average over up to
+a minute of previous (real) time.
+Since the time base over which this is computed varies (since processes may
+be very young) it is possible for the sum of all
+.Cm %cpu
+fields to exceed 100%.
+.It Cm %mem
+Alias:
+.Cm pmem .
+The percentage of real memory used by this process.
+.It Cm acflag
+Alias:
+.Cm acflg .
+Accounting flag.
+.It Cm command
+Alias:
+.Cm args .
+Command name.
+.It Cm cpu
+Short-term CPU usage factor (for scheduling).
+.It Cm cpuid
+CPU ID (zero on single processor systems).
+.It Cm dsiz
+Data size, in Kilobytes.
+.It Cm emul
+Name of system call emulation environment.
+.It Cm flags
+Alias:
+.Cm f .
+The flags (in hexadecimal) associated with the process as in
+the include file
+.Aq Pa sys/proc.h :
+.Bd -literal
+P_ADVLOCK 0x0000001  process may hold a POSIX advisory lock
+P_CONTROLT 0x0000002  process has a controlling terminal
+P_NOCLDSTOP 0x0000008 no SIGCHLD when children stop
+P_PPWAIT 0x0000010    parent is waiting for child to
+		      exec/exit
+P_PROFIL 0x0000020    process has started profiling
+P_SELECT 0x0000040    selecting; wakeup/waiting danger
+P_SINTR 0x0000080     sleep is interruptible
+P_SUGID 0x0000100     process had set ID privileges since
+		      last exec
+P_SYSTEM 0x0000200    system process: no sigs, stats, or
+		      swapping
+P_TIMEOUT 0x0000400   timing out during sleep
+P_TRACED 0x0000800    process is being traced
+P_WAITED 0x0001000   debugging process has waited for child
+P_WEXIT 0x0002000     working on exiting
+P_EXEC 0x0004000      process called exec(3)
+P_OWEUPC 0x0008000    owe process an addupc() call at next
+		      ast
+.\" the routine addupc is not documented in the man pages
+P_FSTRACE 0x0010000   tracing via file system
+P_SSTEP 0x0020000     process needs single-step fixup
+P_SUGIDEXEC 0x0040000 last exec(3) was set[ug]id
+P_NOCLDWAIT 0x0080000 let pid 1 wait for my children
+P_NOZOMBIE 0x0100000  pid 1 waits for me instead of dad
+P_INEXEC 0x0200000    process is doing an exec right now
+P_SYSTRACE 0x0400000  process system call tracing is active
+.Ed
+.It Cm gid
+Effective group.
+.It Cm group
+Text name of effective group ID.
+.It Cm inblk
+Alias:
+.Cm inblock .
+Total blocks read.
+.It Cm jobc
+Job control count.
+.It Cm ktrace
+Tracing flags.
+.It Cm ktracep
+Tracing vnode.
+.It Cm lim
+The soft limit on memory used, specified via a call to
+.Xr setrlimit 2 .
+.It Cm logname
+Alias:
+.Cm login .
+Login name of user who started the process.
+.It Cm lstart
+The exact time the command started, using the
+.Dq %c
+format described in
+.Xr strftime 3 .
+.It Cm majflt
+Total page faults.
+.It Cm minflt
+Total page reclaims.
+.It Cm msgrcv
+Total messages received (reads from pipes/sockets).
+.It Cm msgsnd
+Total messages sent (writes on pipes/sockets).
+.It Cm nice
+Alias:
+.Cm ni .
+The process scheduling increment (see
+.Xr setpriority 2 ) .
+.It Cm nivcsw
+Total involuntary context switches.
+.It Cm nsigs
+Alias:
+.Cm nsignals .
+Total signals taken.
+.It Cm nswap
+Total swaps in/out.
+.It Cm nvcsw
+Total voluntary context switches.
+.It Cm nwchan
+Wait channel (as an address).
+.It Cm oublk
+Alias:
+.Cm oublock .
+Total blocks written.
+.It Cm p_ru
+Resource usage (valid only for zombie processes).
+.It Cm paddr
+Swap address.
+.It Cm pagein
+Pageins (same as
+.Cm majflt ) .
+.It Cm pgid
+Process group number.
+.It Cm pid
+Process ID.
+.It Cm ppid
+Parent process ID.
+.It Cm pri
+Scheduling priority.
+.It Cm re
+Core residency time (in seconds; 127 = infinity).
+.It Cm rgid
+Real group ID.
+.It Cm rgroup
+Text name of real group ID.
+.It Cm rlink
+Reverse link on run queue, or 0.
+.It Cm rss
+The real memory (resident set) size of the process (in 1024 byte units).
+.It Cm rsz
+Alias:
+.Cm rssize .
+Resident set size + (text size / text use count).
+.It Cm ruid
+Real user ID.
+.It Cm ruser
+User name (from
+.Cm ruid ) .
+.It Cm sess
+Session pointer.
+.It Cm sig
+Alias:
+.Cm pending .
+Pending signals.
+.It Cm sigcatch
+Alias:
+.Cm caught .
+Caught signals.
+.It Cm sigignore
+Alias:
+.Cm ignored .
+Ignored signals.
+.It Cm sigmask
+Alias:
+.Cm blocked .
+Blocked signals.
+.It Cm sl
+Sleep time (in seconds; 127 = infinity).
+.It Cm ssiz
+Stack size, in Kilobytes.
+.It Cm start
+Alias:
+.Cm etime .
+The time the command started.
+If the command started less than 24 hours ago, the start time is
+displayed using the
+.Dq %l:%M%p
+format described in
+.Xr strftime 3 .
+If the command started less than 7 days ago, the start time is
+displayed using the
+.Dq %a%I%p
+format.
+Otherwise, the start time is displayed using the
+.Dq %e%b%y
+format.
+.It Cm state
+Alias:
+.Cm stat .
+The state is given by a sequence of letters, for example,
+.Dq RWN .
+The first letter indicates the run state of the process:
+.Pp
+.Bl -tag -width indent -compact
+.It D
+Marks a process in disk (or other short term, uninterruptible) wait.
+.It I
+Marks a process that is idle (sleeping for longer than about 20 seconds).
+.It R
+Marks a runnable process.
+.It S
+Marks a process that is sleeping for less than about 20 seconds.
+.It T
+Marks a stopped process.
+.It Z
+Marks a dead process (a
+.Dq zombie ) .
+.El
+.Pp
+Additional characters after these, if any, indicate additional state
+information:
+.Pp
+.Bl -tag -width indent -compact
+.It +
+The process is in the foreground process group of its control terminal.
+.It \*(Lt
+The process has a raised CPU
+scheduling priority (see
+.Xr setpriority 2 ) .
+.It \*(Gt
+The process has specified a soft limit on memory requirements and is
+currently exceeding that limit; such a process is (necessarily) not
+swapped.
+.\" .It A
+.\" the process has asked for random page replacement
+.\" .Pf ( Dv MADV_RANDOM ,
+.\" from
+.\" .Xr madvise 2 ,
+.\" for example,
+.\" .Xr lisp 1
+.\" in a garbage collect).
+.It E
+The process is trying to exit.
+.It K
+The process is a kernel thread.
+.It N
+The process has a reduced CPU
+scheduling priority.
+.\" .It S
+.\" The process has asked for FIFO
+.\" page replacement
+.\" .Pf ( Dv MADV_SEQUENTIAL ,
+.\" from
+.\" .Xr madvise 2 ,
+.\" for example, a large image processing program using virtual memory to
+.\" sequentially address voluminous data).
+.It s
+The process is a session leader.
+.It V
+The process is suspended during a
+.Xr vfork 2 .
+.It X
+The process is being traced or debugged.
+.It x
+The process is being monitored by
+.Xr systrace 1 .
+.It / Ns Ar n
+On multiprocessor machines, specifies processor number
+.Ar n .
+.El
+.It Cm svgid
+Saved GID from a setgid executable.
+.It Cm svuid
+Saved UID from a setuid executable.
+.It Cm tdev
+Control terminal device number.
+.It Cm time
+Alias:
+.Cm cputime .
+Accumulated CPU time, user + system.
+.It Cm tpgid
+Control terminal process group ID.
+.\".It trss
+.\"Text resident set size, in Kilobytes.
+.It Cm tsess
+Control terminal session pointer.
+.It Cm tsiz
+Text size, in Kilobytes.
+.It Cm tt
+An abbreviation for the pathname of the controlling terminal, if any.
+The abbreviation consists of the two letters following
+.Dq /dev/tty ,
+or, for the console,
+.Dq co .
+This is followed by a
+.Sq -
+if the process can no longer reach that
+controlling terminal (i.e. it has been revoked).
+.It Cm tty
+Full name of control terminal.
+.It Cm ucomm
+Alias:
+.Cm comm .
+Name to be used for accounting.
+.It Cm uid
+Effective user ID.
+.It Cm upr
+Alias:
+.Cm usrpri .
+Scheduling priority on return from system call.
+.It Cm user
+User name (from
+.Cm uid ) .
+.It Cm vsz
+Alias:
+.Cm vsize .
+Virtual size, in Kilobytes.
+.It Cm wchan
+The event (an address in the system) on which a process waits.
+When printed numerically, the initial part of the address is
+trimmed off and the result is printed in hex; for example, 0x80324000 prints
+as 324000.
+.It Cm xstat
+Exit or stop status (valid only for stopped or zombie process).
+.El
+.Sh FILES
+.Bl -tag -width "/var/run/dev.dbXXX" -compact
+.It Pa /dev
+special files and device names
+.It Pa /var/run/dev.db
+.Pa /dev
+name database
+.El
+.Sh EXAMPLES
+Display information on all processes of instance 1234:
+.Pp
+.Dl $ instps -i 1234 -auxw
+.Sh SEE ALSO
+.Xr fstat 1 ,
+.Xr kill 1 ,
+.Xr netstat 1 ,
+.Xr pgrep 1 ,
+.Xr pkill 1 ,
+.Xr procmap 1 ,
+.Xr systat 1 ,
+.Xr top 1 ,
+.Xr w 1 ,
+.Xr strftime 3 ,
+.Xr dev_mkdb 8 ,
+.Xr iostat 8 ,
+.Xr pstat 8 ,
+.Xr vmstat 8
+.\"
+.Sh STANDARDS
+The
+.Nm
+utility should not be used in portable sources.
+.\"
+.Sh CAVEATS
+When printing using the
+.Cm command
+keyword, a process that has exited and
+has a parent that has not yet waited for the process (in other words, a zombie)
+is listed as
+.Dq Aq defunct ,
+and a process which is blocked while trying
+to exit is listed as
+.Dq Aq exiting .
+.Nm
+cannot display file name and arguments given to the process.
+.Sh BUGS
+Since
+.Nm
+cannot run faster than the system and is run as any other scheduled
+process, the information it displays can never be exact.
Index: sbin/instps/keyword.c
===================================================================
RCS file: sbin/instps/keyword.c
diff -N sbin/instps/keyword.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/keyword.c	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,279 @@
+/*	$OpenBSD: keyword.c,v 1.27 2007/04/13 19:20:23 miod Exp $	*/
+/*	$NetBSD: keyword.c,v 1.12.6.1 1996/05/30 21:25:13 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)keyword.c	8.5 (Berkeley) 4/2/94";
+#else
+static char rcsid[] = "$OpenBSD: keyword.c,v 1.27 2007/04/13 19:20:23 miod Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ps.h"
+
+#include <sys/ucred.h>
+#include <sys/sysctl.h>
+
+static VAR *findvar(char *);
+static int  vcmp(const void *, const void *);
+
+#ifdef NOTINUSE
+int	utime(), stime(), ixrss(), idrss(), isrss();
+	{{"utime"}, "UTIME", USER, utime, 4},
+	{{"stime"}, "STIME", USER, stime, 4},
+	{{"ixrss"}, "IXRSS", USER, ixrss, 4},
+	{{"idrss"}, "IDRSS", USER, idrss, 4},
+	{{"isrss"}, "ISRSS", USER, isrss, 4},
+#endif
+
+/* Compute offset in common structures. */
+#define	POFF(x)	offsetof(struct kinfo_proc2, x)
+
+#define	UIDFMT	"u"
+#define	UIDLEN	5
+#define	UID(n1, n2, fn, off) \
+	{ n1, n2, NULL, 0, fn, UIDLEN, 0, off, UINT32, UIDFMT }
+#define	GID(n1, n2, fn, off)	UID(n1, n2, fn, off)
+
+#define	PIDFMT	"d"
+#define	PIDLEN	5
+#define	PID(n1, n2, fn, off) \
+	{ n1, n2, NULL, 0, fn, PIDLEN, 0, off, INT32, PIDFMT }
+
+#define	USERLEN	8
+
+/* Bit types must match their respective entries in struct kinfo_proc2 */
+VAR var[] = {
+	{"%cpu", "%CPU", NULL, NLIST, pcpu, 4},
+	{"%mem", "%MEM", NULL, NLIST, pmem, 4},
+	{"acflag", "ACFLG", NULL, 0, pvar, 3, 0, POFF(p_acflag), UINT16, "x"},
+	{"acflg", "", "acflag"},
+	{"args", "", "command"},
+	{"blocked", "", "sigmask"},
+	{"caught", "", "sigcatch"},
+	{"comm", "", "ucomm"},
+	{"command", "COMMAND", NULL, COMM|LJUST|USER, command, 16},
+	{"cpu", "CPU", NULL, 0, pvar, 3, 0, POFF(p_estcpu), UINT32, "d"},
+	{"cpuid", "CPUID", NULL, 0, pvar, 8, 0, POFF(p_cpuid), UINT64, "lld"},
+	{"cputime", "", "time"},
+	{"dsiz", "DSIZ", NULL, 0, dsize, 4},
+	{"emul", "EMUL", NULL, LJUST, emulname, EMULNAMELEN},
+	{"etime", "", "start"},
+	{"f", "F", NULL, 0, pvar, 7, 0, POFF(p_flag), INT32, "x"},
+	{"flags", "", "f"},
+	GID("gid", "GID", pvar, POFF(p_gid)),
+	{"group", "GROUP", NULL, LJUST, gname, USERLEN},
+	{"ignored", "", "sigignore"},
+	{"inblk", "INBLK", NULL, USER, pvar, 4, 0, POFF(p_uru_inblock), UINT64, "lld"},
+	{"inblock", "", "inblk"},
+	{"jobc", "JOBC", NULL, 0, pvar, 4, 0, POFF(p_jobc), INT16, "d"},
+	{"ktrace", "KTRACE", NULL, 0, pvar, 8, 0, POFF(p_traceflag), INT32, "x"},
+	/* XXX */
+	{"ktracep", "KTRACEP", NULL, 0, pvar, 8, 0, POFF(p_tracep), UINT64, "llx"},
+	{"lim", "LIM", NULL, 0, maxrss, 5},
+	{"login", "LOGIN", NULL, LJUST, logname, MAXLOGNAME},
+	{"logname", "", "login"},
+	{"lstart", "STARTED", NULL, LJUST|USER, lstarted, 28},
+	{"majflt", "MAJFLT", NULL, USER, pvar, 4, 0, POFF(p_uru_majflt), UINT64, "lld"},
+	{"minflt", "MINFLT", NULL, USER, pvar, 4, 0, POFF(p_uru_minflt), UINT64, "lld"},
+	{"msgrcv", "MSGRCV", NULL, USER, pvar, 4, 0, POFF(p_uru_msgrcv), UINT64, "lld"},
+	{"msgsnd", "MSGSND", NULL, USER, pvar, 4, 0, POFF(p_uru_msgsnd), UINT64, "lld"},
+	{"ni", "", "nice"},
+	{"nice", "NI", NULL, 0, pnice, 3},
+	{"nivcsw", "NIVCSW", NULL, USER, pvar, 5, 0, POFF(p_uru_nivcsw), UINT64, "lld"},
+	{"nsignals", "", "nsigs"},
+	{"nsigs", "NSIGS", NULL, USER, pvar, 4, 0, POFF(p_uru_nsignals), UINT64, "lld"},
+	{"nswap", "NSWAP", NULL, USER, pvar, 4, 0, POFF(p_uru_nswap), UINT64, "lld"},
+	{"nvcsw", "NVCSW", NULL, USER, pvar, 5, 0, POFF(p_uru_nvcsw), UINT64, "lld"},
+	/* XXX */
+	{"nwchan", "WCHAN", NULL, 0, pvar, 7, 0, POFF(p_wchan), UINT64, "llx"},
+	{"oublk", "OUBLK", NULL, USER, pvar, 4, 0, POFF(p_uru_oublock), UINT64, "lld"},
+	{"oublock", "", "oublk"},
+	/* XXX */
+	{"p_ru", "P_RU", NULL, 0, pvar, 6, 0, POFF(p_ru), UINT64, "llx"},
+	/* XXX */
+	{"paddr", "PADDR", NULL, 0, pvar, 6, 0, POFF(p_paddr), UINT64, "llx"},
+	{"pagein", "PAGEIN", NULL, USER, pagein, 6},
+	{"pcpu", "", "%cpu"},
+	{"pending", "", "sig"},
+	PID("pgid", "PGID", pvar, POFF(p__pgid)),
+	PID("pid", "PID", pvar, POFF(p_pid)),
+	{"pmem", "", "%mem"},
+	PID("ppid", "PPID", pvar, POFF(p_ppid)),
+	{"pri", "PRI", NULL, 0, pri, 3},
+	{"re", "RE", NULL, INF127, pvar, 3, 0, POFF(p_swtime), UINT32, "u"},
+	GID("rgid", "RGID", pvar, POFF(p_rgid)),
+	/* XXX */
+	{"rgroup", "RGROUP", NULL, LJUST, rgname, USERLEN},
+	{"rlink", "RLINK", NULL, 0, pvar, 8, 0, POFF(p_back), UINT64, "llx"},
+	{"rss", "RSS", NULL, 0, p_rssize, 5},
+	{"rssize", "", "rsz"},
+	{"rsz", "RSZ", NULL, 0, rssize, 4},
+	UID("ruid", "RUID", pvar, POFF(p_ruid)),
+	{"ruser", "RUSER", NULL, LJUST, runame, USERLEN},
+	{"sess", "SESS", NULL, 0, pvar, PTRWIDTH, 0, POFF(p_sess), UINT64, "llx"},
+	{"sig", "PENDING", NULL, 0, pvar, 8, 0, POFF(p_siglist), INT32, "x"},
+	{"sigcatch", "CAUGHT", NULL, 0, pvar, 8, 0, POFF(p_sigcatch), UINT32, "x"},
+	{"sigignore", "IGNORED",
+		NULL, 0, pvar, 8, 0, POFF(p_sigignore), UINT32, "x"},
+	{"sigmask", "BLOCKED", NULL, 0, pvar, 8, 0, POFF(p_sigmask), UINT32, "x"},
+	{"sl", "SL", NULL, INF127, pvar, 3, 0, POFF(p_slptime), UINT32, "u"},
+	{"ssiz", "SSIZ", NULL, 0, ssize, 4},
+	{"start", "STARTED", NULL, LJUST|USER, started, 8},
+	{"stat", "", "state"},
+	{"state", "STAT", NULL, LJUST|NLIST, state, 5},
+	GID("svgid", "SVGID", pvar, POFF(p_svgid)),
+	UID("svuid", "SVUID", pvar, POFF(p_svuid)),
+	{"tdev", "TDEV", NULL, 0, tdev, 4},
+	{"time", "TIME", NULL, USER, cputime, 9},
+	PID("tpgid", "TPGID", pvar, POFF(p_tpgid)),
+	{"tsess", "TSESS", NULL, 0, pvar, PTRWIDTH, 0, POFF(p_tsess), UINT64, "llx"},
+	{"tsiz", "TSIZ", NULL, 0, tsize, 4},
+	{"tt", "TT", NULL, LJUST, tname, 3},
+	{"tty", "TTY", NULL, LJUST, longtname, 8},
+	{"ucomm", "UCOMM", NULL, LJUST, ucomm, MAXCOMLEN},
+	UID("uid", "UID", pvar, POFF(p_uid)),
+	{"upr", "UPR", NULL, 0, pvar, 3, 0, POFF(p_usrpri), UINT8, "d"},
+	{"user", "USER", NULL, LJUST, euname, USERLEN},
+	{"usrpri", "", "upr"},
+	{"vsize", "", "vsz"},
+	{"vsz", "VSZ", NULL, 0, vsize, 5},
+	{"wchan", "WCHAN", NULL, LJUST, wchan, 7},
+	{"xstat", "XSTAT", NULL, 0, pvar, 4, 0, POFF(p_xstat), UINT16, "x"},
+	{""},
+};
+
+void
+showkey(void)
+{
+	VAR *v;
+	int i;
+	char *p, *sep;
+
+	i = 0;
+	sep = "";
+	for (v = var; *(p = v->name); ++v) {
+		int len = strlen(p);
+		if (termwidth && (i += len + 1) > termwidth) {
+			i = len;
+			sep = "\n";
+		}
+		(void) printf("%s%s", sep, p);
+		sep = " ";
+	}
+	(void) printf("\n");
+}
+
+void
+parsefmt(char *p)
+{
+	static struct varent *vtail;
+
+#define	FMTSEP	" \t,\n"
+	while (p && *p) {
+		char *cp;
+		VAR *v;
+		struct varent *vent;
+
+		while ((cp = strsep(&p, FMTSEP)) != NULL && *cp == '\0')
+			/* void */;
+		if (!cp)
+			break;
+		if (!(v = findvar(cp)) || v->parsed == 1)
+			continue;
+		v->parsed = 1;
+		if ((vent = malloc(sizeof(struct varent))) == NULL)
+			err(1, NULL);
+		vent->var = v;
+		vent->next = NULL;
+		if (vhead == NULL)
+			vhead = vtail = vent;
+		else {
+			vtail->next = vent;
+			vtail = vent;
+		}
+	}
+	if (!vhead)
+		errx(1, "no valid keywords");
+}
+
+static VAR *
+findvar(char *p)
+{
+	VAR *v, key;
+	char *hp;
+	int vcmp(const void *, const void *);
+
+	key.name = p;
+
+	hp = strchr(p, '=');
+	if (hp)
+		*hp++ = '\0';
+
+	key.name = p;
+	v = bsearch(&key, var, sizeof(var)/sizeof(VAR) - 1, sizeof(VAR), vcmp);
+
+	if (v && v->alias) {
+		if (hp) {
+			warnx("%s: illegal keyword specification", p);
+			eval = 1;
+		}
+		parsefmt(v->alias);
+		return (NULL);
+	}
+	if (!v) {
+		warnx("%s: keyword not found", p);
+		eval = 1;
+		return (NULL);
+	}
+	if (hp)
+		v->header = hp;
+	return (v);
+}
+
+static int
+vcmp(const void *a, const void *b)
+{
+	return (strcmp(((VAR *)a)->name, ((VAR *)b)->name));
+}
Index: sbin/instps/nlist.c
===================================================================
RCS file: sbin/instps/nlist.c
diff -N sbin/instps/nlist.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/nlist.c	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,103 @@
+/*	$OpenBSD: nlist.c,v 1.15 2005/01/07 20:41:13 otto Exp $	*/
+/*	$NetBSD: nlist.c,v 1.11 1995/03/21 09:08:03 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)nlist.c	8.4 (Berkeley) 4/2/94";
+#else
+static char rcsid[] = "$OpenBSD: nlist.c,v 1.15 2005/01/07 20:41:13 otto Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ps.h"
+
+fixpt_t	ccpu;				/* kernel _ccpu variable */
+int	nlistread;			/* if nlist already read. */
+u_int	mempages;			/* number of pages of phys. memory */
+int	fscale;				/* kernel _fscale variable */
+int	maxslp;
+
+int
+donlist(void)
+{
+	int64_t physmem;
+	int rval, mib[2];
+	size_t siz;
+
+	rval = 0;
+	nlistread = 1;
+
+	siz = sizeof (fscale);
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_FSCALE;
+	if (sysctl(mib, 2, &fscale, &siz, NULL, 0) < 0) {
+		warnx("fscale: failed to get kern.fscale");
+		eval = rval = 1;
+	}
+	siz = sizeof (physmem);
+	mib[0] = CTL_HW;
+	mib[1] = HW_PHYSMEM64;
+	if (sysctl(mib, 2, &physmem, &siz, NULL, 0) < 0) {
+		warnx("physmem: failed to get hw.physmem");
+		eval = rval = 1;
+	}
+	/* translate bytes into page count */
+	mempages = physmem / getpagesize();
+	siz = sizeof (ccpu);
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_CCPU;
+	if (sysctl(mib, 2, &ccpu, &siz, NULL, 0) < 0) {
+		warnx("ccpu: failed to get kern.ccpu");
+		eval = rval = 1;
+	}
+	siz = sizeof (maxslp);
+	mib[0] = CTL_VM;
+	mib[1] = VM_MAXSLP;
+	if (sysctl(mib, 2, &maxslp, &siz, NULL, 0) < 0) {
+		warnx("maxslp: failed to get vm.maxslp");
+		eval = rval = 1;
+	}
+	return (rval);
+}
+
Index: sbin/instps/print.c
===================================================================
RCS file: sbin/instps/print.c
diff -N sbin/instps/print.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/print.c	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,659 @@
+/*	$OpenBSD: print.c,v 1.43 2007/11/06 10:22:29 chl Exp $	*/
+/*	$NetBSD: print.c,v 1.27 1995/09/29 21:58:12 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)print.c	8.6 (Berkeley) 4/16/94";
+#else
+static char rcsid[] = "$OpenBSD: print.c,v 1.43 2007/11/06 10:22:29 chl Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+
+#include <sys/ucred.h>
+#include <sys/sysctl.h>
+#include <uvm/uvm_extern.h>
+
+#include <err.h>
+#include <grp.h>
+#include <math.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tzfile.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#include "ps.h"
+
+extern int needcomm, neednlist;
+
+static char *cmdpart(char *);
+
+#define	min(a,b)	((a) < (b) ? (a) : (b))
+
+static char *
+cmdpart(char *arg0)
+{
+	char *cp;
+
+	return ((cp = strrchr(arg0, '/')) != NULL ? cp + 1 : arg0);
+}
+
+void
+printheader(void)
+{
+	VAR *v;
+	struct varent *vent;
+
+	for (vent = vhead; vent; vent = vent->next) {
+		v = vent->var;
+		if (v->flag & LJUST) {
+			if (vent->next == NULL)	/* last one */
+				(void)printf("%s", v->header);
+			else
+				(void)printf("%-*s", v->width, v->header);
+		} else
+			(void)printf("%*s", v->width, v->header);
+		if (vent->next != NULL)
+			(void)putchar(' ');
+	}
+	(void)putchar('\n');
+}
+
+void
+command(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	int left, wantspace = 0;
+	char **argv, **p;
+
+	v = ve->var;
+	if (ve->next != NULL || termwidth != UNLIMITED) {
+		if (ve->next == NULL) {
+			left = termwidth - (totwidth - v->width);
+			if (left < 1) /* already wrapped, just use std width */
+				left = v->width;
+		} else
+			left = v->width;
+	} else
+		left = -1;
+
+	argv = NULL;
+	if (needcomm) {
+		if (wantspace) {
+			fmt_putc(' ', &left);
+			wantspace = 0;
+		}
+		fmt_puts(kp->p_comm, &left);
+	}
+	if (ve->next && left > 0) {
+		if (wantspace) {
+			fmt_putc(' ', &left);
+			wantspace = 0;
+		}
+		printf("%*s", left, "");
+	}
+}
+
+void
+ucomm(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%-*s", v->width, kp->p_comm);
+}
+
+void
+logname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	if (kp->p_login[0]) {
+		int n = min(v->width, MAXLOGNAME);
+		(void)printf("%-*.*s", n, n, kp->p_login);
+		if (v->width > n)
+			(void)printf("%*s", v->width - n, "");
+	} else
+		(void)printf("%-*s", v->width, "-");
+}
+
+#define pgtok(a)	(((a)*getpagesize())/1024)
+
+void
+state(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	extern int ncpu;
+	int flag;
+	char *cp, state = '\0';
+	VAR *v;
+	char buf[16];
+
+	v = ve->var;
+	flag = kp->p_flag;
+	cp = buf;
+
+	switch (kp->p_stat) {
+
+	case SSTOP:
+		*cp = 'T';
+		break;
+
+	case SSLEEP:
+		if (flag & P_SINTR)	/* interruptible (long) */
+			*cp = kp->p_slptime >= maxslp ? 'I' : 'S';
+		else
+			*cp = 'D';
+		break;
+
+	case SRUN:
+	case SIDL:
+	case SONPROC:
+		state = *cp = 'R';
+		break;
+
+	case SZOMB:
+		*cp = 'Z';
+		break;
+
+	default:
+		*cp = '?';
+	}
+	cp++;
+
+	if (kp->p_nice < NZERO)
+		*cp++ = '<';
+	else if (kp->p_nice > NZERO)
+		*cp++ = 'N';
+	if (flag & P_TRACED)
+		*cp++ = 'X';
+	if (flag & P_SYSTRACE)
+		*cp++ = 'x';
+	if (flag & P_WEXIT && kp->p_stat != SZOMB)
+		*cp++ = 'E';
+	if (flag & P_PPWAIT)
+		*cp++ = 'V';
+	if (flag & P_SYSTEM)
+		*cp++ = 'K';
+	if ((flag & P_SYSTEM) == 0 &&
+	    kp->p_rlim_rss_cur / 1024 < pgtok(kp->p_vm_rssize))
+		*cp++ = '>';
+	if (kp->p_eflag & EPROC_SLEADER)
+		*cp++ = 's';
+	if ((flag & P_CONTROLT) && kp->p__pgid == kp->p_tpgid)
+		*cp++ = '+';
+	*cp = '\0';
+
+	if (state == 'R' && ncpu && kp->p_cpuid != KI_NOCPU) {
+		char pbuf[16];
+
+		snprintf(pbuf, sizeof pbuf, "/%llu", kp->p_cpuid);
+		*++cp = '\0';
+		strlcat(buf, pbuf, sizeof buf);
+		cp = buf + strlen(buf);
+	}
+
+	(void)printf("%-*s", v->width, buf);
+}
+
+void
+pri(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width, kp->p_priority - PZERO);
+}
+
+void
+pnice(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	v = ve->var;
+	(void)printf("%*d", v->width, kp->p_nice - NZERO);
+}
+
+void
+euname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%-*s",
+	    (int)v->width, user_from_uid(kp->p_uid, 0));
+}
+
+void
+runame(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%-*s",
+	    (int)v->width, user_from_uid(kp->p_ruid, 0));
+}
+
+void
+gname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%-*s",
+	    (int)v->width, group_from_gid(kp->p_gid, 0));
+}
+
+void
+rgname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%-*s",
+	    (int)v->width, group_from_gid(kp->p_rgid, 0));
+}
+
+void
+tdev(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	dev_t dev;
+	char buff[16];
+
+	v = ve->var;
+	dev = kp->p_tdev;
+	if (dev == NODEV)
+		(void)printf("%*s", v->width, "??");
+	else {
+		(void)snprintf(buff, sizeof(buff),
+		    "%d/%d", major(dev), minor(dev));
+		(void)printf("%*s", v->width, buff);
+	}
+}
+
+void
+tname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	dev_t dev;
+	char *ttname;
+
+	v = ve->var;
+	dev = kp->p_tdev;
+	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
+		(void)printf("%-*s", v->width, "??");
+	else {
+		if (strncmp(ttname, "tty", 3) == 0)
+			ttname += 3;
+		(void)printf("%*.*s%c", v->width-1, v->width-1, ttname,
+			kp->p_eflag & EPROC_CTTY ? ' ' : '-');
+	}
+}
+
+void
+longtname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	dev_t dev;
+	char *ttname;
+
+	v = ve->var;
+	dev = kp->p_tdev;
+	if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL)
+		(void)printf("%-*s", v->width, "??");
+	else
+		(void)printf("%-*s", v->width, ttname);
+}
+
+void
+started(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	static time_t now;
+	time_t startt;
+	struct tm *tp;
+	char buf[100];
+
+	v = ve->var;
+	if (!kp->p_uvalid) {
+		(void)printf("%-*s", v->width, "-");
+		return;
+	}
+
+	startt = kp->p_ustart_sec;
+	tp = localtime(&startt);
+	if (!now)
+		(void)time(&now);
+	if (now - kp->p_ustart_sec < 24 * SECSPERHOUR) {
+		(void)strftime(buf, sizeof(buf) - 1, "%l:%M%p", tp);
+	} else if (now - kp->p_ustart_sec < 7 * SECSPERDAY) {
+		(void)strftime(buf, sizeof(buf) - 1, "%a%I%p", tp);
+	} else
+		(void)strftime(buf, sizeof(buf) - 1, "%e%b%y", tp);
+	(void)printf("%-*s", v->width, buf);
+}
+
+void
+lstarted(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	time_t startt;
+	char buf[100];
+
+	v = ve->var;
+	if (!kp->p_uvalid) {
+		(void)printf("%-*s", v->width, "-");
+		return;
+	}
+	startt = kp->p_ustart_sec;
+	(void)strftime(buf, sizeof(buf) -1, "%c",
+	    localtime(&startt));
+	(void)printf("%-*s", v->width, buf);
+}
+
+void
+wchan(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	if (kp->p_wchan) {
+		int n;
+
+		if (kp->p_wmesg) {
+			n = min(v->width, WMESGLEN);
+			(void)printf("%-*.*s", n, n, kp->p_wmesg);
+			if (v->width > n)
+				(void)printf("%*s", v->width - n, "");
+		} else
+			(void)printf("%-*lx", v->width,
+			    (long)kp->p_wchan &~ KERNBASE);
+	} else
+		(void)printf("%-*s", v->width, "-");
+}
+
+void
+vsize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width,
+	    pgtok(kp->p_vm_dsize + kp->p_vm_ssize + kp->p_vm_tsize));
+}
+
+void
+rssize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	/* XXX don't have info about shared */
+	(void)printf("%*d", v->width, (kp->p_flag & P_SYSTEM) ? 0 :
+	    pgtok(kp->p_vm_rssize));
+}
+
+void
+p_rssize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width, (kp->p_flag & P_SYSTEM) ? 0 :
+	    pgtok(kp->p_vm_rssize));
+}
+
+void
+cputime(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+	long secs;
+	long psecs;	/* "parts" of a second. first micro, then centi */
+	char obuff[128];
+
+	v = ve->var;
+	if (kp->p_stat == SZOMB || !kp->p_uvalid) {
+		secs = 0;
+		psecs = 0;
+	} else {
+		/*
+		 * This counts time spent handling interrupts.  We could
+		 * fix this, but it is not 100% trivial (and interrupt
+		 * time fractions only work on the sparc anyway).	XXX
+		 */
+		secs = kp->p_rtime_sec;
+		psecs = kp->p_rtime_usec;
+		if (sumrusage) {
+			secs += kp->p_uctime_sec;
+			psecs += kp->p_uctime_usec;
+		}
+		/*
+		 * round and scale to 100's
+		 */
+		psecs = (psecs + 5000) / 10000;
+		secs += psecs / 100;
+		psecs = psecs % 100;
+	}
+	(void)snprintf(obuff, sizeof(obuff),
+	    "%3ld:%02ld.%02ld", secs/60, secs%60, psecs);
+	(void)printf("%*s", v->width, obuff);
+}
+
+double
+getpcpu(const struct kinfo_proc2 *kp)
+{
+	double d;
+
+	if (fscale == 0)
+		return (0.0);
+
+#define	fxtofl(fixpt)	((double)(fixpt) / fscale)
+
+	/* XXX - I don't like this */
+	if (kp->p_swtime == 0)
+		return (0.0);
+	if (rawcpu)
+		return (100.0 * fxtofl(kp->p_pctcpu));
+
+	d = kp->p_swtime * log(fxtofl(ccpu));
+	if (d < -700.0)
+		d = 0.0;		/* avoid IEEE underflow */
+	else
+		d = exp(d);
+	if (d == 1.0)
+		return (0.0);
+	return (100.0 * fxtofl(kp->p_pctcpu) /
+		(1.0 - d));
+}
+
+void
+pcpu(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*.1f", v->width, getpcpu(kp));
+}
+
+double
+getpmem(const struct kinfo_proc2 *kp)
+{
+	double fracmem;
+	int szptudot;
+
+	if (mempages == 0)
+		return (0.0);
+
+	if (kp->p_flag & P_SYSTEM)
+		return (0.0);
+	/* XXX want pmap ptpages, segtab, etc. (per architecture) */
+	szptudot = USPACE/getpagesize();
+	/* XXX don't have info about shared */
+	fracmem = ((float)kp->p_vm_rssize + szptudot)/mempages;
+	return (100.0 * fracmem);
+}
+
+void
+pmem(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*.1f", v->width, getpmem(kp));
+}
+
+void
+pagein(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*llu", v->width,
+	    kp->p_uvalid ? kp->p_uru_majflt : 0);
+}
+
+void
+maxrss(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*lld", v->width, kp->p_rlim_rss_cur / 1024);
+}
+
+void
+tsize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width, pgtok(kp->p_vm_tsize));
+}
+
+void
+dsize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width, pgtok(kp->p_vm_dsize));
+}
+
+void
+ssize(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	(void)printf("%*d", v->width, pgtok(kp->p_vm_ssize));
+}
+
+/*
+ * Generic output routines.  Print fields from various prototype
+ * structures.
+ */
+static void
+printval(char *bp, VAR *v)
+{
+	char ofmt[32];
+
+	snprintf(ofmt, sizeof(ofmt), "%%%s*%s", (v->flag & LJUST) ? "-" : "",
+	    v->fmt);
+
+	/*
+	 * Note that the "INF127" check is nonsensical for types
+	 * that are or can be signed.
+	 */
+#define	GET(type)		(*(type *)bp)
+#define	CHK_INF127(n)		(((n) > 127) && (v->flag & INF127) ? 127 : (n))
+
+	switch (v->type) {
+	case INT8:
+		(void)printf(ofmt, v->width, GET(int8_t));
+		break;
+	case UINT8:
+		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int8_t)));
+		break;
+	case INT16:
+		(void)printf(ofmt, v->width, GET(int16_t));
+		break;
+	case UINT16:
+		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int16_t)));
+		break;
+	case INT32:
+		(void)printf(ofmt, v->width, GET(int32_t));
+		break;
+	case UINT32:
+		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int32_t)));
+		break;
+	case INT64:
+		(void)printf(ofmt, v->width, GET(int64_t));
+		break;
+	case UINT64:
+		(void)printf(ofmt, v->width, CHK_INF127(GET(u_int64_t)));
+		break;
+	default:
+		errx(1, "unknown type %d", v->type);
+	}
+#undef GET
+#undef CHK_INF127
+}
+
+void
+pvar(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+	if ((v->flag & USER) && !kp->p_uvalid)
+		(void)printf("%*s", v->width, "-");
+	else
+		printval((char *)kp + v->off, v);
+}
+
+void
+emulname(const struct kinfo_proc2 *kp, VARENT *ve)
+{
+	VAR *v;
+
+	v = ve->var;
+
+	(void)printf("%-*s", (int)v->width, kp->p_emul);
+}
Index: sbin/instps/ps.c
===================================================================
RCS file: sbin/instps/ps.c
diff -N sbin/instps/ps.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/ps.c	13 Feb 2009 09:20:25 -0000	1.1.2.3
@@ -0,0 +1,465 @@
+/*	$OpenBSD: ps.c,v 1.45 2008/03/08 19:20:12 millert Exp $	*/
+/*	$NetBSD: ps.c,v 1.15 1995/05/18 20:33:25 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993, 1994\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ps.c	8.4 (Berkeley) 4/2/94";
+#else
+static char rcsid[] = "$OpenBSD: ps.c,v 1.45 2008/03/08 19:20:12 millert Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "ps.h"
+
+extern char *__progname;
+
+struct varent *vhead;
+
+int	eval;			/* exit value */
+int	rawcpu;			/* -C */
+int	sumrusage;		/* -S */
+int	termwidth;		/* width of screen (0 == infinity) */
+int	totwidth;		/* calculated width of requested variables */
+
+int	ncpu = 1;
+
+int	needcomm, neednlist;
+
+enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT;
+
+static char	*kludge_oldps_options(char *);
+static int	 pscomp(const void *, const void *);
+static void	 scanvars(void);
+static void	 usage(void);
+
+char dfmt[] = "pid tt state time command";
+char jfmt[] = "user pid ppid pgid sess jobc state tt time command";
+char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command";
+char   o1[] = "pid";
+char   o2[] = "tt state time command";
+char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command";
+char vfmt[] = "pid state time sl re pagein vsz rss lim tsiz %cpu %mem command";
+
+int
+main(int argc, char *argv[])
+{
+	struct kinfo_proc2 *kp, **kinfo;
+	instid_t inst;
+	struct varent *vent;
+	struct winsize ws;
+	struct passwd *pwd;
+	dev_t ttydev;
+	pid_t pid;
+	uid_t uid;
+	int all, ch, flag, i, fmt, lineno, nentries, mib[6];
+	int prtheader, wflag, kflag, what, Uflag, xflg;
+	char errbuf[_POSIX2_LINE_MAX];
+	size_t size;
+
+	if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
+	    ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
+	    ioctl(STDIN_FILENO,  TIOCGWINSZ, &ws) == -1) ||
+	    ws.ws_col == 0)
+		termwidth = 79;
+	else
+		termwidth = ws.ws_col - 1;
+
+	if (argc > 1)
+		argv[1] = kludge_oldps_options(argv[1]);
+
+	all = fmt = prtheader = wflag = kflag = Uflag = xflg = 0;
+	pid = -1;
+	uid = 0;
+	inst = getinstid();
+	ttydev = NODEV;
+
+	while ((ch = getopt(argc, argv,
+	    "aCghi:jkLlmO:o:p:rSTt:U:uvW:wx")) != -1)
+		switch (ch) {
+		case 'a':
+			all = 1;
+			break;
+		case 'C':
+			rawcpu = 1;
+			break;
+		case 'g':
+			break;			/* no-op */
+		case 'h':
+			prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
+			break;
+		case 'i':
+			inst = (instid_t)atoll(optarg);
+			break;
+		case 'j':
+			parsefmt(jfmt);
+			fmt = 1;
+			jfmt[0] = '\0';
+			break;
+		case 'k':
+			kflag++;
+			break;
+		case 'L':
+			showkey();
+			exit(0);
+		case 'l':
+			parsefmt(lfmt);
+			fmt = 1;
+			lfmt[0] = '\0';
+			break;
+		case 'm':
+			sortby = SORTMEM;
+			break;
+		case 'O':
+			parsefmt(o1);
+			parsefmt(optarg);
+			parsefmt(o2);
+			o1[0] = o2[0] = '\0';
+			fmt = 1;
+			break;
+		case 'o':
+			parsefmt(optarg);
+			fmt = 1;
+			break;
+		case 'p':
+			pid = atol(optarg);
+			xflg = 1;
+			break;
+		case 'r':
+			sortby = SORTCPU;
+			break;
+		case 'S':
+			sumrusage = 1;
+			break;
+		case 'T':
+			if ((optarg = ttyname(STDIN_FILENO)) == NULL)
+				errx(1, "stdin: not a terminal");
+			/* FALLTHROUGH */
+		case 't': {
+			struct stat sb;
+			char *ttypath, pathbuf[MAXPATHLEN];
+
+			if (strcmp(optarg, "co") == 0)
+				ttypath = _PATH_CONSOLE;
+			else if (*optarg != '/')
+				(void)snprintf(ttypath = pathbuf,
+				    sizeof(pathbuf), "%s%s", _PATH_TTY, optarg);
+			else
+				ttypath = optarg;
+			if (stat(ttypath, &sb) == -1)
+				err(1, "%s", ttypath);
+			if (!S_ISCHR(sb.st_mode))
+				errx(1, "%s: not a terminal", ttypath);
+			ttydev = sb.st_rdev;
+			break;
+		}
+		case 'U':
+			pwd = getpwnam(optarg);
+			if (pwd == NULL)
+				errx(1, "%s: no such user", optarg);
+			uid = pwd->pw_uid;
+			endpwent();
+			Uflag = xflg = 1;
+			break;
+		case 'u':
+			parsefmt(ufmt);
+			sortby = SORTCPU;
+			fmt = 1;
+			ufmt[0] = '\0';
+			break;
+		case 'v':
+			parsefmt(vfmt);
+			sortby = SORTMEM;
+			fmt = 1;
+			vfmt[0] = '\0';
+			break;
+		case 'w':
+			if (wflag)
+				termwidth = UNLIMITED;
+			else if (termwidth < 131)
+				termwidth = 131;
+			wflag++;
+			break;
+		case 'x':
+			xflg = 1;
+			break;
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (!fmt)
+		parsefmt(dfmt);
+
+	/* XXX - should be cleaner */
+	if (!all && ttydev == NODEV && pid == -1 && !Uflag) {
+		uid = getuid();
+		Uflag = 1;
+	}
+
+	/*
+	 * scan requested variables, noting what structures are needed,
+	 * and adjusting header widths as appropriate.
+	 */
+	scanvars();
+
+	if (neednlist && !nlistread)
+		(void) donlist();
+
+	/*
+	 * get proc list
+	 */
+	if (Uflag) {
+		what = KERN_PROC_UID;
+		flag = uid;
+	} else if (ttydev != NODEV) {
+		what = KERN_PROC_TTY;
+		flag = ttydev;
+	} else if (pid != -1) {
+		what = KERN_PROC_PID;
+		flag = pid;
+	} else if (kflag) {
+		what = KERN_PROC_KTHREAD;
+		flag = 0;
+	} else {
+		what = KERN_PROC_ALL;
+		flag = 0;
+	}
+
+	mib[0] = CTL_HW;
+	mib[1] = HW_NCPU;
+	size = sizeof(ncpu);
+	(void) sysctl(mib, 2, &ncpu, &size, NULL, 0);
+
+	/*
+	 * select procs
+	 */
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_INSTPROC2;
+	mib[2] = inst;
+	mib[3] = what;
+	mib[4] = flag;
+	mib[5] = sizeof(struct kinfo_proc2);
+	mib[6] = 0;
+
+retry:
+	if (sysctl(mib, 7, NULL, &size, NULL, 0) < 0)
+		err(1, "sysctl");
+
+	size = 5 * size / 4;		/* extra slop */
+	if ((kp = malloc(size)) == NULL)
+		err(1, "failed to allocate memory for proc structures");
+	mib[6] = (int)(size / sizeof(struct kinfo_proc2));
+	if (sysctl(mib, 7, kp, &size, NULL, 0) < 0) {
+		if (errno == ENOMEM) {
+			free(kp);
+			goto retry;
+		}
+		err(1, "sysctl");
+	}
+	nentries = (int)(size / sizeof(struct kinfo_proc2));
+
+	/*
+	 * print header
+	 */
+	printheader();
+	if (nentries == 0)
+		exit(1);
+	/*
+	 * sort proc list, we convert from an array of structs to an array
+	 * of pointers to make the sort cheaper.
+	 */
+	if ((kinfo = calloc(sizeof(*kinfo), nentries)) == NULL)
+		err(1, "failed to allocate memory for proc pointers");
+	for (i = 0; i < nentries; i++)
+		kinfo[i] = &kp[i];
+	qsort(kinfo, nentries, sizeof(*kinfo), pscomp);
+	/*
+	 * for each proc, call each variable output function.
+	 */
+	for (i = lineno = 0; i < nentries; i++) {
+		if (xflg == 0 && ((int)kinfo[i]->p_tdev == NODEV ||
+		    (kinfo[i]->p_flag & P_CONTROLT ) == 0))
+			continue;
+		for (vent = vhead; vent; vent = vent->next) {
+			(vent->var->oproc)(kinfo[i], vent);
+			if (vent->next != NULL)
+				(void)putchar(' ');
+		}
+		(void)putchar('\n');
+		if (prtheader && lineno++ == prtheader - 4) {
+			(void)putchar('\n');
+			printheader();
+			lineno = 0;
+		}
+	}
+	exit(eval);
+}
+
+static void
+scanvars(void)
+{
+	struct varent *vent;
+	VAR *v;
+	int i;
+
+	for (vent = vhead; vent; vent = vent->next) {
+		v = vent->var;
+		i = strlen(v->header);
+		if (v->width < i)
+			v->width = i;
+		totwidth += v->width + 1;	/* +1 for space */
+		if (v->flag & COMM)
+			needcomm = 1;
+		if (v->flag & NLIST)
+			neednlist = 1;
+	}
+	totwidth--;
+}
+
+static int
+pscomp(const void *v1, const void *v2)
+{
+	const struct kinfo_proc2 *kp1 = *(const struct kinfo_proc2 **)v1;
+	const struct kinfo_proc2 *kp2 = *(const struct kinfo_proc2 **)v2;
+	int i;
+#define VSIZE(k) ((k)->p_vm_dsize + (k)->p_vm_ssize + (k)->p_vm_tsize)
+
+	if (sortby == SORTCPU && (i = getpcpu(kp2) - getpcpu(kp1)) != 0)
+		return (i);
+	if (sortby == SORTMEM && (i = VSIZE(kp2) - VSIZE(kp1)) != 0)
+		return (i);
+	if ((i = kp1->p_tdev - kp2->p_tdev) == 0 &&
+	    (i = kp1->p_ustart_sec - kp2->p_ustart_sec) == 0)
+		i = kp1->p_ustart_usec - kp2->p_ustart_usec;
+	return (i);
+}
+
+/*
+ * ICK (all for getopt), would rather hide the ugliness
+ * here than taint the main code.
+ *
+ *  ps foo -> ps -foo
+ *  ps 34 -> ps -p34
+ *
+ * The old convention that 't' with no trailing tty arg means the users
+ * tty, is only supported if argv[1] doesn't begin with a '-'.  This same
+ * feature is available with the option 'T', which takes no argument.
+ */
+static char *
+kludge_oldps_options(char *s)
+{
+	size_t len;
+	char *newopts, *ns, *cp;
+
+	len = strlen(s);
+	if ((newopts = ns = malloc(2 + len + 1)) == NULL)
+		err(1, NULL);
+	/*
+	 * options begin with '-'
+	 */
+	if (*s != '-')
+		*ns++ = '-';	/* add option flag */
+
+	/*
+	 * gaze to end of argv[1]
+	 */
+	cp = s + len - 1;
+	/*
+	 * if last letter is a 't' flag with no argument (in the context
+	 * of the oldps options -- option string NOT starting with a '-' --
+	 * then convert to 'T' (meaning *this* terminal, i.e. ttyname(0)).
+	 */
+	if (*cp == 't' && *s != '-')
+		*cp = 'T';
+	else {
+		/*
+		 * otherwise check for trailing number, which *may* be a
+		 * pid.
+		 */
+		while (cp >= s && isdigit(*cp))
+			--cp;
+	}
+	cp++;
+	memmove(ns, s, (size_t)(cp - s));	/* copy up to trailing number */
+	ns += cp - s;
+	/*
+	 * if there's a trailing number, and not a preceding 'p' (pid) or
+	 * 't' (tty) flag, then assume it's a pid and insert a 'p' flag.
+	 */
+	if (isdigit(*cp) && (cp == s || (cp[-1] != 't' && cp[-1] != 'p' &&
+	    (cp - 1 == s || cp[-2] != 't'))))
+		*ns++ = 'p';
+	/* and append the number */
+	(void)strlcpy(ns, cp, newopts + len + 3 - ns);
+
+	return (newopts);
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr,
+	    "usage: %s [-aChjkLlmrSTuvwx] [-i inst] [-O fmt] [-o fmt] [-p pid]\n",
+	    __progname);	
+	(void)fprintf(stderr,
+	    "%-*s[-t tty] [-U username]\n", (int)strlen(__progname) + 8, "");
+	exit(1);
+}
Index: sbin/instps/ps.h
===================================================================
RCS file: sbin/instps/ps.h
diff -N sbin/instps/ps.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sbin/instps/ps.h	12 Feb 2009 14:38:06 -0000	1.1.2.1
@@ -0,0 +1,89 @@
+/*	$OpenBSD: ps.h,v 1.7 2006/10/16 15:00:10 millert Exp $	*/
+/*	$NetBSD: ps.h,v 1.11 1995/09/29 21:57:03 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ps.h	8.1 (Berkeley) 5/31/93
+ */
+
+#define	UNLIMITED	0	/* unlimited terminal width */
+enum type {
+	INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64
+};
+
+struct usave {
+	struct	timeval u_start;
+	struct	rusage u_ru;
+	struct	rusage u_cru;
+	char	u_acflag;
+	char	u_valid;
+};
+
+/* Variables. */
+typedef struct varent {
+	struct varent *next;
+	struct var *var;
+} VARENT;
+
+struct kinfo_proc2;
+typedef struct var {
+	char	*name;		/* name(s) of variable */
+	char	*header;	/* default header */
+	char	*alias;		/* aliases */
+#define	COMM	0x01		/* needs exec arguments and environment (XXX) */
+#define	LJUST	0x02		/* left adjust on output (trailing blanks) */
+#define	USER	0x04		/* needs user structure */
+#define	INF127	0x08		/* 127 = infinity: if > 127, print 127. */
+#define	NLIST	0x10		/* needs nlist info from kernel */
+	u_int	flag;
+				/* output routine */
+	void	(*oproc)(const struct kinfo_proc2 *, struct varent *);
+	short	width;		/* printing width */
+	char	parsed;		/* have we been parsed yet? (avoid dupes) */
+	/*
+	 * The following (optional) elements are hooks for passing information
+	 * to the generic output routines: pvar, evar, uvar (those which print
+	 * simple elements from well known structures: proc, eproc, usave)
+	 */
+	int	off;		/* offset in structure */
+	enum	type type;	/* type of element */
+	char	*fmt;		/* printf format */
+	char	*time;		/* time format */
+	/*
+	 * glue to link selected fields together
+	 */
+} VAR;
+
+#ifdef __LP64__
+#define	PTRWIDTH	16
+#else
+#define	PTRWIDTH	8
+#endif
+
+#include "extern.h"
Index: share/man/man9/Makefile
===================================================================
RCS file: /cvs/OpenBSD/src/share/man/man9/Makefile,v
retrieving revision 1.143
retrieving revision 1.143.4.3
diff -u -r1.143 -r1.143.4.3
--- share/man/man9/Makefile	23 Jul 2008 11:45:21 -0000	1.143
+++ share/man/man9/Makefile	18 Feb 2009 18:20:19 -0000	1.143.4.3
@@ -9,8 +9,10 @@
 	disk.9 disklabel.9 dohooks.9 dopowerhooks.9 \
 	domountroothooks.9 doshutdownhooks.9 dostartuphooks.9 \
 	evcount.9 file.9 \
-	fork1.9 extent.9 getdevvp.9 getnewvnode.9 hash.9 hashinit.9 \
+	fork1.9 forkinst1.9 \
+	extent.9 getdevvp.9 getnewvnode.9 hash.9 hashinit.9 \
 	hardclock.9 hook_establish.9 hz.9 hzto.9 idgen32.9 \
+	inst.9 \
 	ieee80211.9 ieee80211_crypto.9 ieee80211_input.9 ieee80211_ioctl.9 \
 	ieee80211_node.9 ieee80211_output.9 ieee80211_proto.9 \
 	ieee80211_radiotap.9 \
@@ -175,6 +177,12 @@
 MLINKS+=iic.9 iic_acquire_bus.9 iic.9 iic_release_bus.9 iic.9 iic_exec.9 \
 	iic.9 iic_smbus_write_byte.9 iic.9 iic_smbus_read_byte.9 \
 	iic.9 iic_smbus_receive_byte.9
+MLINKS+=inst.9 instpnew.9 \
+	inst.9 instknew.9 \
+	inst.9 instpfind.9 \
+	inst.9 instkfind.9 \
+	inst.9 insthold.9 \
+	inst.9 instfree.9
 MLINKS+=kern.9 imax.9 kern.9 imin.9 kern.9 lmax.9 kern.9 lmin.9 \
 	kern.9 max.9 kern.9 min.9 kern.9 ulmax.9 kern.9 ulmin.9 kern.9 abs.9 \
 	kern.9 assert.9 kern.9 KASSERT.9 kern.9 KDASSERT.9 \
Index: share/man/man9/forkinst1.9
===================================================================
RCS file: share/man/man9/forkinst1.9
diff -N share/man/man9/forkinst1.9
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ share/man/man9/forkinst1.9	18 Feb 2009 18:20:20 -0000	1.1.2.6
@@ -0,0 +1,93 @@
+.\"
+.\" Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\" 
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\" 
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" 
+.Dd Sep 27, 2008
+.Dt FORKINST1 9
+.Os
+.Sh NAME
+.Nm forkinst1
+.Nd create a new process jail
+.\" SECTION
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/proc.h>
+.Ft int
+.Fn "forkinst1" "struct proc *p1" "instid_t id" "register_t *retval"
+.\" SECTION
+.Sh DESCRIPTION
+.Fn forkinst1
+creates a new process out of
+.Ar p1 ,
+which should be the current process, within a new instance.  If
+.Ar id
+is not 
+.Ar INST_NOID 
+and no corresponding instance exists, it will be used as the new
+instance's identifier.  Otherwise, an instance identifier is randomly
+generated.
+.\" PARAGRAPH
+.Pp
+Upon successful completion of the operation,
+.Fa retval
+will hold the following values:
+.Bl -tag -width retval[0]
+.It Fa retval[0]
+This will contain the instid of the new instance.
+.It Fa retval[1]
+In the parent process, this will contain the value 0.
+In the child process, this will contain 1.
+.El
+.\" PARAGRAPH
+.Pp
+Once the new instance's root process begins execution, the 
+.Fn child_return 
+function is invoked, which returns to the userland.
+.\" PARAGRAPH
+.Pp
+The operation of
+.Nm
+is similar to that of
+.Xr fork1 9 ,
+except that the child is registered with a new instance from
+.Xr instpnew 9 .
+Correspondingly, none of the parent's resources are inherited by the
+child process.
+.\" SECTION
+.Sh RETURN VALUES
+Upon successful completion of the fork operation,
+.Fn forkinst1
+returns 0.
+Otherwise, the following error values are returned:
+.Bl -tag -width [ENOMEM]
+.It Bq Er EPERM
+The real user of 
+.Ar p1
+is not 0.
+.It Bq Er ENOMEM
+Memory couldn't be allocated for the new process.
+.It Bq Er EINSTEXIST
+If not
+.Dv INST_NOID ,
+instance 
+.Fa id
+already exists; or
+.It Bq Er EINSTEXIST
+the caller does not have permission to start a new instance.
+.El
+.\" SECTION
+.Sh SEE ALSO
+.Xr forkinst 2 ,
+.Xr killinst 2 ,
+.Xr inst 9
Index: share/man/man9/inst.9
===================================================================
RCS file: share/man/man9/inst.9
diff -N share/man/man9/inst.9
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ share/man/man9/inst.9	18 Feb 2009 18:20:20 -0000	1.1.2.5
@@ -0,0 +1,140 @@
+.\"
+.\" Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+.\" 
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\" 
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\" 
+.Dd Sep 27, 2008
+.Dt INST 9
+.Os
+.\" SECTION
+.Sh NAME
+.Nm instpnew ,
+.Nm instknew ,
+.Nm instpfind ,
+.Nm instkfind ,
+.Nm insthold ,
+.Nm instfree 
+.Nd instance functions
+.\" SECTION
+.Sh SYNOPSIS
+.Fd #include <sys/inst.h>
+.Vt extern struct instlist inst_all;
+.Ft "struct inst *"
+.Fn instknew "instid_t id"
+.Ft "struct inst *"
+.Fn instpnew "struct proc *cp" "instid_t id"
+.Ft "struct inst *"
+.Fn instpfind "struct proc *cp" "instid_t id" "enum instop op"
+.Ft "struct inst *"
+.Fn instkfind "instid_t id"
+.Fn insthold "struct inst *inst"
+.Ft void
+.Fn instfree "struct inst *inst"
+.\" SECTION
+.Sh DESCRIPTION
+The
+.Nm inst
+functions, 
+.Fn instpnew ,
+.Fn instknew ,
+.Fn instpfind ,
+.Fn instkfind ,
+and
+.Fn instfree ,
+functions manage instances run-times.  An instance is a collection of
+resources, at the moment limited to processes.  The processes and
+process data of one instance are invisible to all others.  An instance
+exists while its reference count is non-zero; when the reference count
+is decremented to 0, the instance is freed.
+.\" PARAGRAPH
+.Pp
+Only 
+.Dv INST_MAX
+instances may be allocated.  This is fixed at
+.Dv UINT_MAX - 1 .
+.\" PARAGRAPH
+.Pp
+Variable descriptions follow:
+.Bl -ohang -offset indent
+.It Va inst_all
+List of all instances running on the system.
+.El
+.\" PARAGRAPH
+.Pp
+Function descriptions follow:
+.Bl -ohang -offset indent
+.\" ITEM
+.It Fn instknew
+Creates and registers a new instance, setting its reference count to 1.
+If 
+.Fa id
+is set to 
+.Dv INST_NOID ,
+a random instance identifier is chosen; if not, the argument 
+.Va id
+is used as the new identifier.  This function returns
+.Dv NULL 
+if 
+.Va id
+is already in use.
+.\" ITEM
+.It Fn instpnew
+Like
+.Fn instknew ,
+but associated with a calling process
+.Fa cp .
+May return NULL if operation is not permitted.
+.\" ITEM
+.It Fn instkfind
+Finds an instance by its identifier
+.Fa inst .  
+If 
+.Dv NULL
+is returned, no matching instance could be found.
+.\" ITEM
+.It Fn instpfind
+Like
+.Fn instkfind ,
+but associated with a calling process
+.Fa cp
+and operation
+.Fa op .
+May return NULL if operation is not permitted.
+.\" ITEM
+.It Fn insthold
+Increments an instance's reference count.
+.It Fn instfree
+Decrements the instance's reference count.  If the reference count is 0,
+the instance's resources are freed.
+.El
+.\" PARAGRAPH
+.Pp
+Functions
+.Fn instkfind
+and
+.Fn instknew
+should 
+.Em only
+be used when not associated with calling credentials, i.e., from the
+bottom-half of the kernel.  Use
+.Fn instpfind
+and
+.Fn instpnew
+unless explicitly without context.
+.\" SECTION
+.Sh CODE REFERENCES
+Those functions are implemented in the file
+.Pa sys/kern/kern_inst.c .
+.\" SECTION
+.Sh SEE ALSO
+.Xr forkinst1 9
Index: share/man/man9/kthread.9
===================================================================
RCS file: /cvs/OpenBSD/src/share/man/man9/kthread.9,v
retrieving revision 1.8
retrieving revision 1.8.8.1
diff -u -r1.8 -r1.8.8.1
--- share/man/man9/kthread.9	31 May 2007 19:20:00 -0000	1.8
+++ share/man/man9/kthread.9	18 Feb 2009 12:44:36 -0000	1.8.8.1
@@ -41,9 +41,9 @@
 .Fn kthread_create_deferred "void (*func)(void *)" "void *arg"
 .Sh DESCRIPTION
 Kernel threads are system light-weight processes: cloned from process 0
-(the swapper), sharing its memory map and limits, but with a copy of its
-file descriptor table.
-They don't receive broadcast nor group signals and they can't be swapped.
+(the swapper) in instance 0, sharing its memory map and limits, but with
+a copy of its file descriptor table.  They don't receive broadcast nor
+group signals and they can't be swapped.
 .Pp
 Any process can call
 .Fn kthread_create
@@ -95,3 +95,8 @@
 .Va ecode
 to any sensible purpose from
 .Fn kthread_exit .
+.Sh CAVEATS
+The
+.Fn kthread_create
+function creates all processes in instance 0; if called from a different
+instance, it will disappear.
Index: share/man/man9/pfind.9
===================================================================
RCS file: /cvs/OpenBSD/src/share/man/man9/pfind.9,v
retrieving revision 1.6
retrieving revision 1.6.8.1
diff -u -r1.6 -r1.6.8.1
--- share/man/man9/pfind.9	31 May 2007 19:20:00 -0000	1.6
+++ share/man/man9/pfind.9	20 Sep 2008 00:09:45 -0000	1.6.8.1
@@ -34,9 +34,9 @@
 .Fd #include <sys/cdefs.h>
 .Fd #include <sys/proc.h>
 .Ft "struct proc *"
-.Fn pfind "pid_t pid"
+.Fn pfind "struct inst_proc *" "pid_t pid"
 .Ft "struct pgrp *"
-.Fn pgfind "pid_t pgid"
+.Fn pgfind "struct inst_proc *" "pid_t pgid"
 .Sh DESCRIPTION
 The
 .Fn pfind
Index: share/man/man9/psignal.9
===================================================================
RCS file: /cvs/OpenBSD/src/share/man/man9/psignal.9,v
retrieving revision 1.4
retrieving revision 1.4.4.1
diff -u -r1.4 -r1.4.4.1
--- share/man/man9/psignal.9	26 Jun 2008 05:42:08 -0000	1.4
+++ share/man/man9/psignal.9	20 Sep 2008 00:09:45 -0000	1.4.4.1
@@ -42,7 +42,7 @@
 .Ft void
 .Fn "pgsignal" "struct pgrp *pgrp" "int signum" "int checkctty"
 .Ft void
-.Fn "gsignal" "int pgid" "int signum"
+.Fn "gsignal" "instid_t instid" "int pgid" "int signum"
 .Sh DESCRIPTION
 These functions post a signal to one or more processes.
 The argument
@@ -111,7 +111,9 @@
 function posts signal number
 .Fa signum
 to each member of the process group identified by the group id
-.Fa pgid .
+.Fa pgid 
+in instance
+.Fa instid .
 If
 .Fa pgid
 is zero no action is taken.
Index: sys/arch/amd64/amd64/db_disasm.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/amd64/amd64/db_disasm.c,v
retrieving revision 1.8
retrieving revision 1.8.6.1
diff -u -r1.8 -r1.8.6.1
--- sys/arch/amd64/amd64/db_disasm.c	5 Nov 2007 19:23:24 -0000	1.8
+++ sys/arch/amd64/amd64/db_disasm.c	17 Sep 2008 13:37:32 -0000	1.8.6.1
@@ -94,7 +94,7 @@
 #define	Ril	36			/* long register in instruction */
 #define	Iba	37			/* byte immediate, don't print if 0xa */
 
-struct inst {
+struct dinst {
 	char *	i_name;			/* name */
 	short	i_has_modrm;		/* has regmodrm byte */
 	short	i_size;			/* operand size */
@@ -144,7 +144,7 @@
 	"xcrypt-cfb",	"xcrypt-ofb",	"",		""
 };
 
-struct inst db_inst_0f0x[] = {
+struct dinst db_inst_0f0x[] = {
 /*00*/	{ "",	   TRUE,  NONE,  op1(Ew),     db_Grp6 },
 /*01*/	{ "",	   TRUE,  NONE,  op1(Ew),     db_Grp7 },
 /*02*/	{ "lar",   TRUE,  LONG,  op2(E,R),    0 },
@@ -164,7 +164,7 @@
 /*0f*/	{ "",      FALSE, NONE,  0,	      0 },
 };
 
-struct inst	db_inst_0f2x[] = {
+struct dinst	db_inst_0f2x[] = {
 /*20*/	{ "mov",   TRUE,  LONG,  op2(CR,E),   0 }, /* use E for reg */
 /*21*/	{ "mov",   TRUE,  LONG,  op2(DR,E),   0 }, /* since mod == 11 */
 /*22*/	{ "mov",   TRUE,  LONG,  op2(E,CR),   0 },
@@ -184,7 +184,7 @@
 /*2f*/	{ "",      FALSE, NONE,  0,	      0 },
 };
 
-struct inst	db_inst_0f3x[] = {
+struct dinst	db_inst_0f3x[] = {
 /*30*/	{ "wrmsr", FALSE, NONE,  0,           0 },
 /*31*/	{ "rdtsc", FALSE, NONE,  0,           0 },
 /*32*/	{ "rdmsr", FALSE, NONE,  0,           0 },
@@ -204,7 +204,7 @@
 /*3f*/	{ "",      FALSE, NONE,  0,           0 },
 };
 
-struct inst	db_inst_0f8x[] = {
+struct dinst	db_inst_0f8x[] = {
 /*80*/	{ "jo",    FALSE, NONE,  op1(Dl),     0 },
 /*81*/	{ "jno",   FALSE, NONE,  op1(Dl),     0 },
 /*82*/	{ "jb",    FALSE, NONE,  op1(Dl),     0 },
@@ -224,7 +224,7 @@
 /*8f*/	{ "jnle",  FALSE, NONE,  op1(Dl),     0 },
 };
 
-struct inst	db_inst_0f9x[] = {
+struct dinst	db_inst_0f9x[] = {
 /*90*/	{ "seto",  TRUE,  NONE,  op1(Eb),     0 },
 /*91*/	{ "setno", TRUE,  NONE,  op1(Eb),     0 },
 /*92*/	{ "setb",  TRUE,  NONE,  op1(Eb),     0 },
@@ -244,7 +244,7 @@
 /*9f*/	{ "setnle",TRUE,  NONE,  op1(Eb),     0 },
 };
 
-struct inst	db_inst_0fax[] = {
+struct dinst	db_inst_0fax[] = {
 /*a0*/	{ "push",  FALSE, QUAD,  op1(Si),     0 },
 /*a1*/	{ "pop",   FALSE, QUAD,  op1(Si),     0 },
 /*a2*/	{ "cpuid", FALSE, NONE,  0,	      0 },
@@ -264,7 +264,7 @@
 /*af*/	{ "imul",  TRUE,  LONG,  op2(E,R),    0 },
 };
 
-struct inst	db_inst_0fbx[] = {
+struct dinst	db_inst_0fbx[] = {
 /*b0*/	{ "cmpxchg",TRUE, BYTE,	 op2(R, E),   0 },
 /*b1*/	{ "cmpxchg",TRUE, LONG,	 op2(R, E),   0 },
 /*b2*/	{ "lss",   TRUE,  LONG,  op2(E, R),   0 },
@@ -284,7 +284,7 @@
 /*bf*/	{ "movsw", TRUE,  LONG,  op2(Ew, R),  0 },
 };
 
-struct inst	db_inst_0fcx[] = {
+struct dinst	db_inst_0fcx[] = {
 /*c0*/	{ "xadd",  TRUE,  BYTE,	 op2(R, E),   0 },
 /*c1*/	{ "xadd",  TRUE,  LONG,	 op2(R, E),   0 },
 /*c2*/	{ "",	   FALSE, NONE,	 0,	      0 },
@@ -304,7 +304,7 @@
 /*cf*/	{ "bswap", FALSE, LONG,  op1(Ril),    0 },
 };
 
-struct inst *db_inst_0f[] = {
+struct dinst *db_inst_0f[] = {
 	db_inst_0f0x,
 	NULL,
 	db_inst_0f2x,
@@ -479,7 +479,7 @@
 	"sar"
 };
 
-struct inst db_Grp3[] = {
+struct dinst db_Grp3[] = {
 	{ "test",  TRUE, NONE, op2(I,E), 0 },
 	{ "test",  TRUE, NONE, op2(I,E), 0 },
 	{ "not",   TRUE, NONE, op1(E),   0 },
@@ -490,7 +490,7 @@
 	{ "idiv",  TRUE, NONE, op2(E,A), 0 },
 };
 
-struct inst	db_Grp4[] = {
+struct dinst	db_Grp4[] = {
 	{ "inc",   TRUE, BYTE, op1(E),   0 },
 	{ "dec",   TRUE, BYTE, op1(E),   0 },
 	{ "",      TRUE, NONE, 0,	 0 },
@@ -501,7 +501,7 @@
 	{ "",      TRUE, NONE, 0,	 0 }
 };
 
-struct inst	db_Grp5[] = {
+struct dinst	db_Grp5[] = {
 	{ "inc",   TRUE, LONG, op1(E),   0 },
 	{ "dec",   TRUE, LONG, op1(E),   0 },
 	{ "call",  TRUE, QUAD, op1(Eind),0 },
@@ -512,7 +512,7 @@
 	{ "",      TRUE, NONE, 0,	 0 }
 };
 
-struct inst db_inst_table[256] = {
+struct dinst db_inst_table[256] = {
 /*00*/	{ "add",   TRUE,  BYTE,  op2(R, E),  0 },
 /*01*/	{ "add",   TRUE,  LONG,  op2(R, E),  0 },
 /*02*/	{ "add",   TRUE,  BYTE,  op2(E, R),  0 },
@@ -802,7 +802,7 @@
 /*ff*/	{ "",	   TRUE,  NONE,  0,	     db_Grp5 },
 };
 
-struct inst	db_bad_inst =
+struct dinst	db_bad_inst =
 	{ "???",   FALSE, NONE,  0,	      0 }
 ;
 
@@ -1076,7 +1076,7 @@
 	int	size;
 	int	short_addr;
 	char *	seg;
-	struct inst *	ip;
+	struct dinst *	ip;
 	char *	i_name;
 	int	i_size;
 	int	i_mode;
@@ -1208,12 +1208,12 @@
 	    ip->i_extra == db_GrpA || ip->i_extra == db_GrpB) {
 		i_name = ((char **)ip->i_extra)[f_reg(regmodrm, 0)];
 	} else if (ip->i_extra == db_Grp3) {
-		ip = (struct inst *)ip->i_extra;
+		ip = (struct dinst *)ip->i_extra;
 		ip = &ip[f_reg(regmodrm, 0)];
 		i_name = ip->i_name;
 		i_mode = ip->i_mode;
 	} else if (ip->i_extra == db_Grp4 || ip->i_extra == db_Grp5) {
-		ip = (struct inst *)ip->i_extra;
+		ip = (struct dinst *)ip->i_extra;
 		ip = &ip[f_reg(regmodrm, 0)];
 		i_name = ip->i_name;
 		i_mode = ip->i_mode;
Index: sys/arch/arm/arm/db_trace.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/arm/arm/db_trace.c,v
retrieving revision 1.3
retrieving revision 1.3.10.1
diff -u -r1.3 -r1.3.10.1
--- sys/arch/arm/arm/db_trace.c	29 Nov 2006 12:24:17 -0000	1.3
+++ sys/arch/arm/arm/db_trace.c	16 Sep 2008 23:10:37 -0000	1.3.10.1
@@ -105,6 +105,9 @@
 		frame = (u_int32_t *)(DDB_REGS->tf_r11);
 	else {
 		if (trace_thread) {
+			/* FIXME: instances. */
+			(*pr) ("db_trace.c: operation not supported\n");
+#if 0
 			struct proc *p;
 			struct user *u;
 			(*pr) ("trace: pid %d ", (int)addr);
@@ -120,6 +123,7 @@
 			frame = (u_int32_t *)(u->u_pcb.pcb_un.un_32.pcb32_r11);
 #endif
 			(*pr)("at %p\n", frame);
+#endif
 		} else
 			frame = (u_int32_t *)(addr);
 	}
Index: sys/arch/i386/conf/GENERIC
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.633
retrieving revision 1.633.4.2
diff -u -r1.633 -r1.633.4.2
--- sys/arch/i386/conf/GENERIC	2 Aug 2008 16:09:29 -0000	1.633
+++ sys/arch/i386/conf/GENERIC	18 Feb 2009 12:43:24 -0000	1.633.4.2
@@ -15,6 +15,8 @@
 
 option		USER_PCICONF	# user-space PCI configuration
 
+makeoptions	DEBUG="-g"
+
 #option		VM86		# Virtual 8086 emulation
 option		KVM86		# Kernel Virtual 8086 emulation
 option		USER_LDT	# user-settable LDT; see i386_set_ldt(2)
@@ -30,7 +32,7 @@
 option		COMPAT_BSDOS	# binary compatibility with BSD/OS
 option		COMPAT_AOUT	# a.out binaries are emulated
 
-option		PROCFS		# /proc
+#option		PROCFS		# /proc
 #option		NTFS		# Experimental NTFS support
 
 # or use		root on nfs swap on nfs
Index: sys/arch/i386/i386/db_disasm.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/i386/i386/db_disasm.c,v
retrieving revision 1.15
retrieving revision 1.15.6.1
diff -u -r1.15 -r1.15.6.1
--- sys/arch/i386/i386/db_disasm.c	1 Sep 2007 11:54:02 -0000	1.15
+++ sys/arch/i386/i386/db_disasm.c	12 Sep 2008 13:58:48 -0000	1.15.6.1
@@ -94,7 +94,7 @@
 #define	Ril	36			/* long register in instruction */
 #define	Iba	37			/* byte immediate, don't print if 0xa */
 
-struct inst {
+struct dinst {
 	char *	i_name;			/* name */
 	short	i_has_modrm;		/* has regmodrm byte */
 	short	i_size;			/* operand size */
@@ -149,7 +149,7 @@
 	"",		"",		"",		""
 };
 
-struct inst db_inst_0f0x[] = {
+struct dinst db_inst_0f0x[] = {
 /*00*/	{ "",	   TRUE,  NONE,  op1(Ew),     db_Grp6 },
 /*01*/	{ "",	   TRUE,  NONE,  op1(Ew),     db_Grp7 },
 /*02*/	{ "lar",   TRUE,  LONG,  op2(E,R),    0 },
@@ -169,7 +169,7 @@
 /*0f*/	{ "",      FALSE, NONE,  0,	      0 },
 };
 
-struct inst	db_inst_0f2x[] = {
+struct dinst	db_inst_0f2x[] = {
 /*20*/	{ "mov",   TRUE,  LONG,  op2(CR,E),   0 }, /* use E for reg */
 /*21*/	{ "mov",   TRUE,  LONG,  op2(DR,E),   0 }, /* since mod == 11 */
 /*22*/	{ "mov",   TRUE,  LONG,  op2(E,CR),   0 },
@@ -189,7 +189,7 @@
 /*2f*/	{ "",      FALSE, NONE,  0,	      0 },
 };
 
-struct inst	db_inst_0f3x[] = {
+struct dinst	db_inst_0f3x[] = {
 /*30*/	{ "wrmsr", FALSE, NONE,  0,           0 },
 /*31*/	{ "rdtsc", FALSE, NONE,  0,           0 },
 /*32*/	{ "rdmsr", FALSE, NONE,  0,           0 },
@@ -209,7 +209,7 @@
 /*3f*/	{ "",      FALSE, NONE,  0,           0 },
 };
 
-struct inst	db_inst_0f8x[] = {
+struct dinst	db_inst_0f8x[] = {
 /*80*/	{ "jo",    FALSE, NONE,  op1(Dl),     0 },
 /*81*/	{ "jno",   FALSE, NONE,  op1(Dl),     0 },
 /*82*/	{ "jb",    FALSE, NONE,  op1(Dl),     0 },
@@ -229,7 +229,7 @@
 /*8f*/	{ "jnle",  FALSE, NONE,  op1(Dl),     0 },
 };
 
-struct inst	db_inst_0f9x[] = {
+struct dinst	db_inst_0f9x[] = {
 /*90*/	{ "seto",  TRUE,  NONE,  op1(Eb),     0 },
 /*91*/	{ "setno", TRUE,  NONE,  op1(Eb),     0 },
 /*92*/	{ "setb",  TRUE,  NONE,  op1(Eb),     0 },
@@ -249,7 +249,7 @@
 /*9f*/	{ "setnle",TRUE,  NONE,  op1(Eb),     0 },
 };
 
-struct inst	db_inst_0fax[] = {
+struct dinst	db_inst_0fax[] = {
 /*a0*/	{ "push",  FALSE, NONE,  op1(Si),     0 },
 /*a1*/	{ "pop",   FALSE, NONE,  op1(Si),     0 },
 /*a2*/	{ "cpuid", FALSE, NONE,  0,	      0 },
@@ -269,7 +269,7 @@
 /*af*/	{ "imul",  TRUE,  LONG,  op2(E,R),    0 },
 };
 
-struct inst	db_inst_0fbx[] = {
+struct dinst	db_inst_0fbx[] = {
 /*b0*/	{ "cmpxchg",TRUE, BYTE,	 op2(R, E),   0 },
 /*b1*/	{ "cmpxchg",TRUE, LONG,	 op2(R, E),   0 },
 /*b2*/	{ "lss",   TRUE,  LONG,  op2(E, R),   0 },
@@ -289,7 +289,7 @@
 /*bf*/	{ "movsw", TRUE,  LONG,  op2(Ew, R),  0 },
 };
 
-struct inst	db_inst_0fcx[] = {
+struct dinst	db_inst_0fcx[] = {
 /*c0*/	{ "xadd",  TRUE,  BYTE,	 op2(R, E),   0 },
 /*c1*/	{ "xadd",  TRUE,  LONG,	 op2(R, E),   0 },
 /*c2*/	{ "",	   FALSE, NONE,	 0,	      0 },
@@ -309,7 +309,7 @@
 /*cf*/	{ "bswap", FALSE, LONG,  op1(Ril),    0 },
 };
 
-struct inst *db_inst_0f[] = {
+struct dinst *db_inst_0f[] = {
 	db_inst_0f0x,
 	NULL,
 	db_inst_0f2x,
@@ -484,7 +484,7 @@
 	"sar"
 };
 
-struct inst db_Grp3[] = {
+struct dinst db_Grp3[] = {
 	{ "test",  TRUE, NONE, op2(I,E), 0 },
 	{ "test",  TRUE, NONE, op2(I,E), 0 },
 	{ "not",   TRUE, NONE, op1(E),   0 },
@@ -495,7 +495,7 @@
 	{ "idiv",  TRUE, NONE, op2(E,A), 0 },
 };
 
-struct inst	db_Grp4[] = {
+struct dinst	db_Grp4[] = {
 	{ "inc",   TRUE, BYTE, op1(E),   0 },
 	{ "dec",   TRUE, BYTE, op1(E),   0 },
 	{ "",      TRUE, NONE, 0,	 0 },
@@ -506,7 +506,7 @@
 	{ "",      TRUE, NONE, 0,	 0 }
 };
 
-struct inst	db_Grp5[] = {
+struct dinst	db_Grp5[] = {
 	{ "inc",   TRUE, LONG, op1(E),   0 },
 	{ "dec",   TRUE, LONG, op1(E),   0 },
 	{ "call",  TRUE, NONE, op1(Eind),0 },
@@ -517,7 +517,7 @@
 	{ "",      TRUE, NONE, 0,	 0 }
 };
 
-struct inst db_inst_table[256] = {
+struct dinst db_inst_table[256] = {
 /*00*/	{ "add",   TRUE,  BYTE,  op2(R, E),  0 },
 /*01*/	{ "add",   TRUE,  LONG,  op2(R, E),  0 },
 /*02*/	{ "add",   TRUE,  BYTE,  op2(E, R),  0 },
@@ -807,7 +807,7 @@
 /*ff*/	{ "",	   TRUE,  NONE,  0,	     db_Grp5 },
 };
 
-struct inst	db_bad_inst =
+struct dinst	db_bad_inst =
 	{ "???",   FALSE, NONE,  0,	      0 }
 ;
 
@@ -1077,7 +1077,7 @@
 	int	size;
 	int	short_addr;
 	char *	seg;
-	struct inst *	ip;
+	struct dinst *	ip;
 	char *	i_name;
 	int	i_size;
 	int	i_mode;
@@ -1176,12 +1176,12 @@
 	    ip->i_extra == db_GrpC) {
 		i_name = ((char **)ip->i_extra)[f_reg(regmodrm)];
 	} else if (ip->i_extra == db_Grp3) {
-		ip = (struct inst *)ip->i_extra;
+		ip = (struct dinst *)ip->i_extra;
 		ip = &ip[f_reg(regmodrm)];
 		i_name = ip->i_name;
 		i_mode = ip->i_mode;
 	} else if (ip->i_extra == db_Grp4 || ip->i_extra == db_Grp5) {
-		ip = (struct inst *)ip->i_extra;
+		ip = (struct dinst *)ip->i_extra;
 		ip = &ip[f_reg(regmodrm)];
 		i_name = ip->i_name;
 		i_mode = ip->i_mode;
Index: sys/arch/i386/i386/db_trace.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/i386/i386/db_trace.c,v
retrieving revision 1.13
retrieving revision 1.13.10.1
diff -u -r1.13 -r1.13.10.1
--- sys/arch/i386/i386/db_trace.c	28 Nov 2006 18:56:17 -0000	1.13
+++ sys/arch/i386/i386/db_trace.c	16 Sep 2008 23:10:38 -0000	1.13.10.1
@@ -215,6 +215,9 @@
 	} else if (trace_thread) {
 		(*pr) ("db_trace.c: can't trace thread\n");
 	} else if (trace_proc) {
+		/* FIXME: instances. */
+		(*pr) ("db_trace.c: operation not supported\n");
+#if 0
 		struct proc *p = pfind((pid_t)addr);
 		if (p == NULL) {
 			(*pr) ("db_trace.c: process not found\n");
@@ -223,6 +226,7 @@
 		frame = (struct i386_frame *)p->p_addr->u_pcb.pcb_ebp;
 		callpc = (db_addr_t)
 		    db_get_value((int)&frame->f_retaddr, 4, FALSE);
+#endif
 	} else {
 		frame = (struct i386_frame *)addr;
 		callpc = (db_addr_t)
Index: sys/arch/powerpc/powerpc/pmap.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/powerpc/powerpc/pmap.c,v
retrieving revision 1.105
retrieving revision 1.105.4.1
diff -u -r1.105 -r1.105.4.1
--- sys/arch/powerpc/powerpc/pmap.c	14 Jun 2008 10:55:20 -0000	1.105
+++ sys/arch/powerpc/powerpc/pmap.c	16 Sep 2008 23:10:38 -0000	1.105.4.1
@@ -2578,8 +2578,11 @@
 }
 
 
+/* FIXME: is this even used? */
+#if 0
 /* debugger assist function */
 int pmap_prtrans(u_int pid, vaddr_t va);
+#endif
 
 void
 pmap_print_pted(struct pte_desc *pted, int(*print)(const char *, ...))
@@ -2649,6 +2652,8 @@
 	return 0;
 }
 
+/* FIXME: is this used anywhere? */
+#if 0
 int pmap_dump_pmap(u_int pid);
 int
 pmap_dump_pmap(u_int pid)
@@ -2675,7 +2680,10 @@
 
 	return 0;
 }
+#endif
 
+/* FIXME: is this even used? */
+#if 0
 int
 pmap_prtrans(u_int pid, vaddr_t va)
 {
@@ -2716,6 +2724,7 @@
 
 	return 0;
 }
+#endif
 int pmap_show_mappings(paddr_t pa);
 
 int
Index: sys/arch/sh/sh/db_interface.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/sh/sh/db_interface.c,v
retrieving revision 1.2
retrieving revision 1.2.10.3
diff -u -r1.2 -r1.2.10.3
--- sys/arch/sh/sh/db_interface.c	6 Oct 2006 21:16:57 -0000	1.2
+++ sys/arch/sh/sh/db_interface.c	18 Feb 2009 12:43:24 -0000	1.2.10.3
@@ -367,11 +367,14 @@
 __db_procname_by_asid(int asid)
 {
 	static char notfound[] = "---";
+	struct inst *i;
 	struct proc *p;
 
-	LIST_FOREACH(p, &allproc, p_list) {
-		if (p->p_vmspace->vm_map.pmap->pm_asid == asid)
-			return (p->p_comm);
+	LIST_FOREACH(i, &inst_all, inst_list) {
+		LIST_FOREACH(p, &i->inst_proc->allproc, p_list) {
+			if (p->p_vmspace->vm_map.pmap->pm_asid == asid)
+				return (p->p_comm);
+		}
 	}
 
 	return (notfound);
@@ -601,6 +604,7 @@
 		  char *modif)
 {
 	struct proc *p;
+	struct inst *inst;
 	struct user *u;
 	struct pcb *pcb;
 	uint32_t *t32;
@@ -617,27 +621,29 @@
 		  "stack top    max used    frame top     max used"
 		  "  nest\n");
 
-	LIST_FOREACH(p, &allproc, p_list) {
-		u = p->p_addr;
-		pcb = &u->u_pcb;
-		/* stack */
-		t32 = (uint32_t *)(pcb->pcb_sf.sf_r7_bank - MAX_STACK);
-		for (i = 0; *t32++ == 0xa5a5a5a5; i++)
-			continue;
-		i = MAX_STACK - i * sizeof(int);
-
-		/* frame */
-		t8 = (uint8_t *)((vaddr_t)pcb + PAGE_SIZE - MAX_FRAME);
-		for (j = 0; *t8++ == 0x5a; j++)
-			continue;
-		j = MAX_FRAME - j;
-
-		db_printf("%6d 0x%08x %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
-		    p->p_lid,
-		    pcb->pcb_sf.sf_r7_bank, i, i * 100 / MAX_STACK,
-		    (vaddr_t)pcb + PAGE_SIZE, j, j * 100 / MAX_FRAME,
-		    j / sizeof(struct trapframe),
-		    p->p_comm);
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			u = p->p_addr;
+			pcb = &u->u_pcb;
+			/* stack */
+			t32 = (uint32_t *)(pcb->pcb_sf.sf_r7_bank - MAX_STACK);
+			for (i = 0; *t32++ == 0xa5a5a5a5; i++)
+				continue;
+			i = MAX_STACK - i * sizeof(int);
+	
+			/* frame */
+			t8 = (uint8_t *)((vaddr_t)pcb + PAGE_SIZE - MAX_FRAME);
+			for (j = 0; *t8++ == 0x5a; j++)
+				continue;
+			j = MAX_FRAME - j;
+	
+			db_printf("%6d 0x%08x %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
+			    p->p_lid,
+			    pcb->pcb_sf.sf_r7_bank, i, i * 100 / MAX_STACK,
+			    (vaddr_t)pcb + PAGE_SIZE, j, j * 100 / MAX_FRAME,
+			    j / sizeof(struct trapframe),
+			    p->p_comm);
+		}
 	}
 #undef	MAX_STACK
 #undef	MAX_FRAME
Index: sys/arch/sh/sh/pmap.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/sh/sh/pmap.c,v
retrieving revision 1.9
retrieving revision 1.9.4.3
diff -u -r1.9 -r1.9.4.3
--- sys/arch/sh/sh/pmap.c	26 Jun 2008 05:42:13 -0000	1.9
+++ sys/arch/sh/sh/pmap.c	18 Feb 2009 12:43:24 -0000	1.9.4.3
@@ -1035,6 +1035,7 @@
 __pmap_asid_alloc()
 {
 	struct proc *p;
+	struct inst *i;
 	int i, j, k, n, map, asid;
 
 	/* Search free ASID */
@@ -1053,15 +1054,17 @@
 	}
 
 	/* Steal ASID */
-	LIST_FOREACH(p, &allproc, p_list) {
-		if ((asid = p->p_vmspace->vm_map.pmap->pm_asid) > 0) {
-			pmap_t pmap = p->p_vmspace->vm_map.pmap;
-			pmap->pm_asid = -1;
-			__pmap_asid.hint = asid;
-			/* Invalidate all old ASID entry */
-			sh_tlb_invalidate_asid(pmap->pm_asid);
-
-			return (__pmap_asid.hint);
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			if ((asid = p->p_vmspace->vm_map.pmap->pm_asid) > 0) {
+				pmap_t pmap = p->p_vmspace->vm_map.pmap;
+				pmap->pm_asid = -1;
+				__pmap_asid.hint = asid;
+				/* Invalidate all old ASID entry */
+				sh_tlb_invalidate_asid(pmap->pm_asid);
+	
+				return (__pmap_asid.hint);
+			}
 		}
 	}
 
Index: sys/arch/sparc/conf/GENERIC
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/sparc/conf/GENERIC,v
retrieving revision 1.90
retrieving revision 1.90.8.1
diff -u -r1.90 -r1.90.8.1
--- sys/arch/sparc/conf/GENERIC	29 May 2007 09:54:03 -0000	1.90
+++ sys/arch/sparc/conf/GENERIC	18 Feb 2009 12:43:24 -0000	1.90.8.1
@@ -28,7 +28,7 @@
 # Options for SPARCstation hardware
 option		COMPAT_SUNOS	# compatibility with SunOS binaries
 option		COMPAT_SVR4	# compatibility with SVR4 binaries
-option		PROCFS		# /proc
+#option		PROCFS		# /proc
 
 option		WSEMUL_SUN	# provide sun terminal emulation; required
 option		WSEMUL_NO_VT100	# do not provide vt100 terminal emulation
Index: sys/arch/sparc64/sparc64/db_interface.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/sparc64/sparc64/db_interface.c,v
retrieving revision 1.26
retrieving revision 1.26.4.3
diff -u -r1.26 -r1.26.4.3
--- sys/arch/sparc64/sparc64/db_interface.c	13 Mar 2008 23:29:46 -0000	1.26
+++ sys/arch/sparc64/sparc64/db_interface.c	18 Feb 2009 12:43:24 -0000	1.26.4.3
@@ -815,18 +815,21 @@
 	char *modif;
 {
 	struct proc *p;
+	struct inst *inst;
 
 	/* XXX LOCKING XXX */
-	LIST_FOREACH(p, &allproc, p_list) {
-		if (p->p_stat) {
-			db_printf("process %p:", p);
-			db_printf("pid:%d pmap:%p ctx:%x tf:%p fpstate %p "
-				"lastcall:%s\n",
-				p->p_pid, p->p_vmspace->vm_map.pmap,
-				p->p_vmspace->vm_map.pmap->pm_ctx,
-				p->p_md.md_tf, p->p_md.md_fpstate,
-				(p->p_addr->u_pcb.lastcall)?
-				p->p_addr->u_pcb.lastcall : "Null");
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			if (p->p_stat) {
+				db_printf("process %p:", p);
+				db_printf("inst:%u pid:%d pmap:%p ctx:%x tf:%p fpstate %p "
+					"lastcall:%s\n", p->p_inst->inst_id,
+					p->p_pid, p->p_vmspace->vm_map.pmap,
+					p->p_vmspace->vm_map.pmap->pm_ctx,
+					p->p_md.md_tf, p->p_md.md_fpstate,
+					(p->p_addr->u_pcb.lastcall)?
+					p->p_addr->u_pcb.lastcall : "Null");
+			}
 		}
 	}
 	return;
@@ -886,23 +889,31 @@
 	char *modif;
 {
 	struct proc *p, *pp;
+	struct inst *inst;
 
 	if (!have_addr) {
 		db_printf("What PID do you want to map in?\n");
 		return;
 	}
+	
+	/* 
+	 * FIXME: this doesn't work if multiple procs/same pids can
+	 * co-exist (mult).
+	 */
     
-	LIST_FOREACH(p, &allproc, p_list) {
-		pp = p->p_pptr;
-		if (p->p_stat && p->p_pid == addr) {
-			curproc = p;
-			curpcb = (struct pcb*)p->p_addr;
-			if (p->p_vmspace->vm_map.pmap->pm_ctx) {
-				switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			pp = p->p_pptr;
+			if (p->p_stat && p->p_pid == addr) {
+				curproc = p;
+				curpcb = (struct pcb*)p->p_addr;
+				if (p->p_vmspace->vm_map.pmap->pm_ctx) {
+					switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
+					return;
+				}
+				db_printf("PID %ld has a null context.\n", addr);
 				return;
 			}
-			db_printf("PID %ld has a null context.\n", addr);
-			return;
 		}
 	}
 	db_printf("PID %ld not found.\n", addr);
Index: sys/arch/sparc64/sparc64/db_trace.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/sparc64/sparc64/db_trace.c,v
retrieving revision 1.9
retrieving revision 1.9.8.1
diff -u -r1.9 -r1.9.8.1
--- sys/arch/sparc64/sparc64/db_trace.c	15 Aug 2007 20:10:08 -0000	1.9
+++ sys/arch/sparc64/sparc64/db_trace.c	16 Sep 2008 23:10:38 -0000	1.9.8.1
@@ -79,6 +79,9 @@
 		frame = (vaddr_t)DDB_TF->tf_out[6];
 	else {
 		if (trace_thread) {
+			/* FIXME: instances */
+			(*pr)("db_trace.c: operation not supported\n");
+#if 0
 			struct proc *p;
 			struct user *u;
 			(*pr)("trace: pid %d ", (int)addr);
@@ -90,6 +93,7 @@
 			u = p->p_addr;
 			frame = (vaddr_t)u->u_pcb.pcb_sp;
 			(*pr)("at %p\n", frame);
+#endif
 		} else {
 			frame = (vaddr_t)addr;
 		}
Index: sys/arch/vax/vax/db_machdep.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/arch/vax/vax/db_machdep.c,v
retrieving revision 1.18
retrieving revision 1.18.4.1
diff -u -r1.18 -r1.18.4.1
--- sys/arch/vax/vax/db_machdep.c	30 Mar 2008 18:24:04 -0000	1.18
+++ sys/arch/vax/vax/db_machdep.c	16 Sep 2008 23:10:38 -0000	1.18.4.1
@@ -347,6 +347,9 @@
 	 * if no address then either current proc or panic
 	 */
 	if (have_addr) {
+		/* FIXME: instances */
+		(*pr) ("db_machdep.c: operation not supported\n");
+#if 0
 		p = pfind((int)addr);
 		/* Try to be helpful by looking at it as if it were decimal */
 		if (p == NULL) {
@@ -368,6 +371,7 @@
 				return;
 			}
 		}
+#endif
 	} else {
 		p = curproc;
 		if (p == NULL) {
Index: sys/compat/hpux/hpux_compat.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/compat/hpux/hpux_compat.c,v
retrieving revision 1.29
retrieving revision 1.29.6.1
diff -u -r1.29 -r1.29.6.1
--- sys/compat/hpux/hpux_compat.c	22 Sep 2007 09:57:40 -0000	1.29
+++ sys/compat/hpux/hpux_compat.c	16 Sep 2008 23:10:38 -0000	1.29.6.1
@@ -519,7 +519,7 @@
 		return (EINVAL);
 	if (SCARG(uap, pid) == 0)
 		p = cp;
-	else if ((p = pfind(SCARG(uap, pid))) == 0)
+	else if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == 0)
 		return (ESRCH);
 	nice = p->p_nice;
 	if (nice < NZERO)
@@ -597,7 +597,7 @@
 		 * has the correct value (the child has already trapped
 		 * into the kernel).
 		 */
-		if ((cp = pfind(SCARG(uap, pid))) == 0)
+		if ((cp = pfind(p->p_inst->inst_proc, SCARG(uap, pid))) == 0)
 			return (ESRCH);
 		SCARG(uap, addr) =
 		    (int *)hpux_to_bsd_uoff(SCARG(uap, addr), &isps, cp);
@@ -961,7 +961,7 @@
 
 	if (SCARG(uap, pid) == 0)
 		SCARG(uap, pid) = cp->p_pid;
-	p = pfind(SCARG(uap, pid));
+	p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid));
 	if (p == 0)
 		return (ESRCH);
 	if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
Index: sys/compat/linux/linux_file.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/compat/linux/linux_file.c,v
retrieving revision 1.23
retrieving revision 1.23.10.2
diff -u -r1.23 -r1.23.10.2
--- sys/compat/linux/linux_file.c	25 Sep 2006 07:12:57 -0000	1.23
+++ sys/compat/linux/linux_file.c	18 Sep 2008 17:21:02 -0000	1.23.10.2
@@ -417,12 +417,12 @@
 		if ((long)arg <= 0) {
 			pgid = -(long)arg;
 		} else {
-			struct proc *p1 = pfind((long)arg);
+			struct proc *p1 = pfind(p->p_inst->inst_proc, (long)arg);
 			if (p1 == 0)
 				return (ESRCH);
 			pgid = (long)p1->p_pgrp->pg_id;
 		}
-		pgrp = pgfind(pgid);
+		pgrp = pgfind(p->p_inst->inst_proc, pgid);
 		if (pgrp == NULL || pgrp->pg_session != p->p_session)
 			return EPERM;
 		tp->t_pgrp = pgrp;
Index: sys/compat/linux/linux_misc.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.62
retrieving revision 1.62.4.3
diff -u -r1.62 -r1.62.4.3
--- sys/compat/linux/linux_misc.c	26 Jun 2008 05:42:14 -0000	1.62
+++ sys/compat/linux/linux_misc.c	18 Feb 2009 12:43:24 -0000	1.62.4.3
@@ -1226,7 +1226,7 @@
 	struct proc *targp;
 
 	if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
-		if ((targp = pfind(SCARG(uap, pid))) == 0)
+		if ((targp = pfind(p->p_inst->inst_proc, SCARG(uap, pid))) == 0)
 			return ESRCH;
 	}
 	else
@@ -1320,7 +1320,7 @@
 		return 0;
 	}
 
-	p1 = pfind((int)pid);
+	p1 = pfind(p->p_inst->inst_proc, (int)pid);
 	if (p1 == NULL)
 		return ESRCH;
 
Index: sys/compat/linux/linux_sched.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/compat/linux/linux_sched.c,v
retrieving revision 1.6
retrieving revision 1.6.4.1
diff -u -r1.6 -r1.6.4.1
--- sys/compat/linux/linux_sched.c	26 Jun 2008 05:42:14 -0000	1.6
+++ sys/compat/linux/linux_sched.c	16 Sep 2008 23:10:38 -0000	1.6.4.1
@@ -121,7 +121,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = cp->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -158,7 +158,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = cp->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -202,7 +202,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = cp->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -242,7 +242,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = cp->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
Index: sys/compat/svr4/svr4_misc.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.49
retrieving revision 1.49.6.3
diff -u -r1.49 -r1.49.6.3
--- sys/compat/svr4/svr4_misc.c	1 Oct 2007 12:10:55 -0000	1.49
+++ sys/compat/svr4/svr4_misc.c	18 Feb 2009 12:43:25 -0000	1.49.6.3
@@ -101,7 +101,7 @@
     struct svr4_statvfs *);
 static void bsd_statfs_to_svr4_statvfs64(const struct statfs *,
     struct svr4_statvfs64 *);
-static struct proc *svr4_pfind(pid_t pid);
+static struct proc *svr4_pfind(struct inst_proc *, pid_t pid);
 
 static int svr4_mknod(struct proc *, register_t *, char *,
 			   svr4_mode_t, svr4_dev_t);
@@ -816,17 +816,18 @@
 
 
 static struct proc *
-svr4_pfind(pid)
+svr4_pfind(ip, pid)
+	struct inst_proc *ip;
 	pid_t pid;
 {
 	struct proc *p;
 
 	/* look in the live processes */
-	if ((p = pfind(pid)) != NULL)
+	if ((p = pfind(ip, pid)) != NULL)
 		return p;
 
 	/* look in the zombies */
-	LIST_FOREACH(p, &zombproc, p_list)
+	LIST_FOREACH(p, &ip->zombproc, p_list)
 		if (p->p_pid == pid)
 			return p;
 
@@ -862,7 +863,7 @@
 
 	case 2:			/* getsid(pid) */
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_pfind(p->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		/* 
 		 * we return the pid of the session leader for this
@@ -877,7 +878,7 @@
 	case 4:			/* getpgid(pid) */
 
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_pfind(p->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 
 		*retval = (int) p->p_pgrp->pg_id;
@@ -1091,7 +1092,7 @@
 			 * If we got the child via a ptrace 'attach',
 			 * we need to give it back to the old parent.
 			 */
-			if (p->p_oppid && (t = pfind(p->p_oppid))) {
+			if (p->p_oppid && (t = pfind(p->p_inst->inst_proc, p->p_oppid))) {
 				p->p_oppid = 0;
 				proc_reparent(p, t);
 				psignal(t, SIGCHLD);
Index: sys/conf/files
===================================================================
RCS file: /cvs/OpenBSD/src/sys/conf/files,v
retrieving revision 1.438
retrieving revision 1.438.4.1
diff -u -r1.438 -r1.438.4.1
--- sys/conf/files	21 Jul 2008 19:05:21 -0000	1.438
+++ sys/conf/files	12 Sep 2008 13:58:48 -0000	1.438.4.1
@@ -651,6 +651,7 @@
 file kern/kern_exec.c
 file kern/kern_exit.c
 file kern/kern_fork.c
+file kern/kern_inst.c
 file kern/kern_kthread.c
 file kern/kern_ktrace.c			ktrace
 file kern/kern_lock.c
Index: sys/dev/systrace.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/dev/systrace.c,v
retrieving revision 1.47
retrieving revision 1.47.6.1
diff -u -r1.47 -r1.47.6.1
--- sys/dev/systrace.c	5 Jan 2008 07:33:37 -0000	1.47
+++ sys/dev/systrace.c	16 Sep 2008 23:10:38 -0000	1.47.6.1
@@ -149,15 +149,15 @@
 
 /* Needs to be called with fst locked */
 
-int	systrace_attach(struct fsystrace *, pid_t);
-int	systrace_detach(struct str_process *);
+int	systrace_attach(struct inst *, struct fsystrace *, pid_t);
+int	systrace_detach(struct inst *, struct str_process *);
 int	systrace_answer(struct str_process *, struct systrace_answer *);
 int     systrace_setscriptname(struct str_process *,
 	    struct systrace_scriptname *);
 int     systrace_prepinject(struct str_process *, struct systrace_inject *);
 int     systrace_inject(struct str_process *, int);
 int	systrace_io(struct str_process *, struct systrace_io *);
-int	systrace_policy(struct fsystrace *, struct systrace_policy *);
+int	systrace_policy(struct inst *, struct fsystrace *, struct systrace_policy *);
 int	systrace_preprepl(struct str_process *, struct systrace_replace *);
 int	systrace_replace(struct str_process *, size_t, register_t []);
 int	systrace_getcwd(struct fsystrace *, struct str_process *);
@@ -165,8 +165,8 @@
 void	systrace_replacefree(struct str_process *);
 
 int	systrace_processready(struct str_process *);
-struct proc *systrace_find(struct str_process *);
-struct str_process *systrace_findpid(struct fsystrace *fst, pid_t pid);
+struct proc *systrace_find(struct inst *, struct str_process *);
+struct str_process *systrace_findpid(struct inst *, struct fsystrace *fst, pid_t pid);
 void	systrace_wakeup(struct fsystrace *);
 void	systrace_closepolicy(struct fsystrace *, struct str_policy *);
 int	systrace_insert_process(struct fsystrace *, struct proc *);
@@ -335,7 +335,7 @@
 	rw_enter_write(&fst->lock);
 	systrace_unlock();
 	if (pid) {
-		strp = systrace_findpid(fst, pid);
+		strp = systrace_findpid(p->p_inst, fst, pid);
 		if (strp == NULL) {
 			ret = ESRCH;
 			goto unlock;
@@ -348,11 +348,11 @@
 		if (!pid)
 			ret = EINVAL;
 		else
-			ret = systrace_attach(fst, pid);
+			ret = systrace_attach(p->p_inst, fst, pid);
 		DPRINTF(("%s: attach to %u: %d\n", __func__, pid, ret));
 		break;
 	case STRIOCDETACH:
-		ret = systrace_detach(strp);
+		ret = systrace_detach(p->p_inst, strp);
 		break;
 	case STRIOCREPORT:
 		SET(strp->flags, STR_PROC_REPORT);
@@ -371,7 +371,7 @@
 		ret = systrace_prepinject(strp, (struct systrace_inject *)data);
 		break;
 	case STRIOCPOLICY:
-		ret = systrace_policy(fst, (struct systrace_policy *)data);
+		ret = systrace_policy(p->p_inst, fst, (struct systrace_policy *)data);
 		break;
 	case STRIOCREPLACE:
 		ret = systrace_preprepl(strp, (struct systrace_replace *)data);
@@ -471,7 +471,7 @@
 	    strp = TAILQ_FIRST(&fst->processes)) {
 		struct proc *q = strp->proc;
 
-		systrace_detach(strp);
+		systrace_detach(p->p_inst, strp);
 		psignal(q, SIGKILL);
 	}
 
@@ -610,11 +610,11 @@
 }
 
 struct proc *
-systrace_find(struct str_process *strp)
+systrace_find(struct inst *inst, struct str_process *strp)
 {
 	struct proc *proc;
 
-	if ((proc = pfind(strp->pid)) == NULL)
+	if ((proc = pfind(inst->inst_proc, strp->pid)) == NULL)
 		return (NULL);
 
 	if (proc != strp->proc)
@@ -642,7 +642,7 @@
 		/* Insert Exit message */
 		systrace_msg_child(fst, strp, -1);
 
-		systrace_detach(strp);
+		systrace_detach(proc->p_inst, strp);
 		rw_exit_write(&fst->lock);
 	} else
 		systrace_unlock();
@@ -668,7 +668,7 @@
 
 	if (systrace_insert_process(fst, p))
 		goto out;
-	if ((strp = systrace_findpid(fst, p->p_pid)) == NULL)
+	if ((strp = systrace_findpid(p->p_inst, fst, p->p_pid)) == NULL)
 		panic("systrace_fork");
 
 	/* Reference policy */
@@ -1058,7 +1058,7 @@
 }
 
 int
-systrace_policy(struct fsystrace *fst, struct systrace_policy *pol)
+systrace_policy(struct inst *inst, struct fsystrace *fst, struct systrace_policy *pol)
 {
 	struct str_policy *strpol;
 	struct str_process *strp;
@@ -1085,7 +1085,7 @@
 		if (strpol == NULL)
 			return (EINVAL);
 
-		strp = systrace_findpid(fst, pol->strp_pid);
+		strp = systrace_findpid(inst, fst, pol->strp_pid);
 		if (strp == NULL)
 			return (EINVAL);
 
@@ -1216,12 +1216,12 @@
 }
 
 int
-systrace_attach(struct fsystrace *fst, pid_t pid)
+systrace_attach(struct inst *inst, struct fsystrace *fst, pid_t pid)
 {
 	int error = 0;
 	struct proc *proc, *p = curproc;
 
-	if ((proc = pfind(pid)) == NULL) {
+	if ((proc = pfind(inst->inst_proc, pid)) == NULL) {
 		error = ESRCH;
 		goto out;
 	}
@@ -1550,7 +1550,7 @@
 }
 
 struct str_process *
-systrace_findpid(struct fsystrace *fst, pid_t pid)
+systrace_findpid(struct inst *inst, struct fsystrace *fst, pid_t pid)
 {
 	struct str_process *strp;
 	struct proc *proc = NULL;
@@ -1562,13 +1562,13 @@
 	if (strp == NULL)
 		return (NULL);
 
-	proc = systrace_find(strp);
+	proc = systrace_find(inst, strp);
 
 	return (proc ? strp : NULL);
 }
 
 int
-systrace_detach(struct str_process *strp)
+systrace_detach(struct inst *inst, struct str_process *strp)
 {
 	struct proc *proc;
 	struct fsystrace *fst = NULL;
@@ -1576,7 +1576,7 @@
 
 	DPRINTF(("%s: Trying to detach from %d\n", __func__, strp->pid));
 
-	if ((proc = systrace_find(strp)) != NULL) {
+	if ((proc = systrace_find(inst, strp)) != NULL) {
 		atomic_clearbits_int(&proc->p_flag, P_SYSTRACE);
 		proc->p_systrace = NULL;
 	} else
Index: sys/dev/wscons/wsdisplay_compat_usl.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/dev/wscons/wsdisplay_compat_usl.c,v
retrieving revision 1.19
retrieving revision 1.19.10.1
diff -u -r1.19 -r1.19.10.1
--- sys/dev/wscons/wsdisplay_compat_usl.c	14 Feb 2007 01:12:16 -0000	1.19
+++ sys/dev/wscons/wsdisplay_compat_usl.c	16 Sep 2008 23:10:38 -0000	1.19.10.1
@@ -145,7 +145,7 @@
 usl_sync_check(sd)
 	struct usl_syncdata *sd;
 {
-	if (sd->s_proc == pfind(sd->s_pid))
+	if (sd->s_proc == pfind(sd->s_proc->p_inst->inst_proc, sd->s_pid))
 		return (1);
 	DPRINTF(("usl_sync_check: process %d died\n", sd->s_pid));
 	usl_sync_done(sd);
Index: sys/kern/init_main.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/init_main.c,v
retrieving revision 1.150
retrieving revision 1.150.4.10
diff -u -r1.150 -r1.150.4.10
--- sys/kern/init_main.c	9 Jun 2008 07:07:16 -0000	1.150
+++ sys/kern/init_main.c	18 Feb 2009 18:20:20 -0000	1.150.4.10
@@ -217,6 +217,8 @@
 	tty_init();		/* initialise tty's */
 	cpu_startup();
 
+	printf("cpu is started\n");
+
 	/*
 	 * Initialize mbuf's.  Do this now because we might attempt to
 	 * allocate mbufs or mbuf clusters during autoconfiguration.
@@ -227,6 +229,11 @@
 	soinit();
 
 	/*
+	 * Initialise instance structures.
+	 */
+	instinit();
+
+	/*
 	 * Initialize process and pgrp structures.
 	 */
 	procinit();
@@ -252,16 +259,12 @@
 	/*
 	 * Create process 0 (the swapper).
 	 */
-
 	process0.ps_mainproc = p;
 	TAILQ_INIT(&process0.ps_threads);
 	TAILQ_INSERT_TAIL(&process0.ps_threads, p, p_thr_link);
 	p->p_p = &process0;
 
-	LIST_INSERT_HEAD(&allproc, p, p_list);
 	p->p_pgrp = &pgrp0;
-	LIST_INSERT_HEAD(PIDHASH(0), p, p_hash);
-	LIST_INSERT_HEAD(PGRPHASH(0), &pgrp0, pg_hash);
 	LIST_INIT(&pgrp0.pg_members);
 	LIST_INSERT_HEAD(&pgrp0.pg_members, p, p_pglist);
 
@@ -282,9 +285,23 @@
 	/* Create credentials. */
 	cred0.p_refcnt = 1;
 	p->p_cred = &cred0;
-	p->p_ucred = crget();
+	p->p_ucred = crnew();
 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
 
+	/* 
+	 * FIXME: eventually instances should all be "flat", but for now
+	 * the "main" instance, with id 0,  gets special handling (can't
+	 * be killed).
+	 */
+
+	if (NULL == (p->p_ucred->cr_inst = instknew(0)))
+		panic("couldn't allocate kernel instance");
+
+	p->p_ucred->cr_inst->inst_proc = proc_instinit(p->p_inst);
+
+	pgrp_instadd(p->p_inst->inst_proc, p->p_pgrp);
+	proc_instadd(p->p_inst->inst_proc, p);
+
 	/* Initialize signal state for process 0. */
 	signal_init();
 	p->p_sigacts = &sigacts0;
@@ -422,6 +439,9 @@
 	    &initproc))
 		panic("fork init");
 
+	/* Set "init" process. */
+	p->p_inst->inst_proc->initproc = initproc;
+
 	/*
 	 * Create any kernel threads whose creation was deferred because
 	 * initproc had not yet been created.
@@ -478,7 +498,7 @@
 #else
 	boottime = mono_time = time;	
 #endif
-	LIST_FOREACH(p, &allproc, p_list) {
+	PROCLIST_FOREACH(p, initproc, p_list) {
 		p->p_stats->p_start = boottime;
 		microuptime(&p->p_cpu->ci_schedstate.spc_runtime);
 		p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
Index: sys/kern/init_sysent.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/init_sysent.c,v
retrieving revision 1.103
retrieving revision 1.103.4.3
diff -u -r1.103 -r1.103.4.3
--- sys/kern/init_sysent.c	16 Mar 2008 19:43:41 -0000	1.103
+++ sys/kern/init_sysent.c	13 Feb 2009 09:08:59 -0000	1.103.4.3
@@ -1,10 +1,10 @@
-/*	$OpenBSD$	*/
+/*	\$OpenBSD\$	*/
 
 /*
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;	OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp 
+ * created from;	OpenBSD: syscalls.master,v 1.89 2008/01/05 00:36:13 miod Exp 
  */
 
 #include <sys/param.h>
@@ -836,5 +836,11 @@
 	    sys_fstatfs },			/* 308 = fstatfs */
 	{ 2, s(struct sys_fhstatfs_args), 0,
 	    sys_fhstatfs },			/* 309 = fhstatfs */
+	{ 1, s(struct sys_forkinst_args), 0,
+	    sys_forkinst },			/* 310 = forkinst */
+	{ 0, 0, SY_NOLOCK | 0,
+	    sys_getinstid },			/* 311 = getinstid */
+	{ 2, s(struct sys_killinst_args), 0,
+	    sys_killinst },			/* 312 = killinst */
 };
 
Index: sys/kern/kern_descrip.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_descrip.c,v
retrieving revision 1.79
retrieving revision 1.79.4.3
diff -u -r1.79 -r1.79.4.3
--- sys/kern/kern_descrip.c	12 Jun 2008 18:10:06 -0000	1.79
+++ sys/kern/kern_descrip.c	27 Sep 2008 14:09:44 -0000	1.79.4.3
@@ -383,13 +383,14 @@
 
 			so->so_pgid = (long)SCARG(uap, arg);
 			so->so_siguid = p->p_cred->p_ruid;
+			so->so_siginstid = p->p_inst->inst_id;
 			so->so_sigeuid = p->p_ucred->cr_uid;
 			break;
 		}
 		if ((long)SCARG(uap, arg) <= 0) {
 			SCARG(uap, arg) = (void *)(-(long)SCARG(uap, arg));
 		} else {
-			struct proc *p1 = pfind((long)SCARG(uap, arg));
+			struct proc *p1 = pfind(p->p_inst->inst_proc, (long)SCARG(uap, arg));
 			if (p1 == 0) {
 				error = ESRCH;
 				break;
@@ -838,7 +839,7 @@
 	extern int cmask;
 
 	newfdp = pool_get(&fdesc_pool, PR_WAITOK|PR_ZERO);
-	if (p != NULL) {
+	if (p) {
 		struct filedesc *fdp = p->p_fd;
 
 		newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
Index: sys/kern/kern_event.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_event.c,v
retrieving revision 1.33
retrieving revision 1.33.4.2
diff -u -r1.33 -r1.33.4.2
--- sys/kern/kern_event.c	6 May 2008 20:57:19 -0000	1.33
+++ sys/kern/kern_event.c	18 Sep 2008 21:04:55 -0000	1.33.4.2
@@ -193,7 +193,7 @@
 {
 	struct proc *p;
 
-	p = pfind(kn->kn_id);
+	p = pfind(curproc->p_inst->inst_proc, kn->kn_id);
 	if (p == NULL)
 		return (ESRCH);
 
Index: sys/kern/kern_exit.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_exit.c,v
retrieving revision 1.73
retrieving revision 1.73.4.9
diff -u -r1.73 -r1.73.4.9
--- sys/kern/kern_exit.c	11 May 2008 23:54:40 -0000	1.73
+++ sys/kern/kern_exit.c	18 Feb 2009 12:43:25 -0000	1.73.4.9
@@ -77,6 +77,9 @@
 
 #include <uvm/uvm_extern.h>
 
+
+void		waitinst(struct proc *);
+
 /*
  * exit --
  *	Death of process.
@@ -105,6 +108,35 @@
 }
 #endif
 
+void
+waitinst(struct proc *p)
+{
+	struct proc *q, *nq;
+
+	while ( ! LIST_EMPTY(&p->p_children)) {
+		for (q = LIST_FIRST(&p->p_children); q; q = nq) {
+			nq = LIST_NEXT(q, p_sibling);
+			if (SZOMB != q->p_stat)
+				continue;
+
+			log(LOG_NOTICE, "instance-%u: zapping %d\n", 
+					p->p_inst->inst_id, q->p_pid);
+
+			scheduler_wait_hook(p, q);
+			q->p_xstat = 0;
+			ruadd(&p->p_stats->p_cru, q->p_ru);
+			proc_zap(q);
+		}
+		log(LOG_NOTICE, "instance-%u: sleeping\n",
+				p->p_inst->inst_id);
+		if (LIST_EMPTY(&p->p_children))
+			break;
+		tsleep(p, PUSER, "instwait", 0);
+	}
+	log(LOG_NOTICE, "instance-%u: done waiting\n",
+			p->p_inst->inst_id);
+}
+
 /*
  * Exit: deallocate address space and other resources, change proc state
  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
@@ -115,10 +147,18 @@
 {
 	struct proc *q, *nq;
 
-	if (p->p_pid == 1)
+	if (p->p_pid == 1 && p->p_inst->inst_id == 0)
 		panic("init died (signal %d, exit %d)",
 		    WTERMSIG(rv), WEXITSTATUS(rv));
-	
+
+	/* If the instance's init has died, kill off children. */
+
+	if (p == p->p_inst->inst_proc->initproc) {
+		q = LIST_FIRST(&p->p_children);
+		for (; q; q = LIST_NEXT(q, p_sibling))
+			psignal(q, SIGKILL);
+	}
+
 	/* unlink ourselves from the active threads */
 	TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
 #ifdef RTHREADS
@@ -167,6 +207,7 @@
 	atomic_clearbits_int(&p->p_flag, P_TRACED);
 	if (p->p_flag & P_PPWAIT) {
 		atomic_clearbits_int(&p->p_flag, P_PPWAIT);
+		KASSERT(p->p_pptr);
 		wakeup(p->p_pptr);
 	}
 	p->p_sigignore = ~0;
@@ -232,6 +273,10 @@
 	if (ISSET(p->p_flag, P_SYSTRACE))
 		systrace_exit(p);
 #endif
+
+	if (p == p->p_inst->inst_proc->initproc)
+		waitinst(p);
+
 	/*
 	 * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
 	 */
@@ -246,17 +291,17 @@
          */
 	LIST_REMOVE(p, p_hash);
 	LIST_REMOVE(p, p_list);
-	LIST_INSERT_HEAD(&zombproc, p, p_list);
+	LIST_INSERT_HEAD(&p->p_inst->inst_proc->zombproc, p, p_list);
 
 	/*
 	 * Give orphaned children to init(8).
 	 */
 	q = LIST_FIRST(&p->p_children);
 	if (q)		/* only need this if any child is S_ZOMB */
-		wakeup(initproc);
+		wakeup(p->p_inst->inst_proc->initproc);
 	for (; q != 0; q = nq) {
 		nq = LIST_NEXT(q, p_sibling);
-		proc_reparent(q, initproc);
+		proc_reparent(q, p->p_inst->inst_proc->initproc);
 		/*
 		 * Traced processes are killed
 		 * since their existence means someone is screwing up.
@@ -293,9 +338,10 @@
 	 * the P_NOCLDWAIT flag set, notify process 1 instead (and hope it
 	 * will handle this situation).
 	 */
-	if ((p->p_flag & P_NOZOMBIE) || (p->p_pptr->p_flag & P_NOCLDWAIT)) {
+	if (p->p_pptr && ((p->p_flag & P_NOZOMBIE) || 
+				(p->p_pptr->p_flag & P_NOCLDWAIT))) {
 		struct proc *pp = p->p_pptr;
-		proc_reparent(p, initproc);
+		proc_reparent(p, p->p_inst->inst_proc->initproc);
 		/*
 		 * If this was the last child of our parent, notify
 		 * parent, so in case he was wait(2)ing, he will
@@ -305,9 +351,13 @@
 			wakeup(pp);
 	}
 
-	if (p->p_exitsig != 0)
+	if (p->p_exitsig != 0) {
+		KASSERT(p->p_pptr);
 		psignal(p->p_pptr, P_EXITSIG(p));
-	wakeup(p->p_pptr);
+	}
+
+	if (p->p_pptr)
+		wakeup(p->p_pptr);
 
 	/*
 	 * Release the process's signal state.
@@ -400,7 +450,7 @@
 		LIST_REMOVE(p, p_hash);
 		mtx_leave(&deadproc_mutex);
 		KERNEL_PROC_LOCK(curproc);
-
+		
 		/*
 		 * Give machine-dependent code a chance to free any
 		 * resources it couldn't free while still running on
@@ -417,7 +467,7 @@
 		uvm_exit(p);
 
 		/* Process is now a true zombie. */
-		if ((p->p_flag & P_NOZOMBIE) == 0) {
+		if (p->p_pptr && (p->p_flag & P_NOZOMBIE) == 0) {
 			p->p_stat = SZOMB;
 
 			/* Wake up the parent so it can get exit status. */
@@ -488,7 +538,7 @@
 			 * If we got the child via a ptrace 'attach',
 			 * we need to give it back to the old parent.
 			 */
-			if (p->p_oppid && (t = pfind(p->p_oppid))) {
+			if (p->p_oppid && (t = pfind(p->p_inst->inst_proc, p->p_oppid))) {
 				p->p_oppid = 0;
 				proc_reparent(p, t);
 				if (p->p_exitsig != 0)
@@ -552,7 +602,7 @@
 	if (child->p_pptr == parent)
 		return;
 
-	if (parent == initproc)
+	if (parent == parent->p_inst->inst_proc->initproc)
 		child->p_exitsig = SIGCHLD;
 
 	LIST_REMOVE(child, p_sibling);
@@ -572,8 +622,11 @@
 	 * Unlink it from its process group and free it.
 	 */
 	leavepgrp(p);
-	LIST_REMOVE(p, p_list);	/* off zombproc */
-	LIST_REMOVE(p, p_sibling);
+
+	if (p->p_pptr)
+		LIST_REMOVE(p, p_sibling);
+
+	LIST_REMOVE(p, p_list);
 
 	/*
 	 * Decrement the count of procs running with this uid.
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_fork.c,v
retrieving revision 1.95
retrieving revision 1.95.4.14
diff -u -r1.95 -r1.95.4.14
--- sys/kern/kern_fork.c	11 May 2008 23:54:40 -0000	1.95
+++ sys/kern/kern_fork.c	18 Feb 2009 18:20:20 -0000	1.95.4.14
@@ -70,10 +70,22 @@
 pid_t	lastpid;
 struct	forkstat forkstat;
 
-void fork_return(void *);
-int pidtaken(pid_t);
+void 	fork_return(void *);
+int 	pidtaken(struct inst_proc *, pid_t);
+void 	process_new(struct proc *);
+pid_t	pid_new(struct inst *);
 
-void process_new(struct proc *, struct proc *);
+
+pid_t
+pid_new(struct inst *inst)
+{
+
+	/* Find an unused pid satisfying 1 <= lastpid <= PID_MAX */
+	do {
+		lastpid = 1 + (randompid ? arc4random() : lastpid) % PID_MAX;
+	} while (pidtaken(inst->inst_proc, lastpid));
+	return(lastpid);
+}
 
 void
 fork_return(void *arg)
@@ -107,6 +119,7 @@
 	    NULL, retval, NULL));
 }
 
+
 int
 sys_rfork(struct proc *p, void *v, register_t *retval)
 {
@@ -153,7 +166,7 @@
  * Allocate and initialize a new process.
  */
 void
-process_new(struct proc *newproc, struct proc *parent)
+process_new(struct proc *newproc)
 {
 	struct process *pr;
 
@@ -167,6 +180,131 @@
 /* print the 'table full' message once per 10 seconds */
 struct timeval fork_tfmrate = { 10, 0 };
 
+
+int
+forkinst1(struct proc *p1, instid_t id, register_t *retval)
+{
+	struct proc	*p2;
+	struct vmspace	*vm;
+	vaddr_t		 uaddr;
+	int		 s;
+	struct inst	*inst;
+
+	extern void endtsleep(void *);
+	extern void realitexpire(void *);
+
+	if (0 != p1->p_cred->p_ruid)
+		return(EPERM);
+
+	if (NULL == (inst = instpnew(p1, id)))
+		return(EINSTEXIST);
+
+	(void)chgproccnt(0, 1);
+
+	uaddr = uvm_km_alloc1(kernel_map, USPACE, USPACE_ALIGN, 1);
+	if (uaddr == 0) {
+		(void)chgproccnt(0, -1);
+		instfree(inst);
+		return(ENOMEM);
+	}
+
+	/*
+	 * From now on, we're committed to the fork and cannot fail.
+	 */
+
+	inst->inst_proc = proc_instinit(inst);
+
+	p2 = pool_get(&proc_pool, PR_WAITOK);
+
+	p2->p_stat = SIDL;
+	p2->p_exitsig = 0;
+	p2->p_flag = 0;
+
+	process_new(p2);
+
+	bzero(&p2->p_startzero,
+	    (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
+	bcopy(&p1->p_startcopy, &p2->p_startcopy,
+	    (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
+
+	timeout_set(&p2->p_sleep_to, endtsleep, p2);
+	timeout_set(&p2->p_realit_to, realitexpire, p2);
+
+	p2->p_cpu = p1->p_cpu;
+	p2->p_emul = p1->p_emul;
+	bcopy("init", p2->p_comm, sizeof("init"));
+
+	atomic_setbits_int(&p2->p_flag, p1->p_flag & (P_SUGID | P_SUGIDEXEC));
+
+	p2->p_p->ps_cred = pool_get(&pcred_pool, PR_WAITOK | PR_ZERO);
+	bcopy(p1->p_p->ps_cred, p2->p_p->ps_cred, sizeof(*p2->p_p->ps_cred));
+	p2->p_p->ps_cred->p_refcnt = 1;
+	p2->p_p->ps_cred->pc_ucred = crnew();
+	p2->p_p->ps_cred->pc_ucred->cr_inst = inst;
+
+	p2->p_textvp = p1->p_textvp;
+	if (p2->p_textvp)
+		VREF(p2->p_textvp);
+
+	p2->p_fd = fdinit(p1);
+
+	p2->p_p->ps_limit = limcopy(p1->p_p->ps_limit);
+
+	p2->p_pptr = NULL;
+
+	LIST_INIT(&p2->p_children);
+
+	bzero(&p2->p_sibling, sizeof(p2->p_sibling));
+
+	scheduler_fork_hook(p1, p2);
+
+	p2->p_sigacts = sigactsinit(p1);
+
+	if (p2->p_emul->e_proc_fork)
+		(*p2->p_emul->e_proc_fork)(p2, p1);
+
+	p2->p_addr = (struct user *)uaddr;
+
+	uvm_fork(p1, p2, FALSE, NULL, 0, child_return, p2);
+
+	timeout_set(&p2->p_stats->p_virt_to, virttimer_trampoline, p2);
+	timeout_set(&p2->p_stats->p_prof_to, proftimer_trampoline, p2);
+
+	vm = p2->p_vmspace;
+
+	forkstat.cntfork++;
+	forkstat.sizfork += vm->vm_dsize + vm->vm_ssize;
+
+#ifdef GLOBAL_HASH
+	p2->p_pid = pid_new(p2->p_inst);
+#else
+	p2->p_pid = 1;
+#endif
+
+	proc_instadd(p2->p_inst->inst_proc, p2);
+	bzero(&p2->p_pglist, sizeof(p2->p_pglist));
+	LIST_INSERT_AFTER(p1, p2, p_pglist);
+	pgrpinit(p1, p2);
+
+	SCHED_LOCK(s);
+ 	getmicrotime(&p2->p_stats->p_start);
+	p2->p_acflag = AFORK;
+	p2->p_stat = SRUN;
+	setrunqueue(p2);
+	SCHED_UNLOCK(s);
+
+	uvmexp.forks++;
+
+	/* Set "init" process. */
+	p2->p_inst->inst_proc->initproc = p2;
+
+	retval[0] = p2->p_inst->inst_id;
+	retval[1] = 0;
+
+	return (0);
+}
+
+
 int
 fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
     void (*func)(void *), void *arg, register_t *retval,
@@ -178,6 +316,7 @@
 	int count;
 	vaddr_t uaddr;
 	int s;
+
 	extern void endtsleep(void *);
 	extern void realitexpire(void *);
 
@@ -232,10 +371,10 @@
 		p2->p_p = p1->p_p;
 		TAILQ_INSERT_TAIL(&p2->p_p->ps_threads, p2, p_thr_link);
 	} else {
-		process_new(p2, p1);
+		process_new(p2);
 	}
 #else
-	process_new(p2, p1);
+	process_new(p2);
 #endif
 
 	/*
@@ -381,14 +520,10 @@
 		forkstat.sizkthread += vm->vm_dsize + vm->vm_ssize;
 	}
 
-	/* Find an unused pid satisfying 1 <= lastpid <= PID_MAX */
-	do {
-		lastpid = 1 + (randompid ? arc4random() : lastpid) % PID_MAX;
-	} while (pidtaken(lastpid));
-	p2->p_pid = lastpid;
+	p2->p_pid = pid_new(p2->p_inst);
+
+	proc_instadd(p2->p_inst->inst_proc, p2);
 
-	LIST_INSERT_HEAD(&allproc, p2, p_list);
-	LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
 	LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
 	LIST_INSERT_AFTER(p1, p2, p_pglist);
 	if (p2->p_flag & P_TRACED) {
@@ -474,15 +609,15 @@
  * Checks for current use of a pid, either as a pid or pgid.
  */
 int
-pidtaken(pid_t pid)
+pidtaken(struct inst_proc *ip, pid_t pid)
 {
 	struct proc *p;
 
-	if (pfind(pid) != NULL)
+	if (pfind(ip, pid) != NULL)
 		return (1);
-	if (pgfind(pid) != NULL)
+	if (pgfind(ip, pid) != NULL)
 		return (1);
-	LIST_FOREACH(p, &zombproc, p_list)
+	LIST_FOREACH(p, &ip->zombproc, p_list)
 		if (p->p_pid == pid || p->p_pgid == pid)
 			return (1);
 	return (0);
Index: sys/kern/kern_inst.c
===================================================================
RCS file: sys/kern/kern_inst.c
diff -N sys/kern/kern_inst.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/kern/kern_inst.c	18 Feb 2009 18:20:20 -0000	1.1.2.12
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/inst.h>
+#include <sys/mount.h>
+#include <sys/pool.h>
+#include <sys/signalvar.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/syscallargs.h>
+
+#include <dev/rndvar.h>
+
+#define	INST_HASH(id)	(&inst_htab[(id) & inst_hmask])
+#define	INST_SLOP	(2 * sizeof(struct kinfo_inst))
+
+LIST_HEAD(inst_head, inst);
+
+struct instlist		 inst_all;
+
+struct pool	 	 inst_pool;
+u_long		 	 inst_hmask;
+u_int		 	 inst_count;
+struct inst_head	*inst_htab;
+
+inline int		 instexist(instid_t);
+struct inst 		*instnew(instid_t);
+inline struct inst 	*instfind(instid_t);
+
+int		 	 killinst1(struct inst *, int);
+void		 	 fill_inst(struct inst *, struct kinfo_inst *);
+
+
+void
+instinit(void)
+{
+
+	pool_init(&inst_pool, sizeof(struct inst), 0, 0, 0, 
+			"instpl", &pool_allocator_nointr);
+
+	inst_count = 0;
+	inst_hmask = 0;
+
+	inst_htab = hashinit(16, M_INST, M_NOWAIT, &inst_hmask);
+
+	if (NULL == inst_htab) 
+		panic("instinit: hashinit");
+
+	LIST_INIT(&inst_all);
+}
+
+
+inline int
+instexist(instid_t id)
+{
+	struct inst	*ip;
+
+	LIST_FOREACH(ip, INST_HASH(id), inst_hash)
+		if (ip->inst_id == id)
+			return(1);
+	return(0);
+}
+
+
+inline struct inst *
+instfind(instid_t id)
+{
+	struct inst	*ip;
+
+	LIST_FOREACH(ip, INST_HASH(id), inst_hash)
+		if (ip->inst_id == id)
+			break;
+
+	return(ip);
+}
+
+
+struct inst *
+instkfind(instid_t id)
+{
+
+	/* 
+	 * Find instance without an instance context.  This is allowed
+	 * without needing to check for permission. 
+	 */
+	return(instfind(id));
+}
+
+
+struct inst *
+instpfind(struct proc *cp, instid_t id, enum instop op)
+{
+
+	/* 
+	 * TODO: check for access from one instance to the next.  For
+	 * now, accept all requests from the superuser.
+	 */
+
+	if (suser(cp, 0))
+		return(NULL);
+	return(instfind(id));
+}
+
+
+struct inst *
+instnew(instid_t id)
+{
+	struct inst	*inst;
+
+	if (INST_NOID != id && instexist(id))
+		return(NULL);
+
+	inst = pool_get(&inst_pool, PR_WAITOK|PR_ZERO);
+
+	inst->inst_ref = 1;
+
+	if (INST_NOID == id) {
+		do 
+			inst->inst_id = 1 + arc4random() % INST_MAX;
+		while (instexist(inst->inst_id));
+	}  else
+		inst->inst_id = id;
+	
+	LIST_INSERT_HEAD(INST_HASH(inst->inst_id), inst, inst_hash);
+	LIST_INSERT_HEAD(&inst_all, inst, inst_list);
+	inst_count++;
+
+	return(inst);
+}
+
+
+struct inst *
+instpnew(struct proc *cp, instid_t id)
+{
+
+	/* 
+	 * TODO: check for access to start a new instance.  For now,
+	 * accept all requests from the superuser.
+	 */
+	if (suser(cp, 0))
+		return(NULL);
+	return(instnew(id));
+}
+
+
+struct inst *
+instknew(instid_t id)
+{
+
+	/* 
+	 * New instance without an instance context.  This is allowed
+	 * without needing to check for permission. 
+	 */
+	return(instnew(id));
+}
+
+
+void
+instfree(struct inst *inst)
+{
+	instid_t	 id;
+
+	KASSERT(inst);
+
+	if (--inst->inst_ref != 0)
+		return;
+
+	if (inst->inst_proc)
+		proc_instfree(inst->inst_proc);
+
+	id = inst->inst_id;
+
+	LIST_REMOVE(inst, inst_hash);
+	LIST_REMOVE(inst, inst_list);
+	inst_count--;
+
+	pool_put(&inst_pool, inst);
+}
+
+
+void
+fill_inst(struct inst *p, struct kinfo_inst *ki)
+{
+
+	bzero(ki, sizeof(*ki));
+	ki->inst_id = p->inst_id;
+	ki->inst_ref = p->inst_ref;
+}
+
+
+int
+sysctl_doinst(struct proc *cp, int *name, 
+		u_int namelen, char *where, size_t *sizep)
+{
+	struct inst	*p;
+	char 		*dp;
+	int 		 arg, buflen, elem_size, elem_count, error, 
+			 needed, type, op;
+	struct kinfo_inst *kinst;
+
+	dp = where;
+	buflen = where != NULL ? *sizep : 0;
+	needed = error = 0;
+	type = name[0];
+
+	if (namelen != 5 || name[3] < 0 || name[4] < 0)
+		return (EINVAL);
+
+	op = name[1];
+	arg = name[2];
+	elem_size = name[3];
+	elem_count = name[4];
+	kinst = malloc(sizeof(struct kinfo_inst), M_TEMP, M_WAITOK);
+
+	p = LIST_FIRST(&inst_all);
+
+	for ( ; p; p = LIST_NEXT(p, inst_list)) {
+		switch (op) {
+		case KERN_INST_ALL:
+			break;
+		case KERN_INST_INSTID:
+			if (p->inst_id != (instid_t)arg)
+				continue;
+			break;
+		default:
+			error = EINVAL;
+			goto err;
+		}
+
+		/* For access-control rules... */
+		if (NULL == (p = instpfind(cp, p->inst_id, INST_KPROC)))
+			continue;
+
+		if (buflen >= elem_size && elem_count > 0) {
+			fill_inst(p, kinst);
+			/*
+			 * Copy out elem_size, but not larger than the
+			 * size of a struct kinfo_inst.
+			 */
+			error = copyout(kinst, dp, min(sizeof(*kinst), 
+						elem_size));
+			if (error)
+				goto err;
+
+			dp += elem_size;
+			buflen -= elem_size;
+			elem_count--;
+		}
+		needed += elem_size;
+	}
+
+	if (where != NULL) {
+		*sizep = dp - where;
+		if (needed > *sizep) {
+			error = ENOMEM;
+			goto err;
+		}
+	} else {
+		needed += INST_SLOP;
+		*sizep = needed;
+	}
+
+err:
+	if (kinst)
+		free(kinst, M_TEMP);
+
+	return (error);
+}
+
+
+int
+sys_killinst(struct proc *cp, void *v, register_t *retval)
+{
+	struct sys_killinst_args /* {
+		syscallarg(instid_t) id;
+		syscallarg(int) signum;
+	} */ *uap = v;
+	struct inst	*inst;
+	struct proc	*p;
+	instid_t	 id;
+	int		 signum, nsigs;
+
+	signum = SCARG(uap, signum);
+
+	switch (signum) {
+	case (SIGINST_TERM):
+		/* FALLTHROUGH */
+	case (SIGINST_KILL):
+		break;
+	default:
+		return(EINVAL);
+	}
+
+	id = SCARG(uap, id);
+
+	if (INST_NOID == id) {
+		nsigs = 0;
+		inst = LIST_FIRST(&inst_all);
+
+		for ( ; inst; inst = LIST_NEXT(inst, inst_list)) {
+			/* For access rules. */
+			inst = instpfind(cp, inst->inst_id, INST_SIG);
+			if (NULL == inst) 
+				continue;
+			if (inst->inst_id == cp->p_inst->inst_id)
+				continue;
+			if (inst->inst_id == 0) /* FIXME */
+				continue;
+
+			nsigs++;
+			p = inst->inst_proc->initproc;
+			psignal(p, signum);
+		}
+		return(0 == nsigs ? EINSTSRCH : 0);
+	}
+
+	if (id == 0) /* FIXME */
+		return(EINSTSRCH);
+
+	inst = instpfind(cp, id, INST_SIG);
+	if (NULL == inst) 
+		return(EINSTSRCH);
+
+	p = inst->inst_proc->initproc;
+	psignal(p, signum);
+	return(0);
+}
+
+
+int
+sys_getinstid(struct proc *p, void *v, register_t *retval)
+{
+
+	*retval = p->p_inst->inst_id;
+	return(0);
+}
+
+
+int
+sys_forkinst(struct proc *p, void *v, register_t *retval)
+{
+	struct sys_forkinst_args /* {
+		syscallarg(instid_t) id;
+	} */ *uap = v;
+
+	return(forkinst1(p, SCARG(uap, id), retval));
+}
+
Index: sys/kern/kern_ktrace.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.43
retrieving revision 1.43.4.3
diff -u -r1.43 -r1.43.4.3
--- sys/kern/kern_ktrace.c	22 May 2008 17:04:59 -0000	1.43
+++ sys/kern/kern_ktrace.c	18 Sep 2008 17:21:02 -0000	1.43.4.3
@@ -322,7 +322,7 @@
 	 * Clear all uses of the tracefile
 	 */
 	if (ops == KTROP_CLEARFILE) {
-		LIST_FOREACH(p, &allproc, p_list) {
+		PROCLIST_FOREACH(p, curp, p_list) {
 			if (p->p_tracep == vp) {
 				if (ktrcanset(curp, p)) {
 					p->p_traceflag = 0;
@@ -347,7 +347,7 @@
 		/*
 		 * by process group
 		 */
-		pg = pgfind(-SCARG(uap, pid));
+		pg = pgfind(curp->p_inst->inst_proc, -SCARG(uap, pid));
 		if (pg == NULL) {
 			error = ESRCH;
 			goto done;
@@ -362,7 +362,7 @@
 		/*
 		 * by pid
 		 */
-		p = pfind(SCARG(uap, pid));
+		p = pfind(curp->p_inst->inst_proc, SCARG(uap, pid));
 		if (p == NULL) {
 			error = ESRCH;
 			goto done;
@@ -445,6 +445,7 @@
 ktrwrite(struct proc *p, struct ktr_header *kth)
 {
 	struct uio auio;
+	struct proc *pp;
 	struct iovec aiov[2];
 	int error;
 	struct vnode *vp = p->p_tracep;
@@ -476,7 +477,8 @@
 	 */
 	log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
 	    error);
-	LIST_FOREACH(p, &allproc, p_list) {
+	pp = p;
+	PROCLIST_FOREACH(p, pp, p_list) {
 		if (p->p_tracep == vp) {
 			p->p_traceflag = 0;
 			ktrsettracevnode(p, NULL);
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_proc.c,v
retrieving revision 1.36
retrieving revision 1.36.6.12
diff -u -r1.36 -r1.36.6.12
--- sys/kern/kern_proc.c	10 Oct 2007 15:53:53 -0000	1.36
+++ sys/kern/kern_proc.c	18 Feb 2009 12:43:25 -0000	1.36.6.12
@@ -49,20 +49,18 @@
 #include <sys/signalvar.h>
 #include <sys/pool.h>
 
+
+#ifdef GLOBAL_HASH
+struct pidhhead	*pidhashtbl;
+u_long		 pidhash;
+struct pghhead	*pgrphashtbl;
+u_long		 pgrphash;
+#endif
+
 #define	UIHASH(uid)	(&uihashtbl[(uid) & uihash])
 LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
 u_long uihash;		/* size of hash table - 1 */
 
-/*
- * Other process lists
- */
-struct pidhashhead *pidhashtbl;
-u_long pidhash;
-struct pgrphashhead *pgrphashtbl;
-u_long pgrphash;
-struct proclist allproc;
-struct proclist zombproc;
-
 struct pool proc_pool;
 struct pool process_pool;
 struct pool rusage_pool;
@@ -70,11 +68,9 @@
 struct pool pgrp_pool;
 struct pool session_pool;
 struct pool pcred_pool;
+struct pool instproc_pool;
 
 static void orphanpg(struct pgrp *);
-#ifdef DEBUG
-void pgrpdump(void);
-#endif
 
 /*
  * Initialize global process hashing structures.
@@ -82,16 +78,21 @@
 void
 procinit(void)
 {
-	LIST_INIT(&allproc);
-	LIST_INIT(&zombproc);
-
-
-	pidhashtbl = hashinit(maxproc / 4, M_PROC, M_NOWAIT, &pidhash);
-	pgrphashtbl = hashinit(maxproc / 4, M_PROC, M_NOWAIT, &pgrphash);
 	uihashtbl = hashinit(maxproc / 16, M_PROC, M_NOWAIT, &uihash);
-	if (!pidhashtbl || !pgrphashtbl || !uihashtbl)
+	if (!uihashtbl)
 		panic("procinit: malloc");
 
+#ifdef GLOBAL_HASH
+	pidhash = 0;
+	pgrphash = 0;
+	pidhashtbl = hashinit
+		(maxproc / 4, M_PROC, M_WAITOK, &pidhash);
+	pgrphashtbl = hashinit
+		(maxproc / 4, M_PROC, M_NOWAIT, &pgrphash);
+#endif
+
+	pool_init(&instproc_pool, sizeof(struct inst_proc), 0, 0, 0, 
+			"instprocpl", &pool_allocator_nointr);
 	pool_init(&proc_pool, sizeof(struct proc), 0, 0, 0, "procpl",
 	    &pool_allocator_nointr);
 	pool_init(&process_pool, sizeof(struct process), 0, 0, 0, "processpl",
@@ -108,6 +109,91 @@
 	    &pool_allocator_nointr);
 }
 
+
+struct inst_proc *
+proc_instinit(const struct inst *inst)
+{
+	struct inst_proc *p;
+
+	KASSERT(inst);
+
+	p = pool_get(&instproc_pool, PR_WAITOK|PR_ZERO);
+
+	LIST_INIT(&p->allproc);
+	LIST_INIT(&p->zombproc);
+
+#ifndef GLOBAL_HASH
+	p->pidhash = 0;
+	p->pgrphash = 0;
+
+	p->pidhashtbl = hashinit
+		(maxproc / 4, M_PROC, M_WAITOK, &p->pidhash);
+	p->pgrphashtbl = hashinit
+		(maxproc / 4, M_PROC, M_NOWAIT, &p->pgrphash);
+#else
+	p->instid = inst->inst_id;
+#endif
+
+	return(p);
+}
+
+
+void
+proc_instfree(struct inst_proc *p)
+{
+
+	KASSERT(p);
+	KASSERT(LIST_EMPTY(&p->allproc));
+
+#ifndef GLOBAL_HASH
+	if (p->pidhashtbl) 
+		free(p->pidhashtbl, M_PROC);
+	if (p->pgrphashtbl) 
+		free(p->pgrphashtbl, M_PROC);
+#endif
+}
+
+
+void
+proc_instadd(struct inst_proc *p, struct proc *proc)
+{
+
+	KASSERT(p);
+	KASSERT(proc);
+	KASSERT(proc->p_inst->inst_proc == p);
+	/*
+	 * Insert us into the pid hashtable and the list of all
+	 * processes.
+	 */
+
+#ifdef GLOBAL_HASH
+	LIST_INSERT_HEAD(&pidhashtbl[proc->p_pid & pidhash],
+			proc, p_hash);
+#else
+	LIST_INSERT_HEAD(&p->pidhashtbl[proc->p_pid & p->pidhash],
+			proc, p_hash);
+#endif
+
+	LIST_INSERT_HEAD(&p->allproc, proc, p_list);
+}
+
+
+void
+pgrp_instadd(struct inst_proc *p, struct pgrp *pgrp)
+{
+	KASSERT(p);
+	KASSERT(pgrp);
+
+#ifdef GLOBAL_HASH
+	LIST_INSERT_HEAD(&pgrphashtbl[pgrp->pg_id & pgrphash],
+			pgrp, pg_hash);
+#else
+	LIST_INSERT_HEAD(&p->pgrphashtbl[pgrp->pg_id & p->pgrphash],
+			pgrp, pg_hash);
+#endif
+}
+
+
 /*
  * Change the count associated with number of processes
  * a given user is using.
@@ -158,22 +244,31 @@
 {
 
 	for (; p != curproc; p = p->p_pptr)
-		if (p->p_pid == 0)
+		if (NULL == p || p->p_pid == 0)
 			return (0);
 	return (1);
 }
 
-/*
- * Locate a process by number
- */
+
 struct proc *
-pfind(pid_t pid)
+pfind(struct inst_proc *ip, pid_t pid)
 {
 	struct proc *p;
 
-	LIST_FOREACH(p, PIDHASH(pid), p_hash)
+	KASSERT(ip);
+
+#ifdef GLOBAL_HASH
+	LIST_FOREACH(p, &pidhashtbl[pid & pidhash], p_hash)
+		if (p->p_pid == pid && p->p_inst->inst_id == ip->instid)
+			return (p);
+		else if (p->p_pid == pid)
+			return (NULL);
+#else
+	LIST_FOREACH(p, &ip->pidhashtbl[pid & ip->pidhash], p_hash)
 		if (p->p_pid == pid)
 			return (p);
+#endif
+
 	return (NULL);
 }
 
@@ -181,13 +276,23 @@
  * Locate a process group by number
  */
 struct pgrp *
-pgfind(pid_t pgid)
+pgfind(struct inst_proc *ip, pid_t pgid)
 {
 	struct pgrp *pgrp;
 
-	LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash)
+	KASSERT(ip);
+
+#ifdef GLOBAL_HASH
+	LIST_FOREACH(pgrp, &pgrphashtbl[pgid & pgrphash], pg_hash)
+		if (pgrp->pg_id == pgid && pgrp->pg_inst->inst_id == ip->instid)
+			return (pgrp);
+		else if (pgrp->pg_id == pgid)
+			return (NULL);
+#else
+	LIST_FOREACH(pgrp, &ip->pgrphashtbl[pgid & ip->pgrphash], pg_hash)
 		if (pgrp->pg_id == pgid)
 			return (pgrp);
+#endif
 	return (NULL);
 }
 
@@ -197,7 +302,10 @@
 int
 enterpgrp(struct proc *p, pid_t pgid, int mksess)
 {
-	struct pgrp *pgrp = pgfind(pgid);
+	struct pgrp *pgrp;
+
+	KASSERT(p->p_inst);
+	pgrp = pgfind(p->p_inst->inst_proc, pgid);
 
 #ifdef DIAGNOSTIC
 	if (pgrp != NULL && mksess)	/* firewalls */
@@ -215,7 +323,7 @@
 		if (p->p_pid != pgid)
 			panic("enterpgrp: new pgrp and pid != pgid");
 #endif
-		if ((np = pfind(savepid)) == NULL || np != p)
+		if ((np = pfind(p->p_inst->inst_proc, savepid)) == NULL || np != p)
 			return (ESRCH);
 		pgrp = pool_get(&pgrp_pool, PR_WAITOK);
 		if (mksess) {
@@ -229,21 +337,28 @@
 			sess->s_count = 1;
 			sess->s_ttyvp = NULL;
 			sess->s_ttyp = NULL;
+			KASSERT(p->p_session);
 			bcopy(p->p_session->s_login, sess->s_login,
 			    sizeof(sess->s_login));
 			atomic_clearbits_int(&p->p_flag, P_CONTROLT);
 			pgrp->pg_session = sess;
+#if 0
 #ifdef DIAGNOSTIC
 			if (p != curproc)
 				panic("enterpgrp: mksession and p != curproc");
 #endif
+#endif
 		} else {
+			KASSERT(p->p_session);
 			pgrp->pg_session = p->p_session;
 			pgrp->pg_session->s_count++;
 		}
 		pgrp->pg_id = pgid;
 		LIST_INIT(&pgrp->pg_members);
-		LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
+		pgrp_instadd(p->p_inst->inst_proc, pgrp);
+#ifdef GLOBAL_HASH
+		pgrp->pg_inst = p->p_inst;
+#endif
 		pgrp->pg_jobc = 0;
 	} else if (pgrp == p->p_pgrp)
 		return (0);
@@ -271,6 +386,7 @@
 leavepgrp(struct proc *p)
 {
 
+	KASSERT(p->p_pgrp);
 	LIST_REMOVE(p, p_pglist);
 	if (LIST_EMPTY(&p->p_pgrp->pg_members))
 		pgdelete(p->p_pgrp);
@@ -285,6 +401,8 @@
 pgdelete(struct pgrp *pgrp)
 {
 
+	KASSERT(pgrp);
+	KASSERT(pgrp->pg_session);
 	if (pgrp->pg_session->s_ttyp != NULL && 
 	    pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
 		pgrp->pg_session->s_ttyp->t_pgrp = NULL;
@@ -307,14 +425,20 @@
 fixjobc(struct proc *p, struct pgrp *pgrp, int entering)
 {
 	struct pgrp *hispgrp;
-	struct session *mysession = pgrp->pg_session;
+	struct session *mysession;
+
+	KASSERT(pgrp);
+	KASSERT(p);
+
+	mysession = pgrp->pg_session;
 
 	/*
 	 * Check p's parent to see whether p qualifies its own process
 	 * group; if so, adjust count for p's process group.
 	 */
-	if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
-	    hispgrp->pg_session == mysession) {
+	if (NULL == p->p_pptr || 
+			((hispgrp = p->p_pptr->p_pgrp) != pgrp && 
+			 hispgrp->pg_session == mysession)) {
 		if (entering)
 			pgrp->pg_jobc++;
 		else if (--pgrp->pg_jobc == 0)
@@ -330,6 +454,7 @@
 		if ((hispgrp = p->p_pgrp) != pgrp &&
 		    hispgrp->pg_session == mysession &&
 		    P_ZOMBIE(p) == 0) {
+			KASSERT(hispgrp);
 			if (entering)
 				hispgrp->pg_jobc++;
 			else if (--hispgrp->pg_jobc == 0)
@@ -396,6 +521,7 @@
 db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
 	char *mode;
+	struct inst *i;
 	int doingzomb = 0;
 	struct proc *p, *pp;
     
@@ -413,87 +539,92 @@
 		return;
 	}
 	
-	p = LIST_FIRST(&allproc);
 
 	switch (*mode) {
-
 	case 'a':
-		db_printf("   PID  %-10s  %18s  %18s  %18s\n",
+		db_printf("   PID  %10s  %-10s  %18s  %18s  %18s\n",
 		    "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP");
 		break;
 	case 'n':
-		db_printf("   PID  %5s  %5s  %5s  S  %10s  %-12s  %-16s\n",
+		db_printf("   PID  %10s  %5s  %5s  %5s  S  %10s  %-12s  %-16s\n",
 		    "PPID", "PGRP", "UID", "FLAGS", "WAIT", "COMMAND");
 		break;
 	case 'w':
-		db_printf("   PID  %-16s  %-8s  %18s  %s\n",
+		db_printf("   PID  %10s  %-16s  %-8s  %18s  %s\n",
 		    "COMMAND", "EMUL", "WAIT-CHANNEL", "WAIT-MSG");
 		break;
 	}
 
-	while (p != 0) {
-		pp = p->p_pptr;
-		if (p->p_stat) {
-
-			db_printf("%c%5d  ", p == curproc ? '*' : ' ',
-				p->p_pid);
-
-			switch (*mode) {
-
-			case 'a':
-				db_printf("%-10.10s  %18p  %18p  %18p\n",
-				    p->p_comm, p, p->p_addr, p->p_vmspace);
-				break;
-
-			case 'n':
-				db_printf("%5d  %5d  %5d  %d  %#10x  "
-				    "%-12.12s  %-16s\n",
-				    pp ? pp->p_pid : -1, p->p_pgrp->pg_id,
-				    p->p_cred->p_ruid, p->p_stat, p->p_flag,
-				    (p->p_wchan && p->p_wmesg) ?
-					p->p_wmesg : "", p->p_comm);
-				break;
-
-			case 'w':
-				db_printf("%-16s  %-8s  %18p  %s\n", p->p_comm,
-				    p->p_emul->e_name, p->p_wchan,
-				    (p->p_wchan && p->p_wmesg) ? 
-					p->p_wmesg : "");
-				break;
+	LIST_FOREACH(i, &inst_all, inst_list) {
+		p = LIST_FIRST(&i->inst_proc->allproc);
+	
+		while (p != 0) {
+			pp = p->p_pptr;
+			if (p->p_stat) {
+	
+				db_printf("%c%5d  %10x  ", p == curproc ? '*' : ' ',
+					p->p_pid, p->p_inst->inst_id);
 
+				switch (*mode) {
+	
+				case 'a':
+					db_printf("%-10.10s  %18p  %18p  %18p\n",
+					    p->p_comm, p, p->p_addr, p->p_vmspace);
+					break;
+	
+				case 'n':
+					db_printf("%5d  %5d  %5d  %d  %#10x  "
+					    "%-12.12s  %-16s\n",
+					    pp ? pp->p_pid : -1, p->p_pgrp->pg_id,
+					    p->p_cred->p_ruid, p->p_stat, p->p_flag,
+					    (p->p_wchan && p->p_wmesg) ?
+						p->p_wmesg : "", p->p_comm);
+					break;
+	
+				case 'w':
+					db_printf("%-16s  %-8s  %18p  %s\n", p->p_comm,
+					    p->p_emul->e_name, p->p_wchan,
+					    (p->p_wchan && p->p_wmesg) ? 
+						p->p_wmesg : "");
+					break;
+	
+				}
+			}
+			p = LIST_NEXT(p, p_list);
+			if (p == 0 && doingzomb == 0) {
+				doingzomb = 1;
+				p = LIST_FIRST(&i->inst_proc->zombproc);
 			}
-		}
-		p = LIST_NEXT(p, p_list);
-		if (p == 0 && doingzomb == 0) {
-			doingzomb = 1;
-			p = LIST_FIRST(&zombproc);
 		}
 	}
 }
 #endif
 
-#ifdef DEBUG
+
 void
-pgrpdump(void)
+pgrpinit(struct proc *p1, struct proc *p2)
 {
-	struct pgrp *pgrp;
-	struct proc *p;
-	int i;
+	struct pgrp	*pgrp;
+	struct session	*sess;
 
-	for (i = 0; i <= pgrphash; i++) {
-		if (!LIST_EMPTY(&pgrphashtbl[i])) {
-			printf("\tindx %d\n", i);
-			LIST_FOREACH(pgrp, &pgrphashtbl[i], pg_hash) {
-				printf("\tpgrp %p, pgid %d, sess %p, sesscnt %d, mem %p\n",
-				    pgrp, pgrp->pg_id, pgrp->pg_session,
-				    pgrp->pg_session->s_count,
-				    LIST_FIRST(&pgrp->pg_members));
-				LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
-					printf("\t\tpid %d addr %p pgrp %p\n", 
-					    p->p_pid, p, p->p_pgrp);
-				}
-			}
-		}
-	}
+	KASSERT(p1);
+	KASSERT(p2);
+
+	pgrp = pool_get(&pgrp_pool, PR_WAITOK | PR_ZERO);
+	sess = pool_get(&session_pool, PR_WAITOK | PR_ZERO);
+
+	bcopy(p1->p_session->s_login, 
+			sess->s_login, sizeof(sess->s_login));
+
+	sess->s_count = 1;
+	sess->s_leader = NULL;
+
+	pgrp->pg_session = sess;
+	p2->p_pgrp = pgrp;
+
+	pgrp_instadd(p2->p_inst->inst_proc, pgrp);
+#ifdef GLOBAL_HASH
+	pgrp->pg_inst = p2->p_inst;
+#endif
+	enterpgrp(p2, p2->p_pid, 1);
 }
-#endif /* DEBUG */
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_prot.c,v
retrieving revision 1.31
retrieving revision 1.31.4.6
diff -u -r1.31 -r1.31.4.6
--- sys/kern/kern_prot.c	22 May 2008 21:27:40 -0000	1.31
+++ sys/kern/kern_prot.c	13 Feb 2009 09:08:59 -0000	1.31.4.6
@@ -63,7 +63,8 @@
 	*retval = p->p_p->ps_mainproc->p_pid;
 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_IBCS2) || \
     defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS)
-	retval[1] = p->p_p->ps_mainproc->p_pptr->p_pid;
+	retval[1] = p->p_p->ps_mainproc->p_pptr ? 
+		p->p_p->ps_mainproc->p_pptr->p_pid : -1;
 #endif
 	return (0);
 }
@@ -87,7 +88,8 @@
 sys_getppid(struct proc *p, void *v, register_t *retval)
 {
 
-	*retval = p->p_p->ps_mainproc->p_pptr->p_pid;
+	*retval = p->p_p->ps_mainproc->p_pptr ?
+		p->p_p->ps_mainproc->p_pptr->p_pid : -1;
 	return (0);
 }
 
@@ -113,7 +115,7 @@
 
 	if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid)
 		goto found;
-	if ((targp = pfind(SCARG(uap, pid))) == NULL)
+	if ((targp = pfind(curp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 		return (ESRCH);
 	if (targp->p_session != curp->p_session)
 		return (EPERM);
@@ -132,7 +134,7 @@
 
 	if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid)
 		goto found;
-	if ((targp = pfind(SCARG(uap, pid))) == NULL)
+	if ((targp = pfind(curp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 		return (ESRCH);
 	if (targp->p_session != curp->p_session)
 		return (EPERM);
@@ -234,7 +236,7 @@
 sys_setsid(struct proc *p, void *v, register_t *retval)
 {
 
-	if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
+	if (p->p_pgid == p->p_pid || pgfind(p->p_inst->inst_proc, p->p_pid)) {
 		return (EPERM);
 	} else {
 		(void)enterpgrp(p, p->p_pid, 1);
@@ -276,7 +278,7 @@
 		return (EINVAL);
 
 	if (pid != 0 && pid != curp->p_pid) {
-		if ((targp = pfind(pid)) == 0 || !inferior(targp))
+		if ((targp = pfind(curp->p_inst->inst_proc, pid)) == 0 || !inferior(targp))
 			return (ESRCH);
 		if (targp->p_session != curp->p_session)
 			return (EPERM);
@@ -289,7 +291,7 @@
 	if (pgid == 0)
 		pgid = targp->p_pid;
 	else if (pgid != targp->p_pid)
-		if ((pgrp = pgfind(pgid)) == 0 ||
+		if ((pgrp = pgfind(curp->p_inst->inst_proc, pgid)) == 0 ||
 		    pgrp->pg_session != curp->p_session)
 			return (EPERM);
 	return (enterpgrp(targp, pgid, 0));
@@ -766,16 +768,36 @@
 	return (EPERM);
 }
 
+
 /*
  * Allocate a zeroed cred structure.
  */
 struct ucred *
-crget(void)
+crnew(void)
 {
 	struct ucred *cr;
 
 	cr = pool_get(&ucred_pool, PR_WAITOK|PR_ZERO);
 	cr->cr_ref = 1;
+
+	return (cr);
+}
+
+/*
+ * Allocate a zeroed cred structure.
+ */
+struct ucred *
+crget(struct inst *inst)
+{
+	struct ucred *cr;
+
+	KASSERT(inst);
+
+	cr = pool_get(&ucred_pool, PR_WAITOK|PR_ZERO);
+	cr->cr_ref = 1;
+	cr->cr_inst = inst;
+
+	insthold(cr->cr_inst);
 	return (cr);
 }
 
@@ -787,8 +809,10 @@
 crfree(struct ucred *cr)
 {
 
-	if (--cr->cr_ref == 0)
+	if (--cr->cr_ref == 0) {
+		instfree(cr->cr_inst);
 		pool_put(&ucred_pool, cr);
+	}
 }
 
 /*
@@ -801,7 +825,7 @@
 
 	if (cr->cr_ref == 1)
 		return (cr);
-	newcr = crget();
+	newcr = crget(cr->cr_inst);
 	*newcr = *cr;
 	crfree(cr);
 	newcr->cr_ref = 1;
@@ -816,7 +840,7 @@
 {
 	struct ucred *newcr;
 
-	newcr = crget();
+	newcr = crget(cr->cr_inst);
 	*newcr = *cr;
 	newcr->cr_ref = 1;
 	return (newcr);
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_resource.c,v
retrieving revision 1.33
retrieving revision 1.33.4.6
diff -u -r1.33 -r1.33.4.6
--- sys/kern/kern_resource.c	22 May 2008 17:04:59 -0000	1.33
+++ sys/kern/kern_resource.c	27 Sep 2008 14:09:44 -0000	1.33.4.6
@@ -77,7 +77,7 @@
 		if (SCARG(uap, who) == 0)
 			p = curp;
 		else
-			p = pfind(SCARG(uap, who));
+			p = pfind(curp->p_inst->inst_proc, SCARG(uap, who));
 		if (p == 0)
 			break;
 		low = p->p_nice;
@@ -88,7 +88,7 @@
 
 		if (SCARG(uap, who) == 0)
 			pg = curp->p_pgrp;
-		else if ((pg = pgfind(SCARG(uap, who))) == NULL)
+		else if ((pg = pgfind(curp->p_inst->inst_proc, SCARG(uap, who))) == NULL)
 			break;
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 			if (p->p_nice < low)
@@ -100,7 +100,7 @@
 	case PRIO_USER:
 		if (SCARG(uap, who) == 0)
 			SCARG(uap, who) = curp->p_ucred->cr_uid;
-		LIST_FOREACH(p, &allproc, p_list)
+		PROCLIST_FOREACH(p, curp, p_list)
 			if (p->p_ucred->cr_uid == SCARG(uap, who) &&
 			    p->p_nice < low)
 				low = p->p_nice;
@@ -133,7 +133,7 @@
 		if (SCARG(uap, who) == 0)
 			p = curp;
 		else
-			p = pfind(SCARG(uap, who));
+			p = pfind(curp->p_inst->inst_proc, SCARG(uap, who));
 		if (p == 0)
 			break;
 		error = donice(curp, p, SCARG(uap, prio));
@@ -145,7 +145,7 @@
 		 
 		if (SCARG(uap, who) == 0)
 			pg = curp->p_pgrp;
-		else if ((pg = pgfind(SCARG(uap, who))) == NULL)
+		else if ((pg = pgfind(curp->p_inst->inst_proc, SCARG(uap, who))) == NULL)
 			break;
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 			error = donice(curp, p, SCARG(uap, prio));
@@ -157,7 +157,7 @@
 	case PRIO_USER:
 		if (SCARG(uap, who) == 0)
 			SCARG(uap, who) = curp->p_ucred->cr_uid;
-		LIST_FOREACH(p, &allproc, p_list)
+		PROCLIST_FOREACH(p, curp, p_list)
 			if (p->p_ucred->cr_uid == SCARG(uap, who)) {
 				error = donice(curp, p, SCARG(uap, prio));
 				found++;
@@ -417,8 +417,10 @@
 	}
 
 	newlim = pool_get(&plimit_pool, PR_WAITOK);
+
 	bcopy(lim->pl_rlimit, newlim->pl_rlimit,
-	    sizeof(struct rlimit) * RLIM_NLIMITS);
+			sizeof(struct rlimit) * RLIM_NLIMITS);
+
 	newlim->p_lflags = 0;
 	newlim->p_refcnt = 1;
 	return (newlim);
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_sig.c,v
retrieving revision 1.99
retrieving revision 1.99.4.11
diff -u -r1.99 -r1.99.4.11
--- sys/kern/kern_sig.c	10 Jun 2008 20:41:52 -0000	1.99
+++ sys/kern/kern_sig.c	18 Feb 2009 12:43:25 -0000	1.99.4.11
@@ -294,9 +294,12 @@
 		 * (init) which will reap the zombie.  Because we use
 		 * init to do our dirty work we never set P_NOCLDWAIT
 		 * for PID 1.
+		 *
+		 * Changed because init isn't necessarily process 1.
 		 */
-		if (p->p_pid != 1 && ((sa->sa_flags & SA_NOCLDWAIT) ||
-		    sa->sa_handler == SIG_IGN))
+		if (p == p->p_inst->inst_proc->initproc &&
+				((sa->sa_flags & SA_NOCLDWAIT) ||
+				 sa->sa_handler == SIG_IGN))
 			atomic_setbits_int(&p->p_flag, P_NOCLDWAIT);
 		else
 			atomic_clearbits_int(&p->p_flag, P_NOCLDWAIT);
@@ -578,7 +581,7 @@
 		return (EINVAL);
 	if (SCARG(uap, pid) > 0) {
 		/* kill single process */
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!cansignal(cp, pc, p, SCARG(uap, signum)))
 			return (EPERM);
@@ -613,9 +616,10 @@
 		/* 
 		 * broadcast
 		 */
-		LIST_FOREACH(p, &allproc, p_list) {
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || 
-			    p == cp || !cansignal(cp, pc, p, signum))
+		PROCLIST_FOREACH(p, cp, p_list) {
+			if (p->p_pid <= 1 || p == p->p_inst->inst_proc->initproc ||
+					p->p_flag & P_SYSTEM || p == cp ||
+					!cansignal(cp, pc, p, signum))
 				continue;
 			nfound++;
 			if (signum)
@@ -628,13 +632,14 @@
 			 */
 			pgrp = cp->p_pgrp;
 		else {
-			pgrp = pgfind(pgid);
+			pgrp = pgfind(cp->p_inst->inst_proc, pgid);
 			if (pgrp == NULL)
 				return (ESRCH);
 		}
 		LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
-			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
-			    !cansignal(cp, pc, p, signum))
+			if (p->p_pid <= 1 || p == p->p_inst->inst_proc->initproc ||
+					p->p_flag & P_SYSTEM || 
+					!cansignal(cp, pc, p, signum))
 				continue;
 			nfound++;
 			if (signum && P_ZOMBIE(p) == 0)
@@ -658,22 +663,31 @@
  * process and see if it is permitted.
  */
 void
-csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
+csignal(instid_t instid, pid_t pgid, int signum, uid_t uid, uid_t euid)
 {
 	struct pgrp *pgrp;
 	struct proc *p;
+	struct inst *inst;
 
 	if (pgid == 0)
 		return;
 	if (pgid < 0) {
 		pgid = -pgid;
-		if ((pgrp = pgfind(pgid)) == NULL)
+		inst = instkfind(instid);
+		if (NULL == inst)
+			return;
+		pgrp = pgfind(inst->inst_proc, pgid);
+		if (NULL == pgrp)
 			return;
 		LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
 			if (CANDELIVER(uid, euid, p))
 				psignal(p, signum);
 	} else {
-		if ((p = pfind(pgid)) == NULL)
+		inst = instkfind(instid);
+		if (NULL == inst)
+			return;
+		p = pfind(inst->inst_proc, pgid);
+		if (NULL == p)
 			return;
 		if (CANDELIVER(uid, euid, p))
 			psignal(p, signum);
@@ -684,11 +698,19 @@
  * Send a signal to a process group.
  */
 void
-gsignal(int pgid, int signum)
+gsignal(instid_t instid, int pgid, int signum)
 {
 	struct pgrp *pgrp;
+	struct inst *inst;
+
+	if (0 == pgid)
+		return;
+
+	inst = instkfind(instid);
+	if (NULL == inst)
+		return;
 
-	if (pgid && (pgrp = pgfind(pgid)))
+	if ((pgrp = pgfind(inst->inst_proc, pgid)))
 		pgsignal(pgrp, signum, 0);
 }
 
@@ -999,8 +1021,10 @@
 	setrunnable(p);
 out:
 	SCHED_UNLOCK(s);
-	if (wakeparent)
+	if (wakeparent) {
+		KASSERT(p->p_pptr);
 		wakeup(p->p_pptr);
+	}
 }
 
 /*
@@ -1085,14 +1109,14 @@
 			/*
 			 * Don't take default actions on system processes.
 			 */
-			if (p->p_pid <= 1) {
+			if (p->p_pid <= 1 || p == p->p_inst->inst_proc->initproc) {
 #ifdef DIAGNOSTIC
 				/*
 				 * Are you sure you want to ignore SIGSEGV
 				 * in init? XXX
 				 */
-				printf("Process (pid %d) got signal %d\n",
-				    p->p_pid, signum);
+				printf("Process (pid %d, instid %u) got signal %d\n",
+				    p->p_pid, p->p_inst->inst_id, signum);
 #endif
 				break;		/* == ignore */
 			}
@@ -1194,15 +1218,20 @@
 proc_stop_sweep(void *v)
 {
 	struct proc *p;
+	struct inst *i;
 
-	LIST_FOREACH(p, &allproc, p_list) {
-		if ((p->p_flag & P_STOPPED) == 0)
-			continue;
-		atomic_clearbits_int(&p->p_flag, P_STOPPED);
-
-		if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
-			psignal(p->p_pptr, SIGCHLD);
-		wakeup(p->p_pptr);
+	LIST_FOREACH(i, &inst_all, inst_list) {
+		LIST_FOREACH(p, &i->inst_proc->allproc, p_list) {
+			if ((p->p_flag & P_STOPPED) == 0)
+				continue;
+			atomic_clearbits_int(&p->p_flag, P_STOPPED);
+			if (NULL == p->p_pptr)
+				/* FIXME: this shouldn't happen. */
+				continue;
+			if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
+				psignal(p->p_pptr, SIGCHLD);
+			wakeup(p->p_pptr);
+		}
 	}
 }
 
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.161
retrieving revision 1.161.4.7
diff -u -r1.161 -r1.161.4.7
--- sys/kern/kern_sysctl.c	9 Jun 2008 07:07:16 -0000	1.161
+++ sys/kern/kern_sysctl.c	18 Feb 2009 12:43:25 -0000	1.161.4.7
@@ -255,6 +255,7 @@
 		switch (name[0]) {
 		case KERN_PROC:
 		case KERN_PROC2:
+		case KERN_INSTPROC2:
 		case KERN_PROF:
 		case KERN_MALLOCSTATS:
 		case KERN_TTY:
@@ -271,6 +272,7 @@
 		case KERN_TIMECOUNTER:
 #endif
 		case KERN_CPTIME2:
+		case KERN_INST:
 			break;
 		default:
 			return (ENOTDIR);	/* overloaded */
@@ -341,10 +343,13 @@
 #ifndef SMALL_KERNEL
 	case KERN_PROC:
 	case KERN_PROC2:
-		return (sysctl_doproc(name, namelen, oldp, oldlenp));
+	case KERN_INSTPROC2:
+		return (sysctl_doproc(p, name, namelen, oldp, oldlenp));
 	case KERN_PROC_ARGS:
 		return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
 		     p));
+	case KERN_INST:
+		return (sysctl_doinst(p, name, namelen, oldp, oldlenp));
 #endif
 	case KERN_FILE:
 		return (sysctl_file(oldp, oldlenp));
@@ -977,19 +982,24 @@
 #define KERN_PROCSLOP	(5 * sizeof (struct kinfo_proc))
 
 int
-sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
+sysctl_doproc(struct proc *cp, int *name, 
+		u_int namelen, char *where, size_t *sizep)
 {
-	struct kinfo_proc2 *kproc2 = NULL;
-	struct eproc *eproc = NULL;
+	struct inst *inst;
+	struct kinfo_proc2 *kproc2;
+	struct eproc *eproc;
 	struct proc *p;
 	char *dp;
 	int arg, buflen, doingzomb, elem_size, elem_count;
 	int error, needed, type, op;
 
+	kproc2 = NULL;
+	eproc = NULL;
 	dp = where;
 	buflen = where != NULL ? *sizep : 0;
 	needed = error = 0;
 	type = name[0];
+	inst = cp->p_inst;
 
 	if (type == KERN_PROC) {
 		if (namelen != 3 && !(namelen == 2 &&
@@ -999,7 +1009,7 @@
 		arg = op == KERN_PROC_ALL ? 0 : name[2];
 		elem_size = elem_count = 0;
 		eproc = malloc(sizeof(struct eproc), M_TEMP, M_WAITOK);
-	} else /* if (type == KERN_PROC2) */ {
+	} else if (type == KERN_PROC2) {
 		if (namelen != 5 || name[3] < 0 || name[4] < 0)
 			return (EINVAL);
 		op = name[1];
@@ -1007,8 +1017,21 @@
 		elem_size = name[3];
 		elem_count = name[4];
 		kproc2 = malloc(sizeof(struct kinfo_proc2), M_TEMP, M_WAITOK);
+	} else /* if (type == KERN_INSTPROC2) */ {
+		if (namelen != 6 || name[4] < 0 || name[5] < 0)
+			return (EINVAL);
+		inst = instpfind(cp, name[1], INST_KPROC);
+		if (NULL == inst)
+			return (EINSTSRCH);
+
+		op = name[2];
+		arg = name[3];
+		elem_size = name[4];
+		elem_count = name[5];
+		kproc2 = malloc(sizeof(struct kinfo_proc2), M_TEMP, M_WAITOK);
 	}
-	p = LIST_FIRST(&allproc);
+
+	p = LIST_FIRST(&inst->inst_proc->allproc);
 	doingzomb = 0;
 again:
 	for (; p != 0; p = LIST_NEXT(p, p_list)) {
@@ -1104,7 +1127,7 @@
 		}
 	}
 	if (doingzomb == 0) {
-		p = LIST_FIRST(&zombproc);
+		p = LIST_FIRST(&cp->p_inst->inst_proc->zombproc);
 		doingzomb++;
 		goto again;
 	}
@@ -1128,6 +1151,7 @@
 
 #endif	/* SMALL_KERNEL */
 
+
 /*
  * Fill in an eproc structure for the specified process.
  */
@@ -1385,7 +1409,7 @@
 		return (EOPNOTSUPP);
 	}
 
-	if ((vp = pfind(pid)) == NULL)
+	if ((vp = pfind(cp->p_inst->inst_proc, pid)) == NULL)
 		return (ESRCH);
 
 	if (oldp == NULL) {
Index: sys/kern/sched_bsd.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/sched_bsd.c,v
retrieving revision 1.17
retrieving revision 1.17.4.3
diff -u -r1.17 -r1.17.4.3
--- sys/kern/sched_bsd.c	18 Jul 2008 23:43:31 -0000	1.17
+++ sys/kern/sched_bsd.c	18 Feb 2009 12:43:25 -0000	1.17.4.3
@@ -208,6 +208,7 @@
 {
 	struct timeout *to = (struct timeout *)arg;
 	fixpt_t loadfac = loadfactor(averunnable.ldavg[0]);
+	struct inst *i;
 	struct proc *p;
 	int s;
 	unsigned int newcpu;
@@ -222,50 +223,52 @@
 	phz = stathz ? stathz : profhz;
 	KASSERT(phz);
 
-	LIST_FOREACH(p, &allproc, p_list) {
-		/*
-		 * Increment time in/out of memory and sleep time
-		 * (if sleeping).  We ignore overflow; with 16-bit int's
-		 * (remember them?) overflow takes 45 days.
-		 */
-		p->p_swtime++;
-		if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
-			p->p_slptime++;
-		p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
-		/*
-		 * If the process has slept the entire second,
-		 * stop recalculating its priority until it wakes up.
-		 */
-		if (p->p_slptime > 1)
-			continue;
-		SCHED_LOCK(s);
-		/*
-		 * p_pctcpu is only for ps.
-		 */
-#if	(FSHIFT >= CCPU_SHIFT)
-		p->p_pctcpu += (phz == 100)?
-			((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT):
-                	100 * (((fixpt_t) p->p_cpticks)
-				<< (FSHIFT - CCPU_SHIFT)) / phz;
-#else
-		p->p_pctcpu += ((FSCALE - ccpu) *
-			(p->p_cpticks * FSCALE / phz)) >> FSHIFT;
-#endif
-		p->p_cpticks = 0;
-		newcpu = (u_int) decay_cpu(loadfac, p->p_estcpu);
-		p->p_estcpu = newcpu;
-		resetpriority(p);
-		if (p->p_priority >= PUSER) {
-			if ((p != curproc) &&
-			    p->p_stat == SRUN &&
-			    (p->p_priority / PPQ) != (p->p_usrpri / PPQ)) {
-				remrunqueue(p);
-				p->p_priority = p->p_usrpri;
-				setrunqueue(p);
-			} else
-				p->p_priority = p->p_usrpri;
+	LIST_FOREACH(i, &inst_all, inst_list) {
+		LIST_FOREACH(p, &i->inst_proc->allproc, p_list) {
+			/*
+			 * Increment time in/out of memory and sleep time
+			 * (if sleeping).  We ignore overflow; with 16-bit int's
+			 * (remember them?) overflow takes 45 days.
+			 */
+			p->p_swtime++;
+			if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
+				p->p_slptime++;
+			p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
+			/*
+			 * If the process has slept the entire second,
+			 * stop recalculating its priority until it wakes up.
+			 */
+			if (p->p_slptime > 1)
+				continue;
+			SCHED_LOCK(s);
+			/*
+			 * p_pctcpu is only for ps.
+			 */
+	#if	(FSHIFT >= CCPU_SHIFT)
+			p->p_pctcpu += (phz == 100)?
+				((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT):
+	                	100 * (((fixpt_t) p->p_cpticks)
+					<< (FSHIFT - CCPU_SHIFT)) / phz;
+	#else
+			p->p_pctcpu += ((FSCALE - ccpu) *
+				(p->p_cpticks * FSCALE / phz)) >> FSHIFT;
+	#endif
+			p->p_cpticks = 0;
+			newcpu = (u_int) decay_cpu(loadfac, p->p_estcpu);
+			p->p_estcpu = newcpu;
+			resetpriority(p);
+			if (p->p_priority >= PUSER) {
+				if ((p != curproc) &&
+				    p->p_stat == SRUN &&
+				    (p->p_priority / PPQ) != (p->p_usrpri / PPQ)) {
+					remrunqueue(p);
+					p->p_priority = p->p_usrpri;
+					setrunqueue(p);
+				} else
+					p->p_priority = p->p_usrpri;
+			}
+			SCHED_UNLOCK(s);
 		}
-		SCHED_UNLOCK(s);
 	}
 	uvm_meter();
 	wakeup(&lbolt);
Index: sys/kern/subr_log.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/subr_log.c,v
retrieving revision 1.15
retrieving revision 1.15.6.2
diff -u -r1.15 -r1.15.6.2
--- sys/kern/subr_log.c	3 Sep 2007 17:51:03 -0000	1.15
+++ sys/kern/subr_log.c	20 Sep 2008 00:09:45 -0000	1.15.6.2
@@ -58,6 +58,7 @@
 	struct	selinfo sc_selp;	/* process waiting on select call */
 	int	sc_pgid;		/* process/group for async I/O */
 	uid_t	sc_siguid;		/* uid for process that set sc_pgid */
+	instid_t sc_siginstid;		/* instid for process that set sc_pgid */
 	uid_t	sc_sigeuid;		/* euid for process that set sc_pgid */
 } logsoftc;
 
@@ -257,7 +258,7 @@
 		return;
 	selwakeup(&logsoftc.sc_selp);
 	if (logsoftc.sc_state & LOG_ASYNC)
-		csignal(logsoftc.sc_pgid, SIGIO,
+		csignal(logsoftc.sc_siginstid, logsoftc.sc_pgid, SIGIO,
 		    logsoftc.sc_siguid, logsoftc.sc_sigeuid);
 	if (logsoftc.sc_state & LOG_RDWAIT) {
 		wakeup(msgbufp);
@@ -298,6 +299,7 @@
 	case TIOCSPGRP:
 		logsoftc.sc_pgid = *(int *)data;
 		logsoftc.sc_siguid = p->p_cred->p_ruid;
+		logsoftc.sc_siginstid = p->p_inst->inst_id;
 		logsoftc.sc_sigeuid = p->p_ucred->cr_uid;
 		break;
 
Index: sys/kern/sys_generic.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/sys_generic.c,v
retrieving revision 1.58
retrieving revision 1.58.6.5
diff -u -r1.58 -r1.58.6.5
--- sys/kern/sys_generic.c	7 Sep 2007 15:00:20 -0000	1.58
+++ sys/kern/sys_generic.c	18 Feb 2009 12:43:25 -0000	1.58.6.5
@@ -564,6 +564,7 @@
 
 			so->so_pgid = tmp;
 			so->so_siguid = p->p_cred->p_ruid;
+			so->so_siginstid = p->p_inst->inst_id;
 			so->so_sigeuid = p->p_ucred->cr_uid;
 			error = 0;
 			break;
@@ -571,7 +572,7 @@
 		if (tmp <= 0) {
 			tmp = -tmp;
 		} else {
-			struct proc *p1 = pfind(tmp);
+			struct proc *p1 = pfind(p->p_inst->inst_proc, tmp);
 			if (p1 == 0) {
 				error = ESRCH;
 				break;
@@ -782,15 +783,20 @@
 {
 	struct proc *p;
 	pid_t mypid;
+	instid_t myinst;
 
 	mypid = selector->p_pid;
-	if (sip->si_selpid == mypid)
+	myinst = selector->p_inst->inst_id;
+
+	if (sip->si_selpid == mypid && sip->si_selinst == myinst)
 		return;
-	if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
+	if (sip->si_selpid && (p = pfind(selector->p_inst->inst_proc, sip->si_selpid)) &&
 	    p->p_wchan == (caddr_t)&selwait)
 		sip->si_flags |= SI_COLL;
-	else
+	else {
 		sip->si_selpid = mypid;
+		sip->si_selinst = myinst;
+	}
 }
 
 /*
@@ -800,6 +806,7 @@
 selwakeup(struct selinfo *sip)
 {
 	struct proc *p;
+	struct inst *inst;
 	int s;
 
 	if (sip->si_selpid == 0)
@@ -809,8 +816,14 @@
 		sip->si_flags &= ~SI_COLL;
 		wakeup(&selwait);
 	}
-	p = pfind(sip->si_selpid);
+
+	inst = instkfind(sip->si_selinst);
+	if (NULL == inst)
+		return;
+
+	p = pfind(inst->inst_proc, sip->si_selpid);
 	sip->si_selpid = 0;
+
 	if (p != NULL) {
 		SCHED_LOCK(s);
 		if (p->p_wchan == (caddr_t)&selwait) {
Index: sys/kern/sys_pipe.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/sys_pipe.c,v
retrieving revision 1.54
retrieving revision 1.54.4.1
diff -u -r1.54 -r1.54.4.1
--- sys/kern/sys_pipe.c	11 Jul 2008 14:12:57 -0000	1.54
+++ sys/kern/sys_pipe.c	19 Sep 2008 08:54:27 -0000	1.54.4.1
@@ -89,7 +89,7 @@
 
 void	pipeclose(struct pipe *);
 void	pipe_free_kmem(struct pipe *);
-int	pipe_create(struct pipe *);
+int	pipe_create(struct proc *, struct pipe *);
 int	pipelock(struct pipe *);
 void	pipeunlock(struct pipe *);
 void	pipeselwakeup(struct pipe *);
@@ -111,11 +111,11 @@
 	fdplock(fdp);
 
 	rpipe = pool_get(&pipe_pool, PR_WAITOK);
-	error = pipe_create(rpipe);
+	error = pipe_create(p, rpipe);
 	if (error != 0)
 		goto free1;
 	wpipe = pool_get(&pipe_pool, PR_WAITOK);
-	error = pipe_create(wpipe);
+	error = pipe_create(p, wpipe);
 	if (error != 0)
 		goto free2;
 
@@ -192,7 +192,7 @@
  * initialize and allocate VM and memory for pipe
  */
 int
-pipe_create(struct pipe *cpipe)
+pipe_create(struct proc *proc, struct pipe *cpipe)
 {
 	int error;
 
@@ -215,6 +215,7 @@
 	cpipe->pipe_atime = cpipe->pipe_ctime;
 	cpipe->pipe_mtime = cpipe->pipe_ctime;
 	cpipe->pipe_pgid = NO_PID;
+	cpipe->pipe_instid = proc->p_inst->inst_id;
 
 	return (0);
 }
@@ -257,7 +258,7 @@
 		selwakeup(&cpipe->pipe_sel);
 	}
 	if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_pgid != NO_PID)
-		gsignal(cpipe->pipe_pgid, SIGIO);
+		gsignal(cpipe->pipe_instid, cpipe->pipe_pgid, SIGIO);
 	KNOTE(&cpipe->pipe_sel.si_note, 0);
 }
 
Index: sys/kern/sys_process.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/sys_process.c,v
retrieving revision 1.39
retrieving revision 1.39.8.3
diff -u -r1.39 -r1.39.8.3
--- sys/kern/sys_process.c	10 Apr 2007 17:47:55 -0000	1.39
+++ sys/kern/sys_process.c	18 Feb 2009 12:43:25 -0000	1.39.8.3
@@ -106,7 +106,7 @@
 	else {
 
 		/* Find the process we're supposed to be operating on. */
-		if ((t = pfind(SCARG(uap, pid))) == NULL)
+		if ((t = pfind(p->p_inst->inst_proc, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 	}
 
@@ -367,8 +367,8 @@
 		if (t->p_oppid != t->p_pptr->p_pid) {
 			struct proc *pp;
 
-			pp = pfind(t->p_oppid);
-			proc_reparent(t, pp ? pp : initproc);
+			pp = pfind(p->p_inst->inst_proc, t->p_oppid);
+			proc_reparent(t, pp ? pp : p->p_inst->inst_proc->initproc);
 		}
 
 		/* not being traced any more */
Index: sys/kern/sys_socket.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/sys_socket.c,v
retrieving revision 1.12
retrieving revision 1.12.4.1
diff -u -r1.12 -r1.12.4.1
--- sys/kern/sys_socket.c	23 May 2008 15:51:12 -0000	1.12
+++ sys/kern/sys_socket.c	20 Sep 2008 00:09:45 -0000	1.12.4.1
@@ -103,6 +103,7 @@
 	case SIOCSPGRP:
 		so->so_pgid = *(int *)data;
 		so->so_siguid = p->p_cred->p_ruid;
+		so->so_siginstid = p->p_inst->inst_id;
 		so->so_sigeuid = p->p_ucred->cr_uid;
 		return (0);
 
Index: sys/kern/syscalls.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/syscalls.c,v
retrieving revision 1.104
retrieving revision 1.104.4.3
diff -u -r1.104 -r1.104.4.3
--- sys/kern/syscalls.c	16 Mar 2008 19:43:41 -0000	1.104
+++ sys/kern/syscalls.c	13 Feb 2009 09:08:59 -0000	1.104.4.3
@@ -1,10 +1,10 @@
-/*	$OpenBSD$	*/
+/*	\$OpenBSD\$	*/
 
 /*
  * System call names.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;	OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp 
+ * created from;	OpenBSD: syscalls.master,v 1.89 2008/01/05 00:36:13 miod Exp 
  */
 
 char *syscallnames[] = {
@@ -427,4 +427,7 @@
 	"statfs",			/* 307 = statfs */
 	"fstatfs",			/* 308 = fstatfs */
 	"fhstatfs",			/* 309 = fhstatfs */
+	"forkinst",			/* 310 = forkinst */
+	"getinstid",			/* 311 = getinstid */
+	"killinst",			/* 312 = killinst */
 };
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/syscalls.master,v
retrieving revision 1.90
retrieving revision 1.90.4.3
diff -u -r1.90 -r1.90.4.3
--- sys/kern/syscalls.master	16 Mar 2008 19:42:57 -0000	1.90
+++ sys/kern/syscalls.master	13 Feb 2009 09:08:59 -0000	1.90.4.3
@@ -618,3 +618,6 @@
 308	STD		{ int sys_fstatfs(int fd, struct statfs *buf); }
 309	STD		{ int sys_fhstatfs(const fhandle_t *fhp, \
 			    struct statfs *buf); }
+310	STD		{ instid_t sys_forkinst(instid_t id); }
+311	STD NOLOCK	{ instid_t sys_getinstid(void); }
+312	STD		{ int sys_killinst(instid_t id, int signum); }
Index: sys/kern/tty.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/tty.c,v
retrieving revision 1.77
retrieving revision 1.77.4.1
diff -u -r1.77 -r1.77.4.1
--- sys/kern/tty.c	28 Jul 2008 06:13:22 -0000	1.77
+++ sys/kern/tty.c	18 Sep 2008 17:21:03 -0000	1.77.4.1
@@ -990,7 +990,7 @@
 		atomic_setbits_int(&p->p_flag, P_CONTROLT);
 		break;
 	case TIOCSPGRP: {		/* set pgrp of tty */
-		struct pgrp *pgrp = pgfind(*(int *)data);
+		struct pgrp *pgrp = pgfind(p->p_inst->inst_proc, *(int *)data);
 
 		if (!isctty(p, tp))
 			return (ENOTTY);
Index: sys/kern/tty_pty.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/tty_pty.c,v
retrieving revision 1.38
retrieving revision 1.38.4.1
diff -u -r1.38 -r1.38.4.1
--- sys/kern/tty_pty.c	2 Aug 2008 11:39:38 -0000	1.38
+++ sys/kern/tty_pty.c	12 Sep 2008 13:58:49 -0000	1.38.4.1
@@ -1044,7 +1044,7 @@
 	/*
 	 * Get us a fresh cred with root privileges.
 	 */
-	cred = crget();
+	cred = crget(p->p_inst);
 	error = VOP_OPEN(vp, FREAD|FWRITE, cred, p);
 	if (!error) {
 		/* update atime/mtime */
@@ -1185,7 +1185,7 @@
 			vattr.va_gid = gid;
 			vattr.va_mode = (S_IRUSR|S_IWUSR|S_IWGRP) & ALLPERMS;
 			/* Get a fake cred to pretend we're root. */
-			cred = crget();
+			cred = crget(p->p_inst);
 			error = VOP_SETATTR(snd.ni_vp, &vattr, cred, p);
 			crfree(cred);
 			if (error) {
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/uipc_socket.c,v
retrieving revision 1.71
retrieving revision 1.71.4.1
diff -u -r1.71 -r1.71.4.1
--- sys/kern/uipc_socket.c	14 Jun 2008 10:55:21 -0000	1.71
+++ sys/kern/uipc_socket.c	20 Sep 2008 00:09:45 -0000	1.71.4.1
@@ -1201,7 +1201,8 @@
 void
 sohasoutofband(struct socket *so)
 {
-	csignal(so->so_pgid, SIGURG, so->so_siguid, so->so_sigeuid);
+	csignal(so->so_siginstid, so->so_pgid, 
+			SIGURG, so->so_siguid, so->so_sigeuid);
 	selwakeup(&so->so_rcv.sb_sel);
 }
 
Index: sys/kern/uipc_socket2.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.44
retrieving revision 1.44.4.1
diff -u -r1.44 -r1.44.4.1
--- sys/kern/uipc_socket2.c	23 May 2008 15:51:12 -0000	1.44
+++ sys/kern/uipc_socket2.c	20 Sep 2008 00:09:45 -0000	1.44.4.1
@@ -178,6 +178,7 @@
 	so->so_egid = head->so_egid;
 	so->so_rgid = head->so_rgid;
 	so->so_cpid = head->so_cpid;
+	so->so_siginstid = head->so_siginstid;
 	so->so_siguid = head->so_siguid;
 	so->so_sigeuid = head->so_sigeuid;
 
@@ -324,7 +325,8 @@
 		wakeup(&sb->sb_cc);
 	}
 	if (so->so_state & SS_ASYNC)
-		csignal(so->so_pgid, SIGIO, so->so_siguid, so->so_sigeuid);
+		csignal(so->so_siginstid, so->so_pgid, SIGIO, 
+				so->so_siguid, so->so_sigeuid);
 	KNOTE(&sb->sb_sel.si_note, 0);
 }
 
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.148
retrieving revision 1.148.4.2
diff -u -r1.148 -r1.148.4.2
--- sys/kern/vfs_syscalls.c	28 Jul 2008 14:21:17 -0000	1.148
+++ sys/kern/vfs_syscalls.c	16 Sep 2008 23:10:38 -0000	1.148.4.2
@@ -64,7 +64,7 @@
 
 static int change_dir(struct nameidata *, struct proc *);
 
-void checkdirs(struct vnode *);
+void checkdirs(struct proc *, struct vnode *);
 
 int copyout_statfs(struct statfs *, void *, struct proc *);
 
@@ -297,7 +297,7 @@
 	if (!error) {
 		vfsp->vfc_refcount++;
 		CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
-		checkdirs(vp);
+		checkdirs(p, vp);
 		VOP_UNLOCK(vp, 0, p);
  		if ((mp->mnt_flag & MNT_RDONLY) == 0)
  			error = vfs_allocate_syncvnode(mp);
@@ -320,7 +320,7 @@
  * mounted. If so, replace them with the new mount point.
  */
 void
-checkdirs(struct vnode *olddp)
+checkdirs(struct proc *curp, struct vnode *olddp)
 {
 	struct filedesc *fdp;
 	struct vnode *newdp;
@@ -330,7 +330,7 @@
 		return;
 	if (VFS_ROOT(olddp->v_mountedhere, &newdp))
 		panic("mount: lost mount");
-	LIST_FOREACH(p, &allproc, p_list) {
+	PROCLIST_FOREACH(p, curp, p_list) {
 		fdp = p->p_fd;
 		if (fdp->fd_cdir == olddp) {
 			vrele(fdp->fd_cdir);
Index: sys/miscfs/procfs/procfs_ctl.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/miscfs/procfs/procfs_ctl.c,v
retrieving revision 1.21
retrieving revision 1.21.8.2
diff -u -r1.21 -r1.21.8.2
--- sys/miscfs/procfs/procfs_ctl.c	18 Jun 2007 08:30:07 -0000	1.21
+++ sys/miscfs/procfs/procfs_ctl.c	27 Sep 2008 14:09:44 -0000	1.21.8.2
@@ -138,6 +138,7 @@
 		atomic_setbits_int(&p->p_flag, P_TRACED);
 		p->p_xstat = 0;		/* XXX ? */
 		if (p->p_pptr != curp) {
+			/* FIXME: instances */
 			p->p_oppid = p->p_pptr->p_pid;
 			proc_reparent(p, curp);
 		}
@@ -187,10 +188,11 @@
 		atomic_clearbits_int(&p->p_flag, P_TRACED);
 
 		/* give process back to original parent */
+		KASSERT(p->p_pptr); /* FIXME: instances. */
 		if (p->p_oppid != p->p_pptr->p_pid) {
 			struct proc *pp;
 
-			pp = pfind(p->p_oppid);
+			pp = pfind(curp->p_inst->inst_proc, p->p_oppid);
 			if (pp)
 				proc_reparent(p, pp);
 		}
Index: sys/miscfs/procfs/procfs_subr.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/miscfs/procfs/procfs_subr.c,v
retrieving revision 1.28
retrieving revision 1.28.6.1
diff -u -r1.28 -r1.28.6.1
--- sys/miscfs/procfs/procfs_subr.c	9 Dec 2007 21:34:32 -0000	1.28
+++ sys/miscfs/procfs/procfs_subr.c	16 Sep 2008 23:10:38 -0000	1.28.6.1
@@ -201,7 +201,7 @@
 	struct pfsnode *pfs = VTOPFS(vp);
 	struct proc *p;
 
-	p = pfind(pfs->pfs_pid);
+	p = pfind(curp->p_inst->inst_proc, pfs->pfs_pid);
 	if (p == 0)
 		return (EINVAL);
 	/* Do not permit games to be played with init(8) */
Index: sys/miscfs/procfs/procfs_vfsops.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/miscfs/procfs/procfs_vfsops.c,v
retrieving revision 1.25
retrieving revision 1.25.8.3
diff -u -r1.25 -r1.25.8.3
--- sys/miscfs/procfs/procfs_vfsops.c	18 Jun 2007 08:30:07 -0000	1.25
+++ sys/miscfs/procfs/procfs_vfsops.c	18 Feb 2009 12:43:25 -0000	1.25.8.3
@@ -76,6 +76,11 @@
 	struct procfs_args args;
 	int error;
 
+	/* FIXME - instances. */
+	log(LOG_ERR, "procfs: not supported with instances");
+	return(EINVAL);
+	/* FIXME - instances. */
+
 	if (UIO_MX & (UIO_MX-1)) {
 		log(LOG_ERR, "procfs: invalid directory entry size");
 		return (EINVAL);
Index: sys/miscfs/procfs/procfs_vnops.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.45
retrieving revision 1.45.4.4
diff -u -r1.45 -r1.45.4.4
--- sys/miscfs/procfs/procfs_vnops.c	9 Jun 2008 23:38:37 -0000	1.45
+++ sys/miscfs/procfs/procfs_vnops.c	18 Feb 2009 12:43:26 -0000	1.45.4.4
@@ -197,7 +197,7 @@
 	struct proc *p2;		/* traced */
 	int error;
 
-	if ((p2 = pfind(pfs->pfs_pid)) == 0)
+	if ((p2 = pfind(p1->p_inst->inst_proc, pfs->pfs_pid)) == 0)
 		return (ENOENT);	/* was ESRCH, jsp */
 
 	switch (pfs->pfs_type) {
@@ -294,7 +294,8 @@
 	struct vnode *vp = ap->a_vp;
 	struct pfsnode *pfs = VTOPFS(vp);
 
-	if (pfind(pfs->pfs_pid) == NULL && !(vp->v_flag & VXLOCK))
+	/* FIXME: instances. */
+	if (pfind(proc0.p_inst->inst_proc, pfs->pfs_pid) == NULL && !(vp->v_flag & VXLOCK))
 		vgone(vp);
 
 	return (0);
@@ -424,7 +425,8 @@
 		break;
 
 	default:
-		procp = pfind(pfs->pfs_pid);
+		/* FIXME: instances. */
+		procp = pfind(proc0.p_inst->inst_proc, pfs->pfs_pid);
 		if (procp == 0)
 			return (ENOENT);
 	}
@@ -704,7 +706,7 @@
 		if (pid == NO_PID)
 			break;
 
-		p = pfind(pid);
+		p = pfind(curp->p_inst->inst_proc, pid);
 		if (p == 0)
 			break;
 
@@ -732,7 +734,7 @@
 			return (error);
 		}
 
-		p = pfind(pfs->pfs_pid);
+		p = pfind(curp->p_inst->inst_proc, pfs->pfs_pid);
 		if (p == 0)
 			break;
 
@@ -837,7 +839,8 @@
 		struct proc *p;
 		struct proc_target *pt;
 
-		p = pfind(pfs->pfs_pid);
+		/* FIXME: instances. */
+		p = pfind(proc0.p_inst->inst_proc, pfs->pfs_pid);
 		if (p == NULL)
 			break;
 
@@ -873,7 +876,9 @@
 		int doingzomb = 0;
 #endif
 		int pcnt = i;
-		volatile struct proc *p = LIST_FIRST(&allproc);
+		/* FIXME */
+		volatile struct proc *p = 
+			LIST_FIRST(&curproc->p_inst->inst_proc->allproc);
 
 		if (pcnt > 3)
 			pcnt = 3;
@@ -950,7 +955,7 @@
 #ifdef PROCFS_ZOMBIE
 		if (p == 0 && doingzomb == 0) {
 			doingzomb = 1;
-			p = LIST_FIRST(&zombproc);
+			p = LIST_FIRST(curproc->p_inst->inst_proc->zombproc);
 			goto again;
 		}
 #endif
Index: sys/net/bpf.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/net/bpf.c,v
retrieving revision 1.68
retrieving revision 1.68.6.2
diff -u -r1.68 -r1.68.6.2
--- sys/net/bpf.c	25 Jan 2008 16:14:56 -0000	1.68
+++ sys/net/bpf.c	20 Sep 2008 00:09:45 -0000	1.68.6.2
@@ -492,7 +492,7 @@
 {
 	wakeup((caddr_t)d);
 	if (d->bd_async && d->bd_sig)
-		csignal(d->bd_pgid, d->bd_sig,
+		csignal(d->bd_siginstid, d->bd_pgid, d->bd_sig,
 		    d->bd_siguid, d->bd_sigeuid);
 
 	selwakeup(&d->bd_sel);
@@ -856,6 +856,7 @@
 	 */
 	case TIOCSPGRP:		/* Process or group to send signals to */
 		d->bd_pgid = *(int *)addr;
+		d->bd_siginstid = p->p_inst->inst_id;
 		d->bd_siguid = p->p_cred->p_ruid;
 		d->bd_sigeuid = p->p_ucred->cr_uid;
 		break;
Index: sys/net/bpfdesc.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/net/bpfdesc.h,v
retrieving revision 1.17
retrieving revision 1.17.12.1
diff -u -r1.17 -r1.17.12.1
--- sys/net/bpfdesc.h	25 Mar 2006 22:41:47 -0000	1.17
+++ sys/net/bpfdesc.h	19 Sep 2008 11:07:33 -0000	1.17.12.1
@@ -82,6 +82,7 @@
 	int		bd_async;	/* non-zero if packet reception should generate signal */
 	int		bd_sig;		/* signal to send upon packet reception */
 	pid_t		bd_pgid;	/* process or group id for signal */
+	instid_t	bd_siginstid;	/* instance for process for signal */
 	uid_t		bd_siguid;	/* uid for process that set pgid */
 	uid_t		bd_sigeuid;	/* euid for process that set pgid */
 	u_int		bd_ref;		/* reference count */
Index: sys/net/if_tun.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/net/if_tun.c,v
retrieving revision 1.94
retrieving revision 1.94.4.2
diff -u -r1.94 -r1.94.4.2
--- sys/net/if_tun.c	4 Aug 2008 18:55:08 -0000	1.94
+++ sys/net/if_tun.c	20 Sep 2008 00:09:45 -0000	1.94.4.2
@@ -90,6 +90,7 @@
 	struct arpcom	arpcom;		/* ethernet common data */
 	u_short		tun_flags;	/* misc flags */
 	pid_t		tun_pgid;	/* the process group - if any */
+	instid_t	tun_siginstid;	/* instid for process that set tun_pgid */
 	uid_t		tun_siguid;	/* uid for process that set tun_pgid */
 	uid_t		tun_sigeuid;	/* euid for process that set tun_pgid */
 	struct selinfo	tun_rsel;	/* read select */
@@ -585,7 +586,7 @@
 		wakeup((caddr_t)tp);
 	}
 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
-		csignal(tp->tun_pgid, SIGIO,
+		csignal(tp->tun_siginstid, tp->tun_pgid, SIGIO,
 		    tp->tun_siguid, tp->tun_sigeuid);
 	selwakeup(&tp->tun_rsel);
 	KNOTE(&tp->tun_rsel.si_note, 0);
@@ -669,6 +670,7 @@
 		break;
 	case TIOCSPGRP:
 		tp->tun_pgid = *(int *)data;
+		tp->tun_siginstid = p->p_inst->inst_id;
 		tp->tun_siguid = p->p_cred->p_ruid;
 		tp->tun_sigeuid = p->p_ucred->cr_uid;
 		break;
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.79
retrieving revision 1.79.4.1
diff -u -r1.79 -r1.79.4.1
--- sys/nfs/nfs_vfsops.c	28 Jul 2008 13:35:14 -0000	1.79
+++ sys/nfs/nfs_vfsops.c	12 Sep 2008 13:58:49 -0000	1.79.4.1
@@ -125,7 +125,7 @@
 	if (error)
 		return (error);
 	vp = NFSTOV(np);
-	cred = crget();
+	cred = crget(p->p_inst);
 	cred->cr_ngroups = 0;
 	if (v3 && (nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
 		(void)nfs_fsinfo(nmp, vp, cred, p);
Index: sys/sys/_types.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/_types.h,v
retrieving revision 1.2
retrieving revision 1.2.4.1
diff -u -r1.2 -r1.2.4.1
--- sys/sys/_types.h	16 Mar 2008 19:42:57 -0000	1.2
+++ sys/sys/_types.h	12 Sep 2008 13:58:49 -0000	1.2.4.1
@@ -58,6 +58,7 @@
 typedef	__int32_t	__suseconds_t;	/* microseconds (signed) */
 typedef __uint64_t	__fsblkcnt_t;	/* file system block count */
 typedef __uint64_t	__fsfilcnt_t;	/* file system file count */
+typedef __uint32_t	__instid_t;	/* instance id */
 
 /*
  * mbstate_t is an opaque object to keep conversion state, during multibyte
Index: sys/sys/errno.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/errno.h,v
retrieving revision 1.20
retrieving revision 1.20.6.2
diff -u -r1.20 -r1.20.6.2
--- sys/sys/errno.h	3 Sep 2007 14:37:52 -0000	1.20
+++ sys/sys/errno.h	13 Feb 2009 09:09:00 -0000	1.20.6.2
@@ -166,8 +166,13 @@
 #endif /* __BSD_VISIBLE */
 #define	EIDRM		89		/* Identifier removed */
 #define	ENOMSG		90		/* No message of desired type */
+
+/* instances */
+#define	EINSTSRCH	91		/* instance not found */
+#define	EINSTEXIST	92
+
 #if __BSD_VISIBLE
-#define	ELAST		90		/* Must be equal largest errno */
+#define	ELAST		92		/* Must be equal largest errno */
 #endif /* __BSD_VISIBLE */
 
 #ifdef _KERNEL
Index: sys/sys/inst.h
===================================================================
RCS file: sys/sys/inst.h
diff -N sys/sys/inst.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/sys/inst.h	18 Feb 2009 18:20:20 -0000	1.1.2.10
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@mult.bsd.lv>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef _SYS_INST_H_
+#define	_SYS_INST_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#define	INST_MAX	(UINT_MAX - 1)
+#define	INST_NOID	(UINT_MAX)
+
+#define	SIGINST_TERM	(15)	/* Send SIGTERM to root. */
+#define	SIGINST_KILL	(9)	/* Send SIGKILL to root. */
+
+struct	inst_proc;
+
+struct	inst {
+	struct inst_proc*inst_proc;
+	LIST_ENTRY(inst) inst_hash;
+	LIST_ENTRY(inst) inst_list;
+	instid_t	 inst_id;
+	u_int		 inst_ref;
+};
+
+#ifdef _KERNEL
+#define insthold(inst) (inst)->inst_ref++
+
+LIST_HEAD(instlist, inst);
+
+extern struct instlist	 inst_all;
+
+enum	instop {
+	INST_KPROC,	/* Read-only statistics. */
+	INST_SIG	/* Deliver signal to a process. */
+};
+
+void			 instinit(void);
+struct inst		*instknew(instid_t);
+struct inst		*instpnew(struct proc *, instid_t);
+struct inst		*instpfind(struct proc *, 
+				instid_t, enum instop);
+struct inst		*instkfind(instid_t);
+void			 instfree(struct inst *);
+
+#endif	/* _KERNEL */
+
+#endif	/* !_SYS_INST_H_ */
Index: sys/sys/malloc.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/malloc.h,v
retrieving revision 1.92
retrieving revision 1.92.4.1
diff -u -r1.92 -r1.92.4.1
--- sys/sys/malloc.h	22 Jun 2008 15:52:54 -0000	1.92
+++ sys/sys/malloc.h	12 Sep 2008 13:58:49 -0000	1.92.4.1
@@ -99,6 +99,7 @@
 #define	M_PROC		41	/* Proc structures */
 #define	M_SUBPROC	42	/* Proc sub-structures */
 #define	M_VCLUSTER	43	/* Cluster for VFS */
+#define	M_INST		44	/* Instance structures */
 /* 45-46 - free */
 #define	M_MFSNODE	46	/* MFS vnode private part */
 /* 47-48 - free */
@@ -230,7 +231,7 @@
 	"proc",		/* 41 M_PROC */ \
 	"subproc",	/* 42 M_SUBPROC */ \
 	"VFS cluster",	/* 43 M_VCLUSTER */ \
-	NULL, \
+	"inst", 	/* 44 M_INST */ \
 	NULL, \
 	"MFS node",	/* 46 M_MFSNODE */ \
 	NULL, \
Index: sys/sys/pipe.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/pipe.h,v
retrieving revision 1.13
retrieving revision 1.13.14.1
diff -u -r1.13 -r1.13.14.1
--- sys/sys/pipe.h	21 Nov 2005 18:16:46 -0000	1.13
+++ sys/sys/pipe.h	19 Sep 2008 08:54:27 -0000	1.13.14.1
@@ -77,6 +77,7 @@
 	struct	timespec pipe_atime;	/* time of last access */
 	struct	timespec pipe_mtime;	/* time of last modify */
 	struct	timespec pipe_ctime;	/* time of status change */
+	instid_t pipe_instid;
 	int	pipe_pgid;		/* process/group for async I/O */
 	struct	pipe *pipe_peer;	/* link with other direction */
 	u_int	pipe_state;		/* pipe status info */
Index: sys/sys/proc.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/proc.h,v
retrieving revision 1.103
retrieving revision 1.103.4.12
diff -u -r1.103 -r1.103.4.12
--- sys/sys/proc.h	5 May 2008 15:37:41 -0000	1.103
+++ sys/sys/proc.h	18 Feb 2009 12:43:26 -0000	1.103.4.12
@@ -53,6 +53,14 @@
 #define __need_process
 #endif
 
+/* 
+ * This refers to whether we internally use "functional" isolation on
+ * the process table in order to speed up performance.  This has NOT
+ * been determined to significantly slow/speed performance, so it'll be
+ * deprecated.  TODO.
+ */
+#define GLOBAL_HASH	0
+
 /*
  * One structure allocated per session.
  */
@@ -71,6 +79,9 @@
 	LIST_ENTRY(pgrp) pg_hash;	/* Hash chain. */
 	LIST_HEAD(, proc) pg_members;	/* Pointer to pgrp members. */
 	struct	session *pg_session;	/* Pointer to session. */
+#ifdef GLOBAL_HASH
+	struct	inst	*pg_inst;
+#endif
 	pid_t	pg_id;			/* Pgrp id. */
 	int	pg_jobc;	/* # procs qualifying pgrp for job control */
 };
@@ -162,6 +173,7 @@
 	struct	sigacts *p_sigacts;	/* Signal actions, state */
 #define	p_cred		p_p->ps_cred
 #define	p_ucred		p_cred->pc_ucred
+#define	p_inst		p_cred->pc_ucred->cr_inst
 #define	p_rlimit	p_p->ps_limit->pl_rlimit
 
 	int	p_exitsig;		/* Signal to send to parent on exit. */
@@ -340,7 +352,6 @@
 	long	ui_lockcnt;	/* lockf structs */
 };
 
-struct uidinfo *uid_find(uid_t);
 
 /*
  * We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t,
@@ -375,21 +386,36 @@
 #define EXIT_NORMAL	0x00000001
 #define EXIT_THREAD	0x00000002
 
-#define	PIDHASH(pid)	(&pidhashtbl[(pid) & pidhash])
-extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
+LIST_HEAD(proclist, proc);
+LIST_HEAD(pidhhead, proc);
+LIST_HEAD(pghhead, pgrp);
+
+#ifdef GLOBAL_HASH
+extern struct pidhhead *pidhashtbl;
 extern u_long pidhash;
 
-#define	PGRPHASH(pgid)	(&pgrphashtbl[(pgid) & pgrphash])
-extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl;
+extern struct pghhead *pgrphashtbl;
 extern u_long pgrphash;
+#endif
 
-extern struct proc proc0;		/* Process slot for swapper. */
-extern int nprocs, maxproc;		/* Current and max number of procs. */
-extern int randompid;			/* fork() should create random pid's */
+struct	inst_proc {
+	struct proclist	 allproc;
+	struct proclist	 zombproc;
+#ifdef GLOBAL_HASH
+	instid_t	 instid; 
+#else /*!GLOBAL_HASH*/
+	struct pidhhead *pidhashtbl;
+	u_long		 pidhash;
+	struct pghhead	*pgrphashtbl;
+	u_long		 pgrphash;
+#endif /*!GLOBAL_HASH*/
+	struct proc	*initproc;
+};
 
-LIST_HEAD(proclist, proc);
-extern struct proclist allproc;		/* List of all processes. */
-extern struct proclist zombproc;	/* List of zombie processes. */
+
+extern struct proc proc0;		/* Process slot for swapper. */
+extern int nprocs, maxproc;		/* Max number of procs. */
+extern int randompid;
 
 extern struct proc *initproc;		/* Process slots for init, pager. */
 extern struct proc *syncerproc;		/* filesystem syncer daemon */
@@ -403,8 +429,9 @@
 
 struct simplelock;
 
-struct proc *pfind(pid_t);	/* Find process by id. */
-struct pgrp *pgfind(pid_t);	/* Find process group by id. */
+struct uidinfo *uid_find(uid_t);
+struct proc *pfind(struct inst_proc *, pid_t);
+struct pgrp *pgfind(struct inst_proc *, pid_t);
 void	proc_printit(struct proc *p, const char *modif,
     int (*pr)(const char *, ...));
 
@@ -427,6 +454,7 @@
 void	exit1(struct proc *, int, int);
 void	exit2(struct proc *);
 void	cpu_exit(struct proc *);
+int	forkinst1(struct proc *, instid_t, register_t *);
 int	fork1(struct proc *, int, int, void *, size_t, void (*)(void *),
 	    void *, register_t *, struct proc **);
 int	groupmember(gid_t, struct ucred *);
@@ -461,7 +489,16 @@
 void	proc_trampoline_mp(void);	/* XXX */
 #endif
 
-int proc_isunder(struct proc *, struct proc *);
+int	proc_isunder(struct proc *, struct proc *);
+
+void		  pgrpinit(struct proc *, struct proc *);
+struct inst_proc *proc_instinit(const struct inst *);
+void		  proc_instfree(struct inst_proc *);
+void		  proc_instadd(struct inst_proc *, struct proc *);
+void		  pgrp_instadd(struct inst_proc *, struct pgrp *);
+
+#define	PROCLIST_FOREACH(x, y, z) \
+	LIST_FOREACH(x, &(y)->p_inst->inst_proc->allproc, z)
 
 #endif	/* _KERNEL */
 #endif	/* !_SYS_PROC_H_ */
Index: sys/sys/selinfo.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/selinfo.h,v
retrieving revision 1.3
retrieving revision 1.3.8.1
diff -u -r1.3 -r1.3.8.1
--- sys/sys/selinfo.h	25 Jul 2007 23:11:53 -0000	1.3
+++ sys/sys/selinfo.h	19 Sep 2008 08:54:27 -0000	1.3.8.1
@@ -41,6 +41,7 @@
  * notified when I/O becomes possible.
  */
 struct selinfo {
+	instid_t si_selinst;
 	pid_t	si_selpid;	/* process to be notified */
 	struct	klist si_note;	/* kernel note list */
 	short	si_flags;	/* see below */
Index: sys/sys/signalvar.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/signalvar.h,v
retrieving revision 1.16
retrieving revision 1.16.10.2
diff -u -r1.16 -r1.16.10.2
--- sys/sys/signalvar.h	6 Feb 2007 18:42:37 -0000	1.16
+++ sys/sys/signalvar.h	20 Sep 2008 00:09:45 -0000	1.16.10.2
@@ -154,8 +154,8 @@
  */
 int	coredump(struct proc *p);
 void	execsigs(struct proc *p);
-void	gsignal(int pgid, int sig);
-void	csignal(pid_t pgid, int signum, uid_t uid, uid_t euid);
+void	gsignal(instid_t instid, int pgid, int sig);
+void	csignal(instid_t instid, pid_t pgid, int signum, uid_t uid, uid_t euid);
 int	issignal(struct proc *p);
 void	pgsignal(struct pgrp *pgrp, int sig, int checkctty);
 void	postsig(int sig);
Index: sys/sys/socketvar.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/socketvar.h,v
retrieving revision 1.41
retrieving revision 1.41.4.1
diff -u -r1.41 -r1.41.4.1
--- sys/sys/socketvar.h	23 May 2008 15:51:12 -0000	1.41
+++ sys/sys/socketvar.h	20 Sep 2008 00:09:45 -0000	1.41.4.1
@@ -72,6 +72,7 @@
 	short	so_timeo;		/* connection timeout */
 	u_short	so_error;		/* error affecting connection */
 	pid_t	so_pgid;		/* pgid for signals */
+	instid_t so_siginstid;		/* instid of process who set so_pgid */
 	uid_t	so_siguid;		/* uid of process who set so_pgid */
 	uid_t	so_sigeuid;		/* euid of process who set so_pgid */
 	u_long	so_oobmark;		/* chars to oob mark */
Index: sys/sys/syscall.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/syscall.h,v
retrieving revision 1.101
retrieving revision 1.101.4.3
diff -u -r1.101 -r1.101.4.3
--- sys/sys/syscall.h	16 Mar 2008 19:43:41 -0000	1.101
+++ sys/sys/syscall.h	13 Feb 2009 09:09:00 -0000	1.101.4.3
@@ -1,10 +1,10 @@
-/*	$OpenBSD$	*/
+/*	\$OpenBSD\$	*/
 
 /*
  * System call numbers.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;	OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp 
+ * created from;	OpenBSD: syscalls.master,v 1.89 2008/01/05 00:36:13 miod Exp 
  */
 
 /* syscall: "syscall" ret: "int" args: "int" "..." */
@@ -698,4 +698,13 @@
 /* syscall: "fhstatfs" ret: "int" args: "const fhandle_t *" "struct statfs *" */
 #define	SYS_fhstatfs	309
 
-#define	SYS_MAXSYSCALL	310
+/* syscall: "forkinst" ret: "instid_t" args: "instid_t" */
+#define	SYS_forkinst	310
+
+/* syscall: "getinstid" ret: "instid_t" args: */
+#define	SYS_getinstid	311
+
+/* syscall: "killinst" ret: "int" args: "instid_t" "int" */
+#define	SYS_killinst	312
+
+#define	SYS_MAXSYSCALL	313
Index: sys/sys/syscallargs.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/syscallargs.h,v
retrieving revision 1.103
retrieving revision 1.103.4.3
diff -u -r1.103 -r1.103.4.3
--- sys/sys/syscallargs.h	16 Mar 2008 19:43:41 -0000	1.103
+++ sys/sys/syscallargs.h	13 Feb 2009 09:09:00 -0000	1.103.4.3
@@ -1,10 +1,10 @@
-/*	$OpenBSD$	*/
+/*	\$OpenBSD\$	*/
 
 /*
  * System call argument lists.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from;	OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp 
+ * created from;	OpenBSD: syscalls.master,v 1.89 2008/01/05 00:36:13 miod Exp 
  */
 
 #ifdef	syscallarg
@@ -1259,6 +1259,15 @@
 	syscallarg(struct statfs *) buf;
 };
 
+struct sys_forkinst_args {
+	syscallarg(instid_t) id;
+};
+
+struct sys_killinst_args {
+	syscallarg(instid_t) id;
+	syscallarg(int) signum;
+};
+
 /*
  * System call prototypes.
  */
@@ -1580,3 +1589,6 @@
 int	sys_statfs(struct proc *, void *, register_t *);
 int	sys_fstatfs(struct proc *, void *, register_t *);
 int	sys_fhstatfs(struct proc *, void *, register_t *);
+int	sys_forkinst(struct proc *, void *, register_t *);
+int	sys_getinstid(struct proc *, void *, register_t *);
+int	sys_killinst(struct proc *, void *, register_t *);
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/sysctl.h,v
retrieving revision 1.92
retrieving revision 1.92.6.2
diff -u -r1.92 -r1.92.6.2
--- sys/sys/sysctl.h	9 Feb 2008 15:10:58 -0000	1.92
+++ sys/sys/sysctl.h	31 Jan 2009 19:14:55 -0000	1.92.6.2
@@ -184,7 +184,9 @@
 #define	KERN_TIMECOUNTER	69	/* node: timecounter */
 #define	KERN_MAXLOCKSPERUID	70	/* int: locks per uid */
 #define	KERN_CPTIME2		71	/* array: cp_time2 */
-#define	KERN_MAXID		72	/* number of valid kern ids */
+#define	KERN_INST		72	/* struct: instance entries */
+#define	KERN_INSTPROC2		73	/* struct: process entries */
+#define	KERN_MAXID		74	/* number of valid kern ids */
 
 #define	CTL_KERN_NAMES { \
 	{ 0, 0 }, \
@@ -259,6 +261,7 @@
  	{ "timecounter", CTLTYPE_NODE }, \
  	{ "maxlocksperuid", CTLTYPE_INT }, \
  	{ "cp_time2", CTLTYPE_STRUCT }, \
+ 	{ "inst", CTLTYPE_STRUCT }, \
 }
 
 /*
@@ -269,6 +272,11 @@
 #define KERN_EMUL_NAME		0
 #define KERN_EMUL_ENABLED	1
 
+/*
+ * KERN_INST subtypes
+ */
+#define	KERN_INST_ALL		0	/* everything */
+#define	KERN_INST_INSTID	1	/* by instance id */		
 
 /*
  * KERN_PROC subtypes
@@ -347,6 +355,11 @@
 
 #define KI_NOCPU	(~(u_int64_t)0)
 
+struct kinfo_inst {
+	u_int32_t inst_id;
+	u_int32_t inst_ref;
+};
+
 struct kinfo_proc2 {
 	u_int64_t p_forw;		/* PTR: linked run/sleep queue. */
 	u_int64_t p_back;
@@ -687,7 +700,8 @@
 int sysctl_rdstruct(void *, size_t *, void *, const void *, int);
 int sysctl_struct(void *, size_t *, void *, size_t, void *, int);
 int sysctl_file(char *, size_t *);
-int sysctl_doproc(int *, u_int, char *, size_t *);
+int sysctl_doproc(struct proc *, int *, u_int, char *, size_t *);
+int sysctl_doinst(struct proc *, int *, u_int, char *, size_t *);
 struct radix_node;
 struct walkarg;
 int sysctl_dumpentry(struct radix_node *, void *);
Index: sys/sys/types.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/types.h,v
retrieving revision 1.31
retrieving revision 1.31.4.1
diff -u -r1.31 -r1.31.4.1
--- sys/sys/types.h	16 Mar 2008 19:42:57 -0000	1.31
+++ sys/sys/types.h	12 Sep 2008 13:58:49 -0000	1.31.4.1
@@ -148,6 +148,7 @@
 typedef	__suseconds_t	suseconds_t;	/* microseconds (signed) */
 typedef	__fsblkcnt_t	fsblkcnt_t;	/* file system block count */
 typedef	__fsfilcnt_t	fsfilcnt_t;	/* file system file count */
+typedef	__instid_t	instid_t;	/* instance id */
 
 /*
  * XPG4.2 states that inclusion of <netinet/in.h> must pull these
Index: sys/sys/ucred.h
===================================================================
RCS file: /cvs/OpenBSD/src/sys/sys/ucred.h,v
retrieving revision 1.6
retrieving revision 1.6.24.3
diff -u -r1.6 -r1.6.24.3
--- sys/sys/ucred.h	15 Aug 2003 20:32:20 -0000	1.6
+++ sys/sys/ucred.h	13 Feb 2009 09:09:00 -0000	1.6.24.3
@@ -35,6 +35,8 @@
 #ifndef _SYS_UCRED_H_
 #define	_SYS_UCRED_H_
 
+#include <sys/inst.h>			/* For struct inst */
+
 /*
  * Credentials.
  */
@@ -44,6 +46,7 @@
 	gid_t	cr_gid;			/* effective group id */
 	short	cr_ngroups;		/* number of groups */
 	gid_t	cr_groups[NGROUPS];	/* groups */
+	struct	inst *cr_inst;		/* instance */
 };
 #define NOCRED ((struct ucred *)-1)	/* no credential available */
 #define FSCRED ((struct ucred *)-2)	/* filesystem credential */
@@ -56,7 +59,8 @@
 struct ucred	*crcopy(struct ucred *cr);
 struct ucred	*crdup(struct ucred *cr);
 void		crfree(struct ucred *cr);
-struct ucred	*crget(void);
+struct ucred	*crget(struct inst *inst);
+struct ucred	*crnew(void);
 int		suser(struct proc *p, u_int flags);
 int		suser_ucred(struct ucred *cred);
 
Index: sys/uvm/uvm_glue.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/uvm/uvm_glue.c,v
retrieving revision 1.47
retrieving revision 1.47.8.3
diff -u -r1.47 -r1.47.8.3
--- sys/uvm/uvm_glue.c	26 May 2007 20:26:51 -0000	1.47
+++ sys/uvm/uvm_glue.c	18 Feb 2009 12:43:26 -0000	1.47.8.3
@@ -352,6 +352,7 @@
 uvm_swapout_threads(void)
 {
 	struct proc *p;
+	struct inst *i;
 	struct proc *outp, *outp2;
 	int outpri, outpri2;
 	int didswap = 0;
@@ -369,27 +370,29 @@
 	 */
 	outp = outp2 = NULL;
 	outpri = outpri2 = 0;
-	LIST_FOREACH(p, &allproc, p_list) {
-		if (!swappable(p))
-			continue;
-		switch (p->p_stat) {
-		case SRUN:
-			if (p->p_swtime > outpri2) {
-				outp2 = p;
-				outpri2 = p->p_swtime;
+	LIST_FOREACH(i, &inst_all, inst_list) {
+		LIST_FOREACH(p, &i->inst_proc->allproc, p_list) {
+			if (!swappable(p))
+				continue;
+			switch (p->p_stat) {
+			case SRUN:
+				if (p->p_swtime > outpri2) {
+					outp2 = p;
+					outpri2 = p->p_swtime;
+				}
+				continue;
+				
+			case SSLEEP:
+			case SSTOP:
+				if (p->p_slptime >= maxslp) {
+					pmap_collect(p->p_vmspace->vm_map.pmap);
+					didswap++;
+				} else if (p->p_slptime > outpri) {
+					outp = p;
+					outpri = p->p_slptime;
+				}
+				continue;
 			}
-			continue;
-			
-		case SSLEEP:
-		case SSTOP:
-			if (p->p_slptime >= maxslp) {
-				pmap_collect(p->p_vmspace->vm_map.pmap);
-				didswap++;
-			} else if (p->p_slptime > outpri) {
-				outp = p;
-				outpri = p->p_slptime;
-			}
-			continue;
 		}
 	}
 
Index: sys/uvm/uvm_meter.c
===================================================================
RCS file: /cvs/OpenBSD/src/sys/uvm/uvm_meter.c,v
retrieving revision 1.24
retrieving revision 1.24.6.3
diff -u -r1.24 -r1.24.6.3
--- sys/uvm/uvm_meter.c	15 Dec 2007 03:42:57 -0000	1.24
+++ sys/uvm/uvm_meter.c	18 Feb 2009 12:43:26 -0000	1.24.6.3
@@ -100,20 +100,23 @@
 {
 	int i, nrun;
 	struct proc *p;
+	struct inst *inst;
 
 	nrun = 0;
-	LIST_FOREACH(p, &allproc, p_list) {
-		switch (p->p_stat) {
-		case SSLEEP:
-			if (p->p_priority > PZERO || p->p_slptime > 1)
-				continue;
-		/* FALLTHROUGH */
-		case SRUN:
-		case SONPROC:
-			if (p == p->p_cpu->ci_schedstate.spc_idleproc)
-				continue;
-		case SIDL:
-			nrun++;
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			switch (p->p_stat) {
+			case SSLEEP:
+				if (p->p_priority > PZERO || p->p_slptime > 1)
+					continue;
+			/* FALLTHROUGH */
+			case SRUN:
+			case SONPROC:
+				if (p == p->p_cpu->ci_schedstate.spc_idleproc)
+					continue;
+			case SIDL:
+				nrun++;
+			}
 		}
 	}
 	for (i = 0; i < 3; i++)
@@ -236,6 +239,7 @@
 	struct vmtotal *totalp;
 {
 	struct proc *p;
+	struct inst *inst;
 #if 0
 	struct vm_map_entry *	entry;
 	struct vm_map *map;
@@ -248,52 +252,54 @@
 	 * calculate process statistics
 	 */
 
-	LIST_FOREACH(p, &allproc, p_list) {
-		if (p->p_flag & P_SYSTEM)
-			continue;
-		switch (p->p_stat) {
-		case 0:
-			continue;
-
-		case SSLEEP:
-		case SSTOP:
-			if (p->p_priority <= PZERO)
-				totalp->t_dw++;
-			else if (p->p_slptime < maxslp)
-				totalp->t_sl++;
-			if (p->p_slptime >= maxslp)
+	LIST_FOREACH(inst, &inst_all, inst_list) {
+		LIST_FOREACH(p, &inst->inst_proc->allproc, p_list) {
+			if (p->p_flag & P_SYSTEM)
 				continue;
-			break;
-
-		case SRUN:
-		case SIDL:
-		case SONPROC:
-			totalp->t_rq++;
-			if (p->p_stat == SIDL)
+			switch (p->p_stat) {
+			case 0:
 				continue;
-			break;
+	
+			case SSLEEP:
+			case SSTOP:
+				if (p->p_priority <= PZERO)
+					totalp->t_dw++;
+				else if (p->p_slptime < maxslp)
+					totalp->t_sl++;
+				if (p->p_slptime >= maxslp)
+					continue;
+				break;
+	
+			case SRUN:
+			case SIDL:
+			case SONPROC:
+				totalp->t_rq++;
+				if (p->p_stat == SIDL)
+					continue;
+				break;
+			}
+			/*
+			 * note active objects
+			 */
+	#if 0
+			/*
+			 * XXXCDC: BOGUS!  rethink this.   in the mean time
+			 * don't do it.
+			 */
+			paging = 0;
+			vm_map_lock(map);
+			for (map = &p->p_vmspace->vm_map, entry = map->header.next;
+			    entry != &map->header; entry = entry->next) {
+				if (entry->is_a_map || entry->is_sub_map ||
+				    entry->object.uvm_obj == NULL)
+					continue;
+				/* XXX how to do this with uvm */
+			}
+			vm_map_unlock(map);
+			if (paging)
+				totalp->t_pw++;
+	#endif
 		}
-		/*
-		 * note active objects
-		 */
-#if 0
-		/*
-		 * XXXCDC: BOGUS!  rethink this.   in the mean time
-		 * don't do it.
-		 */
-		paging = 0;
-		vm_map_lock(map);
-		for (map = &p->p_vmspace->vm_map, entry = map->header.next;
-		    entry != &map->header; entry = entry->next) {
-			if (entry->is_a_map || entry->is_sub_map ||
-			    entry->object.uvm_obj == NULL)
-				continue;
-			/* XXX how to do this with uvm */
-		}
-		vm_map_unlock(map);
-		if (paging)
-			totalp->t_pw++;
-#endif
 	}
 	/*
 	 * Calculate object memory usage statistics.
