diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/acorn26/acorn26/vm_machdep.c mult-netbsd-3.1/sys/arch/acorn26/acorn26/vm_machdep.c
--- NetBSD-3.1/sys/arch/acorn26/acorn26/vm_machdep.c	2006-10-23 19:54:45.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/acorn26/acorn26/vm_machdep.c	2007-11-11 19:41:30.000000000 +0000
@@ -169,20 +169,20 @@
 }
 
 void
-cpu_exit(struct lwp *l)
+cpu_exit(struct inst *i, struct lwp *l)
 {
-	int s;
+	int 	s;
 
 	/*
 	 * We're still running on l's stack here.  This is a little
 	 * dangerous, since we're about to free it, but no-one's going
-	 * to get a chance to reallocate it before we call
-	 * cpu_switch().  Well, I hope they're not anyway.
+	 * to get a chance to reallocate it before we call cpu_switch().
+	 * Well, I hope they're not anyway.
 	 *
-	 * A more conventional approach would be to run on lwp0's
-	 * stack or to have a special stack for this purpose.
+	 * A more conventional approach would be to run on lwp0's stack
+	 * or to have a special stack for this purpose.
 	 */
-	lwp_exit2(l);
+	lwp_exit2(i, l);
 	SCHED_LOCK(s);		/* expected by cpu_switch */
 	cpu_switch(NULL, NULL);
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/alpha/alpha/linux_syscall.c mult-netbsd-3.1/sys/arch/alpha/alpha/linux_syscall.c
--- NetBSD-3.1/sys/arch/alpha/alpha/linux_syscall.c	2003-10-31 03:28:12.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/alpha/alpha/linux_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -97,7 +97,6 @@
 #if defined(_KERNEL_OPT)
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
@@ -114,9 +113,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/alpha/alpha/osf1_syscall.c mult-netbsd-3.1/sys/arch/alpha/alpha/osf1_syscall.c
--- NetBSD-3.1/sys/arch/alpha/alpha/osf1_syscall.c	2003-10-31 03:28:12.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/alpha/alpha/osf1_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -97,7 +97,6 @@
 #if defined(_KERNEL_OPT)
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
@@ -114,9 +113,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/alpha/alpha/syscall.c mult-netbsd-3.1/sys/arch/alpha/alpha/syscall.c
--- NetBSD-3.1/sys/arch/alpha/alpha/syscall.c	2004-07-17 05:56:32.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/alpha/alpha/syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -96,7 +96,6 @@
 
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
@@ -112,9 +111,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/amd64/amd64/netbsd32_syscall.c mult-netbsd-3.1/sys/arch/amd64/amd64/netbsd32_syscall.c
--- NetBSD-3.1/sys/arch/amd64/amd64/netbsd32_syscall.c	2004-02-13 17:07:56.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/amd64/amd64/netbsd32_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -41,7 +41,6 @@
 
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,9 +52,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/amd64/amd64/syscall.c mult-netbsd-3.1/sys/arch/amd64/amd64/syscall.c
--- NetBSD-3.1/sys/arch/amd64/amd64/syscall.c	2003-10-31 03:28:12.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/amd64/amd64/syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -41,7 +41,6 @@
 
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,9 +52,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/arm/arm/linux_syscall.c mult-netbsd-3.1/sys/arch/arm/arm/linux_syscall.c
--- NetBSD-3.1/sys/arch/arm/arm/linux_syscall.c	2004-08-01 15:19:00.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/arm/arm/linux_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -75,7 +75,6 @@
  */
 
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_syscall_debug.h"
 
 #include <sys/param.h>
@@ -92,9 +91,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <uvm/uvm_extern.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/arm/arm/syscall.c mult-netbsd-3.1/sys/arch/arm/arm/syscall.c
--- NetBSD-3.1/sys/arch/arm/arm/syscall.c	2004-10-24 07:58:14.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/arm/arm/syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -77,7 +77,6 @@
  */
 
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_syscall_debug.h"
 
 #include <sys/param.h>
@@ -95,9 +94,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <uvm/uvm_extern.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/hppa/hppa/trap.c mult-netbsd-3.1/sys/arch/hppa/hppa/trap.c
--- NetBSD-3.1/sys/arch/hppa/hppa/trap.c	2005-02-17 14:19:49.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/hppa/hppa/trap.c	2007-11-09 18:08:20.000000000 +0000
@@ -78,7 +78,6 @@
 #include "opt_kgdb.h"
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -89,9 +88,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/proc.h>
 #include <sys/signalvar.h>
 #include <sys/user.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/conf/MULT mult-netbsd-3.1/sys/arch/i386/conf/MULT
--- NetBSD-3.1/sys/arch/i386/conf/MULT	1970-01-01 01:00:00.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/i386/conf/MULT	2007-11-18 17:09:07.000000000 +0000
@@ -0,0 +1,1299 @@
+# $NetBSD: GENERIC,v 1.661.2.14 2006/07/31 12:35:22 tron Exp $
+#
+# GENERIC machine description file
+#
+# This machine description file is used to generate the default NetBSD
+# kernel.  The generic kernel does not include all options, subsystems
+# and device drivers, but should be useful for most applications.
+#
+# The machine description file can be customised for your specific
+# machine to reduce the kernel size and improve its performance.
+#
+# For further information on compiling NetBSD kernels, see the config(8)
+# man page.
+#
+# For further information on hardware support for this architecture, see
+# the intro(4) man page.  For further information about kernel options
+# for this architecture, see the options(4) man page.  For an explanation
+# of each device driver in this file see the section 4 man page for the
+# device.
+
+include 	"arch/i386/conf/std.i386"
+
+options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
+
+#ident 		"GENERIC-$Revision: 1.1 $"
+
+maxusers	32		# estimated number of users
+
+# CPU support.  At least one is REQUIRED.
+options 	I386_CPU
+options 	I486_CPU
+options 	I586_CPU
+options 	I686_CPU
+
+# CPU-related options.
+options 	MATH_EMULATE	# floating point emulation
+options 	VM86		# virtual 8086 emulation
+options 	USER_LDT	# user-settable LDT; used by WINE
+# insert delay no-ops in interrupts; recommended on very old machines
+#options 	PIC_DELAY
+
+# Enhanced SpeedStep Technology in the Pentium M
+options 	ENHANCED_SPEEDSTEP
+#options 	EST_FREQ_USERWRITE	# any user can set frequency
+
+options 	MTRR		# memory-type range register syscall support
+# doesn't work with MP just yet..
+#options 	PERFCTRS	# performance-monitoring counters support
+
+# delay between "rebooting ..." message and hardware reset, in milliseconds
+#options 	CPURESET_DELAY=2000
+
+# This option allows you to force a serial console at the specified
+# I/O address.   see console(4) for details.
+#options 	CONSDEVNAME="\"com\"",CONADDR=0x2f8,CONSPEED=57600
+#	you don't want the option below ON iff you are using the
+#	serial console option of the new boot strap code.
+#options 	CONS_OVERRIDE	# Always use above! independent of boot info
+
+# The following options override the memory sizes passed in from the boot
+# block.  Use them *only* if the boot block is unable to determine the correct
+# values.  Note that the BIOS may *correctly* report less than 640k of base
+# memory if the extended BIOS data area is located at the top of base memory
+# (as is the case on most recent systems).
+#options 	REALBASEMEM=639		# size of base memory (in KB)
+#options 	REALEXTMEM=15360	# size of extended memory (in KB)
+
+# Standard system options
+
+options 	INSECURE	# disable kernel security levels - X needs this
+
+options 	RTC_OFFSET=0	# hardware clock is this many mins. west of GMT
+options 	NTP		# NTP phase/frequency locked loop
+#options 	NO_TSC_TIME	# Don't use TSC microtime, even if available.
+				# Improves time behavior under VMware.
+
+options 	KTRACE		# system call tracing via ktrace(1)
+#options 	SYSTRACE	# system call vetting via systrace(1) (byeeee)
+
+options 	SYSVMSG		# System V-like message queues
+options 	SYSVSEM		# System V-like semaphores
+#options 	SEMMNI=10	# number of semaphore identifiers
+#options 	SEMMNS=60	# number of semaphores in system
+#options 	SEMUME=10	# max number of undo entries per process
+#options 	SEMMNU=30	# number of undo structures in system
+options 	SYSVSHM		# System V-like memory sharing
+#options 	SHMMAXPGS=2048	# 2048 pages is the default
+options 	P1003_1B_SEMAPHORE	# p1003.1b semaphore support
+
+options 	LKM		# loadable kernel modules
+
+options 	USERCONF	# userconf(4) support
+#options 	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
+options 	SYSCTL_INCLUDE_DESCR	# Include sysctl descriptions in kernel
+
+# Beep when it is safe to power down the system (requires sysbeep)
+#options 	BEEP_ONHALT
+# Some tunable details of the above feature (default values used below)
+#options 	BEEP_ONHALT_COUNT=3	# Times to beep
+#options 	BEEP_ONHALT_PITCH=1500	# Default frequency (in Hz)
+#options 	BEEP_ONHALT_PERIOD=250	# Default duration (in msecs)
+
+# Enable experimental buffer queue strategy for better responsiveness under
+# high disk I/O load. Likely stable but not yet the default.
+#options 	NEW_BUFQ_STRATEGY
+
+# Diagnostic/debugging support options
+options 	DIAGNOSTIC	# expensive kernel consistency checks
+options 	DEBUG		# expensive debugging checks/support
+#options 	KMEMSTATS	# kernel memory statistics (vmstat -m)
+options 	DDB		# in-kernel debugger
+options 	DDB_ONPANIC=1	# see also sysctl(8): `ddb.onpanic'
+options 	DDB_HISTORY_SIZE=512	# enable history editing in DDB
+#options 	KGDB		# remote debugger
+#options 	KGDB_DEVNAME="\"com\"",KGDB_DEVADDR=0x3f8,KGDB_DEVRATE=9600
+makeoptions	DEBUG="-g"	# compile full symbol table
+
+# Compatibility options
+options 	COMPAT_NOMID	# NetBSD 0.8, 386BSD, and BSDI
+options 	COMPAT_09	# NetBSD 0.9
+options 	COMPAT_10	# NetBSD 1.0
+options 	COMPAT_11	# NetBSD 1.1
+options 	COMPAT_12	# NetBSD 1.2, 386BSD, and BSDI
+options 	COMPAT_13	# NetBSD 1.3, 386BSD, and BSDI
+options 	COMPAT_14	# NetBSD 1.4
+options 	COMPAT_15	# NetBSD 1.5
+options 	COMPAT_16	# NetBSD 1.6
+options 	COMPAT_20	# NetBSD 2.0
+options 	COMPAT_43	# 4.3BSD, 386BSD, and BSDI
+options 	COMPAT_386BSD_MBRPART # recognize old partition ID
+#options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
+
+options 	COMPAT_OSSAUDIO	# OSS (Voxware) audio driver compatibility
+options 	COMPAT_SVR4	# binary compatibility with SVR4
+options 	COMPAT_IBCS2	# binary compatibility with SCO and ISC
+options 	COMPAT_LINUX	# binary compatibility with Linux
+options 	COMPAT_FREEBSD	# binary compatibility with FreeBSD
+#options 	COMPAT_MACH	# binary compatibility with Mach binaries
+#options 	COMPAT_DARWIN	# binary compatibility with Darwin binaries
+#options 	EXEC_MACHO	# exec MACH-O binaries
+#options 	COMPAT_PECOFF	# kernel support to run Win32 apps
+options 	COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
+
+# File systems
+file-system 	FFS		# UFS
+file-system 	EXT2FS		# second extended file system (linux)
+file-system 	LFS		# log-structured file system
+file-system 	MFS		# memory file system
+file-system 	NFS		# Network File System client
+file-system 	NTFS		# Windows/NT file system (experimental)
+file-system 	CD9660		# ISO 9660 + Rock Ridge file system
+file-system 	MSDOSFS		# MS-DOS file system
+file-system 	FDESC		# /dev/fd
+#file-system 	KERNFS		# /kern (removed, byeeee!)
+file-system 	NULLFS		# loopback file system
+file-system 	OVERLAY		# overlay file system
+file-system 	PORTAL		# portal filesystem (still experimental)
+#file-system 	PROCFS		# /proc (removed, byeeee!)
+file-system 	UMAPFS		# NULLFS + uid and gid remapping
+file-system 	UNION		# union file system
+file-system	CODA		# Coda File System; also needs vcoda (below)
+file-system	SMBFS		# experimental - CIFS; also needs nsmb (below)
+
+# File system options
+options 	QUOTA		# UFS quotas
+#options 	FFS_EI		# FFS Endian Independent support
+options 	SOFTDEP		# FFS soft updates support.
+#options	UFS_DIRHASH	# UFS Large Directory Hashing - Experimental
+options 	NFSSERVER	# Network File System server
+#options 	FFS_NO_SNAPSHOT	# ffs snapshots
+#options 	EXT2FS_SYSTEM_FLAGS # makes ext2fs file flags (append and
+				# immutable) behave as system flags.
+
+# Networking options
+#options 	GATEWAY		# packet forwarding
+options 	INET		# IP + ICMP + TCP + UDP
+options 	INET6		# IPV6
+#options 	IPSEC		# IP security
+#options 	IPSEC_ESP	# IP security (encryption part; define w/IPSEC)
+#options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
+#options 	IPSEC_DEBUG	# debug for IP security
+#options 	MROUTING	# IP multicast routing
+#options 	PIM		# Protocol Independent Multicast
+options 	NS		# XNS
+#options 	NSIP		# XNS tunneling over IP
+options 	ISO,TPIP	# OSI
+#options 	EON		# OSI tunneling over IP
+options 	CCITT,LLC,HDLC	# X.25
+options 	NETATALK	# AppleTalk networking protocols
+options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+options 	PPP_DEFLATE	# Deflate compression support for PPP
+options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+options 	PFIL_HOOKS	# pfil(9) packet filter hooks
+options 	IPFILTER_LOG	# ipmon(8) log support
+#options 	IPFILTER_DEFAULT_BLOCK	# block all packets by default
+#options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
+
+#options 	ALTQ		# Manipulate network interfaces' output queues
+#options 	ALTQ_BLUE	# Stochastic Fair Blue
+#options 	ALTQ_CBQ	# Class-Based Queueing
+#options 	ALTQ_CDNR	# Diffserv Traffic Conditioner
+#options 	ALTQ_FIFOQ	# First-In First-Out Queue
+#options 	ALTQ_FLOWVALVE	# RED/flow-valve (red-penalty-box)
+#options 	ALTQ_HFSC	# Hierarchical Fair Service Curve
+#options 	ALTQ_LOCALQ	# Local queueing discipline
+#options 	ALTQ_PRIQ	# Priority Queueing
+#options 	ALTQ_RED	# Random Early Detection
+#options 	ALTQ_RIO	# RED with IN/OUT
+#options 	ALTQ_WFQ	# Weighted Fair Queueing
+
+# These options control the verified exec feature
+#options VERIFIED_EXEC
+#
+# Uncomment the fingerprint methods below that are desired.  Note that
+# removing fingerprint methods will have almost no impact on the kernel
+# code size.
+#
+#options VERIFIED_EXEC_FP_RMD160
+#options VERIFIED_EXEC_FP_SHA256
+#options VERIFIED_EXEC_FP_SHA384
+#options VERIFIED_EXEC_FP_SHA512
+#options VERIFIED_EXEC_FP_SHA1
+#options VERIFIED_EXEC_FP_MD5
+#
+#options VERIFIED_EXEC_DEBUG
+#options VERIFIED_EXEC_DEBUG_VERBOSE
+
+# These options enable verbose messages for several subsystems.
+# Warning, these may compile large string tables into the kernel!
+#options 	ACPIVERBOSE	# verbose ACPI device autoconfig messages
+options 	EISAVERBOSE	# verbose EISA device autoconfig messages
+options 	MIIVERBOSE	# verbose PHY autoconfig messages
+options 	PCIVERBOSE	# verbose PCI device autoconfig messages
+#options 	PCI_CONFIG_DUMP	# verbosely dump PCI config space
+#options 	PCMCIAVERBOSE	# verbose PCMCIA configuration messages
+options 	SCSIVERBOSE	# human readable SCSI error messages
+options 	USBVERBOSE	# verbose USB device autoconfig messages
+#options 	PNPBIOSVERBOSE	# verbose PnP BIOS messages
+#options 	PNPBIOSDEBUG	# more fulsome PnP BIOS debugging messages
+options 	I2OVERBOSE	# verbose I2O driver messages
+options 	MCAVERBOSE	# verbose MCA device autoconfig messages
+
+options 	NFS_BOOT_DHCP,NFS_BOOT_BOOTPARAM
+
+#
+# wscons options
+#
+# builtin terminal emulations
+#options 	WSEMUL_SUN		# sun terminal emulation
+options 	WSEMUL_VT100		# VT100 / VT220 emulation
+# customization of console and kernel output - see dev/wscons/wsdisplayvar.h
+options 	WSDISPLAY_CUSTOM_OUTPUT	# color customization from wsconsctl(8)
+#options 	WS_DEFAULT_FG=WSCOL_WHITE
+#options 	WS_DEFAULT_BG=WSCOL_BLACK
+#options 	WS_DEFAULT_COLATTR="(0)"
+#options 	WS_DEFAULT_MONOATTR="(0)"
+options 	WS_KERNEL_FG=WSCOL_GREEN
+#options 	WS_KERNEL_BG=WSCOL_BLACK
+#options 	WS_KERNEL_COLATTR=""
+#options 	WS_KERNEL_MONOATTR=""
+# customization of console border color
+options 	WSDISPLAY_CUSTOM_BORDER	# border customization from wsconsctl(8)
+#options 	WSDISPLAY_BORDER_COLOR=WSCOL_BLUE	# default color
+# compatibility to other console drivers
+options 	WSDISPLAY_COMPAT_PCVT		# emulate some ioctls
+options 	WSDISPLAY_COMPAT_SYSCONS	# emulate some ioctls
+options 	WSDISPLAY_COMPAT_USL		# VT handling
+options 	WSDISPLAY_COMPAT_RAWKBD		# can get raw scancodes
+# see dev/pckbc/wskbdmap_mfii.c for implemented layouts
+#options 	PCKBD_LAYOUT="(KB_DE | KB_NODEAD)"
+# allocate a number of virtual screens at autoconfiguration time
+#options 	WSDISPLAY_DEFAULTSCREENS=4
+# use a large software cursor that doesn't blink
+options 	PCDISPLAY_SOFTCURSOR
+# modify the screen type of the console; defaults to "80x25"
+#options 	VGA_CONSOLE_SCREENTYPE="\"80x24\""
+# work around a hardware bug that loaded fonts don't work; found on ATI cards
+#options 	VGA_CONSOLE_ATI_BROKEN_FONTSEL
+# the following enables some functions to get mouse console support.
+# if you want a really secure system, it may be better not to enable them,
+# see wsmoused(8), section SECURITY CONSIDERATIONS for more info.
+#options 	WSDISPLAY_CHARFUNCS		# mouse console support
+# console scrolling support.
+#options 	WSDISPLAY_SCROLLSUPPORT
+# enable VGA raster mode capable of displaying multilingual text on console
+#options 	VGA_RASTERCONSOLE
+
+# Kernel root file system and dump configuration.
+config		netbsd	root on ? type ?
+#config		netbsd	root on sd0a type ffs
+#config		netbsd	root on ? type nfs
+
+#
+# Device configuration
+#
+
+mainbus0 at root
+
+cpu* at mainbus?
+#ioapic* at mainbus?
+
+# Doesn't do anything yet.
+#p64h2apic* at pci? dev? function?	# P64H2 IOxAPIC
+
+#apm0	at mainbus0			# Advanced power management
+
+# Tuning for power management, see apm(4) for more details.
+#options 	APM_NO_IDLE		# Don't call BIOS CPU idle function
+#options 	APM_V10_ONLY		# Use only the APM 1.0 calls
+#options 	APM_NO_POWEROFF		# Don't power off on halt(8)
+#options 	APM_POWER_PRINT		# Print stats on the console
+#options 	APM_DISABLE_INTERRUPTS=0 # Don't disable interrupts
+
+
+# Basic Bus Support
+
+# Advanced Configuration and Power Interface
+
+# This option can be used to retrieve CPU and APIC information.
+# that I/O APICs can be used if ACPI is enabled below.
+# To use the I/O APIC(s), enable the ioapic line above.
+#options 	MPBIOS		# configure CPUs and APICs using MPBIOS
+#options 	MPBIOS_SCANPCI	# find PCI roots using MPBIOS
+#options 	MPACPI		# configure CPUs and APICs using ACPI
+				# (acpi at mainbus must also be enabled)
+#options 	MPACPI_SCANPCI	# find PCI roots using MPACPI
+
+#acpi0 		at mainbus0
+#options 	ACPI_PCI_FIXUP		# PCI interrupt routing via ACPI
+#options 	ACPI_ACTIVATE_DEV	# If set, activate inactive devices
+#options 	ACPICA_PEDANTIC		# force strict conformance to the Spec.
+#options 	ACPI_DISABLE_ON_POWEROFF	# disable acpi on power off
+
+# ACPI devices
+#acpiacad* 	at acpi?		# ACPI AC Adapter
+#acpibat* 	at acpi?		# ACPI Battery
+#acpibut* 	at acpi?		# ACPI Button
+#acpiec* 	at acpi?		# ACPI Embedded Controller
+#acpilid* 	at acpi?		# ACPI Lid Switch
+#acpitz* 	at acpi?		# ACPI Thermal Zone
+
+# Mainboard devices
+#com* 		at acpi?		# Serial communications interface
+#fdc* 		at acpi?		# Floppy disk controller
+#joy*		at acpi?		# Joystick/Game port
+#lpt* 		at acpi?		# Parallel port
+#mpu*		at acpi?		# Roland MPU-401 MIDI UART
+#npx*		at acpi?		# Math coprocessor
+#pckbc*  	at acpi?		# PC keyboard controller
+#wss* 		at acpi?		# NeoMagic 256AV in wss mode
+
+# Sony Vaio jog dial
+#spic* 		at acpi?		# Sony Programmable I/O Controller
+#wsmouse* 	at spic?
+
+# Toshiba Libretto devices
+#vald* at acpi?
+
+# Plug-and-Play BIOS and attached devices
+
+#pnpbios*	at mainbus?
+
+# mainboard audio chips
+#ess*		at pnpbios? index ?	# ESS AudioDrive
+#sb*		at pnpbios? index ?	# NeoMagic 256AV in sb mode
+#wss*		at pnpbios? index ?	# NeoMagic 256AV in wss mode
+#ym*		at pnpbios? index ?	# OPL3-SA3
+
+# com port
+# If enabled, consider changing "com0", "com1", and "com2" under "ISA Serial
+# Interfaces" to "com*", otherwise com2 will attach at pnpbios? and there
+# will be no com0.  A side effect is pcmcia (and other) com? previously
+# starting at com3 may attach as com1 or com2.
+#com*		at pnpbios? index ?	# serial ports
+
+# parallel port
+# The above "com*" comments apply, cf. "lpt0" under "ISA parallel
+# "printer interfaces".
+#lpt*		at pnpbios? index ?	# parallel ports
+
+#pckbc*		at pnpbios? index ?	# PC keyboard/mouse controller
+#fdc*		at pnpbios? index ?	# floppy controller
+#npx*		at pnpbios? index ?	# Math coprocessor
+
+# IDE controller on Toshiba Portege 3000 series (crippled PCI device)
+#pciide* 	at pnpbios? index ?
+
+# PCI bus support
+pci*	at mainbus? bus ?
+pci*	at pchb? bus ?
+pci*	at ppb? bus ?
+
+# Configure PCI using BIOS information
+#options 	PCIBIOS			# PCI BIOS support
+#options 	PCIBIOSVERBOSE		# PCI BIOS verbose info
+#options 	PCIBIOS_ADDR_FIXUP	# fixup PCI I/O addresses
+#options 	PCIBIOS_BUS_FIXUP	# fixup PCI bus numbering
+#options 	PCIBIOS_INTR_FIXUP	# fixup PCI interrupt routing
+#options 	PCIBIOS_IRQS_HINT=0x0a00 # PCI interrupts hint. IRQ 9 or 11
+#options 	PCIBIOS_INTR_GUESS	# see pcibios(4)
+#options 	PCIBIOS_LIBRETTO_FIXUP	# this code makes the Toshiba Libretto
+					# L2/L3 work, but should not be enabled
+					# on anything else.
+#options 	PCIBIOS_SHARP_MM20_FIXUP # this code makes the Sharp MM 20
+					# work, but should not be enabled
+					# on anything else.
+#options 	PCIINTR_DEBUG		# super-verbose PCI interrupt fixup
+
+# System Controllers
+elansc* at pci? dev ? function ?	# AMD Elan SC520 System Controller
+
+# PCI bridges
+#ichlpcib* at pci? dev ? function ?	# Intel ICH PCI-ISA w/ watchdog and
+					# SpeedStep support
+pchb*	at pci? dev ? function ?	# PCI-Host bridges
+pceb*	at pci? dev ? function ?	# PCI-EISA bridges
+pcib*	at pci? dev ? function ?	# PCI-ISA bridges
+pcmb*	at pci? dev ? function ?	# PCI-MCA bridges
+ppb*	at pci? dev ? function ?	# PCI-PCI bridges
+# XXX 'puc's aren't really bridges, but there's no better place for them here
+puc*	at pci? dev ? function ?	# PCI "universal" comm. cards
+
+agp* 	at pchb?
+
+
+# EISA bus support
+eisa0	at mainbus?
+eisa0	at pceb?
+
+# ISA bus support
+#isa0	at ichlpcib?
+isa0	at mainbus?
+isa0	at pceb?
+isa0	at pcib?
+
+# PCMCIA bus support
+pcmcia* at pcic? controller ? socket ?
+pcmcia* at tcic? controller ? socket ?
+
+# MCA bus support
+mca0	at mainbus?
+
+# ISA PCMCIA controllers
+pcic0	at isa? port 0x3e0 iomem 0xd0000 iosiz 0x10000
+pcic1	at isa? port 0x3e2 iomem 0xe0000 iosiz 0x4000
+pcic2	at isa? port 0x3e4 iomem 0xe0000 iosiz 0x4000
+tcic0	at isa? port 0x240 iomem 0xd0000 iosiz 0x10000
+
+# PCI PCMCIA controllers
+pcic0	at pci? dev? function ?
+
+# ISA Plug-and-Play bus support
+isapnp0 at isa?
+
+# ISA Plug-and-Play PCMCIA controllers
+pcic*	at isapnp?
+
+# CardBus bridge support
+cbb*		at pci? dev ? function ?
+cardslot*	at cbb?
+
+# CardBus bus support
+cardbus*	at cardslot?
+pcmcia* 	at cardslot?
+
+# Coprocessor Support
+
+# Math Coprocessor support
+npx0	at isa? port 0xf0 irq 13	# x86 math coprocessor
+
+
+# Console Devices
+
+# ISA console
+#pc0	at isa? port 0x60 irq 1		# pccons generic PC console driver
+# Keyboard layout configuration for pccons
+#options 	FRENCH_KBD
+#options 	FINNISH_KBD
+#options 	GERMAN_KBD
+#options 	NORWEGIAN_KBD
+
+
+# wscons
+pckbc0		at isa?			# pc keyboard controller
+pckbd*		at pckbc?		# PC keyboard
+pms*		at pckbc?		# PS/2 mouse for wsmouse
+#options 	PMS_DISABLE_POWERHOOK	# Disable PS/2 reset on resume
+#options 	PMS_SYNAPTICS_TOUCHPAD	# Enable support for Synaptics Touchpads
+vga0		at isa?
+vga*		at pci? dev ? function ?
+pcdisplay0	at isa?			# CGA, MDA, EGA, HGA
+#machfb* 	at pci? dev ? function ? # ATI Mach64 framebuffer driver
+wsdisplay*	at vga? console ?
+wsdisplay*	at pcdisplay? console ?
+#wsdisplay* 	at machfb? console ?
+wskbd*		at pckbd? console ?
+wsmouse*	at pms? mux 0
+
+pcppi0		at isa?
+sysbeep0	at pcppi?
+
+# Serial Devices
+
+# PCI serial interfaces
+com*	at puc? port ?			# 16x50s on "universal" comm boards
+cy*	at pci? dev ? function ?	# Cyclades Cyclom-Y serial boards
+cz*	at pci? dev ? function ?	# Cyclades-Z multi-port serial boards
+
+# ISA Plug-and-Play serial interfaces
+com*	at isapnp?			# Modems and serial boards
+
+# PCMCIA serial interfaces
+com*	at pcmcia? function ?		# Modems and serial cards
+
+pcmcom* at pcmcia? function ?		# PCMCIA multi-port serial cards
+com*	at pcmcom? slave ?		# ...and the slave devices
+
+# CardBus serial interfaces
+#com*	at cardbus? dev ? function ?	# Modems and serial cards
+
+# ISA serial interfaces
+#options 	COM_HAYESP		# adds Hayes ESP serial board support
+com0	at isa? port 0x3f8 irq 4	# Standard PC serial ports
+com1	at isa? port 0x2f8 irq 3
+com2	at isa? port 0x3e8 irq 5
+#com3	at isa? port 0x2e8 irq 9
+#ast0	at isa? port 0x1a0 irq 5	# AST 4-port serial cards
+#com*	at ast? slave ?
+#boca0	at isa? port 0x100 irq 5	# BOCA 8-port serial cards
+#boca0	at isa? port 0x100 irq 5	# BOCA 16-port serial cards (BB2016)
+#boca1	at isa? port 0x140 irq 5	# this line is also needed for BB2016
+#com*	at boca? slave ?
+#tcom0	at isa? port 0x100 irq 7	# TC-800 8-port serial cards
+#com*	at tcom? slave ?
+#rtfps0	at isa? port 0x1230 irq 10	# RT 4-port serial cards
+#com*	at rtfps? slave ?
+#cy0	at isa? iomem 0xd4000 irq 12	# Cyclades serial cards
+#addcom0 at isa? port 0x108 irq 5	# Addonics FlexPort 8S
+#com*	at addcom? slave ?
+#moxa0	at isa?	port 0x100 irq 5	# MOXA C168H serial card (experimental)
+#com*	at moxa? slave ?
+#ioat*	at isa? port 0x220 irq 5	# BOCA IOAT66 6-port serial card
+#com*	at ioat? slave ?
+
+# MCA serial interfaces
+com*	at mca? slot ?			# 16x50s on comm boards
+
+# Parallel Printer Interfaces
+
+# PCI parallel printer interfaces
+lpt*	at puc? port ?			# || ports on "universal" comm boards
+
+# ISA parallel printer interfaces
+lpt0	at isa? port 0x378 irq 7	# standard PC parallel ports
+lpt1	at isa? port 0x278
+lpt2	at isa? port 0x3bc
+
+# Hardware monitors
+
+# AMD 768 and 8111 power/ACPI controllers
+amdpm*	at pci? dev ? function ?	# RNG and SMBus 1.0 interface
+#iic*	at amdpm?			# sensors below are on this bus
+#adt7463c* at iic? addr 0x2C		# Unknown other motherboard(s)
+#adt7463c* at iic? addr 0x2D		# Tyan S2881
+#adt7463c* at iic? addr 0x2E		# Tyan S2882-D
+
+# LM7[89] and compatible hardware monitors
+#lm0	at isa?	port 0x290		# other common ports: 0x280, 0x310
+
+# PC87366 hardware monitor
+#nsclpcsio*	at isa?
+
+# VIA VT82C686A hardware monitor
+#viapm*	at pci? dev ? function ?
+#viaenv* at viapm?
+
+
+# I2O devices
+iop*	at pci? dev ? function ?	# I/O processor
+iopsp*	at iop? tid ?			# SCSI/FC-AL ports
+ld*	at iop? tid ?			# block devices
+dpti*	at iop? tid 0			# DPT/Adaptec control interface
+
+
+# SCSI Controllers and Devices
+
+# PCI SCSI controllers
+adv*	at pci? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI
+adw*	at pci? dev ? function ?	# AdvanSys 9x0UW[D], 3940U[2,3]W SCSI
+ahc*	at pci? dev ? function ?	# Adaptec [23]94x, aic78x0 SCSI
+ahd*	at pci? dev ? function ?	# Adaptec 29320, 39320 (aic790x) SCSI
+bha*	at pci? dev ? function ?	# BusLogic 9xx SCSI
+dpt*	at pci? dev ? function ?	# DPT SmartCache/SmartRAID
+iha*	at pci? dev ? function ?	# Initio INIC-940/950 SCSI
+isp*	at pci? dev ? function ?	# Qlogic ISP [12]0x0 SCSI/FibreChannel
+mly*	at pci? dev ? function ?	# Mylex AcceleRAID and eXtremeRAID
+mpt*	at pci? dev ? function ?	# LSI Fusion SCSI/FC
+njs*	at pci? dev ? function ?	# Workbit NinjaSCSI-32
+pcscp*	at pci? dev ? function ?	# AMD 53c974 PCscsi-PCI SCSI
+siop*	at pci? dev ? function ?	# Symbios 53c8xx SCSI
+esiop*	at pci? dev ? function ?	# Symbios 53c875 SCSI and newer
+#options 	SIOP_SYMLED		# drive the act. LED in software
+trm*	at pci? dev ? function ?	# Tekram DC-395U/UW/F, DC-315/U SCSI
+
+# EISA SCSI controllers
+ahb*	at eisa? slot ?			# Adaptec 174[02] SCSI
+ahc*	at eisa? slot ?			# Adaptec 274x, aic7770 SCSI
+bha*	at eisa? slot ?			# BusLogic 7xx SCSI
+dpt*	at eisa? slot ?			# DPT EATA SCSI
+uha*	at eisa? slot ?			# UltraStor 24f SCSI
+
+# PCMCIA SCSI controllers
+aic*	at pcmcia? function ?		# Adaptec APA-1460 SCSI
+esp*	at pcmcia? function ?		# Qlogic ESP406/FAS408 SCSI
+
+# ISA Plug-and-Play SCSI controllers
+aha*	at isapnp? 			# Adaptec AHA-154[02
+aic*	at isapnp?			# Adaptec AHA-1520B
+
+# ISA SCSI controllers
+adv0	at isa? port ? irq ? drq ?	# AdvanSys APB-514[02] SCSI
+aha0	at isa? port 0x330 irq ? drq ?	# Adaptec 154[02] SCSI
+aha1	at isa? port 0x334 irq ? drq ?
+ahc0	at isa? port ? irq ?		# Adaptec 284x SCSI
+aic0	at isa? port 0x340 irq 11	# Adaptec 152[02] SCSI
+bha0	at isa? port 0x330 irq ? drq ?	# BusLogic [457]4X SCSI
+bha1	at isa? port 0x334 irq ? drq ?
+# The "nca" and "dpt" probes might give false hits or hang your machine.
+#dpt0	at isa? port 0x170 irq ? drq ?	# DPT SmartCache/SmartRAID
+#nca0	at isa? port 0x360 irq 15	# Port-mapped NCR 53C80 controller
+#nca1	at isa? iomem 0xd8000 irq 5	# Memory-mapped controller (T128, etc.)
+sea0	at isa? iomem 0xc8000 irq 5	# Seagate/Future Domain SCSI
+uha0	at isa? port 0x330 irq ? drq ?	# UltraStor [13]4f SCSI
+uha1	at isa? port 0x340 irq ? drq ?
+wds0	at isa? port 0x350 irq 15 drq 6	# WD7000 and TMC-7000 controllers
+wds1	at isa? port 0x358 irq 11 drq 5
+
+# CardBus SCSI cards
+#adv*	at cardbus? dev ? function ?	# AdvanSys 1200[A,B], 9xx[U,UA] SCSI
+#ahc*	at cardbus? dev ? function ?	# Adaptec ADP-1480
+#njs*	at cardbus? dev ? function ?	# Workbit NinjaSCSI-32
+
+# MCA SCSI cards
+aha*	at mca? slot ?			# Adaptec AHA-1640
+
+# SCSI bus support
+scsibus* at scsi?
+
+# SCSI devices
+sd*	at scsibus? target ? lun ?	# SCSI disk drives
+st*	at scsibus? target ? lun ?	# SCSI tape drives
+cd*	at scsibus? target ? lun ?	# SCSI CD-ROM drives
+ch*	at scsibus? target ? lun ?	# SCSI autochangers
+ses*	at scsibus? target ? lun ?	# SCSI Enclosure Services devices
+ss*	at scsibus? target ? lun ?	# SCSI scanners
+uk*	at scsibus? target ? lun ?	# SCSI unknown
+
+
+# RAID controllers and devices
+aac*	at pci? dev ? function ?	# Adaptec AAC family
+amr*	at pci? dev ? function ?	# AMI/LSI Logic MegaRAID
+cac*	at eisa? slot ?			# Compaq EISA array controllers
+cac*	at pci? dev ? function ?	# Compaq PCI array controllers
+ciss*	at pci? dev ? function ?	# HP Smart Array controllers
+icp*	at pci? dev ? function ?	# ICP-Vortex GDT & Intel RAID
+mlx*	at pci? dev ? function ?	# Mylex DAC960 & DEC SWXCR family
+mlx*	at eisa? slot ?			# Mylex DAC960 & DEC SWXCR family
+twe*	at pci? dev ? function ?	# 3ware Escalade RAID controllers
+twa*	at pci? dev ? function ?	# 3ware Escalade 9xxx RAID controllers
+
+ld*	at aac? unit ?			# logical disk devices
+ld*	at amr? unit ?
+ld*	at cac? unit ?
+ld*	at icp? unit ?
+ld*	at twe? unit ?
+ld*	at twa? unit ?
+ld*	at mlx? unit ?
+
+icpsp*	at icp? unit ?			# SCSI pass-through
+
+# IDE and related devices
+# PCI IDE controllers - see pciide(4) for supported hardware.
+# The 0x0001 flag force the driver to use DMA, even if the driver doesn't know
+# how to set up DMA modes for this chip. This may work, or may cause
+# a machine hang with some controllers.
+pciide* 	at pci? dev ? function ? flags 0x0000	# GENERIC pciide driver
+acardide*	at pci? dev ? function ?	# Acard IDE controllers
+aceride* 	at pci? dev ? function ?	# Acer Lab IDE controllers
+artsata* 	at pci? dev ? function ?	# Intel i31244 SATA controller
+cmdide* 	at pci? dev ? function ?	# CMD tech IDE controllers
+cypide* 	at pci? dev ? function ?	# Cypress IDE controllers
+geodeide* 	at pci? dev ? function ?	# AMD Geode IDE controllers
+hptide* 	at pci? dev ? function ?	# Triones/HighPoint IDE controllers
+iteide* 	at pci? dev ? function ?	# IT Express IDE controllers
+ixpide* 	at pci? dev ? function ?	# ATI IXP IDE controllers
+optiide* 	at pci? dev ? function ?	# Opti IDE controllers
+piixide* 	at pci? dev ? function ?	# Intel IDE controllers
+pdcide* 	at pci? dev ? function ?	# Promise IDE controllers
+pdcsata*	at pci? dev ? function ?	# Promise SATA150 controllers
+rccide* 	at pci? dev ? function ?	# ServerWorks IDE controllers
+satalink*	at pci? dev ? function ?	# SiI SATALink controllers
+siside* 	at pci? dev ? function ?	# SiS IDE controllers
+slide*  	at pci? dev ? function ?	# Symphony Labs IDE controllers
+svwsata* 	at pci? dev ? function ?	# ServerWorks SATA controllers
+stpcide*	at pci? dev ? function ?	# STMicro STPC IDE controllers
+viaide* 	at pci? dev ? function ?	# VIA/AMD/Nvidia IDE controllers
+
+# ISA Plug-and-Play IDE controllers
+wdc*	at isapnp?
+
+# PCMCIA IDE controllers
+wdc*	at pcmcia? function ?
+
+# ISA ST506, ESDI, and IDE controllers
+# Use flags 0x01 if you want to try to use 32bits data I/O (the driver will
+# fall back to 16bits I/O if 32bits I/O are not functional).
+# Some controllers pass the initial 32bit test, but will fail later.
+wdc0	at isa? port 0x1f0 irq 14 flags 0x00
+wdc1	at isa? port 0x170 irq 15 flags 0x00
+
+# ATA (IDE) bus support
+atabus* at ata?
+
+# IDE drives
+# Flags are used only with controllers that support DMA operations
+# and mode settings (e.g. some pciide controllers)
+# The lowest order four bits (rightmost digit) of the flags define the PIO
+# mode to use, the next set of four bits the DMA mode and the third set the
+# UltraDMA mode. For each set of four bits, the 3 lower bits define the mode
+# to use, and the last bit must be 1 for this setting to be used.
+# For DMA and UDMA, 0xf (1111) means 'disable'.
+# 0x0fac means 'use PIO mode 4, DMA mode 2, disable UltraDMA'.
+# (0xc=1100, 0xa=1010, 0xf=1111)
+# 0x0000 means "use whatever the drive claims to support".
+wd*	at atabus? drive ? flags 0x0000
+
+# ATA RAID configuration support, as found on some Promise controllers.
+pseudo-device	ataraid
+ld*	at ataraid? vendtype ? unit ?
+
+# ATAPI bus support
+atapibus* at atapi?
+
+# ATAPI devices
+# flags have the same meaning as for IDE drives.
+cd*	at atapibus? drive ? flags 0x0000	# ATAPI CD-ROM drives
+sd*	at atapibus? drive ? flags 0x0000	# ATAPI disk drives
+st*	at atapibus? drive ? flags 0x0000	# ATAPI tape drives
+uk*	at atapibus? drive ? flags 0x0000	# ATAPI unknown
+
+
+# Miscellaneous mass storage devices
+
+# ISA floppy
+fdc0	at isa? port 0x3f0 irq 6 drq 2	# standard PC floppy controllers
+#fdc1	at isa? port 0x370 irq ? drq ?
+fd*	at fdc? drive ?			# the drives themselves
+# some machines need you to do this instead of fd*
+#fd0	at fdc0 drive 0
+
+# ISA CD-ROM devices
+#mcd0	at isa? port 0x300 irq 10	# Mitsumi CD-ROM drives
+
+# ISA tape devices
+# note: the wt driver conflicts unpleasantly with SMC boards at the
+# same I/O address. The probe reprograms their EEPROMs. Don't
+# uncomment it unless you are actually using it.
+#wt0	at isa? port 0x308 irq 5 drq 1	# Archive and Wangtek QIC tape drives
+
+# MCA ESDI devices
+edc*	at mca? slot ?			# IBM ESDI Disk Controllers
+ed*	at edc?
+
+
+# Network Interfaces
+
+# PCI network interfaces
+an*	at pci? dev ? function ?	# Aironet PC4500/PC4800 (802.11)
+#ath*	at pci? dev ? function ?	# Atheros 5210/5211/5212 802.11
+atw*	at pci? dev ? function ?	# ADMtek ADM8211 (802.11)
+bce* 	at pci? dev ? function ?	# Broadcom 4401 10/100 Ethernet
+bge* 	at pci? dev ? function ?	# Broadcom 570x gigabit Ethernet
+dge*	at pci? dev ? function ?	# Intel 82597 10GbE LR
+en*	at pci? dev ? function ?	# ENI/Adaptec ATM
+ep*	at pci? dev ? function ?	# 3Com 3c59x
+epic*	at pci? dev ? function ?	# SMC EPIC/100 Ethernet
+esh*	at pci? dev ? function ?	# Essential HIPPI card
+ex*	at pci? dev ? function ?	# 3Com 90x[BC]
+fpa*	at pci? dev ? function ?	# DEC DEFPA FDDI
+fxp*	at pci? dev ? function ?	# Intel EtherExpress PRO 10+/100B
+ipw*	at pci? dev ? function ?	# Intel PRO/Wireless 2100
+iwi*	at pci? dev ? function ?	# Intel PRO/Wireless 2200BG
+gsip*	at pci? dev ? function ?	# NS83820 Gigabit Ethernet
+hme*	at pci? dev ? function ?	# Sun Microelectronics STP2002-STQ
+le*	at pci? dev ? function ?	# PCnet-PCI Ethernet
+lmc*	at pci? dev ? function ?	# Lan Media Corp SSI/HSSI/DS3
+mtd*	at pci? dev ? function ?	# Myson MTD803 3-in-1 Ethernet
+ne*	at pci? dev ? function ?	# NE2000-compatible Ethernet
+nfe*	at pci?	dev ? function ?	# NVIDIA nForce Ethernet
+ntwoc*	at pci? dev ? function ?	# Riscom/N2 PCI Sync Serial
+pcn*	at pci? dev ? function ?	# AMD PCnet-PCI Ethernet
+re*	at pci? dev ? function ?	# Realtek 8139C+/8169/8169S/8110S
+rtk*	at pci? dev ? function ?	# Realtek 8129/8139
+sf*	at pci? dev ? function ?	# Adaptec AIC-6915 Ethernet
+sip*	at pci? dev ? function ?	# SiS 900/DP83815 Ethernet
+skc*	at pci? dev ? function ?	# SysKonnect SK9821 Gigabit Ethernet
+sk*	at skc?				# SysKonnect SK9821 Gigabit Ethernet
+ste*	at pci? dev ? function ?	# Sundance ST-201 Ethernet
+stge*	at pci? dev ? function ?	# Sundance/Tamarack TC9021 Gigabit
+ti*	at pci? dev ? function ?	# Alteon ACEnic gigabit Ethernet
+tl*	at pci? dev ? function ?	# ThunderLAN-based Ethernet
+tlp*	at pci? dev ? function ?	# DECchip 21x4x and clones
+txp*	at pci? dev ? function ?	# 3com 3cr990
+vge*	at pci? dev ? function ?	# VIATech VT612X Gigabit Ethernet
+vr*	at pci? dev ? function ?	# VIA Rhine Fast Ethernet
+wi*	at pci? dev ? function ?	# Intersil Prism Mini-PCI (802.11b)
+wm*	at pci? dev ? function ?	# Intel 8254x gigabit
+xge*	at pci? dev ? function ?	# Neterion (S2io) Xframe-I 10GbE
+
+# EISA network interfaces
+ep*	at eisa? slot ?			# 3Com 3c579 Ethernet
+fea*	at eisa? slot ?			# DEC DEFEA FDDI
+tlp*	at eisa? slot ?			# DEC DE-425 Ethernet
+
+# ISA Plug-and-Play network interfaces
+an*	at isapnp?			# Aironet 802.11
+ep*	at isapnp?			# 3Com 3c509 Ethernet
+fmv*	at isapnp?			# Fujitsu FMV-183
+le*	at isapnp?			# AMD PCnet-ISA Ethernet
+ne*	at isapnp?			# NE2000-compatible Ethernet
+tr*	at isapnp?			# IBM/3COM TROPIC Token-Ring
+
+# PCMCIA network interfaces
+an*	at pcmcia? function ?		# Aironet PC4500/PC4800 (802.11)
+awi*	at pcmcia? function ?		# BayStack 650/660 (802.11FH/DS)
+cnw*	at pcmcia? function ?		# Xircom/Netwave AirSurfer
+cs*	at pcmcia? function ?		# CS89xx Ethernet
+ep*	at pcmcia? function ?		# 3Com 3c589 and 3c562 Ethernet
+mbe*	at pcmcia? function ?		# MB8696x based Ethernet
+ne*	at pcmcia? function ?		# NE2000-compatible Ethernet
+ray*	at pcmcia? function ?		# Raytheon Raylink (802.11)
+sm*	at pcmcia? function ?		# Megahertz Ethernet
+# tr at pcmcia has problems with Cardbus bridges
+#tr*	at pcmcia? function ?		# TROPIC based Token-Ring
+wi*	at pcmcia? function ?		# Lucent/Intersil WaveLan IEEE (802.11)
+xirc*	at pcmcia? function ?		# Xircom CreditCard Ethernet
+com*	at xirc?
+xi*	at xirc?
+mhzc*	at pcmcia? function ?		# Megahertz Ethernet/Modem combo cards
+com*	at mhzc?
+sm*	at mhzc?
+
+# ISA network interfaces
+ate0	at isa? port 0x2a0 irq ?		# AT1700
+cs0	at isa? port 0x300 iomem ? irq ? drq ?	# CS8900 Ethernet
+ec0	at isa? port 0x250 iomem 0xd8000 irq 9	# 3Com 3c503 Ethernet
+eg0	at isa? port 0x280 irq 9		# 3C505 ethernet cards
+el0	at isa? port 0x300 irq 9		# 3C501 ethernet cards
+ep*	at isa? port ? irq ?			# 3C509 ethernet cards
+ef0	at isa? port 0x360 iomem 0xd0000 irq 7	# 3C507
+ai0	at isa? port 0x360 iomem 0xd0000 irq 7	# StarLAN
+fmv0	at isa? port 0x2a0 irq ?		# FMV-181/182
+ix0	at isa? port 0x300 irq 10		# EtherExpress/16
+iy0	at isa? port 0x360 irq ?		# EtherExpress PRO 10 ISA
+lc0	at isa? port 0x320 iomem ? irq ?	# DEC EtherWORKS III (LEMAC)
+#depca0	at isa? port 0x300 iomem 0xc8000 iosiz 0x8000 irq 5	# DEPCA
+#le*	at depca?
+nele0	at isa? port 0x320 irq 9 drq 7		# NE2100
+le*	at nele?
+#ntwoc0	at isa? port 0x300 irq 5 iomem 0xc8000 flags 1	# Riscom/N2 sync serial
+bicc0	at isa? port 0x320 irq 10 drq 7		# BICC IsoLan
+le*	at bicc?
+ne0	at isa? port 0x280 irq 9		# NE[12]000 ethernet cards
+ne1	at isa? port 0x300 irq 10
+sm0	at isa? port 0x300 irq 10		# SMC91C9x Ethernet
+tr0	at isa? port 0xa20 iomem 0xd8000 irq ?	# IBM TROPIC based Token-Ring
+tr1	at isa? port 0xa24 iomem 0xd0000 irq ?	# IBM TROPIC based Token-Ring
+tr*	at isa? port ? irq ?			# 3COM TROPIC based Token-Ring
+we0	at isa? port 0x280 iomem 0xd0000 irq 9	# WD/SMC Ethernet
+we1	at isa? port 0x300 iomem 0xcc000 irq 10
+
+# CardBus network cards
+#ath*	at cardbus? dev ? function ?	# Atheros 5210/5211/5212 802.11
+#atw*	at cardbus? dev ? function ?	# ADMtek ADM8211 (802.11)
+#ex*	at cardbus? dev ? function ?	# 3Com 3C575TX
+#fxp*	at cardbus? dev ? function ?	# Intel i8255x
+#rtk*	at cardbus? dev ? function ?	# Realtek 8129/8139
+#tlp*	at cardbus? dev ? function ?	# DECchip 21143
+
+# MCA network cards
+elmc*	at mca? slot ?			# 3Com EtherLink/MC (3c523)
+ep*	at mca? slot ?			# 3Com EtherLink III (3c529)
+we*	at mca? slot ?			# WD/SMC Ethernet
+ate*	at mca? slot ?			# Allied Telesis AT1720
+ne*	at mca? slot ?			# Novell NE/2 and clones
+tr*	at mca? slot ?			# IBM Token Ring adapter
+le*	at mca? slot ?			# SKNET Personal/MC2+
+
+# MII/PHY support
+acphy*	at mii? phy ?			# Altima AC101 and AMD Am79c874 PHYs
+amhphy* at mii? phy ?			# AMD 79c901 Ethernet PHYs
+bmtphy* at mii? phy ?			# Broadcom BCM5201 and BCM5202 PHYs
+brgphy* at mii? phy ?			# Broadcom BCM5400-family PHYs
+ciphy*	at mii? phy ?			# Cicada CS8201 Gig-E PHYs
+dmphy*	at mii? phy ?			# Davicom DM9101 PHYs
+exphy*	at mii? phy ?			# 3Com internal PHYs
+gentbi* at mii? phy ?			# Generic Ten-Bit 1000BASE-[CLS]X PHYs
+glxtphy* at mii? phy ?			# Level One LXT-1000 PHYs
+gphyter* at mii? phy ?			# NS83861 Gig-E PHY
+icsphy* at mii? phy ?			# Integrated Circuit Systems ICS189x
+igphy*	at mii? phy ?			# Intel IGP01E1000
+inphy*	at mii? phy ?			# Intel 82555 PHYs
+iophy*	at mii? phy ?			# Intel 82553 PHYs
+lxtphy* at mii? phy ?			# Level One LXT-970 PHYs
+makphy* at mii? phy ?			# Marvell Semiconductor 88E1000 PHYs
+nsphy*	at mii? phy ?			# NS83840 PHYs
+nsphyter* at mii? phy ? 		# NS83843 PHYs
+pnaphy* at mii? phy ?			# generic HomePNA PHYs
+qsphy*	at mii? phy ?			# Quality Semiconductor QS6612 PHYs
+sqphy*	at mii? phy ?			# Seeq 80220/80221/80223 PHYs
+tlphy*	at mii? phy ?			# ThunderLAN PHYs
+tqphy*	at mii? phy ?			# TDK Semiconductor PHYs
+ukphy*	at mii? phy ?			# generic unknown PHYs
+urlphy* at mii? phy ?			# Realtek RTL8150L internal PHYs
+
+
+# USB Controller and Devices
+
+# PCI USB controllers
+ehci*	at pci?	dev ? function ?	# Enhanced Host Controller
+ohci*	at pci?	dev ? function ?	# Open Host Controller
+uhci*	at pci?	dev ? function ?	# Universal Host Controller (Intel)
+
+# CardBus USB controllers
+#ehci*	at cardbus? dev ? function ?	# Enhanced Host Controller
+#ohci*	at cardbus? dev ? function ?	# Open Host Controller
+
+# ISA USB controllers
+#slhci0	at isa? port 0x300 irq 5	# ScanLogic SL811HS
+
+# USB bus support
+usb*	at ehci?
+usb*	at ohci?
+usb*	at uhci?
+#usb*	at slhci?
+
+# USB Hubs
+uhub*	at usb?
+uhub*	at uhub? port ? configuration ? interface ?
+
+# USB HID device
+uhidev*	at uhub? port ? configuration ? interface ?
+
+# USB Mice
+ums*	at uhidev? reportid ?
+wsmouse* at ums? mux 0
+
+# USB eGalax touch-panel
+uep*	at uhub? port ?
+wsmouse* at uep? mux 0
+
+# USB Keyboards
+ukbd*	at uhidev? reportid ?
+wskbd*	at ukbd? console ? mux 1
+
+# USB Generic HID devices
+uhid*	at uhidev? reportid ?
+
+# USB Printer
+ulpt*	at uhub? port ? configuration ? interface ?
+
+# USB Modem
+umodem*	at uhub? port ? configuration ?
+ucom*	at umodem?
+
+# USB Mass Storage
+umass*	at uhub? port ? configuration ? interface ?
+scsibus* at umass?
+wd*	at umass?
+
+# USB audio
+uaudio*	at uhub? port ? configuration ?
+
+# USB MIDI
+umidi* at uhub? port ? configuration ?
+
+# USB IrDA
+# USB-IrDA bridge spec
+uirda* at uhub? port ? configuration ? interface ?
+irframe* at uirda?
+
+# SigmaTel STIr4200 USB/IrDA Bridge
+ustir* at uhub? port ?
+irframe* at ustir?
+
+# USB Ethernet adapters
+aue*	at uhub? port ?		# ADMtek AN986 Pegasus based adapters
+axe*	at uhub? port ?		# ASIX AX88172 based adapters
+cdce*	at uhub? port ?		# CDC, Ethernet Networking Control Model
+cue*	at uhub? port ?		# CATC USB-EL1201A based adapters
+kue*	at uhub? port ?		# Kawasaki LSI KL5KUSB101B based adapters
+udav*	at uhub? port ?		# Davicom DM9601 based adapters
+url*	at uhub? port ?		# Realtek RTL8150L based adapters
+
+# USB 802.11b adapters
+atu*	at uhub? port ?		# Atmel AT76C50XX based adapters
+
+# Prolific PL2301/PL2302 host-to-host adapter
+upl*	at uhub? port ?
+
+# Serial adapters
+ubsa*	at uhub? port ?		# Belkin serial adapter
+ucom*	at ubsa? portno ?
+
+uftdi*	at uhub? port ?		# FTDI FT8U100AX serial adapter
+ucom*	at uftdi? portno ?
+
+umct*	at uhub? port ?		# MCT USB-RS232 serial adapter
+ucom*	at umct? portno ?
+
+uplcom* at uhub? port ? 	# I/O DATA USB-RSAQ2 serial adapter
+ucom*	at uplcom? portno ?
+
+uvscom* at uhub? port ? 	# SUNTAC Slipper U VS-10U serial adapter
+ucom*	at uvscom? portno ?
+
+# Diamond Multimedia Rio 500
+urio*	at uhub? port ?
+
+# USB Handspring Visor
+uvisor*	at uhub? port ?
+ucom*	at uvisor?
+
+# Kyocera AIR-EDGE PHONE
+ukyopon* at uhub? port ?
+ucom*	at ukyopon? portno ?
+
+# USB scanners
+uscanner* at uhub? port ?
+
+# USB scanners that use SCSI emulation, e.g., HP5300
+usscanner* at uhub? port ?
+
+# Y@P firmware loader
+uyap* at uhub? port ?
+
+# D-Link DSB-R100 USB radio
+udsbr*	at uhub? port ?
+radio*	at udsbr?
+
+# USB Generic driver
+ugen*	at uhub? port ?
+
+
+# IrDA and Consumer Ir devices
+
+# Toshiba Oboe
+oboe* 	at pci? dev ? function ?
+irframe* at oboe?
+
+# PCI IEEE1394 controllers
+#fwohci* at pci? dev ? function ?	# IEEE1394 Open Host Controller
+
+# CardBus IEEE1394 controllers
+#fwohci* at cardbus? dev ? function ?	# IEEE1394 Open Host Controller
+
+#fw*	at fwbus?			# IP over 1394
+
+# IEEE1394 nodes
+#fwnode* at fwbus? idhi ? idlo ?
+#sbpscsi* at fwnode?
+#scsibus* at sbpscsi?
+
+# Audio Devices
+
+# PCI audio devices
+auacer* at pci? dev ? function ?	# ALi M5455 integrated AC'97 Audio
+auich*	at pci? dev ? function ?	# Intel ICH integrated AC'97 Audio
+auixp*	at pci? dev ? function ?	# ATI IXP AC'97 Audio
+autri*	at pci? dev ? function ?	# Trident 4DWAVE based AC'97 Audio
+auvia*	at pci? dev ? function ?	# VIA VT82C686A integrated AC'97 Audio
+azalia*	at pci? dev ? function ?	# High Definition Audio
+clcs*	at pci? dev ? function ?	# Cirrus Logic CS4280
+clct*	at pci? dev ? function ?	# Cirrus Logic CS4281
+cmpci*	at pci? dev ? function ?	# C-Media CMI8338/8738
+eap*	at pci? dev ? function ?	# Ensoniq AudioPCI
+emuxki* at pci? dev ? function ?	# Creative SBLive! and PCI512
+esa*	at pci? dev ? function ?	# ESS Allegro-1 / Maestro-3 PCI Audio
+esm*	at pci? dev ? function ?	# ESS Maestro-1/2/2e PCI Audio Accelerator
+eso*	at pci? dev ? function ?	# ESS Solo-1 PCI AudioDrive
+fms*	at pci? dev ? function ?	# Forte Media FM801
+neo*	at pci? dev ? function ?	# NeoMagic 256 AC'97 Audio
+sv*	at pci? dev ? function ?	# S3 SonicVibes
+yds*	at pci? dev ? function ?	# Yamaha DS-1 PCI Audio
+
+# ISA Plug-and-Play audio devices
+ess*	at isapnp?			# ESS Tech ES1887, ES1888, ES888 audio
+guspnp* at isapnp?			# Gravis Ultra Sound PnP audio
+sb*	at isapnp?			# SoundBlaster-compatible audio
+wss*	at isapnp?			# Windows Sound System
+ym*	at isapnp?			# Yamaha OPL3-SA3 audio
+
+# ISA audio devices
+# the "aria" probe might give false hits
+#aria0	at isa? port 0x290 irq 10 		# Aria
+#ess0	at isa? port 0x220 irq 5 drq 1 drq2 5	# ESS 18XX
+gus0	at isa? port 0x220 irq 7 drq 1 drq2 6	# Gravis Ultra Sound
+pas0	at isa? port 0x220 irq 7 drq 1		# ProAudio Spectrum
+#pss0	at isa? port 0x220 irq 7 drq 6		# Personal Sound System
+#sp0	at pss0 port 0x530 irq 10 drq 0		# 	sound port driver
+sb0	at isa? port 0x220 irq 5 drq 1 drq2 5	# SoundBlaster
+wss0	at isa? port 0x530 irq 10 drq 0	drq2 1	# Windows Sound System
+
+# PCMCIA audio devices
+#esl*	at pcmcia? function ?			# ESS 1688 AudioDrive
+
+#cms0	at isa? port 0x220			# Creative Music System
+
+# OPL[23] FM synthesizers
+#opl0	at isa? port 0x388	# use only if not attached to sound card
+opl*	at cmpci? flags 1
+#opl*	at esl?
+opl*	at eso?
+opl*	at ess?
+opl*	at fms?
+opl*	at sb?
+opl*	at sv?
+opl*	at wss?
+opl*	at yds?
+opl*	at ym?
+
+# Audio support
+audio*	at audiobus?
+
+# MPU 401 UARTs
+#mpu*	at isa? port 0x330 irq 9	# MPU401 or compatible card
+mpu*	at cmpci?
+mpu*	at eso?
+mpu*	at fms?
+mpu*	at sb?
+mpu*	at yds?
+mpu*	at ym?
+
+# MIDI support
+midi*	at midibus?
+midi*	at pcppi?		# MIDI interface to the PC speaker
+
+# The spkr driver provides a simple tone interface to the built in speaker.
+#spkr0	at pcppi?		# PC speaker
+
+
+# FM-Radio devices
+# ISA radio devices
+#az0	at isa? port 0x350      # Aztech/PackardBell FM Radio Card
+#az1	at isa? port 0x358
+#rt0	at isa? port 0x20c      # AIMS Lab Radiotrack & compatible
+#rt1	at isa? port 0x284
+#rt2	at isa? port 0x30c
+#rt3	at isa? port 0x384
+#rtii0	at isa? port 0x20c      # AIMS Lab Radiotrack II FM Radio Card
+#rtii1	at isa? port 0x30c
+#sf2r0	at isa? port 0x384      # SoundForte RadioLink SF16-FMR2 FM Radio Card
+
+# PCI radio devices
+#gtp*	at pci? dev ? function ? # Guillemot Maxi Radio FM 2000 Radio Card
+
+# Radio support
+#radio*	at az?
+#radio*	at gtp?
+#radio*	at rt?
+#radio*	at rtii?
+#radio*	at sf2r?
+
+
+# TV cards
+
+# Brooktree 848/849/878/879 based TV cards
+bktr* at pci? dev ? function ?
+radio* at bktr?
+
+
+# Mice
+
+# ISA busmice
+lms0	at isa? port 0x23c irq 5	# Logitech bus mouse
+lms1	at isa? port 0x238 irq 5
+mms0	at isa? port 0x23c irq 5	# Microsoft InPort mouse
+mms1	at isa? port 0x238 irq 5
+wsmouse*	at lms? mux 0
+wsmouse*	at mms? mux 0
+
+
+# Cryptographic Devices
+
+# PCI cryptographic devices
+hifn*	at pci? dev ? function ?	# Hifn 7755/7811/795x
+ubsec*	at pci? dev ? function ?	# Broadcom 5501/5601/580x/582x
+
+
+# Joysticks
+
+#joy*	at pnpbios? index ?		# Game port
+
+# ISA Plug-and-Play joysticks
+joy*	at isapnp?			# Game ports (usually on audio cards)
+
+# PCI joysticks
+joy*	at pci?				# Game ports (usually on audio cards)
+joy*	at eso?				# ESS Solo-1 on-board joystick
+
+# ISA joysticks. Probe is a little strange; add only if you have one.
+#joy0	at isa? port 0x201
+
+
+# Miscellaneous Devices
+
+geodewdog* at pci? dev ? function ?	# AMD Geode SC1100 watchdog timer
+
+# Planetconnect Satellite receiver driver.
+#satlink0 at isa? port 0x300 drq 1
+
+# Middle Digital, Inc. PCI-Weasel serial console board control
+# devices (watchdog timer, etc.)
+weasel* at pci?
+
+# Pull in optional local configuration
+include	"arch/i386/conf/GENERIC.local"
+
+
+# Pseudo-Devices
+
+pseudo-device 	crypto		# opencrypto framework
+
+# disk/mass storage pseudo-devices
+pseudo-device	ccd		4	# concatenated/striped disk devices
+#pseudo-device	cgd		4	# cryptographic disk devices
+pseudo-device	raid		8	# RAIDframe disk driver
+options 	RAID_AUTOCONFIG		# auto-configuration of RAID components
+# Options to enable various other RAIDframe RAID types.
+#options 	RF_INCLUDE_EVENODD=1
+#options 	RF_INCLUDE_RAID5_RS=1
+#options 	RF_INCLUDE_PARITYLOGGING=1
+#options 	RF_INCLUDE_CHAINDECLUSTER=1
+#options 	RF_INCLUDE_INTERDECLUSTER=1
+#options 	RF_INCLUDE_PARITY_DECLUSTERING=1
+#options 	RF_INCLUDE_PARITY_DECLUSTERING_DS=1
+pseudo-device	fss		4	# file system snapshot device
+
+# Vinum
+# pseudo-device	vinum		8	# Vinum
+# options 	VINUMDEBUG
+
+pseudo-device	md		1	# memory disk device (ramdisk)
+pseudo-device	vnd		4	# disk-like interface to files
+options 	VND_COMPRESSION		# compressed vnd(4)
+
+# network pseudo-devices
+pseudo-device	bpfilter	8	# Berkeley packet filter
+pseudo-device	ipfilter		# IP filter (firewall) and NAT
+pseudo-device	loop			# network loopback
+pseudo-device	ppp		2	# Point-to-Point Protocol
+pseudo-device	pppoe			# PPP over Ethernet (RFC 2516)
+pseudo-device	sl		2	# Serial Line IP
+pseudo-device	strip		2	# Starmode Radio IP (Metricom)
+pseudo-device	irframetty		# IrDA frame line discipline
+pseudo-device	tap			# virtual Ethernet
+pseudo-device	tun		2	# network tunneling over tty
+pseudo-device	gre		2	# generic L3 over IP tunnel
+pseudo-device	gif		4	# IPv[46] over IPv[46] tunnel (RFC1933)
+#pseudo-device	faith		1	# IPv[46] tcp relay translation i/f
+#pseudo-device	stf		1	# 6to4 IPv6 over IPv4 encapsulation
+pseudo-device	vlan			# IEEE 802.1q encapsulation
+pseudo-device	bridge			# simple inter-network bridging
+#options 	BRIDGE_IPF		# bridge uses IP/IPv6 pfil hooks too
+#pseudo-device	pf			# PF packet filter
+#pseudo-device	pflog			# PF log if
+
+# miscellaneous pseudo-devices
+pseudo-device	pty			# pseudo-terminals
+pseudo-device	tb		1	# tablet line discipline
+pseudo-device	sequencer	1	# MIDI sequencer
+# rnd works; RND_COM does not on port i386 yet.
+pseudo-device	rnd			# /dev/random and in-kernel generator
+#options 	RND_COM			# use "com" randomness as well (BROKEN)
+pseudo-device	clockctl		# user control of clock subsystem
+
+# a pseudo device needed for Coda	# also needs CODA (above)
+pseudo-device	vcoda		4	# coda minicache <-> venus comm.
+
+# a pseudo device needed for SMBFS
+pseudo-device	nsmb			# experimental - SMB requester
+
+# a pseudo device needed for verified exec
+#pseudo-device veriexec		1
+
+# wscons pseudo-devices
+pseudo-device	wsmux			# mouse & keyboard multiplexor
+pseudo-device	wsfont
+pseudo-device	ksyms			# /dev/ksyms
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/db_trace.c mult-netbsd-3.1/sys/arch/i386/i386/db_trace.c
--- NetBSD-3.1/sys/arch/i386/i386/db_trace.c	2004-02-28 20:30:58.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/db_trace.c	2007-11-10 19:27:10.000000000 +0000
@@ -395,7 +395,8 @@
 			struct user *u;
 			struct lwp *l;
 			(*pr)("trace: pid %d ", (int)addr);
-			p = pfind(addr);
+			/* FIXME - instances */
+			p = pfind(NULL, addr);
 			if (p == NULL) {
 				(*pr)("not found\n");
 				return;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/freebsd_syscall.c mult-netbsd-3.1/sys/arch/i386/i386/freebsd_syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/freebsd_syscall.c	2004-02-13 18:57:19.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/freebsd_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -42,7 +42,6 @@
 #if defined(_KERNEL_OPT)
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/param.h>
@@ -54,9 +53,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/ibcs2_syscall.c mult-netbsd-3.1/sys/arch/i386/i386/ibcs2_syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/ibcs2_syscall.c	2004-02-13 18:57:19.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/ibcs2_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -43,7 +43,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_vm86.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/param.h>
@@ -55,9 +54,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/linux_syscall.c mult-netbsd-3.1/sys/arch/i386/i386/linux_syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/linux_syscall.c	2004-02-13 18:57:19.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/linux_syscall.c	2007-11-09 18:08:20.000000000 +0000
@@ -43,7 +43,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_vm86.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/param.h>
@@ -55,9 +54,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/mach_machdep.c mult-netbsd-3.1/sys/arch/i386/i386/mach_machdep.c
--- NetBSD-3.1/sys/arch/i386/i386/mach_machdep.c	2004-02-13 11:36:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/mach_machdep.c	2007-11-18 14:10:50.000000000 +0000
@@ -170,6 +170,7 @@
 	 * Copy right from parent. Will disaprear
 	 * the day we will have struct lwp.  
 	 */
+	KASSERT(p->p_pptr);
 	mach_copy_right(p->p_pptr, p); 
 
 	tf = trapframe(p);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/mach_syscall.c mult-netbsd-3.1/sys/arch/i386/i386/mach_syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/mach_syscall.c	2003-10-31 03:28:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/mach_syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -42,7 +42,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_vm86.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,9 +52,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/svr4_syscall.c mult-netbsd-3.1/sys/arch/i386/i386/svr4_syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/svr4_syscall.c	2004-02-13 18:57:19.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/i386/i386/svr4_syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -43,7 +43,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_vm86.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #endif
 
 #include <sys/param.h>
@@ -55,9 +54,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/syscall.c mult-netbsd-3.1/sys/arch/i386/i386/syscall.c
--- NetBSD-3.1/sys/arch/i386/i386/syscall.c	2004-09-30 22:32:27.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/i386/i386/syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -42,7 +42,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_vm86.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,9 +52,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/i386/i386/trap.c mult-netbsd-3.1/sys/arch/i386/i386/trap.c
--- NetBSD-3.1/sys/arch/i386/i386/trap.c	2005-10-11 22:04:19.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/i386/i386/trap.c	2007-11-12 16:59:26.000000000 +0000
@@ -101,6 +101,7 @@
 #include <sys/ucontext.h>
 #include <sys/sa.h>
 #include <sys/savar.h>
+#include <sys/inst.h>
 #include <uvm/uvm_extern.h>
 
 #include <machine/cpu.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/m68k/m68k/linux_syscall.c mult-netbsd-3.1/sys/arch/m68k/m68k/linux_syscall.c
--- NetBSD-3.1/sys/arch/m68k/m68k/linux_syscall.c	2003-10-31 03:28:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/m68k/m68k/linux_syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -115,7 +115,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_execfmt.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,9 +127,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <machine/psl.h>
 #include <machine/cpu.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/m68k/m68k/m68k_syscall.c mult-netbsd-3.1/sys/arch/m68k/m68k/m68k_syscall.c
--- NetBSD-3.1/sys/arch/m68k/m68k/m68k_syscall.c	2004-08-28 23:06:28.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/m68k/m68k/m68k_syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -115,7 +115,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_execfmt.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_compat_netbsd.h"
 #include "opt_compat_aout_m68k.h"
 
@@ -131,9 +130,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <machine/psl.h>
 #include <machine/cpu.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/m68k/m68k/sunos_syscall.c mult-netbsd-3.1/sys/arch/m68k/m68k/sunos_syscall.c
--- NetBSD-3.1/sys/arch/m68k/m68k/sunos_syscall.c	2003-10-31 03:28:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/m68k/m68k/sunos_syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -115,7 +115,6 @@
 #include "opt_syscall_debug.h"
 #include "opt_execfmt.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -128,9 +127,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <machine/psl.h>
 #include <machine/cpu.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/mips/mips/syscall.c mult-netbsd-3.1/sys/arch/mips/mips/syscall.c
--- NetBSD-3.1/sys/arch/mips/mips/syscall.c	2004-04-04 06:32:20.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/mips/mips/syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -118,7 +118,6 @@
 
 #if defined(_KERNEL_OPT)
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_syscall_debug.h"
 #endif
 
@@ -130,9 +129,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 #include <sys/sa.h>
 #include <sys/savar.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/pc532/pc532/trap.c mult-netbsd-3.1/sys/arch/pc532/pc532/trap.c
--- NetBSD-3.1/sys/arch/pc532/pc532/trap.c	2005-01-31 07:18:52.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/pc532/pc532/trap.c	2007-11-09 18:08:21.000000000 +0000
@@ -83,7 +83,6 @@
 #include "opt_kgdb.h"
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_ns381.h"
 
 #include <sys/param.h>
@@ -99,9 +98,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/syscall.h>
 #ifdef KGDB
 #include <sys/kgdb.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/powerpc/ibm4xx/trap.c mult-netbsd-3.1/sys/arch/powerpc/ibm4xx/trap.c
--- NetBSD-3.1/sys/arch/powerpc/ibm4xx/trap.c	2005-02-25 07:09:58.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/powerpc/ibm4xx/trap.c	2007-11-09 18:08:21.000000000 +0000
@@ -72,7 +72,6 @@
 #include "opt_altivec.h"
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_syscall_debug.h"
 
 #include <sys/param.h>
@@ -87,9 +86,6 @@
 #include <sys/pool.h>
 #include <sys/sa.h>
 #include <sys/savar.h>
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/userret.h>
 
 #include <uvm/uvm_extern.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/powerpc/powerpc/db_interface.c mult-netbsd-3.1/sys/arch/powerpc/powerpc/db_interface.c
--- NetBSD-3.1/sys/arch/powerpc/powerpc/db_interface.c	2003-12-17 04:04:40.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/powerpc/powerpc/db_interface.c	2007-11-23 10:17:18.000000000 +0000
@@ -13,6 +13,7 @@
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
+#include <sys/inst.h>
 
 #include <dev/cons.h>
 
@@ -207,18 +208,29 @@
 static void
 db_ppc4xx_ctx(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
 {
-	struct proc *p;
+	struct proc 	*p;
+	struct isnt	*i;
 
-	/* XXX LOCKING XXX */
-	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
-		if (p->p_stat) {
-			db_printf("process %p:", p);
-			db_printf("pid:%d pmap:%p ctx:%d %s\n",
-				p->p_pid, p->p_vmspace->vm_map.pmap,
-				p->p_vmspace->vm_map.pmap->pm_ctx,
-				p->p_comm);
+	instlist_lock_read();
+
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		for (p = i->i_allproc.lh_first; p; 
+				p = p->p_list.le_next) {
+			if (p->p_stat) {
+				db_printf("process %p:", p);
+				db_printf("pid:%d pmap:%p ctx:%d %s\n",
+					p->p_pid, 
+					p->p_vmspace->vm_map.pmap,
+					p->p_vmspace->vm_map.pmap->pm_ctx,
+					p->p_comm);
+			}
 		}
+		proclist_unlock_read(i);
 	}
+
+	instlist_unlock_read();
+
 	return;
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/powerpc/powerpc/syscall.c mult-netbsd-3.1/sys/arch/powerpc/powerpc/syscall.c
--- NetBSD-3.1/sys/arch/powerpc/powerpc/syscall.c	2003-10-31 03:28:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/powerpc/powerpc/syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -34,7 +34,6 @@
 
 #include "opt_altivec.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_multiprocessor.h"
 /* DO NOT INCLUDE opt_compat_XXX.h */
 /* If needed, they will be included by file that includes this one */
@@ -49,9 +48,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <uvm/uvm_extern.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sh3/sh3/db_interface.c mult-netbsd-3.1/sys/arch/sh3/sh3/db_interface.c
--- NetBSD-3.1/sys/arch/sh3/sh3/db_interface.c	2005-03-08 22:04:22.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sh3/sh3/db_interface.c	2007-11-23 10:17:18.000000000 +0000
@@ -350,13 +350,23 @@
 char *
 __db_procname_by_asid(int asid)
 {
-	static char notfound[] = "---";
-	struct proc *p;
-
-	LIST_FOREACH(p, &allproc, p_list) {
-		if (p->p_vmspace->vm_map.pmap->pm_asid == asid)
+	static char 	notfound[] = "---";
+	struct proc 	*p;
+	struct inst	*i;
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(p, &i->i_allproc, p_list) {
+			if (p->p_vmspace->vm_map.pmap->pm_asid != asid)
+				continue;
+			proclist_unlock_read(i);
+			instlist_unlock_read();
 			return (p->p_comm);
+		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
 
 	return (notfound);
 }
@@ -577,12 +587,13 @@
 void
 db_stackcheck_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
 {
-	struct lwp *l;
-	struct user *u;
-	struct pcb *pcb;
-	uint32_t *t32;
-	uint8_t *t8;
-	int i, j;
+	struct lwp 	*l;
+	struct user 	*u;
+	struct pcb 	*pcb;
+	uint32_t 	*t32;
+	uint8_t 	*t8;
+	int 		i, j;
+	struct inst	*inst;
 
 #define	MAX_STACK	(USPACE - PAGE_SIZE)
 #define	MAX_FRAME	(PAGE_SIZE - sizeof(struct user))
@@ -594,28 +605,34 @@
 		  "stack top    max used    frame top     max used"
 		  "  nest\n");
 
-	LIST_FOREACH(l, &alllwp, l_list) {
-		u = l->l_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.%-6d 0x%08x %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
-		    l->l_proc->p_pid, l->l_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),
-		    l->l_proc->p_comm);
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) {
+		proclist_lock_read(inst);
+		LIST_FOREACH(l, &inst->i_alllwp, l_list) {
+			u = l->l_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.%-6d 0x%08x %6d (%3d%%) 0x%08lx %6d (%3d%%) %d %s\n",
+					l->l_proc->p_pid, l->l_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),
+					l->l_proc->p_comm);
+		}
+		proclist_unlock_read();
 	}
+	instlist_unlock_read();
 #undef	MAX_STACK
 #undef	MAX_FRAME
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sh3/sh3/exception.c mult-netbsd-3.1/sys/arch/sh3/sh3/exception.c
--- NetBSD-3.1/sys/arch/sh3/sh3/exception.c	2004-03-24 15:38:41.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sh3/sh3/exception.c	2007-11-09 18:08:21.000000000 +0000
@@ -85,7 +85,6 @@
 #include "opt_kgdb.h"
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -101,9 +100,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #ifdef DDB
 #include <sh3/db_machdep.h>
 #endif
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sh3/sh3/pmap.c mult-netbsd-3.1/sys/arch/sh3/sh3/pmap.c
--- NetBSD-3.1/sys/arch/sh3/sh3/pmap.c	2003-12-30 12:33:19.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sh3/sh3/pmap.c	2007-11-23 10:17:18.000000000 +0000
@@ -971,8 +971,9 @@
 int
 __pmap_asid_alloc()
 {
-	struct proc *p;
-	int i, j, k, n, map, asid;
+	struct proc 	*p;
+	int 		i, j, k, n, map, asid;
+	struct inst	*inst;
 
 	/* Search free ASID */
 	i = __pmap_asid.hint >> 5;
@@ -990,17 +991,25 @@
 	}
 
 	/* 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);
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) {
+		proclist_lock_read(inst);
+		LIST_FOREACH(p, &inst->i_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);
+				proclist_unlock_read(inst);
+				instlist_unlock_read();
+				return (__pmap_asid.hint);
+			}
 		}
+		proclist_unlock_read(inst);
 	}
+	instlist_unlock_read();
 
 	panic("No ASID allocated.");
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sh5/sh5/syscall.c mult-netbsd-3.1/sys/arch/sh5/sh5/syscall.c
--- NetBSD-3.1/sys/arch/sh5/sh5/syscall.c	2003-10-31 03:28:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sh5/sh5/syscall.c	2007-11-09 18:08:21.000000000 +0000
@@ -134,7 +134,6 @@
 
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -149,9 +148,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <machine/cpu.h>
 #include <machine/trap.h>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sparc/sparc/trap.c mult-netbsd-3.1/sys/arch/sparc/sparc/trap.c
--- NetBSD-3.1/sys/arch/sparc/sparc/trap.c	2005-02-03 16:15:06.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sparc/sparc/trap.c	2007-11-09 18:08:21.000000000 +0000
@@ -53,7 +53,6 @@
 
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_compat_svr4.h"
 #include "opt_compat_sunos.h"
 #include "opt_sparc_arch.h"
@@ -76,9 +75,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <uvm/uvm_extern.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sparc64/sparc64/db_interface.c mult-netbsd-3.1/sys/arch/sparc64/sparc64/db_interface.c
--- NetBSD-3.1/sys/arch/sparc64/sparc64/db_interface.c	2005-10-30 18:18:13.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sparc64/sparc64/db_interface.c	2007-11-23 10:17:19.000000000 +0000
@@ -865,25 +865,31 @@
 	db_expr_t count;
 	char *modif;
 {
-	struct proc *p;
-	struct lwp *l;
-
-	/* 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\n",
-				p->p_pid, p->p_vmspace->vm_map.pmap,
-				p->p_vmspace->vm_map.pmap->pm_ctx);
-			LIST_FOREACH(l, &p->p_lwps, l_sibling) {
-				db_printf("\tlwp %p: lid:%d tf:%p fpstate %p "
-					"lastcall:%s\n",
-					l, l->l_lid, l->l_md.md_tf, l->l_md.md_fpstate,
-					(l->l_addr->u_pcb.lastcall)?
-					l->l_addr->u_pcb.lastcall : "Null");
+	struct proc 	*p;
+	struct lwp 	*l;
+	struct inst	*i;
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(p, &i->i_allproc, p_list) {
+			if (p->p_stat) {
+				db_printf("process %p:", p);
+				db_printf("pid:%d pmap:%p ctx:%x\n",
+						p->p_pid, p->p_vmspace->vm_map.pmap,
+						p->p_vmspace->vm_map.pmap->pm_ctx);
+				LIST_FOREACH(l, &p->p_lwps, l_sibling) {
+					db_printf("\tlwp %p: lid:%d tf:%p fpstate %p "
+							"lastcall:%s\n",
+							l, l->l_lid, l->l_md.md_tf, l->l_md.md_fpstate,
+							(l->l_addr->u_pcb.lastcall)?
+							l->l_addr->u_pcb.lastcall : "Null");
+				}
 			}
 		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
 	return;
 }
 
@@ -940,31 +946,41 @@
 	db_expr_t count;
 	char *modif;
 {
-	struct proc *p, *pp;
+	struct proc 	*p;
+	struct inst	*i;
 
 	if (!have_addr) {
 		db_printf("What PID do you want to map in?\n");
 		return;
 	}
-    
-	LIST_FOREACH(p, &allproc, p_list) {
-		pp = p->p_pptr;
-		if (p->p_stat && p->p_pid == addr) {
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(p, &i->i_allproc, p_list) {
+			if (p->p_stat && p->p_pid == addr) {
 #if 0
-/* XXX Do we need to do the following too?: */
-			extern struct pcb *cpcb;
+				/* XXX Do we need to do the following too? */
+				extern struct pcb *cpcb;
 
-			curlwp = p;
-			cpcb = (struct pcb*)p->p_addr;
+				curlwp = p;
+				cpcb = (struct pcb*)p->p_addr;
 #endif
-			if (p->p_vmspace->vm_map.pmap->pm_ctx) {
-				switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
+				if (p->p_vmspace->vm_map.pmap->pm_ctx) {
+					switchtoctx(p->p_vmspace->vm_map.pmap->pm_ctx);
+					proclist_unlock_read(i);
+					instlist_unlock_read();
+					return;
+				}
+				db_printf("PID %ld has a null context.\n", addr);
+				proclist_unlock_read(i);
+				instlist_unlock_read();
 				return;
 			}
-			db_printf("PID %ld has a null context.\n", addr);
-			return;
 		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
 	db_printf("PID %ld not found.\n", addr);
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/sparc64/sparc64/trap.c mult-netbsd-3.1/sys/arch/sparc64/sparc64/trap.c
--- NetBSD-3.1/sys/arch/sparc64/sparc64/trap.c	2005-02-12 09:38:28.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/sparc64/sparc64/trap.c	2007-11-09 18:08:21.000000000 +0000
@@ -57,7 +57,6 @@
 #include "opt_ddb.h"
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_compat_svr4.h"
 #include "opt_compat_netbsd32.h"
 
@@ -80,9 +79,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #include <uvm/uvm_extern.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/vax/vax/pmap.c mult-netbsd-3.1/sys/arch/vax/vax/pmap.c
--- NetBSD-3.1/sys/arch/vax/vax/pmap.c	2004-03-19 20:17:51.000000000 +0000
+++ mult-netbsd-3.1/sys/arch/vax/vax/pmap.c	2007-11-23 10:17:19.000000000 +0000
@@ -670,43 +670,51 @@
 static int
 pmap_rmproc(struct pmap *pm)
 {
-	struct pmap *ppm;
-	struct lwp *l;
-	struct lwp *outl, *outl2;
-	int outpri, outpri2;
-	int didswap = 0;
-	extern int maxslp;
+	struct pmap 	*ppm;
+	struct lwp 	*l;
+	struct lwp 	*outl, *outl2;
+	int 		outpri, outpri2;
+	int 		didswap = 0;
+	struct inst	*i;
+
+	extern int 	maxslp;
 
 	outl = outl2 = NULL;
 	outpri = outpri2 = 0;
-	proclist_lock_read();
-	LIST_FOREACH(l, &alllwp, l_list) {
-		if (!swappable(l, pm))
-			continue;
-		ppm = l->l_proc->p_vmspace->vm_map.pmap;
-		if (ppm->pm_p0lr == 0 && ppm->pm_p1lr == NPTEPERREG)
-			continue; /* Already swapped */
-		switch (l->l_stat) {
-		case LSRUN:
-		case LSONPROC:
-			if (l->l_swtime > outpri2) {
-				outl2 = l;
-				outpri2 = l->l_swtime;
-			}
-			continue;
-		case LSSLEEP:
-		case LSSTOP:
-			if (l->l_slptime >= maxslp) {
-				rmspace(l->l_proc->p_vmspace->vm_map.pmap);
-				didswap++;
-			} else if (l->l_slptime > outpri) {
-				outl = l;
-				outpri = l->l_slptime;
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			if (!swappable(l, pm))
+				continue;
+			ppm = l->l_proc->p_vmspace->vm_map.pmap;
+			if (ppm->pm_p0lr == 0 && ppm->pm_p1lr == NPTEPERREG)
+				continue; /* Already swapped */
+			switch (l->l_stat) {
+			case LSRUN:
+			case LSONPROC:
+				if (l->l_swtime > outpri2) {
+					outl2 = l;
+					outpri2 = l->l_swtime;
+				}
+				continue;
+			case LSSLEEP:
+			case LSSTOP:
+				if (l->l_slptime >= maxslp) {
+					rmspace(l->l_proc->p_vmspace->vm_map.pmap);
+					didswap++;
+				} else if (l->l_slptime > outpri) {
+					outl = l;
+					outpri = l->l_slptime;
+				}
+				continue;
 			}
-			continue;
 		}
+		proclist_unlock_read(i);
 	}
-	proclist_unlock_read();
+	instlist_unlock_read();
+
 	if (didswap == 0) {
 		if ((l = outl) == NULL)
 			l = outl2;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/arch/vax/vax/trap.c mult-netbsd-3.1/sys/arch/vax/vax/trap.c
--- NetBSD-3.1/sys/arch/vax/vax/trap.c	2004-09-02 03:18:38.000000000 +0100
+++ mult-netbsd-3.1/sys/arch/vax/vax/trap.c	2007-11-09 18:08:21.000000000 +0000
@@ -37,7 +37,6 @@
 
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_multiprocessor.h"
 
 #include <sys/types.h>
@@ -68,9 +67,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 #ifdef TRAPDEBUG
 volatile int startsysc = 0, faultdebug = 0;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/common/kern_info_09.c mult-netbsd-3.1/sys/compat/common/kern_info_09.c
--- NetBSD-3.1/sys/compat/common/kern_info_09.c	2003-12-04 19:38:22.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/common/kern_info_09.c	2007-11-09 18:23:29.000000000 +0000
@@ -43,6 +43,7 @@
 #include <sys/unistd.h>
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
+#include <sys/inst.h>
 
 #include <sys/mount.h>
 #include <sys/sa.h>
@@ -102,7 +103,9 @@
 	char *dp, *ep;
 
 	strncpy(outsname.sysname, ostype, sizeof(outsname.sysname));
-	strncpy(outsname.nodename, hostname, sizeof(outsname.nodename));
+	if (NULL != l)
+		strncpy(outsname.nodename, l->l_inst->i_host, 
+				sizeof(outsname.nodename));
 	strncpy(outsname.release, osrelease, sizeof(outsname.release));
 	dp = outsname.version;
 	ep = &outsname.version[sizeof(outsname.version) - 1];
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/common/kern_info_43.c mult-netbsd-3.1/sys/compat/common/kern_info_43.c
--- NetBSD-3.1/sys/compat/common/kern_info_43.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/common/kern_info_43.c	2007-11-09 18:23:29.000000000 +0000
@@ -49,6 +49,7 @@
 #include <sys/syslog.h>
 #include <sys/unistd.h>
 #include <sys/resourcevar.h>
+#include <sys/inst.h>
 
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
@@ -222,11 +223,26 @@
 				size = sizeof(ksi) +
 				    strlen(ostype) + strlen(cpu_model) +
 				    strlen(osrelease) + strlen(machine) +
-				    strlen(version) + strlen(hostname) + 6;
+				    strlen(version) + 6;
+				if (NULL != l)
+					size += inst_get_hostnamelen(l);
 				error = 0;
 				break;
 			}
 
+			/*
+			 * FIXME.  Ugly hack to switch on instance
+			 * "soft" resources versus hard-coded machine
+			 * ones.  
+			 */
+#define COPYINST(fld, key)						\
+			ksi.fld = us - (u_long) usi;			\
+			error = inst_copyoutstr_hostname		\
+					(l, us, 1024, &len);		\
+			if (0 != error)					\
+				return(error);				\
+			us += len
+				
 #define COPY(fld)							\
 			ksi.fld = us - (u_long) usi;			\
 			if ((error = copyoutstr(fld, us, 1024, &len)) != 0)\
@@ -256,7 +272,7 @@
 			ksi.child_max = CHILD_MAX;
 
 			ksi.boottime = boottime;
-			COPY(hostname);
+			COPYINST(hostname, i_host);
 
 			size = (us - (char *) &usi[1]) + sizeof(ksi);
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/darwin/darwin_ptrace.c mult-netbsd-3.1/sys/compat/darwin/darwin_ptrace.c
--- NetBSD-3.1/sys/compat/darwin/darwin_ptrace.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/darwin/darwin_ptrace.c	2007-11-10 19:27:10.000000000 +0000
@@ -79,9 +79,12 @@
 
 	ded = (struct darwin_emuldata *)p->p_emuldata;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	switch (req) {
 	case DARWIN_PT_ATTACHEXC:
-		if ((t = pfind(SCARG(uap, pid))) == NULL)
+		if ((t = pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 
 		if (t->p_emul != &emul_darwin)
@@ -110,7 +113,7 @@
 	case DARWIN_PT_DETACH: {
 		int had_sigexc = 0;
 
-		if ((t = pfind(SCARG(uap, pid))) == NULL)
+		if ((t = pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 
 		if ((t->p_emul == &emul_darwin) &&
@@ -141,7 +144,7 @@
 	case DARWIN_PT_THUPDATE: {
 		int signo = SCARG(uap, data);
 
-		if ((t = pfind(SCARG(uap, pid))) == NULL)
+		if ((t = pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 
 		/* Checks from native ptrace */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/darwin/darwin_sysctl.c mult-netbsd-3.1/sys/compat/darwin/darwin_sysctl.c
--- NetBSD-3.1/sys/compat/darwin/darwin_sysctl.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/darwin/darwin_sysctl.c	2007-11-18 14:10:50.000000000 +0000
@@ -828,7 +828,7 @@
 	de->e_vm.vm_taddr = p->p_vmspace->vm_taddr;
 	de->e_vm.vm_daddr = p->p_vmspace->vm_daddr;
 	de->e_vm.vm_maxsaddr = p->p_vmspace->vm_maxsaddr;
-	de->e_ppid = p->p_pptr->p_pid;
+	de->e_ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
 	de->e_pgid = p->p_pgid;
 	de->e_jobc = p->p_pgrp->pg_jobc;
 	if ((p->p_flag & P_CONTROLT) && (p->p_session->s_ttyp != NULL)) {
@@ -917,12 +917,16 @@
 	char *arg;
 	char *tmp;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	if (namelen != 1)
 		return (EINVAL);
 	pid = name[0];
 
 	/* check pid */
-	if ((p = pfind(pid)) == NULL)
+	if ((p = pfind(l->l_proc->p_inst, pid)) == NULL)
 		return (EINVAL);
 
 	/* only root or same user change look at the environment */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/freebsd/freebsd_sched.c mult-netbsd-3.1/sys/compat/freebsd/freebsd_sched.c
--- NetBSD-3.1/sys/compat/freebsd/freebsd_sched.c	2003-01-18 07:33:16.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/freebsd/freebsd_sched.c	2007-11-10 19:27:10.000000000 +0000
@@ -80,6 +80,10 @@
 	struct freebsd_sched_param lp;
 	struct proc *p;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	/*
 	 * We only check for valid parameters and return afterwards.
 	 */
@@ -93,7 +97,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = l->l_proc->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(l->l_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(l->l_proc == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -120,6 +124,10 @@
 	struct proc *p;
 	struct freebsd_sched_param lp;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	/*
 	 * We only check for valid parameters and return a dummy
 	 * priority afterwards.
@@ -130,7 +138,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = l->l_proc->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(l->l_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(l->l_proc == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -160,6 +168,10 @@
 	struct freebsd_sched_param lp;
 	struct proc *p;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	/*
 	 * We only check for valid parameters and return afterwards.
 	 */
@@ -173,7 +185,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = l->l_proc->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(l->l_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(l->l_proc == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -204,6 +216,10 @@
 	} */ *uap = v;
 	struct proc *p;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	*retval = -1;
 
 	/*
@@ -212,7 +228,7 @@
 	if (SCARG(uap, pid) != 0) {
 		struct pcred *pc = l->l_proc->p_cred;
 
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(l->l_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(l->l_proc == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/hpux/hpux_compat.c mult-netbsd-3.1/sys/compat/hpux/hpux_compat.c
--- NetBSD-3.1/sys/compat/hpux/hpux_compat.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/hpux/hpux_compat.c	2007-11-10 19:27:10.000000000 +0000
@@ -426,21 +426,24 @@
 	register_t *retval;
 {
 	struct hpux_sys_utssys_args *uap = v;
-	int i;
-	int error;
+	int 			i, error;
 	struct hpux_utsname	ut;
+	char			tmphost[MAXHOSTNAMELEN];
+	size_t			tmphostlen;
 
 	switch (SCARG(uap, request)) {
 	/* uname */
 	case 0:
 		memset(&ut, 0, sizeof(ut));
 
+		inst_get_hostname(l, tmphost, MAXHOSTNAMELEN);
+
 		strncpy(ut.sysname, ostype, sizeof(ut.sysname));
 		ut.sysname[sizeof(ut.sysname) - 1] = '\0';
 
 		/* copy hostname (sans domain) to nodename */
-		for (i = 0; i < 8 && hostname[i] != '.'; i++)
-			ut.nodename[i] = hostname[i];
+		for (i = 0; i < 8 && tmphost[i] != '.'; i++)
+			ut.nodename[i] = tmphost[i];
 		ut.nodename[i] = '\0';
 
 		strncpy(ut.release, osrelease, sizeof(ut.release));
@@ -460,12 +463,14 @@
 	case 5:
 		/* SCARG(uap, dev) is length */
 		i = SCARG(uap, dev);
+		tmphostlen = inst_get_hostnamelen(l);
 		if (i < 0) {
 			error = EINVAL;
 			break;
-		} else if (i > hostnamelen + 1)
-			i = hostnamelen + 1;
-		error = copyout((caddr_t)hostname, (caddr_t)SCARG(uap, uts), i);
+		} else if (i > tmphostlen + 1)
+			i = tmphostlen + 1;
+
+		error = inst_copyout_hostname(l, (caddr_t)SCARG(uap, uts), i);
 		break;
 
 	case 1:	/* ?? */
@@ -580,13 +585,16 @@
 	struct proc *p;
 	int nice, error;
 
+	KASSERT(NULL != lp);
+	KASSERT(NULL != lp->l_inst);
+
 	if (SCARG(uap, prio) < RTPRIO_MIN && SCARG(uap, prio) > RTPRIO_MAX &&
 	    SCARG(uap, prio) != RTPRIO_NOCHG &&
 	    SCARG(uap, prio) != RTPRIO_RTOFF)
 		return (EINVAL);
 	if (SCARG(uap, pid) == 0)
 		p = lp->l_proc;
-	else if ((p = pfind(SCARG(uap, pid))) == 0)
+	else if ((p = pfind(lp->l_inst, SCARG(uap, pid))) == 0)
 		return (ESRCH);
 	nice = p->p_nice - NZERO;
 	if (nice < 0)
@@ -931,9 +939,12 @@
 	struct proc *cp = lp->l_proc;
 	struct proc *p;
 
+	KASSERT(NULL != lp);
+	KASSERT(NULL != lp->l_inst);
+
 	if (SCARG(uap, pid) == 0)
 		SCARG(uap, pid) = cp->p_pid;
-	p = pfind(SCARG(uap, pid));
+	p = pfind(lp->l_inst, SCARG(uap, pid));
 	if (p == 0)
 		return (ESRCH);
 	if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/ibcs2/ibcs2_misc.c mult-netbsd-3.1/sys/compat/ibcs2/ibcs2_misc.c
--- NetBSD-3.1/sys/compat/ibcs2/ibcs2_misc.c	2005-10-01 11:39:27.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/ibcs2/ibcs2_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -132,6 +132,7 @@
 
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
+#include <sys/inst.h>
 
 #if defined(__i386__)
 #include <i386/include/reg.h>
@@ -1667,7 +1668,9 @@
 
 	(void)memset(&uts, 0, sizeof(uts));
 	(void)strncpy(uts.sysname, ostype, 8);
-	(void)strncpy(uts.nodename, hostname, 8);
+
+	inst_get_hostname(l, uts.nodename, 8);
+
 	(void)strncpy(uts.release, osrelease, 15);
 	(void)strncpy(uts.kid, "kernel id 1", 19);
 	(void)strncpy(uts.machine, machine, 8);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/ibcs2/ibcs2_stat.c mult-netbsd-3.1/sys/compat/ibcs2/ibcs2_stat.c
--- NetBSD-3.1/sys/compat/ibcs2/ibcs2_stat.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/ibcs2/ibcs2_stat.c	2007-11-09 18:23:30.000000000 +0000
@@ -42,6 +42,7 @@
 #include <sys/vnode.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 #include <compat/ibcs2/ibcs2_types.h>
 #include <compat/ibcs2/ibcs2_fcntl.h>
@@ -367,7 +368,9 @@
 
 		memset(&sut, 0, ibcs2_utsname_len);
 		memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
-		memcpy(sut.nodename, hostname, sizeof(sut.nodename));
+
+		inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
+
 		sut.nodename[sizeof(sut.nodename)-1] = '\0';
 		memcpy(sut.release, osrelease, sizeof(sut.release) - 1);
 		strlcpy(sut.version, "1", sizeof(sut.version));
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/irix/irix_exec.c mult-netbsd-3.1/sys/compat/irix/irix_exec.c
--- NetBSD-3.1/sys/compat/irix/irix_exec.c	2005-09-18 21:09:51.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/irix/irix_exec.c	2007-11-23 10:17:19.000000000 +0000
@@ -200,8 +200,8 @@
 	/*
 	 * Send SIGHUP to child process as requested using prctl(2)
 	 */
-	proclist_lock_read();
-	PROCLIST_FOREACH(pp, &allproc) {
+	proclist_lock_read(p->p_inst);
+	PROCLIST_FOREACH(pp, &p->p_inst->i_allproc) {
 		/* Select IRIX processes */
 		if (irix_check_exec(pp) == 0)
 			continue;
@@ -210,7 +210,7 @@
 		if (ied->ied_termchild && pp->p_pptr == p)
 			psignal(pp, native_to_svr4_signo[SIGHUP]);
 	}
-	proclist_unlock_read();
+	proclist_unlock_read(p->p_inst);
 
 	/*
 	 * Remove the process from share group processes list, if revelant.
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/irix/irix_misc.c mult-netbsd-3.1/sys/compat/irix/irix_misc.c
--- NetBSD-3.1/sys/compat/irix/irix_misc.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/irix/irix_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -112,8 +112,7 @@
 	strncpy(sut.sysname, irix_si_os_name, sizeof(sut.sysname));
 	sut.sysname[sizeof(sut.sysname) - 1] = '\0';
 
-	strncpy(sut.nodename, hostname, sizeof(sut.nodename));
-	sut.nodename[sizeof(sut.nodename) - 1] = '\0';
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 
 	strncpy(sut.release, irix_release, sizeof(sut.release));
 	sut.release[sizeof(sut.release) - 1] = '\0';
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/irix/irix_prctl.c mult-netbsd-3.1/sys/compat/irix/irix_prctl.c
--- NetBSD-3.1/sys/compat/irix/irix_prctl.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/irix/irix_prctl.c	2007-11-19 15:54:40.000000000 +0000
@@ -52,6 +52,7 @@
 #include <sys/filedesc.h>
 #include <sys/vnode.h>
 #include <sys/resourcevar.h>
+#include <sys/inst.h>
 
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_map.h>
@@ -100,6 +101,9 @@
 	struct proc *p = l->l_proc;
 	unsigned int option = SCARG(uap, option);
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_inst);
+
 #ifdef DEBUG_IRIX
 	printf("irix_sys_prctl(): option = %d\n", option);
 #endif
@@ -110,7 +114,7 @@
 		int shmask = 0;
 		struct irix_emuldata *ied;
 
-		p2 = pfind((pid_t)SCARG(uap, arg1));
+		p2 = pfind(l->l_inst, (pid_t)SCARG(uap, arg1));
 
 		if (p2 == p || SCARG(uap, arg1) == 0) {
 			/* XXX return our own shmask */
@@ -177,7 +181,7 @@
 		if (pid == 0)
 			pid = p->p_pid;
 
-		if ((target = pfind(pid)) == NULL)
+		if ((target = pfind(l->l_inst, pid)) == NULL)
 			return ESRCH;
 
 		if (irix_check_exec(target) == 0)
@@ -489,8 +493,9 @@
 		parent->p_cred->p_refcnt++;
 		p2->p_cred = parent->p_cred;
 		if (--pc->p_refcnt == 0) {
+			/*inst_urelease(pc->pc_ucred);*/
 			crfree(pc->pc_ucred);
-			pool_put(&pcred_pool, pc);
+			pcred_free(pc);
 		}
 	}
 
@@ -498,6 +503,7 @@
 	 * Handle shared process limits
 	 */
 	if (inh & IRIX_PR_SULIMIT) {
+		KASSERT(NULL != parent->p_inst);
 		pl = p2->p_limit;
 		parent->p_limit->p_refcnt++;
 		p2->p_limit = parent->p_limit;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/irix/irix_syssgi.c mult-netbsd-3.1/sys/compat/irix/irix_syssgi.c
--- NetBSD-3.1/sys/compat/irix/irix_syssgi.c	2005-02-26 23:10:18.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/irix/irix_syssgi.c	2007-11-10 19:27:10.000000000 +0000
@@ -109,6 +109,9 @@
 	int request = SCARG(uap, request);
 	void *arg1, *arg2, *arg3;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 #ifdef DEBUG_IRIX
 	printf("irix_sys_syssgi(): request = %d\n", request);
 #endif
@@ -217,7 +220,7 @@
 		arg1 = SCARG(uap, arg1); /* PID of the process */
 		arg2 = SCARG(uap, arg2); /* Address of user buffer */
 		arg3 = SCARG(uap, arg3); /* Length of user buffer */
-		tp = pfind((pid_t)arg1);
+		tp = pfind(p->p_inst, (pid_t)arg1);
 		if (tp == NULL || \
 		    tp->p_psstr == NULL || \
 		    tp->p_psstr->ps_argvstr == NULL || \
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/arch/i386/linux_ptrace.c mult-netbsd-3.1/sys/compat/linux/arch/i386/linux_ptrace.c
--- NetBSD-3.1/sys/compat/linux/arch/i386/linux_ptrace.c	2005-02-26 23:10:19.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/linux/arch/i386/linux_ptrace.c	2007-11-10 19:27:10.000000000 +0000
@@ -146,6 +146,9 @@
 	struct linux_fpctx *linux_fpregs = NULL;
 	int addr;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	request = SCARG(uap, request);
 
 	if ((request != LINUX_PTRACE_PEEKUSR) &&
@@ -157,7 +160,7 @@
 		return EIO;
 
 	/* Find the process we're supposed to be operating on. */
-	if ((t = pfind(SCARG(uap, pid))) == NULL)
+	if ((t = pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 		return ESRCH;
 
 	/*
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/common/linux_file.c mult-netbsd-3.1/sys/compat/linux/common/linux_file.c
--- NetBSD-3.1/sys/compat/linux/common/linux_file.c	2005-03-10 14:12:28.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/linux/common/linux_file.c	2007-11-10 19:27:10.000000000 +0000
@@ -315,6 +315,9 @@
 	cmd = SCARG(uap, cmd);
 	arg = (caddr_t) SCARG(uap, arg);
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_inst);
+
 	switch (cmd) {
 	case LINUX_F_DUPFD:
 		cmd = F_DUPFD;
@@ -463,12 +466,12 @@
 		if ((long)arg <= 0) {
 			pgid = -(long)arg;
 		} else {
-			struct proc *p1 = pfind((long)arg);
+			struct proc *p1 = pfind(l->l_inst, (long)arg);
 			if (p1 == NULL)
 				return (ESRCH);
 			pgid = (long)p1->p_pgrp->pg_id;
 		}
-		pgrp = pgfind(pgid);
+		pgrp = pgfind(l->l_inst, pgid);
 		if (pgrp == NULL || pgrp->pg_session != p->p_session)
 			return EPERM;
 		tp->t_pgrp = pgrp;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/common/linux_misc.c mult-netbsd-3.1/sys/compat/linux/common/linux_misc.c
--- NetBSD-3.1/sys/compat/linux/common/linux_misc.c	2005-11-01 22:31:17.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/linux/common/linux_misc.c	2007-11-23 10:17:19.000000000 +0000
@@ -95,6 +95,7 @@
 #include <sys/unistd.h>
 #include <sys/swap.h>		/* for SWAP_ON */
 #include <sys/sysctl.h>		/* for KERN_DOMAINNAME */
+#include <sys/inst.h>
 
 #include <sys/ptrace.h>
 #include <machine/ptrace.h>
@@ -444,11 +445,11 @@
 	struct linux_utsname luts;
 
 	strncpy(luts.l_sysname, linux_sysname, sizeof(luts.l_sysname));
-	strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
+	inst_get_hostname(l, luts.l_nodename, sizeof(luts.l_nodename));
 	strncpy(luts.l_release, linux_release, sizeof(luts.l_release));
 	strncpy(luts.l_version, linux_version, sizeof(luts.l_version));
 	strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
-	strncpy(luts.l_domainname, domainname, sizeof(luts.l_domainname));
+	inst_get_domainname(l, luts.l_domainname, sizeof(luts.l_domainname));
 
 	return copyout(&luts, SCARG(uap, up), sizeof(luts));
 }
@@ -1074,8 +1075,11 @@
 	struct proc *p = l->l_proc;
 	struct proc *targp;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
-		if ((targp = pfind(SCARG(uap, pid))) == 0)
+		if ((targp = pfind(p->p_inst, SCARG(uap, pid))) == 0)
 			return ESRCH;
 	}
 	else
@@ -1593,7 +1597,7 @@
 	si.bufferram = uvmexp.filepages * uvmexp.pagesize;
 	si.totalswap = uvmexp.swpages * uvmexp.pagesize;
 	si.freeswap = (uvmexp.swpages - uvmexp.swpginuse) * uvmexp.pagesize;
-	si.procs = nprocs;
+	si.procs = l->l_inst->i_nprocs;
 
 	/* The following are only present in newer Linux kernels. */
 	si.totalbig = 0;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/common/linux_oldolduname.c mult-netbsd-3.1/sys/compat/linux/common/linux_oldolduname.c
--- NetBSD-3.1/sys/compat/linux/common/linux_oldolduname.c	2003-01-19 16:41:46.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/linux/common/linux_oldolduname.c	2007-11-09 18:23:30.000000000 +0000
@@ -43,6 +43,7 @@
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/mount.h>
+#include <sys/inst.h>
 
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
@@ -69,7 +70,7 @@
 	struct linux_oldoldutsname luts;
 
 	strncpy(luts.l_sysname, linux_sysname, sizeof(luts.l_sysname));
-	strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
+	inst_get_hostname(l, luts.l_nodename, sizeof(luts.l_nodename));
 	strncpy(luts.l_release, linux_release, sizeof(luts.l_release));
 	strncpy(luts.l_version, linux_version, sizeof(luts.l_version));
 	strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/common/linux_olduname.c mult-netbsd-3.1/sys/compat/linux/common/linux_olduname.c
--- NetBSD-3.1/sys/compat/linux/common/linux_olduname.c	2003-01-18 08:04:38.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/linux/common/linux_olduname.c	2007-11-09 18:23:30.000000000 +0000
@@ -45,6 +45,7 @@
 #include <sys/mbuf.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
+#include <sys/inst.h>
 
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
@@ -72,7 +73,7 @@
 	struct linux_oldutsname luts;
 
 	strncpy(luts.l_sysname, linux_sysname, sizeof(luts.l_sysname));
-	strncpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
+	inst_get_hostname(l, luts.l_nodename, sizeof(luts.l_nodename));
 	strncpy(luts.l_release, linux_release, sizeof(luts.l_release));
 	strncpy(luts.l_version, linux_version, sizeof(luts.l_version));
 	strncpy(luts.l_machine, machine, sizeof(luts.l_machine));
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/linux/common/linux_sched.c mult-netbsd-3.1/sys/compat/linux/common/linux_sched.c
--- NetBSD-3.1/sys/compat/linux/common/linux_sched.c	2004-09-10 23:22:20.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/linux/common/linux_sched.c	2007-11-11 13:27:02.000000000 +0000
@@ -133,6 +133,8 @@
 	struct linux_sched_param lp;
 	struct proc *p;
 
+	KASSERT(NULL != cp);
+	KASSERT(NULL != cp->p_inst);
 /*
  * We only check for valid parameters and return afterwards.
  */
@@ -147,7 +149,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, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -175,6 +177,9 @@
 	struct proc *p;
 	struct linux_sched_param lp;
 
+	KASSERT(NULL != cp);
+	KASSERT(NULL != cp->p_inst);
+
 /*
  * We only check for valid parameters and return a dummy priority afterwards.
  */
@@ -184,7 +189,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, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -215,6 +220,9 @@
 	struct linux_sched_param lp;
 	struct proc *p;
 
+	KASSERT(NULL != cp);
+	KASSERT(NULL != cp->p_inst);
+
 /*
  * We only check for valid parameters and return afterwards.
  */
@@ -229,7 +237,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, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
@@ -261,6 +269,9 @@
 	struct proc *cp = cl->l_proc;
 	struct proc *p;
 
+	KASSERT(NULL != cp);
+	KASSERT(NULL != cp->p_inst);
+
 	*retval = -1;
 /*
  * We only check for valid parameters and return afterwards.
@@ -269,7 +280,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, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		if (!(cp == p ||
 		      pc->pc_ucred->cr_uid == 0 ||
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/mach/mach_exception.c mult-netbsd-3.1/sys/compat/mach/mach_exception.c
--- NetBSD-3.1/sys/compat/mach/mach_exception.c	2005-02-26 23:10:19.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/mach/mach_exception.c	2007-11-18 14:10:50.000000000 +0000
@@ -167,7 +167,8 @@
 
 		sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
 		SCHED_LOCK(s);
-		p->p_pptr->p_nstopchild++;
+		if (p->p_pptr)
+			p->p_pptr->p_nstopchild++;
 		p->p_stat = SSTOP;
 		exc_l->l_stat = LSSTOP;
 		p->p_nrlwps--;
@@ -224,13 +225,15 @@
 	 * a dying parent, a signal is sent instead of the
 	 * notification, this fixes the problem.
 	 */
-	if ((exc_l->l_proc->p_flag & P_TRACED) &&
-	    (exc_l->l_proc->p_pptr->p_flag & P_WEXIT)) {
+	if (exc_l->l_proc->p_flag & P_TRACED) {
+		KASSERT(exc_l->l_proc->p_pptr);
+		if (exc_l->l_proc->p_pptr->p_flag & P_WEXIT) {
 #ifdef DEBUG_MACH
-		printf("mach_exception: deadlock avoided\n");
+			printf("mach_exception: deadlock avoided\n");
 #endif
-		error = EINVAL;
-		goto out;
+			error = EINVAL;
+			goto out;
+		}
 	}
 
 	if (exc_port->mp_datatype != MACH_MP_EXC_INFO) {
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/mach/mach_message.c mult-netbsd-3.1/sys/compat/mach/mach_message.c
--- NetBSD-3.1/sys/compat/mach/mach_message.c	2005-02-26 23:10:19.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/mach/mach_message.c	2007-11-23 10:17:19.000000000 +0000
@@ -1243,50 +1243,57 @@
 void
 mach_debug_message(void)
 {
-	struct lwp *l;
+	struct lwp 	*l;
+	struct inst	*i;
 	struct mach_emuldata *med;
 	struct mach_right *mr;
 	struct mach_right *mrs;
 	struct mach_port *mp;
 	struct mach_message *mm;
 
-	LIST_FOREACH(l, &alllwp, l_list) {
-		if ((l->l_proc->p_emul != &emul_mach) &&
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			if ((l->l_proc->p_emul != &emul_mach) &&
 #ifdef COMPAT_DARWIN
-		    (l->l_proc->p_emul != &emul_darwin) &&
+			    (l->l_proc->p_emul != &emul_darwin) &&
 #endif
-		    1)
-			continue;
-
-		med = l->l_proc->p_emuldata;
-		LIST_FOREACH(mr, &med->med_right, mr_list)
-			if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
-				mp = mr->mr_port;
-				if (mp == NULL)
-					continue;
-
-				printf("port %p(%d) ", mp, mp->mp_count);
-
-				TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
-					printf("%d ", mm->mm_msg->msgh_id);
-
-				printf("\n");
+			    1)
 				continue;
-			}
-			/* Port set... */
-			LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
-				mp = mrs->mr_port;
-				if (mp == NULL)
+	
+			med = l->l_proc->p_emuldata;
+			LIST_FOREACH(mr, &med->med_right, mr_list)
+				if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
+					mp = mr->mr_port;
+					if (mp == NULL)
+						continue;
+	
+					printf("port %p(%d) ", mp, mp->mp_count);
+	
+					TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
+						printf("%d ", mm->mm_msg->msgh_id);
+	
+					printf("\n");
 					continue;
-
-				printf("port %p(%d) ", mp, mp->mp_count);
-
-				TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
-					printf("%d ", mm->mm_msg->msgh_id);
-
-				printf("\n");
-			}
+				}
+				/* Port set... */
+				LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
+					mp = mrs->mr_port;
+					if (mp == NULL)
+						continue;
+	
+					printf("port %p(%d) ", mp, mp->mp_count);
+	
+					TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
+						printf("%d ", mm->mm_msg->msgh_id);
+	
+					printf("\n");
+				}
+		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
 	return;
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/mach/mach_port.c mult-netbsd-3.1/sys/compat/mach/mach_port.c
--- NetBSD-3.1/sys/compat/mach/mach_port.c	2005-02-26 23:10:20.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/mach/mach_port.c	2007-11-23 10:17:19.000000000 +0000
@@ -1000,47 +1000,54 @@
 	struct mach_emuldata *med;
 	struct mach_right *mr;
 	struct mach_right *mrs;
-	struct proc *p;
+	struct proc 	*p;
+	struct inst	*i;
 
-	PROCLIST_FOREACH(p, &allproc) {
-		if ((p->p_emul != &emul_mach) &&
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		PROCLIST_FOREACH(p, &i->i_allproc) {
+			if ((p->p_emul != &emul_mach) &&
 #ifdef COMPAT_DARWIN
-		    (p->p_emul != &emul_darwin) &&
+					(p->p_emul != &emul_darwin) &&
 #endif
-		    1)
-			continue;
-
-		med = p->p_emuldata;
-		LIST_FOREACH(mr, &med->med_right, mr_list) {
-			if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
-				printf("pid %d: %p(%x)=>%p",
-				    p->p_pid, mr, mr->mr_type, mr->mr_port);
-				if (mr->mr_port && mr->mr_port->mp_recv)
-					printf("[%p]\n",
-					    mr->mr_port->mp_recv->mr_sethead);
-				else
-					printf("[NULL]\n");
-
+					1)
 				continue;
-			}
-
-			/* Port set... */
-			printf("pid %d: set %p(%x) ",
-			    p->p_pid, mr, mr->mr_type);
-			LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
-				printf("%p(%x)=>%p",
-				    mrs, mrs->mr_type, mrs->mr_port);
-				if (mrs->mr_port && mrs->mr_port->mp_recv)
-					printf("[%p]",
-					    mrs->mr_port->mp_recv->mr_sethead);
-				else
-					printf("[NULL]");
 
-				printf(" ");
+			med = p->p_emuldata;
+			LIST_FOREACH(mr, &med->med_right, mr_list) {
+				if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
+					printf("pid %d: %p(%x)=>%p",
+							p->p_pid, mr, mr->mr_type, mr->mr_port);
+					if (mr->mr_port && mr->mr_port->mp_recv)
+						printf("[%p]\n",
+								mr->mr_port->mp_recv->mr_sethead);
+					else
+						printf("[NULL]\n");
+
+					continue;
+				}
+
+				/* Port set... */
+				printf("pid %d: set %p(%x) ",
+						p->p_pid, mr, mr->mr_type);
+				LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
+					printf("%p(%x)=>%p",
+							mrs, mrs->mr_type, mrs->mr_port);
+					if (mrs->mr_port && mrs->mr_port->mp_recv)
+						printf("[%p]",
+								mrs->mr_port->mp_recv->mr_sethead);
+					else
+						printf("[NULL]");
+
+					printf(" ");
+				}
+				printf("\n");
 			}
-			printf("\n");
 		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
 	return;
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/mach/mach_task.c mult-netbsd-3.1/sys/compat/mach/mach_task.c
--- NetBSD-3.1/sys/compat/mach/mach_task.c	2005-02-26 23:10:20.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/mach/mach_task.c	2007-11-10 19:27:10.000000000 +0000
@@ -668,6 +668,9 @@
 	struct proc *t;
 	int error;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_inst);
+
 	/*
 	 * target_tport is used because the task may be on
 	 * a different host. (target_tport, pid) is unique.
@@ -679,7 +682,7 @@
 	    l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
 		return EPERM;
 
-	if ((t = pfind(SCARG(uap, pid))) == NULL)
+	if ((t = pfind(l->l_inst, SCARG(uap, pid))) == NULL)
 		return ESRCH;
 
 	/* Allowed only if the UID match, if setuid, or if superuser */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/netbsd32/netbsd32_execve.c mult-netbsd-3.1/sys/compat/netbsd32/netbsd32_execve.c
--- NetBSD-3.1/sys/compat/netbsd32/netbsd32_execve.c	2005-09-12 14:45:06.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/netbsd32/netbsd32_execve.c	2007-11-18 14:10:50.000000000 +0000
@@ -387,6 +387,7 @@
 	p->p_flag |= P_EXEC;
 	if (p->p_flag & P_PPWAIT) {
 		p->p_flag &= ~P_PPWAIT;
+		KASSERT(p->p_pptr);
 		wakeup((caddr_t) p->p_pptr);
 	}
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/osf1/osf1_misc.c mult-netbsd-3.1/sys/compat/osf1/osf1_misc.c
--- NetBSD-3.1/sys/compat/osf1/osf1_misc.c	2006-04-25 08:51:47.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/osf1/osf1_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -287,9 +287,10 @@
 	register_t *retval;
 {
 	struct osf1_sys_sysinfo_args *uap = v;
-	const char *string;
-	size_t slen;
-	int error;
+	const char 	*string;
+	char		buf[MAXHOSTNAMELEN];
+	size_t 		slen;
+	int 		error;
 
 	error = 0;
 	switch (SCARG(uap, cmd)) {
@@ -298,7 +299,8 @@
 		break;
 
 	case OSF1_SI_HOSTNAME:
-		string = hostname;
+		inst_get_hostname(l, buf, MAXHOSTNAMELEN);
+		string = &buf[0];
 		break;
 
 	case OSF1_SI_RELEASE:
@@ -371,7 +373,9 @@
 	/* XXX would use stackgap, but our struct utsname is too big! */
 
         strncpy(u.sysname, ostype, sizeof(u.sysname));
-        strncpy(u.nodename, hostname, sizeof(u.nodename));
+
+	inst_get_hostname(l, u.nodename, sizeof(u.nodename));
+
         strncpy(u.release, osrelease, sizeof(u.release));
         dp = u.version;
         ep = &u.version[sizeof(u.version) - 1];
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/sunos/sunos_misc.c mult-netbsd-3.1/sys/compat/sunos/sunos_misc.c
--- NetBSD-3.1/sys/compat/sunos/sunos_misc.c	2005-10-01 11:39:27.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/sunos/sunos_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -810,8 +810,7 @@
 	memset(&sut, 0, sizeof(sut));
 
 	memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
-	memcpy(sut.nodename, hostname, sizeof(sut.nodename));
-	sut.nodename[sizeof(sut.nodename)-1] = '\0';
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 	memcpy(sut.release, osrelease, sizeof(sut.release) - 1);
 	memcpy(sut.version, "1", sizeof(sut.version) - 1);
 	memcpy(sut.machine, machine, sizeof(sut.machine) - 1);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/sunos32/sunos32_misc.c mult-netbsd-3.1/sys/compat/sunos32/sunos32_misc.c
--- NetBSD-3.1/sys/compat/sunos32/sunos32_misc.c	2005-10-01 11:39:27.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/sunos32/sunos32_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -1058,7 +1058,7 @@
 	memset(&sut, 0, sizeof(sut));
 
 	memcpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
-	memcpy(sut.nodename, hostname, sizeof(sut.nodename));
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 	sut.nodename[sizeof(sut.nodename)-1] = '\0';
 	memcpy(sut.release, osrelease, sizeof(sut.release) - 1);
 	memcpy(sut.version, "1", sizeof(sut.version) - 1);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/svr4/svr4_misc.c mult-netbsd-3.1/sys/compat/svr4/svr4_misc.c
--- NetBSD-3.1/sys/compat/svr4/svr4_misc.c	2005-10-01 11:39:26.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/svr4/svr4_misc.c	2007-11-10 19:27:10.000000000 +0000
@@ -114,7 +114,8 @@
     struct svr4_statvfs *));
 static void bsd_statvfs_to_svr4_statvfs64 __P((const struct statvfs *,
     struct svr4_statvfs64 *));
-#define svr4_pfind(pid) p_find((pid), PFIND_UNLOCK | PFIND_ZOMBIE)
+#define svr4_pfind(inst, pid) \
+	p_find((inst), (pid), PFIND_UNLOCK | PFIND_ZOMBIE)
 
 static int svr4_mknod __P((struct lwp *, register_t *, const char *,
     svr4_mode_t, svr4_dev_t));
@@ -964,6 +965,9 @@
 	struct svr4_sys_pgrpsys_args *uap = v;
 	struct proc *p = l->l_proc;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	switch (SCARG(uap, cmd)) {
 	case 1:			/* setpgrp() */
 		/*
@@ -982,7 +986,7 @@
 
 	case 2:			/* getsid(pid) */
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		/*
 		 * This has already been initialized to the pid of
@@ -997,7 +1001,7 @@
 	case 4:			/* getpgid(pid) */
 
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 
 		*retval = (int) p->p_pgrp->pg_id;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/svr4/svr4_stat.c mult-netbsd-3.1/sys/compat/svr4/svr4_stat.c
--- NetBSD-3.1/sys/compat/svr4/svr4_stat.c	2005-02-26 23:10:21.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/svr4/svr4_stat.c	2007-11-09 18:23:30.000000000 +0000
@@ -59,6 +59,7 @@
 
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 #include <compat/svr4/svr4_types.h>
 #include <compat/svr4/svr4_signal.h>
@@ -562,8 +563,7 @@
 	strncpy(sut.sysname, ostype, sizeof(sut.sysname));
 	sut.sysname[sizeof(sut.sysname) - 1] = '\0';
 
-	strncpy(sut.nodename, hostname, sizeof(sut.nodename));
-	sut.nodename[sizeof(sut.nodename) - 1] = '\0';
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 
 	strncpy(sut.release, osrelease, sizeof(sut.release));
 	sut.release[sizeof(sut.release) - 1] = '\0';
@@ -586,11 +586,10 @@
 	register_t *retval;
 {
 	struct svr4_sys_systeminfo_args *uap = v;
-	const char *str = NULL;
-	int name[2];
-	int error;
-	size_t len;
-	char buf[256];
+	const char 	*str = NULL;
+	int 		name[2], error;
+	size_t 		len;
+	char 		buf[256], hostbuf[MAXHOSTNAMELEN];
 
 	u_int rlen = SCARG(uap, len);
 
@@ -600,7 +599,8 @@
 		break;
 
 	case SVR4_SI_HOSTNAME:
-		str = hostname;
+		inst_get_hostname(l, hostbuf, MAXHOSTNAMELEN);
+		str = &hostbuf[0];
 		break;
 
 	case SVR4_SI_RELEASE:
@@ -629,7 +629,8 @@
 		break;
 
 	case SVR4_SI_SRPC_DOMAIN:
-		str = domainname;
+		inst_get_domainname(l, hostbuf, MAXHOSTNAMELEN);
+		str = &hostbuf[0];
 		break;
 
 	case SVR4_SI_PLATFORM:
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/svr4_32/svr4_32_misc.c mult-netbsd-3.1/sys/compat/svr4_32/svr4_32_misc.c
--- NetBSD-3.1/sys/compat/svr4_32/svr4_32_misc.c	2005-10-01 11:39:27.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/svr4_32/svr4_32_misc.c	2007-11-10 19:27:11.000000000 +0000
@@ -114,7 +114,8 @@
     struct svr4_32_statvfs *));
 static void bsd_statvfs_to_svr4_32_statvfs64 __P((const struct statvfs *,
     struct svr4_32_statvfs64 *));
-#define svr4_32_pfind(pid) p_find((pid), PFIND_UNLOCK | PFIND_ZOMBIE)
+#define svr4_32_pfind(inst, pid) \
+	p_find((inst), (pid), PFIND_UNLOCK | PFIND_ZOMBIE)
 
 static int svr4_32_mknod __P((struct lwp *, register_t *, const char *,
     svr4_32_mode_t, svr4_32_dev_t));
@@ -980,6 +981,9 @@
 	struct svr4_32_sys_pgrpsys_args *uap = v;
 	struct proc *p = l->l_proc;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	switch (SCARG(uap, cmd)) {
 	case 1:			/* setpgrp() */
 		/*
@@ -998,7 +1002,7 @@
 
 	case 2:			/* getsid(pid) */
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_32_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_32_pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 		/*
 		 * This has already been initialized to the pid of
@@ -1013,7 +1017,7 @@
 	case 4:			/* getpgid(pid) */
 
 		if (SCARG(uap, pid) != 0 &&
-		    (p = svr4_32_pfind(SCARG(uap, pid))) == NULL)
+		    (p = svr4_32_pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return ESRCH;
 
 		*retval = (int) p->p_pgrp->pg_id;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/svr4_32/svr4_32_stat.c mult-netbsd-3.1/sys/compat/svr4_32/svr4_32_stat.c
--- NetBSD-3.1/sys/compat/svr4_32/svr4_32_stat.c	2005-02-26 23:10:21.000000000 +0000
+++ mult-netbsd-3.1/sys/compat/svr4_32/svr4_32_stat.c	2007-11-09 18:23:30.000000000 +0000
@@ -582,8 +582,7 @@
 	strncpy(sut.sysname, ostype, sizeof(sut.sysname));
 	sut.sysname[sizeof(sut.sysname) - 1] = '\0';
 
-	strncpy(sut.nodename, hostname, sizeof(sut.nodename));
-	sut.nodename[sizeof(sut.nodename) - 1] = '\0';
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 
 	strncpy(sut.release, osrelease, sizeof(sut.release));
 	sut.release[sizeof(sut.release) - 1] = '\0';
@@ -606,12 +605,11 @@
 	register_t *retval;
 {
 	struct svr4_32_sys_systeminfo_args *uap = v;
-	struct proc *p = l->l_proc;
-	const char *str = NULL;
-	int name[2];
-	int error;
-	size_t len;
-	char buf[256];
+	struct proc 	*p = l->l_proc;
+	const char 	*str = NULL;
+	int 		name[2], error;
+	size_t 		len;
+	char 		buf[256], hostbuf[MAXHOSTNAMELEN];
 
 	u_int rlen = SCARG(uap, len);
 
@@ -621,7 +619,8 @@
 		break;
 
 	case SVR4_SI_HOSTNAME:
-		str = hostname;
+		inst_get_hostname(l, hostbuf, MAXHOSTNAMELEN);
+		str = &hostbuf[0];
 		break;
 
 	case SVR4_SI_RELEASE:
diff -r -u -N --exclude CVS NetBSD-3.1/sys/compat/ultrix/ultrix_misc.c mult-netbsd-3.1/sys/compat/ultrix/ultrix_misc.c
--- NetBSD-3.1/sys/compat/ultrix/ultrix_misc.c	2005-09-18 21:09:50.000000000 +0100
+++ mult-netbsd-3.1/sys/compat/ultrix/ultrix_misc.c	2007-11-09 18:23:30.000000000 +0000
@@ -423,7 +423,7 @@
 	memset(&sut, 0, sizeof(sut));
 
 	strncpy(sut.sysname, ostype, sizeof(sut.sysname) - 1);
-	strncpy(sut.nodename, hostname, sizeof(sut.nodename) - 1);
+	inst_get_hostname(l, sut.nodename, sizeof(sut.nodename));
 	strncpy(sut.release, osrelease, sizeof(sut.release) - 1);
 	dp = sut.version;
 	ep = &sut.version[sizeof(sut.version) - 1];
diff -r -u -N --exclude CVS NetBSD-3.1/sys/conf/files mult-netbsd-3.1/sys/conf/files
--- NetBSD-3.1/sys/conf/files	2006-04-09 00:32:10.000000000 +0100
+++ mult-netbsd-3.1/sys/conf/files	2007-11-18 17:09:08.000000000 +0000
@@ -18,7 +18,6 @@
 defflag				KMEMSTATS
 defflag				KCONT
 defflag				KTRACE
-defflag				SYSTRACE
 defparam			MAXUPRC
 defparam			RTC_OFFSET
 defparam			HZ
@@ -1138,11 +1137,11 @@
 include "fs/smbfs/files.smbfs"
 include "fs/union/files.union"
 include "miscfs/fdesc/files.fdesc"
-include "miscfs/kernfs/files.kernfs"
+#include "miscfs/kernfs/files.kernfs"
 include "miscfs/nullfs/files.nullfs"
 include "miscfs/overlay/files.overlay"
 include "miscfs/portal/files.portal"
-include "miscfs/procfs/files.procfs"
+#include "miscfs/procfs/files.procfs"
 include "miscfs/umapfs/files.umapfs"
 include "nfs/files.nfs"
 include "ufs/files.ufs"
@@ -1219,6 +1218,7 @@
 file	kern/kern_exec.c
 file	kern/kern_exit.c
 file	kern/kern_fork.c
+file	kern/kern_inst.c
 file	kern/kern_kcont.c		kcont
 file	kern/kern_kthread.c
 file	kern/kern_ktrace.c
@@ -1236,7 +1236,6 @@
 file	kern/kern_resource.c
 file	kern/kern_sa.c
 file	kern/kern_sig.c
-file	kern/kern_systrace.c		systrace
 file	kern/kern_subr.c
 file	kern/kern_synch.c
 file	kern/kern_sysctl.c
diff -r -u -N --exclude CVS NetBSD-3.1/sys/ddb/db_xxx.c mult-netbsd-3.1/sys/ddb/db_xxx.c
--- NetBSD-3.1/sys/ddb/db_xxx.c	2005-02-26 23:04:17.000000000 +0000
+++ mult-netbsd-3.1/sys/ddb/db_xxx.c	2007-11-11 13:27:02.000000000 +0000
@@ -92,7 +92,8 @@
 		/*NOTREACHED*/
 	}
 
-	p = pfind((pid_t)pid);
+	/* FIXME - instances */
+	p = pfind(NULL, (pid_t)pid);
 	if (p == NULL) {
 		db_error("no such proc\n");
 		/*NOTREACHED*/
@@ -113,6 +114,8 @@
 void
 db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
+	/* FIXME - instances */
+#if 0
 	int i;
 
 	char *mode;
@@ -224,6 +227,7 @@
 			}
 		}
 	}
+#endif
 }
 
 void
diff -r -u -N --exclude CVS NetBSD-3.1/sys/dev/cons.c mult-netbsd-3.1/sys/dev/cons.c
--- NetBSD-3.1/sys/dev/cons.c	2005-02-27 00:26:58.000000000 +0000
+++ mult-netbsd-3.1/sys/dev/cons.c	2007-12-09 13:38:53.000000000 +0000
@@ -90,6 +90,7 @@
 #include <sys/file.h>
 #include <sys/conf.h>
 #include <sys/vnode.h>
+#include <sys/inst.h>
 
 #include <dev/cons.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/dev/wscons/wsdisplay_compat_usl.c mult-netbsd-3.1/sys/dev/wscons/wsdisplay_compat_usl.c
--- NetBSD-3.1/sys/dev/wscons/wsdisplay_compat_usl.c	2005-01-02 15:43:49.000000000 +0000
+++ mult-netbsd-3.1/sys/dev/wscons/wsdisplay_compat_usl.c	2007-11-10 19:27:11.000000000 +0000
@@ -137,7 +137,8 @@
 static int
 usl_sync_check(struct usl_syncdata *sd)
 {
-	if (sd->s_proc == pfind(sd->s_pid))
+	/* FIXME - instances */
+	if (sd->s_proc == pfind(NULL, sd->s_pid))
 		return (1);
 	printf("usl_sync_check: process %d died\n", sd->s_pid);
 	usl_sync_done(sd);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/dist/ipf/netinet/ip_fil_netbsd.c mult-netbsd-3.1/sys/dist/ipf/netinet/ip_fil_netbsd.c
--- NetBSD-3.1/sys/dist/ipf/netinet/ip_fil_netbsd.c	2005-04-04 19:25:38.000000000 +0100
+++ mult-netbsd-3.1/sys/dist/ipf/netinet/ip_fil_netbsd.c	2007-11-26 15:08:35.000000000 +0000
@@ -426,17 +426,12 @@
 /*
  * Filter ioctl interface.
  */
-int iplioctl(dev, cmd, data, mode
-#if (NetBSD >= 199511)
-, p)
-struct proc *p;
-#else
-)
-#endif
+int iplioctl(dev, cmd, data, mode, p)
 dev_t dev;
 u_long cmd;
 caddr_t data;
 int mode;
+struct proc *p;
 {
 	int s;
 	int error = 0, unit = 0, tmp;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/fs/cd9660/cd9660_rrip.c mult-netbsd-3.1/sys/fs/cd9660/cd9660_rrip.c
--- NetBSD-3.1/sys/fs/cd9660/cd9660_rrip.c	2005-02-26 22:58:55.000000000 +0000
+++ mult-netbsd-3.1/sys/fs/cd9660/cd9660_rrip.c	2007-11-09 18:23:30.000000000 +0000
@@ -180,9 +180,12 @@
 
 		case ISO_SUSP_CFLAG_HOST:
 			/* Inserting hostname i.e. "kurt.tools.de" */
+#if 0
+			/* FIXME - needs to be instance-ified */
 			inbuf = hostname;
 			wlen = hostnamelen;
-			break;
+#endif
+			return(0);
 
 		case ISO_SUSP_CFLAG_CONTINUE:
 			cont = 1;
@@ -252,9 +255,12 @@
 
 	case ISO_SUSP_CFLAG_HOST:
 		/* Inserting hostname i.e. "kurt.tools.de" */
+#if 0
+		/* FIXME - needs to be instance-ified */
 		inbuf = hostname;
 		wlen = hostnamelen;
-		break;
+#endif
+		return(0);
 
 	case ISO_SUSP_CFLAG_CONTINUE:
 		cont = 1;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/fs/ptyfs/ptyfs_subr.c mult-netbsd-3.1/sys/fs/ptyfs/ptyfs_subr.c
--- NetBSD-3.1/sys/fs/ptyfs/ptyfs_subr.c	2004-11-11 19:19:59.000000000 +0000
+++ mult-netbsd-3.1/sys/fs/ptyfs/ptyfs_subr.c	2007-11-09 18:23:30.000000000 +0000
@@ -144,7 +144,8 @@
 		     p);
 		if ((error = namei(&nd)) != 0)
 			goto out;
-		cred = crget();
+
+		cred = crdupinst(p);
 		error = VOP_GETATTR(nd.ni_vp, &va, cred, p);
 		crfree(cred);
 		VOP_UNLOCK(nd.ni_vp, 0);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/fs/union/union_vfsops.c mult-netbsd-3.1/sys/fs/union/union_vfsops.c
--- NetBSD-3.1/sys/fs/union/union_vfsops.c	2006-01-08 15:45:11.000000000 +0000
+++ mult-netbsd-3.1/sys/fs/union/union_vfsops.c	2007-11-18 14:10:50.000000000 +0000
@@ -227,6 +227,7 @@
 	}
 
 	um->um_cred = p->p_ucred;
+	/* FIXME - instances */
 	crhold(um->um_cred);
 	um->um_cmode = UN_DIRMODE &~ p->p_cwdi->cwdi_cmask;
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/core_elf32.c mult-netbsd-3.1/sys/kern/core_elf32.c
--- NetBSD-3.1/sys/kern/core_elf32.c	2004-09-17 15:11:24.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/core_elf32.c	2007-11-18 14:10:50.000000000 +0000
@@ -317,7 +317,7 @@
 		    sizeof(cpi.cpi_sigcatch));
 
 		cpi.cpi_pid = p->p_pid;
-		cpi.cpi_ppid = p->p_pptr->p_pid;
+		cpi.cpi_ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
 		cpi.cpi_pgrp = p->p_pgid;
 		cpi.cpi_sid = p->p_session->s_sid;
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/init_main.c mult-netbsd-3.1/sys/kern/init_main.c
--- NetBSD-3.1/sys/kern/init_main.c	2006-01-20 20:48:41.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/init_main.c	2007-12-16 14:56:45.000000000 +0000
@@ -81,7 +81,6 @@
 #include "opt_multiprocessor.h"
 #include "opt_pipe.h"
 #include "opt_syscall_debug.h"
-#include "opt_systrace.h"
 #include "opt_posix.h"
 #include "opt_kcont.h"
 #include "opt_verified_exec.h"
@@ -117,6 +116,7 @@
 #include <sys/sysctl.h>
 #include <sys/event.h>
 #include <sys/mbuf.h>
+#include <sys/inst.h>
 #ifdef FAST_IPSEC
 #include <netipsec/ipsec.h>
 #endif
@@ -132,9 +132,6 @@
 #ifdef P1003_1B_SEMAPHORE
 #include <sys/ksem.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 #include <sys/domain.h>
 #include <sys/namei.h>
 #if NOPENCRYPTO > 0
@@ -186,7 +183,6 @@
 #ifndef curlwp
 struct	lwp *curlwp = &lwp0;
 #endif
-struct	proc *initproc;
 
 int	nofile = NOFILE;
 int	maxuprc = MAXUPRC;
@@ -216,55 +212,58 @@
 void
 main(void)
 {
-	struct lwp *l;
-	struct proc *p;
-	struct pdevinit *pdev;
-	int s, error;
-	u_int i;
-	rlim_t lim;
-	extern struct pdevinit pdevinit[];
-	extern void schedcpu(void *);
-#if defined(NFSSERVER) || defined(NFS)
-	extern void nfs_init(void);
-#endif
+	struct lwp 		*l;
+	struct proc 		*p;
+	struct pdevinit 	*pdev;
+	int 			s, error;
+	u_int 			i;
+	rlim_t 			lim;
 #ifdef NVNODE_IMPLICIT
-	int usevnodes;
+	int 			usevnodes;
 #endif
+	extern struct pdevinit	pdevinit[];
 
-	/*
-	 * Initialize the current LWP pointer (curlwp) before
-	 * any possible traps/probes to simplify trap processing.
-	 */
+	extern void 		schedcpu(void *);
+#if defined(NFSSERVER) || defined(NFS)
+	extern void 		nfs_init(void);
+#endif
+
+	/* Initialize the current LWP pointer (curlwp) before any possible
+	 * traps/probes to simplify trap processing.  These will later
+	 * refer to the swapper; they have a limited instance. */
 	l = &lwp0;
 	curlwp = l;
 	l->l_cpu = curcpu();
 	l->l_proc = &proc0;
 	l->l_lid = 1;
 
-	/*
-	 * Attempt to find console and initialize
-	 * in case of early panic or other messages.
-	 */
+	/* Attempt to find console and initialize in case of early panic or
+	 * other messages. */
 	consinit();
+
 	printf("%s", copyright);
 
+	printf("NETBSD-MULT IS ALPHA SOFTWARE: USE AT YOUR OWN RISK!\n");
+
 	KERNEL_LOCK_INIT();
 
+	/* Initialise the virtual memory manager. */
 	uvm_init();
 
 	/* Do machine-dependent initialization. */
 	cpu_startup();
 
+	/* Initialise the instance subsystem. */
+	inst_init();
+
 	/* Initialize callouts. */
 	callout_startup();
 
 	/* Initialize the buffer cache */
 	bufinit();
 
-	/*
-	 * Initialize mbuf's.  Do this now because we might attempt to
-	 * allocate mbufs or mbuf clusters during autoconfiguration.
-	 */
+	/* Initialize mbuf's.  Do this now because we might attempt to
+	 * allocate mbufs or mbuf clusters during autoconfiguration. */
 	mbinit();
 
 	/* Initialize sockets. */
@@ -275,48 +274,51 @@
         kcont_init();
 #endif
 
-	/*
-	 * The following things must be done before autoconfiguration.
-	 */
-	evcnt_init();		/* initialize event counters */
-	tty_init();		/* initialize tty list */
+	/* These things must be done before autoconfiguration. */
+
+	/* Initialize event counters. */
+	evcnt_init();		
+
+	/* Initialise tty list. */
+	tty_init();
 #if NRND > 0
-	rnd_init();		/* initialize RNG */
+	/* Initialise RNGs. */
+	rnd_init();
 #endif
 #if NOPENCRYPTO > 0
-	/* Initialize crypto subsystem before configuring crypto hardware. */
+	/* Initialize crypto subsystem before crypto hardware. */
 	(void)crypto_init();
 #endif
 	/* Initialize the sysctl subsystem. */
 	sysctl_init();
-
-	/* Initialize process and pgrp structures. */
-	procinit();
-
 #ifdef LKM
 	/* Initialize the LKM system. */
 	lkm_init();
 #endif
-
-	/*
-	 * Create process 0 (the swapper).
-	 */
+	/* Create process 0 (the swapper).  */
 	p = &proc0;
+
+	/* Create credentials and generate the initial instance. */
+	cred0.p_refcnt = 1;
+	p->p_cred = &cred0;
+	p->p_ucred = crget(inst_alloc(INST_NOWAIT));
+	p->p_ucred->cr_ngroups = 1;
+	p->p_ucred->cr_inst->i_nprocs = 1;
+	strncpy(p->p_comm, "swapper", MAXCOMLEN);
+
 	proc0_insert(p, l, &pgrp0, &session0);
 
-	/*
-	 * Set P_NOCLDWAIT so that kernel threads are reparented to
-	 * init(8) when they exit.  init(8) can easily wait them out
-	 * for us.
-	 */
+	/* Set P_NOCLDWAIT so that kernel threads are reparented to
+	 * init(8) when they exit.  init(8) can easily wait them out for
+	 * us.  XXX - this doesn't work with instances. */
 	p->p_flag = P_SYSTEM | P_NOCLDWAIT;
 	p->p_stat = SACTIVE;
 	p->p_nice = NZERO;
 	p->p_emul = &emul_netbsd;
+
 #ifdef __HAVE_SYSCALL_INTERN
 	(*p->p_emul->e_syscall_intern)(p);
 #endif
-	strncpy(p->p_comm, "swapper", MAXCOMLEN);
 
 	l->l_flag = L_INMEM;
 	l->l_stat = LSONPROC;
@@ -324,12 +326,6 @@
 
 	callout_init(&l->l_tsleep_ch);
 
-	/* Create credentials. */
-	cred0.p_refcnt = 1;
-	p->p_cred = &cred0;
-	p->p_ucred = crget();
-	p->p_ucred->cr_ngroups = 1;	/* group 0 */
-
 	/* Create the file descriptor table. */
 	p->p_fd = &filedesc0.fd_fd;
 	fdinit1(&filedesc0);
@@ -378,7 +374,7 @@
 	/*
 	 * Charge root for one process.
 	 */
-	(void)chgproccnt(0, 1);
+	(void)chgproccnt(p->p_inst, 0, 1);
 
 	rqinit();
 
@@ -464,9 +460,6 @@
 	/* Initialize system accouting. */
 	acct_init();
 
-#ifdef SYSTRACE
-	systrace_init();
-#endif
 	/*
 	 * Initialize signal-related data structures, and signal state
 	 * for proc0.
@@ -487,7 +480,9 @@
 	 * wait for us to inform it that the root file system has been
 	 * mounted.
 	 */
-	if (fork1(l, 0, SIGCHLD, NULL, 0, start_init, NULL, NULL, &initproc))
+	/* FIXME - initproc doesn't exist in the kernel's instance */
+	if (forkinst1(start_init, NULL, "/", NULL, 
+				&proc0.p_inst->i_initproc))
 		panic("fork init");
 
 	/*
@@ -558,18 +553,19 @@
 	 * info.  All other processes are kthreads, which merely
 	 * share proc0's CWD info.
 	 */
-	initproc->p_cwdi->cwdi_cdir = rootvnode;
-	VREF(initproc->p_cwdi->cwdi_cdir);
-	initproc->p_cwdi->cwdi_rdir = NULL;
+	proc0.p_inst->i_initproc->p_cwdi->cwdi_cdir = rootvnode;
+	VREF(proc0.p_inst->i_initproc->p_cwdi->cwdi_cdir);
+	proc0.p_inst->i_initproc->p_cwdi->cwdi_rdir = NULL;
 
 	/*
 	 * Now can look at time, having had a chance to verify the time
 	 * from the file system.  Reset p->p_rtime as it may have been
 	 * munched in mi_switch() after the time got set.
 	 */
-	proclist_lock_read();
+	proclist_lock_read(proc0.p_inst);
+
 	s = splsched();
-	LIST_FOREACH(p, &allproc, p_list) {
+	LIST_FOREACH(p, &proc0.p_inst->i_allproc, p_list) {
 		KASSERT((p->p_flag & P_MARKER) == 0);
 		p->p_stats->p_start = mono_time = boottime = time;
 		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
@@ -579,7 +575,7 @@
 		p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
 	}
 	splx(s);
-	proclist_unlock_read();
+	proclist_unlock_read(proc0.p_inst);
 
 	/* Create the pageout daemon kernel thread. */
 	uvm_swap_init();
@@ -587,8 +583,8 @@
 		panic("fork pagedaemon");
 
 	/* Create the filesystem syncer kernel thread. */
-	if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
-		panic("fork syncer");
+	if (kthread_create1(instdaemon, NULL, NULL, "instdaemon"))
+		panic("fork instdaemon");
 
 	/* Create the aiodone daemon kernel thread. */
 	if (kthread_create1(uvm_aiodone_daemon, NULL, &uvm.aiodoned_proc,
@@ -604,6 +600,11 @@
 	exec_init(1);
 
 	/*
+	 * Label our instance as running.
+	 */
+	proc0.p_inst->i_state = INST_RUNNING;
+
+	/*
 	 * Okay, now we can let init(8) exec!  It's off to userland!
 	 */
 	start_init_exec = 1;
@@ -653,26 +654,28 @@
 static void
 start_init(void *arg)
 {
-	struct lwp *l = arg;
-	struct proc *p = l->l_proc;
-	vaddr_t addr;
+	struct lwp 	*l = arg;
+	struct proc 	*p = l->l_proc;
+	vaddr_t 	addr;
 	struct sys_execve_args /* {
 		syscallarg(const char *) path;
 		syscallarg(char * const *) argp;
 		syscallarg(char * const *) envp;
 	} */ args;
-	int options, i, error;
-	register_t retval[2];
-	char flags[4], *flagsp;
-	const char *path, *slash;
-	char *ucp, **uap, *arg0, *arg1 = NULL;
-	char ipath[129];
-	int ipx, len;
+	int 		options, i, error;
+	register_t 	retval[2];
+	char 		flags[4], *flagsp;
+	const char 	*path, *slash;
+	char 		*ucp, **uap, *arg0, *arg1 = NULL;
+	char 		ipath[129];
+	int 		ipx, len;
 
 	/*
 	 * Now in process 1.
 	 */
 	strncpy(p->p_comm, "init", MAXCOMLEN);
+	p->p_inst->i_initproc = p;
+	p->p_inst->i_state = INST_RUNNING;
 
 	/*
 	 * Wait for main() to tell us that it's safe to exec.
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/init_sysctl.c mult-netbsd-3.1/sys/kern/init_sysctl.c
--- NetBSD-3.1/sys/kern/init_sysctl.c	2006-04-07 13:31:52.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/init_sysctl.c	2007-12-18 18:02:09.000000000 +0000
@@ -70,6 +70,7 @@
 #include <sys/exec.h>
 #include <sys/conf.h>
 #include <sys/device.h>
+#include <sys/inst.h>
 #define	VERIEXEC_NEED_NODE
 #include <sys/verified_exec.h>
 
@@ -93,6 +94,7 @@
  */
 #define KERN_PROCSLOP	(5 * sizeof(struct kinfo_proc))
 #define KERN_LWPSLOP	(5 * sizeof(struct kinfo_lwp))
+#define KERN_INSTSLOP	(5 * sizeof(struct kinfo_inst))
 
 #ifndef MULTIPROCESSOR
 #define	sysctl_ncpus()	(1)
@@ -119,7 +121,7 @@
 static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
 static int sysctl_kern_securelevel(SYSCTLFN_PROTO);
 static int sysctl_kern_hostid(SYSCTLFN_PROTO);
-static int sysctl_setlen(SYSCTLFN_PROTO);
+static int sysctl_kern_hostname(SYSCTLFN_PROTO);
 static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
 static int sysctl_kern_file(SYSCTLFN_PROTO);
 static int sysctl_kern_autonice(SYSCTLFN_PROTO);
@@ -135,7 +137,6 @@
 static int sysctl_kern_sbmax(SYSCTLFN_PROTO);
 static int sysctl_kern_urnd(SYSCTLFN_PROTO);
 static int sysctl_kern_lwp(SYSCTLFN_PROTO);
-static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
 static int sysctl_kern_root_partition(SYSCTLFN_PROTO);
 static int sysctl_kern_drivers(SYSCTLFN_PROTO);
 static int sysctl_kern_file2(SYSCTLFN_PROTO);
@@ -143,11 +144,13 @@
 static int sysctl_kern_veriexec(SYSCTLFN_PROTO);
 #endif
 static int sysctl_doeproc(SYSCTLFN_PROTO);
+static int sysctl_doeinst(SYSCTLFN_PROTO);
 static int sysctl_kern_proc_args(SYSCTLFN_PROTO);
 static int sysctl_hw_usermem(SYSCTLFN_PROTO);
 static int sysctl_hw_cnmagic(SYSCTLFN_PROTO);
 static int sysctl_hw_ncpu(SYSCTLFN_PROTO);
 
+static void fill_inst(struct inst *, struct kinfo_inst *);
 static void fill_kproc2(struct proc *, struct kinfo_proc2 *);
 static void fill_lwp(struct lwp *l, struct kinfo_lwp *kl);
 static void fill_file(struct kinfo_file *, const struct file *, struct proc *,
@@ -320,7 +323,7 @@
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_STRING, "hostname",
 		       SYSCTL_DESCR("System hostname"),
-		       sysctl_setlen, 0, &hostname, MAXHOSTNAMELEN,
+		       sysctl_kern_hostname, 0, NULL, MAXHOSTNAMELEN,
 		       CTL_KERN, KERN_HOSTNAME, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_HEX,
@@ -396,7 +399,7 @@
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_STRING, "domainname",
 		       SYSCTL_DESCR("YP domain name"),
-		       sysctl_setlen, 0, &domainname, MAXHOSTNAMELEN,
+		       sysctl_kern_hostname, 0, NULL, MAXHOSTNAMELEN,
 		       CTL_KERN, KERN_DOMAINNAME, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
@@ -645,12 +648,11 @@
 		       sysctl_kern_lwp, 0, NULL, 0,
 		       CTL_KERN, KERN_LWP, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
-		       CTLTYPE_INT, "forkfsleep",
-		       SYSCTL_DESCR("Milliseconds to sleep on fork failure due "
-				    "to process limits"),
-		       sysctl_kern_forkfsleep, 0, NULL, 0,
-		       CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "lwp_inst",
+		       SYSCTL_DESCR("Instance LWP information"),
+		       sysctl_kern_lwp, 0, NULL, 0,
+		       CTL_KERN, KERN_LWP_INST, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_IMMEDIATE,
 		       CTLTYPE_INT, "posix_threads",
@@ -769,6 +771,20 @@
 #endif /* VERIFIED_EXEC */
 }
 
+SYSCTL_SETUP(sysctl_kern_inst_setup,
+		"system kern.inst subtree setup")
+{
+	sysctl_createv(clog, 0, NULL, NULL,
+			CTLFLAG_PERMANENT, CTLTYPE_NODE, "kern", NULL,
+			NULL, 0, NULL, 0, CTL_KERN, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT, CTLTYPE_NODE, "inst",
+		       SYSCTL_DESCR("System-wide instance information"),
+		       sysctl_doeinst, 0, NULL, 0,
+		       CTL_KERN, KERN_INST, CTL_EOL);
+}
+
+
 SYSCTL_SETUP(sysctl_kern_proc_setup,
 	     "sysctl kern.proc/proc2/proc_args subtree setup")
 {
@@ -787,6 +803,12 @@
 		       CTL_KERN, KERN_PROC, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "proc2_inst",
+		       SYSCTL_DESCR("Instance-wide process information"),
+		       sysctl_doeproc, 0, NULL, 0,
+		       CTL_KERN, KERN_PROC2_INST, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT,
 		       CTLTYPE_NODE, "proc2",
 		       SYSCTL_DESCR("Machine-independent process information"),
 		       sysctl_doeproc, 0, NULL, 0,
@@ -797,24 +819,15 @@
 		       SYSCTL_DESCR("Process argument information"),
 		       sysctl_kern_proc_args, 0, NULL, 0,
 		       CTL_KERN, KERN_PROC_ARGS, CTL_EOL);
-
-	/*
-	  "nodes" under these:
-
-	  KERN_PROC_ALL
-	  KERN_PROC_PID pid
-	  KERN_PROC_PGRP pgrp
-	  KERN_PROC_SESSION sess
-	  KERN_PROC_TTY tty
-	  KERN_PROC_UID uid
-	  KERN_PROC_RUID uid
-	  KERN_PROC_GID gid
-	  KERN_PROC_RGID gid
-
-	  all in all, probably not worth the effort...
-	*/
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "proc_args_inst",
+		       SYSCTL_DESCR("Instance process argument information"),
+		       sysctl_kern_proc_args, 0, NULL, 0,
+		       CTL_KERN, KERN_PROC_ARGS_INST, CTL_EOL);
 }
 
+
 SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
 {
 	u_int u;
@@ -1142,32 +1155,40 @@
 	return (0);
 }
 
+
 /*
- * sysctl helper function for kern.hostname and kern.domainnname.
- * resets the relevant recorded length when the underlying name is
- * changed.
+ * Helper for kern.hostname.  Returns the hostname associated with the
+ * LWP's instance.
  */
 static int
-sysctl_setlen(SYSCTLFN_ARGS)
+sysctl_kern_hostname(SYSCTLFN_ARGS)
 {
-	int error;
+	int 		error;
+	char		buf[MAXHOSTNAMELEN];
+	struct sysctlnode node;
 
-	error = sysctl_lookup(SYSCTLFN_CALL(rnode));
-	if (error || newp == NULL)
-		return (error);
+	buf[0] = 0;
 
-	switch (rnode->sysctl_num) {
-	case KERN_HOSTNAME:
-		hostnamelen = strlen((const char*)rnode->sysctl_data);
-		break;
-	case KERN_DOMAINNAME:
-		domainnamelen = strlen((const char*)rnode->sysctl_data);
-		break;
+	if (oldp) {
+		if (KERN_HOSTNAME == rnode->sysctl_num)
+			inst_get_hostname(l, buf, *oldlenp);
+		else
+			inst_get_domainname(l, buf, *oldlenp);
 	}
 
-	return (0);
+	node = *rnode;
+	node.sysctl_data = &buf[0];
+
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || NULL == newp) 
+		return(error);
+
+	if (KERN_HOSTNAME == rnode->sysctl_num)
+		return (inst_set_hostname(l, buf));
+	return (inst_set_domainname(l, buf));
 }
 
+
 /*
  * sysctl helper routine for kern.clockrate.  assembles a struct on
  * the fly to be returned to the caller.
@@ -1196,10 +1217,14 @@
 static int
 sysctl_kern_file(SYSCTLFN_ARGS)
 {
-	int error;
-	size_t buflen;
-	struct file *fp;
-	char *start, *where;
+	int 		error;
+	size_t 		buflen;
+	struct file 	*fp;
+	char 		*start, *where;
+
+	KASSERT(l);
+	KASSERT(l->l_proc);
+	KASSERT(l->l_inst);
 
 	start = where = oldp;
 	buflen = *oldlenp;
@@ -1207,27 +1232,29 @@
 		/*
 		 * overestimate by 10 files
 		 */
-		*oldlenp = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
+		*oldlenp = sizeof(l->l_inst->i_filehead) + 
+			(l->l_inst->i_nfiles + 10) * sizeof(struct file);
 		return (0);
 	}
 
 	/*
 	 * first copyout filehead
 	 */
-	if (buflen < sizeof(filehead)) {
+	if (buflen < sizeof(l->l_inst->i_filehead)) {
 		*oldlenp = 0;
 		return (0);
 	}
-	error = copyout(&filehead, where, sizeof(filehead));
+	error = copyout(&l->l_inst->i_filehead, 
+			where, sizeof(l->l_inst->i_filehead));
 	if (error)
 		return (error);
-	buflen -= sizeof(filehead);
-	where += sizeof(filehead);
+	buflen -= sizeof(l->l_inst->i_filehead);
+	where += sizeof(l->l_inst->i_filehead);
 
 	/*
 	 * followed by an array of file structures
 	 */
-	LIST_FOREACH(fp, &filehead, f_list) {
+	LIST_FOREACH(fp, &l->l_inst->i_filehead, f_list) {
 		if (buflen < sizeof(struct file)) {
 			*oldlenp = where - start;
 			return (ENOMEM);
@@ -1745,11 +1772,13 @@
 sysctl_kern_lwp(SYSCTLFN_ARGS)
 {
 	struct kinfo_lwp klwp;
-	struct proc *p;
-	struct lwp *l2;
-	char *where, *dp;
-	int pid, elem_size, elem_count;
-	int buflen, needed, error;
+	struct proc 	*p;
+	struct lwp 	*l2;
+	char 		*where, *dp;
+	int 		pid, elem_size, elem_count,
+			buflen, needed, error;
+	u_int 		uuid;
+	struct inst 	*i;
 
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
@@ -1758,15 +1787,33 @@
 	buflen = where != NULL ? *oldlenp : 0;
 	error = needed = 0;
 
-	if (newp != NULL || namelen != 3)
+	if (newp != NULL)
 		return (EINVAL);
-	pid = name[0];
-	elem_size = name[1];
-	elem_count = name[2];
 
-	p = pfind(pid);
-	if (p == NULL)
+	if (KERN_LWP == rnode->sysctl_num) {
+		if (namelen != 3)
+			return (EINVAL);
+		pid = name[0];
+		uuid = l->l_inst->i_uuid;
+		elem_size = name[1];
+		elem_count = name[2];
+	} else {
+		if (namelen != 4)
+			return (EINVAL);
+		uuid = (u_int)name[0];
+		pid = name[1];
+		elem_size = name[2];
+		elem_count = name[3];
+	}
+
+	if (NULL == (i = inst_lookup(uuid)))
 		return (ESRCH);
+
+	if (NULL == (p = pfind(i, pid))) {
+		inst_release(i);
+		return (ESRCH);
+	}
+
 	LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
 		if (buflen >= elem_size && elem_count > 0) {
 			fill_lwp(l2, &klwp);
@@ -1784,6 +1831,7 @@
 		}
 		needed += elem_size;
 	}
+	inst_release(i);
 
 	if (where != NULL) {
 		*oldlenp = dp - where;
@@ -1794,44 +1842,12 @@
 		*oldlenp = needed;
 	}
 	return (0);
+
  cleanup:
+	inst_release(i);
 	return (error);
 }
 
-/*
- * sysctl helper routine for kern.forkfsleep node.  ensures that the
- * given value is not too large or two small, and is at least one
- * timer tick if not zero.
- */
-static int
-sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
-{
-	/* userland sees value in ms, internally is in ticks */
-	extern int forkfsleep;		/* defined in kern/kern_fork.c */
-	int error, timo, lsleep;
-	struct sysctlnode node;
-
-	lsleep = forkfsleep * 1000 / hz;
-	node = *rnode;
-	node.sysctl_data = &lsleep;
-	error = sysctl_lookup(SYSCTLFN_CALL(&node));
-	if (error || newp == NULL)
-		return (error);
-
-	/* refuse negative values, and overly 'long time' */
-	if (lsleep < 0 || lsleep > MAXSLP * 1000)
-		return (EINVAL);
-
-	timo = mstohz(lsleep);
-
-	/* if the interval is >0 ms && <1 tick, use 1 tick */
-	if (lsleep != 0 && timo == 0)
-		forkfsleep = 1;
-	else
-		forkfsleep = timo;
-
-	return (0);
-}
 
 /*
  * sysctl helper routine for kern.root_partition
@@ -1846,6 +1862,7 @@
 	return (sysctl_lookup(SYSCTLFN_CALL(&node)));
 }
 
+
 /*
  * sysctl helper function for kern.drivers
  */
@@ -1903,14 +1920,18 @@
 static int
 sysctl_kern_file2(SYSCTLFN_ARGS)
 {
-	struct proc *p;
-	struct file *fp;
+	struct proc 	*p;
+	struct file 	*fp;
 	struct filedesc *fd;
 	struct kinfo_file kf;
-	char *dp;
-	u_int i, op;
-	size_t len, needed, elem_size, out_size;
-	int error, arg, elem_count;
+	char 		*dp;
+	u_int 		i, op;
+	size_t 		len, needed, elem_size, out_size;
+	int 		error, arg, elem_count;
+
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_inst);
 
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
@@ -1938,7 +1959,7 @@
 		 */
 		if (arg != 0)
 			return (EINVAL);
-		LIST_FOREACH(fp, &filehead, f_list) {
+		LIST_FOREACH(fp, &l->l_inst->i_filehead, f_list) {
 			if (len >= elem_size && elem_count > 0) {
 				fill_file(&kf, fp, NULL, 0);
 				error = copyout(&kf, dp, out_size);
@@ -1958,8 +1979,8 @@
 		if (arg < -1)
 			/* -1 means all processes */
 			return (EINVAL);
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		proclist_lock_read(l->l_inst);
+		PROCLIST_FOREACH(p, &l->l_inst->i_allproc) {
 			if (p->p_stat == SIDL)
 				/* skip embryonic processes */
 				continue;
@@ -1988,7 +2009,7 @@
 				}
 			}
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(l->l_inst);
 		break;
 	default:
 		return (EINVAL);
@@ -2040,29 +2061,112 @@
 	}
 }
 
+
+static int
+sysctl_doeinst(SYSCTLFN_ARGS)
+{
+	struct kinfo_inst ui;
+	struct inst	*i;
+	char 		*where, *dp2;
+	int 		op;
+	u_int 		elem_size, elem_count;
+	size_t 		buflen, needed;
+	int 		error;
+
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_inst);
+
+	if (namelen == 1 && name[0] == CTL_QUERY)
+		return (sysctl_query(SYSCTLFN_CALL(rnode)));
+
+	dp2 = where = oldp;
+	buflen = where != NULL ? *oldlenp : 0;
+	error = 0;
+	needed = 0;
+
+	if (3 != namelen) 
+		return(EINVAL);
+
+	op = name[0];
+	elem_size = name[1];
+	elem_count = name[2];
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		switch (op) {
+		case (KERN_INST_CUR):
+			if (i->i_uuid != l->l_inst->i_uuid)
+				continue;
+			break;
+		case (KERN_INST_ALL):
+			break;
+		default:
+			error = EINVAL;
+			goto cleanup;
+		}
+		if (buflen >= elem_size && elem_count > 0) {
+			fill_inst(i, &ui);
+			error = copyout(&ui, dp2, 
+					min(sizeof(ui), elem_size));
+			if (error)
+				goto cleanup;
+			dp2 += elem_size;
+			buflen -= elem_size;
+			elem_count--;
+		}
+		needed += elem_size;
+		if (KERN_INST_CUR == op)
+			/* We don't need any more. */
+			break;
+	}
+	instlist_unlock_read();
+
+	if (where != NULL) {
+		*oldlenp = dp2 - where;
+		if (needed > *oldlenp)
+			return(ENOMEM);
+	} else {
+		needed += KERN_INSTSLOP;
+		*oldlenp = needed;
+	}
+	return(0);
+
+ cleanup:
+	instlist_unlock_read();
+	return(error);
+}
+
+
 static int
 sysctl_doeproc(SYSCTLFN_ARGS)
 {
-	struct eproc eproc;
+	struct eproc	eproc;
 	struct kinfo_proc2 kproc2;
 	struct kinfo_proc *dp;
-	struct proc *p;
+	struct proc	*p;
 	const struct proclist_desc *pd;
-	char *where, *dp2;
-	int type, op, arg;
-	u_int elem_size, elem_count;
-	size_t buflen, needed;
-	int error;
+	char		*where, *dp2;
+	struct inst	*i;
+	int		type, op, arg;
+	u_int		elem_size, elem_count, uuid;
+	size_t		buflen, needed;
+	int		error;
+
+	KASSERT(l);
+	KASSERT(l->l_proc);
+	KASSERT(l->l_inst);
 
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
 
+	i = NULL;
 	dp = oldp;
 	dp2 = where = oldp;
 	buflen = where != NULL ? *oldlenp : 0;
 	error = 0;
 	needed = 0;
 	type = rnode->sysctl_num;
+	uuid = l->l_inst->i_uuid;
 
 	if (type == KERN_PROC) {
 		if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
@@ -2073,6 +2177,14 @@
 		else
 			arg = 0;		/* Quell compiler warning */
 		elem_size = elem_count = 0;	/* Ditto */
+	} else if (type == KERN_PROC2_INST) {
+		if (namelen != 5)
+			return (EINVAL);
+		uuid = (u_int)name[0];
+		op = name[1];
+		arg = name[2];
+		elem_size = name[3];
+		elem_count = name[4];
 	} else {
 		if (namelen != 4)
 			return (EINVAL);
@@ -2082,9 +2194,16 @@
 		elem_count = name[3];
 	}
 
-	proclist_lock_read();
+	if (NULL == (i = inst_lookup(uuid)))
+		return (ESRCH);
+	if (INST_RUNNING != i->i_state) {
+		inst_release(i);
+		return (ESRCH);
+	}
+
+	proclist_lock_read(i);
+	pd = i->i_proclists;
 
-	pd = proclists;
 again:
 	PROCLIST_FOREACH(p, pd->pd_list) {
 		/*
@@ -2193,7 +2312,9 @@
 	pd++;
 	if (pd->pd_list != NULL)
 		goto again;
-	proclist_unlock_read();
+
+	proclist_unlock_read(i);
+	inst_release(i);
 
 	if (where != NULL) {
 		if (type == KERN_PROC)
@@ -2207,8 +2328,13 @@
 		*oldlenp = needed;
 	}
 	return (0);
+
  cleanup:
-	proclist_unlock_read();
+
+	KASSERT(i);
+	proclist_unlock_read(i);
+	inst_release(i);
+
 	return (error);
 }
 
@@ -2226,16 +2352,29 @@
 	vaddr_t argv;
 	pid_t pid;
 	int nargv, type, error;
-	char *arg;
-	char *tmp;
+	char *arg, *tmp;
+	u_int uuid;
+	struct inst *inst;
 
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
 
-	if (newp != NULL || namelen != 2)
+	if (newp != NULL)
 		return (EINVAL);
-	pid = name[0];
-	type = name[1];
+
+	if (KERN_PROC_ARGS == rnode->sysctl_num) {
+		if (namelen != 2)
+			return (EINVAL);
+		uuid = l->l_inst->i_uuid;
+		pid = name[0];
+		type = name[1];
+	} else {
+		if (namelen != 3)
+			return (EINVAL);
+		uuid = (u_int)name[0];
+		pid = name[1];
+		type = name[2];
+	}
 
 	switch (type) {
 	case KERN_PROC_ARGV:
@@ -2249,15 +2388,24 @@
 	}
 
 	/* check pid */
-	if ((p = pfind(pid)) == NULL)
+
+	if (NULL == (inst = inst_lookup(uuid))) {
 		return (EINVAL);
+	}
+
+	if ((p = pfind(inst, pid)) == NULL) {
+		inst_release(inst);
+		return (EINVAL);
+	}
 
 	/* only root or same user change look at the environment */
 	if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
 		if (up->p_ucred->cr_uid != 0) {
 			if (up->p_cred->p_ruid != p->p_cred->p_ruid ||
-			    up->p_cred->p_ruid != p->p_cred->p_svuid)
+			    up->p_cred->p_ruid != p->p_cred->p_svuid) {
+				inst_release(inst);
 				return (EPERM);
+			}
 		}
 	}
 
@@ -2266,6 +2414,7 @@
 			*oldlenp = sizeof (int);
 		else
 			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
+		inst_release(inst);
 		return (0);
 	}
 
@@ -2273,15 +2422,19 @@
 	 * Zombies don't have a stack, so we can't read their psstrings.
 	 * System processes also don't have a user stack.
 	 */
-	if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0)
+	if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
+		inst_release(inst);
 		return (EINVAL);
+	}
 
 	/*
 	 * Lock the process down in memory.
 	 */
 	/* XXXCDC: how should locking work here? */
-	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
+	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
+		inst_release(inst);
 		return (EFAULT);
+	}
 
 	p->p_vmspace->vm_refcnt++;	/* XXX */
 
@@ -2303,8 +2456,9 @@
 	auio.uio_rw = UIO_READ;
 	auio.uio_procp = NULL;
 	error = uvm_io(&p->p_vmspace->vm_map, &auio);
-	if (error)
+	if (error){ 
 		goto done;
+	}
 
 	if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV)
 		memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv));
@@ -2327,6 +2481,7 @@
 		memcpy(&tmp, (char *)&pss + p->p_psenv, sizeof(tmp));
 		break;
 	default:
+		inst_release(inst);
 		return (EINVAL);
 	}
 	auio.uio_offset = (off_t)(unsigned long)tmp;
@@ -2389,8 +2544,8 @@
 
 done:
 	uvmspace_free(p->p_vmspace);
-
 	free(arg, M_TEMP);
+	inst_release(inst);
 	return (error);
 }
 
@@ -2582,10 +2737,7 @@
 	ki->p_flag = p->p_flag;
 
 	ki->p_pid = p->p_pid;
-	if (p->p_pptr)
-		ki->p_ppid = p->p_pptr->p_pid;
-	else
-		ki->p_ppid = 0;
+	ki->p_ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
 	ki->p_sid = p->p_session->s_sid;
 	ki->p__pgid = p->p_pgrp->pg_id;
 
@@ -2768,6 +2920,29 @@
 		kl->l_cpuid = KI_NOCPU;
 }
 
+void
+fill_inst(struct inst *i, struct kinfo_inst *ui)
+{
+	KASSERT(NULL != i);
+	KASSERT(NULL != ui);
+
+	simple_lock(&i->i_lock);
+	ui->i_uuid = i->i_uuid;
+	ui->i_refcnt = i->i_refcnt;
+	ui->i_state = (u_int32_t)i->i_state;
+
+	strlcpy(ui->i_host, i->i_host, MAXHOSTNAMELEN);
+	strlcpy(ui->i_domain, i->i_domain, MAXHOSTNAMELEN);
+	simple_unlock(&i->i_lock);
+
+	ui->i_ncreds = i->i_ncreds;
+	ui->i_nprocs = i->i_nprocs;
+	ui->i_nsess = i->i_nsess;
+	ui->i_nfiles = i->i_nfiles;
+	ui->i_npipes = i->i_npipes;
+	ui->i_nsocks = i->i_nsocks;
+}
+
 /*
  * Fill in an eproc structure for the specified process.
  */
@@ -2801,10 +2976,8 @@
 		if (l->l_wmesg)
 			strncpy(ep->e_wmesg, l->l_wmesg, WMESGLEN);
 	}
-	if (p->p_pptr)
-		ep->e_ppid = p->p_pptr->p_pid;
-	else
-		ep->e_ppid = 0;
+
+	ep->e_ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
 	ep->e_pgid = p->p_pgrp->pg_id;
 	ep->e_sid = ep->e_sess->s_sid;
 	ep->e_jobc = p->p_pgrp->pg_jobc;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/init_sysent.c mult-netbsd-3.1/sys/kern/init_sysent.c
--- NetBSD-3.1/sys/kern/init_sysent.c	2005-02-27 00:02:40.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/init_sysent.c	2007-11-15 13:34:52.000000000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init_sysent.c,v 1.163 2005/02/27 00:02:40 perry Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call switch table.
@@ -8,7 +8,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.163 2005/02/27 00:02:40 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD$");
 
 #include "opt_ktrace.h"
 #include "opt_nfsserver.h"
@@ -25,6 +25,7 @@
 #include <sys/mount.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 #ifdef COMPAT_43
 #define	compat_43(func) __CONCAT(compat_43_,func)
@@ -994,8 +995,8 @@
 	    sys_pselect },			/* 373 = pselect */
 	{ 4, s(struct sys_pollts_args), 0,
 	    sys_pollts },			/* 374 = pollts */
-	{ 0, 0, 0,
-	    sys_nosys },			/* 375 = filler */
+	{ 1, s(struct sys_instctl_args), 0,
+	    sys_instctl },			/* 375 = instctl */
 	{ 0, 0, 0,
 	    sys_nosys },			/* 376 = filler */
 	{ 0, 0, 0,
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_acct.c mult-netbsd-3.1/sys/kern/kern_acct.c
--- NetBSD-3.1/sys/kern/kern_acct.c	2004-12-13 08:46:43.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_acct.c	2007-11-26 15:42:56.000000000 +0000
@@ -1,4 +1,6 @@
-/*	$NetBSD: kern_acct.c,v 1.60 2004/12/13 08:46:43 yamt Exp $	*/
+/* $Id: kern_acct.c,v 1.8 2007/11/26 15:42:56 kristaps Exp $ */
+
+/* $NetBSD: kern_acct.c,v 1.60 2004/12/13 08:46:43 yamt Exp $ */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -94,117 +96,184 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
+
+enum acct_st_t 
+{ 
+	ACCT_STOP, 
+	ACCT_ACTIVE, 
+	ACCT_SUSPENDED 
+};
+
+struct inst_acct
+{
+	enum acct_st_t	acct_state; 	/* Current account state. */
+	struct vnode	*acct_vp; 	/* Current vnode pointer. */
+	struct ucred	*acct_ucred; 	/* Account-file owner. */
+	struct lock	acct_lock; 	/* Serialise access. */
+};
+
+
+/*
+ * These refer to global resources: the dkwatcher.
+ */
+
+struct proc	*acct_dkwatcher;	/* Free discspace checker. */
+struct lock	acct_lock; 		/* Serialise access. */
+
+
+void
+acct_init(void)
+{
+	lockinit(&acct_lock, PWAIT, "acctglk", 0, 0);
+	acct_dkwatcher = NULL;
+}
+
+
+int
+inst_acct_alloc(inst_acct_t *p, int flags)
+{
+	struct inst_acct *i;
+
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_acct), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_acct));
+
+	i->acct_state = ACCT_STOP;
+	i->acct_vp = NULLVP;
+	i->acct_ucred = NULL;
+	lockinit(&i->acct_lock, PWAIT, "acctlk", 0, 0);
+
+	*p = i;
+	return(1);
+}
+
+void
+inst_acct_free(inst_acct_t p)
+{
+	KASSERT(p);
+	free(p, M_INST);
+}
+
+
 /*
  * The routines implemented in this file are described in:
  *      Leffler, et al.: The Design and Implementation of the 4.3BSD
  *	    UNIX Operating System (Addison Welley, 1989)
  * on pages 62-63.
  *
- * Arguably, to simplify accounting operations, this mechanism should
- * be replaced by one in which an accounting log file (similar to /dev/klog)
- * is read by a user process, etc.  However, that has its own problems.
+ * Arguably, to simplify accounting operations, this mechanism should be
+ * replaced by one in which an accounting log file (similar to
+ * /dev/klog) is read by a user process, etc.  However, that has its own
+ * problems.
+ *
+ * A significant amount of this was re-written to support multiple
+ * instance contexts.
  */
 
-/*
- * The global accounting state and related data.  Gain the lock before
- * accessing these variables.
- */
-enum {
-	ACCT_STOP,
-	ACCT_ACTIVE,
-	ACCT_SUSPENDED
-} acct_state;				/* The current accounting state. */
-struct vnode *acct_vp;			/* Accounting vnode pointer. */
-struct ucred *acct_ucred;		/* Credential of accounting file
-					   owner (i.e root).  Used when
- 					   accounting file i/o.  */
-struct proc *acct_dkwatcher;		/* Free disk space checker. */
+#define	ACCT_LOCK(p)						\
+do {								\
+	(void) lockmgr(&(p)->acct_lock, LK_EXCLUSIVE, NULL);	\
+} while (/* CONSTCOND */0)
 
-/*
- * Lock to serialize system calls and kernel threads.
- */
-struct	lock acct_lock;
-#define	ACCT_LOCK()						\
+#define	ACCT_GLOBAL_LOCK()					\
 do {								\
 	(void) lockmgr(&acct_lock, LK_EXCLUSIVE, NULL);		\
 } while (/* CONSTCOND */0)
-#define	ACCT_UNLOCK()						\
+
+#define	ACCT_UNLOCK(p)						\
+do {								\
+	(void) lockmgr(&(p)->acct_lock, LK_RELEASE, NULL);	\
+} while (/* CONSTCOND */0)
+
+#define	ACCT_GLOBAL_UNLOCK()					\
 do {								\
 	(void) lockmgr(&acct_lock, LK_RELEASE, NULL);		\
 } while (/* CONSTCOND */0)
 
+
 /*
- * Internal accounting functions.
- * The former's operation is described in Leffler, et al., and the latter
- * was provided by UCB with the 4.4BSD-Lite release
- */
-comp_t	encode_comp_t(u_long, u_long);
-void	acctwatch(void *);
-void	acct_stop(void);
-int	acct_chkfree(void);
+ * Internal accounting functions.  The former's operation is described
+ * in Leffler, et al., and the latter was provided by UCB with the
+ * 4.4BSD-Lite release.
+ */
+static comp_t	encode_comp_t(u_long, u_long);
+static int	acct_chkfree(struct inst_acct *, int *);
+static void	acct_stop(struct inst_acct *);
 
 /*
- * Values associated with enabling and disabling accounting
+ * Kernel-thread started to watch accounts.
+ */
+void		acctwatch(void *);
+
+/* 
+ * Values associated with enabling and disabling accounting.  Note that
+ * these don't change, so we're free to leave them as they are.  If they
+ * do change, we must put them in the instance.
  */
 int	acctsuspend = 2;	/* stop accounting when < 2% free space left */
 int	acctresume = 4;		/* resume when free space risen to > 4% */
 int	acctchkfreq = 15;	/* frequency (in seconds) to check space */
 
-void
-acct_init()
-{
-
-	acct_state = ACCT_STOP;
-	acct_vp = NULLVP;
-	acct_ucred = NULL;
-	lockinit(&acct_lock, PWAIT, "acctlk", 0, 0);
-}
 
-void
-acct_stop()
+static void
+acct_stop(struct inst_acct *p)
 {
-	int error;
+	int 	error;
+
+	KASSERT(p);
 
-	if (acct_vp != NULLVP && acct_vp->v_type != VBAD) {
-		error = vn_close(acct_vp, FWRITE, acct_ucred, NULL);
+	if (p->acct_vp != NULLVP && p->acct_vp->v_type != VBAD) {
+		error = vn_close(p->acct_vp, FWRITE, 
+				p->acct_ucred, NULL);
 #ifdef DIAGNOSTIC
-		if (error != 0)
+		if (0 != error)
 			printf("acct_stop: failed to close, errno = %d\n",
-			    error);
+					error);
 #endif
-		acct_vp = NULLVP;
+		p->acct_vp = NULLVP;
 	}
-	if (acct_ucred != NULL) {
-		crfree(acct_ucred);
-		acct_ucred = NULL;
+	if (NULL != p->acct_ucred) {
+		crfree(p->acct_ucred);
+		p->acct_ucred = NULL;
 	}
-	acct_state = ACCT_STOP;
+	p->acct_state = ACCT_STOP;
 }
 
-int
-acct_chkfree()
+
+static int
+acct_chkfree(struct inst_acct *a, int *p)
 {
-	int error;
-	struct statvfs sb;
-	int64_t bavail;
+	int 		error;
+	struct statvfs	sb;
+	int64_t		bavail;
+
+	KASSERT(a);
 
-	error = VFS_STATVFS(acct_vp->v_mount, &sb, NULL);
+	error = VFS_STATVFS(a->acct_vp->v_mount, &sb, NULL);
 	if (error != 0)
 		return (error);
 
 	bavail = sb.f_bfree - sb.f_bresvd;
 
-	switch (acct_state) {
+	switch (a->acct_state) {
 	case ACCT_SUSPENDED:
+		if (p)
+			(*p)++;
 		if (bavail > acctresume * sb.f_blocks / 100) {
-			acct_state = ACCT_ACTIVE;
-			log(LOG_NOTICE, "Accounting resumed\n");
+			a->acct_state = ACCT_ACTIVE;
+			log(LOG_NOTICE, "accounting resumed\n");
 		}
 		break;
 	case ACCT_ACTIVE:
+		if (p)
+			(*p)++;
 		if (bavail <= acctsuspend * sb.f_blocks / 100) {
-			acct_state = ACCT_SUSPENDED;
-			log(LOG_NOTICE, "Accounting suspended\n");
+			a->acct_state = ACCT_SUSPENDED;
+			log(LOG_NOTICE, "accounting suspended\n");
 		}
 		break;
 	case ACCT_STOP:
@@ -213,22 +282,24 @@
 	return (0);
 }
 
+
 /*
  * Accounting system call.  Written based on the specification and
  * previous implementation done by Mark Tinguely.
  */
 int
-sys_acct(l, v, retval)
-	struct lwp *l;
-	void *v;
-	register_t *retval;
+sys_acct(struct lwp *l, void *v, register_t *retval)
 {
 	struct sys_acct_args /* {
 		syscallarg(const char *) path;
 	} */ *uap = v;
 	struct nameidata nd;
-	int error;
-	struct proc *p = l->l_proc;
+	struct inst_acct *a;
+	int 		error;
+	struct proc 	*p;
+
+	p = l->l_proc;
+	a = p->p_inst->i_acct;
 
 	/* Make sure that the caller is root. */
 	if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
@@ -258,7 +329,7 @@
 		if ((pad = (va.va_size % sizeof(struct acct))) != 0) {
 			u_quad_t size = va.va_size - pad;
 #ifdef DIAGNOSTIC
-			printf("Size of accounting file not a multiple of "
+			printf("size of accounting file not a multiple of "
 			    "%lu - incomplete record truncated\n",
 			    (unsigned long)sizeof(struct acct));
 #endif
@@ -273,73 +344,86 @@
 		VOP_UNLOCK(nd.ni_vp, 0);
 	}
 
-	ACCT_LOCK();
+	ACCT_LOCK(a);
 
 	/*
-	 * If accounting was previously enabled, kill the old space-watcher,
-	 * free credential for accounting file i/o,
-	 * ... (and, if no new file was specified, leave).
+	 * If accounting was previously enabled, kill the old
+	 * space-watcher, free credential for accounting file i/o, ...
+	 * (and, if no new file was specified, leave).
 	 */
-	acct_stop();
+	acct_stop(a);
 	if (SCARG(uap, path) == NULL)
 		goto out;
 
 	/*
-	 * Save the new accounting file vnode and credential,
-	 * and schedule the new free space watcher.
+	 * Save the new accounting file vnode and credential, and
+	 * schedule the new free space watcher.
 	 */
-	acct_state = ACCT_ACTIVE;
-	acct_vp = nd.ni_vp;
-	acct_ucred = p->p_ucred;
-	crhold(acct_ucred);
+	a->acct_state = ACCT_ACTIVE;
+	a->acct_vp = nd.ni_vp;
+	a->acct_ucred = p->p_ucred;
+	crhold(a->acct_ucred);
+	inst_hold(p->p_inst);
 
-	error = acct_chkfree();		/* Initial guess. */
+	error = acct_chkfree(a, NULL);
 	if (error != 0) {
-		acct_stop();
+		acct_stop(a);
 		goto out;
 	}
 
+	ACCT_GLOBAL_LOCK();
 	if (acct_dkwatcher == NULL) {
-		error = kthread_create1(acctwatch, NULL, &acct_dkwatcher,
-		    "acctwatch");
-		if (error != 0)
-			acct_stop();
+		error = kthread_create1(acctwatch, NULL,
+				&acct_dkwatcher, "acctwatch");
+		if (error != 0) {
+			acct_stop(a);
+			inst_release(p->p_inst);
+		}
 	}
+	ACCT_GLOBAL_UNLOCK();
 
  out:
-	ACCT_UNLOCK();
+	ACCT_UNLOCK(a);
 	return (error);
+
  bad:
 	vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
 	return error;
 }
 
+
 /*
- * Write out process accounting information, on process exit.
- * Data to be written out is specified in Leffler, et al.
- * and are enumerated below.  (They're also noted in the system
- * "acct.h" header file.)
+ * Write out process accounting information, on process exit.  Data to
+ * be written out is specified in Leffler, et al.  and are enumerated
+ * below.  (They're also noted in the system "acct.h" header file.)
  */
 int
-acct_process(p)
-	struct proc *p;
+acct_process(struct proc *p)
 {
-	struct acct acct;
-	struct rusage *r;
-	struct timeval ut, st, tmp;
-	int s, t, error = 0;
-	struct plimit *oplim = NULL;
+	struct acct	acct;
+	struct rusage	*r;
+	struct timeval	ut, st, tmp;
+	int 		s, t, error;
+	struct plimit	*oplim;
+	struct inst_acct *a;
+
+	error = 0;
+	oplim = NULL;
+
+	KASSERT(p);
+	KASSERT(p->p_inst);
+	KASSERT(p->p_inst->i_acct);
+	a = p->p_inst->i_acct;
 
-	ACCT_LOCK();
+	ACCT_LOCK(a);
 
 	/* If accounting isn't enabled, don't bother */
-	if (acct_state != ACCT_ACTIVE)
+	if (a->acct_state != ACCT_ACTIVE)
 		goto out;
 
 	/*
 	 * Raise the file limit so that accounting can't be stopped by
 	 * the user.
-	 *
 	 * XXX We should think about the CPU limit, too.
 	 */
 	if (p->p_limit->p_refcnt > 1) {
@@ -395,12 +479,12 @@
 	/*
 	 * Now, just write the accounting information to the file.
 	 */
-	VOP_LEASE(acct_vp, p, p->p_ucred, LEASE_WRITE);
-	error = vn_rdwr(UIO_WRITE, acct_vp, (caddr_t)&acct,
+	VOP_LEASE(a->acct_vp, p, p->p_ucred, LEASE_WRITE);
+	error = vn_rdwr(UIO_WRITE, a->acct_vp, (caddr_t)&acct,
 	    sizeof(acct), (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT,
-	    acct_ucred, NULL, NULL);
+	    a->acct_ucred, NULL, NULL);
 	if (error != 0)
-		log(LOG_ERR, "Accounting: write failed %d\n", error);
+		log(LOG_ERR, "accounting: write failed: %d\n", error);
 
 	if (oplim) {
 		limfree(p->p_limit);
@@ -408,25 +492,26 @@
 	}
 
  out:
-	ACCT_UNLOCK();
+	ACCT_UNLOCK(a);
 	return (error);
 }
 
+
 /*
- * Encode_comp_t converts from ticks in seconds and microseconds
- * to ticks in 1/AHZ seconds.  The encoding is described in
- * Leffler, et al., on page 63.
+ * Encode_comp_t converts from ticks in seconds and microseconds to
+ * ticks in 1/AHZ seconds.  The encoding is described in Leffler, et
+ * al., on page 63.
  */
 
 #define	MANTSIZE	13			/* 13 bit mantissa. */
 #define	EXPSIZE		3			/* Base 8 (3 bit) exponent. */
 #define	MAXFRACT	((1 << MANTSIZE) - 1)	/* Maximum fractional value. */
 
-comp_t
-encode_comp_t(s, us)
-	u_long s, us;
+
+static comp_t
+encode_comp_t(u_long s, u_long us)
 {
-	int exp, rnd;
+	int 		exp, rnd;
 
 	exp = 0;
 	rnd = 0;
@@ -451,44 +536,65 @@
 	return (exp);
 }
 
+
 /*
- * Periodically check the file system to see if accounting
- * should be turned on or off.  Beware the case where the vnode
- * has been vgone()'d out from underneath us, e.g. when the file
+ * Kernel-thread to periodically check the file system to see if
+ * accounting should be turned on or off.  Beware the case where the
+ * vnode has been vgone()'d out from underneath us, e.g. when the file
  * system containing the accounting file has been forcibly unmounted.
+ * Make sure, also, that the creating instance still exists.
  */
 void
-acctwatch(arg)
-	void *arg;
+acctwatch(void *arg)
 {
-	int error;
+	int 		error, cnt;
+	struct inst	*i;
+	struct inst_acct *a;
 
-	log(LOG_NOTICE, "Accounting started\n");
-	ACCT_LOCK();
-	while (acct_state != ACCT_STOP) {
-		if (acct_vp->v_type == VBAD) {
-			log(LOG_NOTICE, "Accounting terminated\n");
-			acct_stop();
+	log(LOG_NOTICE, "accounting started\n");
+
+acctwatch_start:
+
+	cnt = 0;
+
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		a = i->i_acct;
+		KASSERT(a);
+		ACCT_LOCK(a);
+
+		if (ACCT_STOP == a->acct_state) {
+			ACCT_UNLOCK(a);
 			continue;
 		}
 
-		error = acct_chkfree();
+		if (a->acct_vp->v_type == VBAD)
+			acct_stop(a);
+		error = acct_chkfree(a, &cnt);
 #ifdef DIAGNOSTIC
 		if (error != 0)
 			printf("acctwatch: failed to statvfs, error = %d\n",
-			    error);
+					error);
 #endif
+		ACCT_UNLOCK(a);
+	}
+	instlist_unlock_read();
 
-		ACCT_UNLOCK();
+	if (cnt > 0) {
 		error = tsleep(acctwatch, PSWP, "actwat", acctchkfreq * hz);
-		ACCT_LOCK();
 #ifdef DIAGNOSTIC
 		if (error != 0 && error != EWOULDBLOCK)
 			printf("acctwatch: sleep error %d\n", error);
 #endif
+		goto acctwatch_start;
 	}
+
+	log(LOG_NOTICE, "accounting terminated\n");
+
+	ACCT_GLOBAL_LOCK();
 	acct_dkwatcher = NULL;
-	ACCT_UNLOCK();
+	ACCT_GLOBAL_UNLOCK();
 
 	kthread_exit(0);
 }
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_descrip.c mult-netbsd-3.1/sys/kern/kern_descrip.c
--- NetBSD-3.1/sys/kern/kern_descrip.c	2005-05-28 13:41:08.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_descrip.c	2007-11-26 15:08:35.000000000 +0000
@@ -64,25 +64,24 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
-/*
- * Descriptor management.
- */
-struct filelist	filehead;	/* head of list of open files */
-int		nfiles;		/* actual number of open files */
-POOL_INIT(file_pool, sizeof(struct file), 0, 0, 0, "filepl",
-    &pool_allocator_nointr);
-POOL_INIT(cwdi_pool, sizeof(struct cwdinfo), 0, 0, 0, "cwdipl",
-    &pool_allocator_nointr);
-POOL_INIT(filedesc0_pool, sizeof(struct filedesc0), 0, 0, 0, "fdescpl",
-    &pool_allocator_nointr);
+#include <sys/inst.h>
+
+
+static POOL_INIT(file_pool, sizeof(struct file), 
+		0, 0, 0, "filepl", &pool_allocator_nointr);
+
+static POOL_INIT(cwdi_pool, sizeof(struct cwdinfo), 
+		0, 0, 0, "cwdipl", &pool_allocator_nointr);
+
+static POOL_INIT(filedesc0_pool, sizeof(struct filedesc0), 
+		0, 0, 0, "fdescpl", &pool_allocator_nointr);
 
-/* Global file list lock */
-static struct simplelock filelist_slock = SIMPLELOCK_INITIALIZER;
 
 MALLOC_DEFINE(M_FILE, "file", "Open file structure");
 MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
 MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer");
 
+
 static __inline void	fd_used(struct filedesc *, int);
 static __inline void	fd_unused(struct filedesc *, int);
 static __inline int	find_next_zero(uint32_t *, int, u_int);
@@ -90,13 +89,16 @@
 int			find_last_set(struct filedesc *, int);
 int			fcntl_forfs(int, struct proc *, int, void *);
 
+
 dev_type_open(filedescopen);
 
+
 const struct cdevsw filedesc_cdevsw = {
 	filedescopen, noclose, noread, nowrite, noioctl,
 	nostop, notty, nopoll, nommap, nokqfilter,
 };
 
+
 static __inline int
 find_next_zero(uint32_t *bitmap, int want, u_int bits)
 {
@@ -128,6 +130,7 @@
 	return (off << NDENTRYSHIFT) + ffs(~sub) - 1;
 }
 
+
 int
 find_last_set(struct filedesc *fd, int last)
 {
@@ -819,6 +822,7 @@
 	uint32_t	*newhimap = NULL, *newlomap = NULL;
 
 	fdp = p->p_fd;
+	KASSERT(NULL != p->p_inst);
 
 restart:
 	oldnfiles = fdp->fd_nfiles;
@@ -828,12 +832,14 @@
 	else
 		nfiles = 2 * oldnfiles;
 
-	newofile = malloc(nfiles * OFILESIZE, M_FILEDESC, M_WAITOK);
+	newofile = malloc
+		(nfiles * OFILESIZE, M_FILEDESC, M_WAITOK);
 	if (NDHISLOTS(nfiles) > NDHISLOTS(oldnfiles)) {
 		newhimap = malloc(NDHISLOTS(nfiles) * sizeof(uint32_t),
-		    M_FILEDESC, M_WAITOK);
-		newlomap = malloc(NDLOSLOTS(nfiles) * sizeof(uint32_t),
-		    M_FILEDESC, M_WAITOK);
+				M_FILEDESC, M_WAITOK);
+		newlomap = malloc(NDLOSLOTS
+				(nfiles) * sizeof(uint32_t),
+				M_FILEDESC, M_WAITOK);
 	}
 
 	simple_lock(&fdp->fd_slock);
@@ -922,6 +928,8 @@
 	struct file	*fp, *fq;
 	int		error, i;
 
+	KASSERT(p->p_inst);
+
  restart:
 	if ((error = fdalloc(p, 0, &i)) != 0) {
 		if (error == ENOSPC) {
@@ -932,10 +940,10 @@
 	}
 
 	fp = pool_get(&file_pool, PR_WAITOK);
-	simple_lock(&filelist_slock);
-	if (nfiles >= maxfiles) {
+	simple_lock(&p->p_inst->i_filelist_lock);
+	if (p->p_inst->i_nfiles >= maxfiles) {
 		tablefull("file", "increase kern.maxfiles or MAXFILES");
-		simple_unlock(&filelist_slock);
+		simple_unlock(&p->p_inst->i_filelist_lock);
 		fd_unused(p->p_fd, i);
 		pool_put(&file_pool, fp);
 		return (ENFILE);
@@ -946,21 +954,22 @@
 	 * of open files at that point, otherwise put it at the front of
 	 * the list of open files.
 	 */
-	nfiles++;
+	p->p_inst->i_nfiles++;
 	memset(fp, 0, sizeof(struct file));
 	fp->f_iflags = FIF_LARVAL;
 	if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {
 		LIST_INSERT_AFTER(fq, fp, f_list);
 	} else {
-		LIST_INSERT_HEAD(&filehead, fp, f_list);
+		LIST_INSERT_HEAD(&p->p_inst->i_filehead, fp, f_list);
 	}
-	simple_unlock(&filelist_slock);
+	simple_unlock(&p->p_inst->i_filelist_lock);
 	KDASSERT(p->p_fd->fd_ofiles[i] == NULL);
 	p->p_fd->fd_ofiles[i] = fp;
 	simple_lock_init(&fp->f_slock);
 	fp->f_count = 1;
 	fp->f_cred = p->p_ucred;
 	crhold(fp->f_cred);
+
 	if (resultfp) {
 		fp->f_usecount = 1;
 		*resultfp = fp;
@@ -976,23 +985,29 @@
 void
 ffree(struct file *fp)
 {
+	struct inst	*i;
+
+	KASSERT(fp->f_cred->cr_inst);
+	i = fp->f_cred->cr_inst;
 
 #ifdef DIAGNOSTIC
 	if (fp->f_usecount)
 		panic("ffree");
 #endif
 
-	simple_lock(&filelist_slock);
+	simple_lock(&i->i_filelist_lock);
 	LIST_REMOVE(fp, f_list);
+	i->i_nfiles--;
+	simple_unlock(&i->i_filelist_lock);
+
 	crfree(fp->f_cred);
 #ifdef DIAGNOSTIC
 	fp->f_count = 0; /* What's the point? */
 #endif
-	nfiles--;
-	simple_unlock(&filelist_slock);
 	pool_put(&file_pool, fp);
 }
 
+
 /*
  * Create an initial cwdinfo structure, using the same current and root
  * directories as p.
@@ -1074,18 +1089,17 @@
  * directories as p.
  */
 struct filedesc *
-fdinit(struct proc *p)
+fdinit(void)
 {
 	struct filedesc0 *newfdp;
 
 	newfdp = pool_get(&filedesc0_pool, PR_WAITOK);
 	memset(newfdp, 0, sizeof(struct filedesc0));
-
 	fdinit1(newfdp);
-
 	return (&newfdp->fd_fd);
 }
 
+
 /*
  * Initialize a file descriptor table.
  */
@@ -1143,7 +1157,7 @@
 {
 	struct filedesc *newfd;
 
-	newfd = fdinit(p);
+	newfd = fdinit();
 	fdfree(p);
 	p->p_fd = newfd;
 }
@@ -1163,6 +1177,8 @@
 	newfdp->fd_refcnt = 1;
 	simple_lock_init(&newfdp->fd_slock);
 
+	KASSERT(NULL != p->p_inst);
+
 restart:
 	nfiles = fdp->fd_nfiles;
 	lastfile = fdp->fd_lastfile;
@@ -1194,7 +1210,8 @@
 	}
 
 	simple_lock(&fdp->fd_slock);
-	if (nfiles != fdp->fd_nfiles || lastfile != fdp->fd_lastfile) {
+	if (nfiles != fdp->fd_nfiles || 
+			lastfile != fdp->fd_lastfile) {
 		simple_unlock(&fdp->fd_slock);
 		if (i > NDFILE)
 			free(newfdp->fd_ofiles, M_FILEDESC);
@@ -1766,10 +1783,13 @@
 	if (closed[0] != '\0') {
 		pp = p->p_pptr;
 		log(LOG_WARNING, "set{u,g}id pid %d (%s) "
-		    "was invoked by uid %d ppid %d (%s) "
-		    "with fd %s closed\n",
-		    p->p_pid, p->p_comm, pp->p_ucred->cr_uid,
-		    pp->p_pid, pp->p_comm, &closed[1]);
+				"was invoked by uid %d ppid %d (%s) "
+				"with fd %s closed\n",
+				p->p_pid, p->p_comm, 
+				pp ? pp->p_ucred->cr_uid : 0,
+				pp ? pp->p_pid : 0, 
+				pp ? pp->p_comm : "(null)",
+				&closed[1]);
 	}
 	return (0);
 }
@@ -1796,7 +1816,7 @@
 		break;
 	}
 
-	if (id > 0 && !pfind(id))
+	if (id > 0 && ! pfind(p->p_inst, id))
 		return (ESRCH);
 	else if (id < 0 && (error = pgid_in_session(p, -id)))
 		return (error);
@@ -1828,20 +1848,23 @@
  * Send signal to descriptor owner, either process or process group.
  */
 void
-fownsignal(pid_t pgid, int signo, int code, int band, void *fdescdata)
+fownsignal(struct inst *i, pid_t pgid, int signo, 
+		int code, int band, void *fdescdata)
 {
-	struct proc *p1;
-	ksiginfo_t ksi;
+	struct proc 	*p1;
+	ksiginfo_t 	ksi;
+
+	KASSERT(i);
 
-	memset(&ksi, 0, sizeof(ksi));
+	(void)memset(&ksi, 0, sizeof(ksi));
 	ksi.ksi_signo = signo;
 	ksi.ksi_code = code;
 	ksi.ksi_band = band;
 
-	if (pgid > 0 && (p1 = pfind(pgid)))
+	if (pgid > 0 && (p1 = pfind(i, pgid)))
 		kpsignal(p1, &ksi, fdescdata);
 	else if (pgid < 0)
-		kgsignal(-pgid, &ksi, fdescdata);
+		kgsignal(i, -pgid, &ksi, fdescdata);
 }
 
 int
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_event.c mult-netbsd-3.1/sys/kern/kern_event.c
--- NetBSD-3.1/sys/kern/kern_event.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_event.c	2007-11-26 15:08:35.000000000 +0000
@@ -53,6 +53,7 @@
 #include <sys/filedesc.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 static int	kqueue_scan(struct file *fp, size_t maxevents,
 		    struct kevent *ulistp, const struct timespec *timeout,
@@ -146,10 +147,37 @@
 	{ NULL,			0,		NULL },	/* end of list */
 };
 
-		/* User defined kfilters */
-static struct kfilter	*user_kfilters;		/* array */
-static int		user_kfilterc;		/* current offset */
-static int		user_kfiltermaxc;	/* max size so far */
+
+struct inst_kevt
+{
+	struct kfilter	*user_kfilters;		/* array */
+	int		user_kfilterc;		/* current offset */
+	int		user_kfiltermaxc;	/* max size thusfar */
+};
+
+
+int
+inst_kevt_alloc(inst_kevt_t *p, int flags)
+{
+	struct inst_kevt *i;
+
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_kevt), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_kevt));
+	*p = i;
+	return(1);
+}
+
+
+void
+inst_kevt_free(inst_kevt_t p)
+{
+	KASSERT(p);
+	free(p, M_INST);
+}
+
 
 /*
  * Find kfilter entry by name, or NULL if not found.
@@ -166,135 +194,157 @@
 	return (NULL);
 }
 
+
 static struct kfilter *
-kfilter_byname_user(const char *name)
+kfilter_byname_user(struct inst_kevt *p, const char *name)
 {
 	int i;
 
+	KASSERT(p);
+
 	/* user_kfilters[] could be NULL if no filters were registered */
-	if (!user_kfilters)
+	if (!p->user_kfilters)
 		return (NULL);
 
-	for (i = 0; user_kfilters[i].name != NULL; i++) {
-		if (user_kfilters[i].name != '\0' &&
-		    strcmp(name, user_kfilters[i].name) == 0)
-			return (&user_kfilters[i]);
+	for (i = 0; p->user_kfilters[i].name != NULL; i++) {
+		if (p->user_kfilters[i].name != '\0' &&
+		    strcmp(name, p->user_kfilters[i].name) == 0)
+			return (&p->user_kfilters[i]);
 	}
 	return (NULL);
 }
 
+
 static const struct kfilter *
-kfilter_byname(const char *name)
+kfilter_byname(struct inst_kevt *p, const char *name)
 {
 	const struct kfilter *kfilter;
 
+	KASSERT(p);
+
 	if ((kfilter = kfilter_byname_sys(name)) != NULL)
 		return (kfilter);
 
-	return (kfilter_byname_user(name));
+	return (kfilter_byname_user(p, name));
 }
 
+
 /*
- * Find kfilter entry by filter id, or NULL if not found.
- * Assumes entries are indexed in filter id order, for speed.
+ * Find kfilter entry by filter id, or NULL if not found.  Assumes
+ * entries are indexed in filter id order, for speed.
  */
 static const struct kfilter *
-kfilter_byfilter(uint32_t filter)
+kfilter_byfilter(struct inst_kevt *p, uint32_t filter)
 {
 	const struct kfilter *kfilter;
 
 	if (filter < EVFILT_SYSCOUNT)	/* it's a system filter */
 		kfilter = &sys_kfilters[filter];
-	else if (user_kfilters != NULL &&
-	    filter < EVFILT_SYSCOUNT + user_kfilterc)
+	else if (p->user_kfilters != NULL &&
+	    filter < EVFILT_SYSCOUNT + p->user_kfilterc)
 					/* it's a user filter */
-		kfilter = &user_kfilters[filter - EVFILT_SYSCOUNT];
+		kfilter = &p->user_kfilters[filter - EVFILT_SYSCOUNT];
 	else
 		return (NULL);		/* out of range */
 	KASSERT(kfilter->filter == filter);	/* sanity check! */
 	return (kfilter);
 }
 
+
 /*
  * Register a new kfilter. Stores the entry in user_kfilters.
  * Returns 0 if operation succeeded, or an appropriate errno(2) otherwise.
  * If retfilter != NULL, the new filterid is returned in it.
  */
 int
-kfilter_register(const char *name, const struct filterops *filtops,
-    int *retfilter)
+kfilter_register(struct inst *i, const char *name, 
+		const struct filterops *filtops, int *retfilter)
 {
-	struct kfilter *kfilter;
-	void *space;
-	int len;
+	struct kfilter	*kfilter;
+	void		*space;
+	int		len;
 
+	KASSERT(i);
 	if (name == NULL || name[0] == '\0' || filtops == NULL)
 		return (EINVAL);	/* invalid args */
-	if (kfilter_byname(name) != NULL)
+	if (kfilter_byname(i->i_kevt, name) != NULL)
 		return (EEXIST);	/* already exists */
-	if (user_kfilterc > 0xffffffff - EVFILT_SYSCOUNT)
+	if (i->i_kevt->user_kfilterc > 0xffffffff - EVFILT_SYSCOUNT)
 		return (EINVAL);	/* too many */
 
 	/* check if need to grow user_kfilters */
-	if (user_kfilterc + 1 > user_kfiltermaxc) {
+	if (i->i_kevt->user_kfilterc + 1 > 
+			i->i_kevt->user_kfiltermaxc) {
 		/*
 		 * Grow in KFILTER_EXTENT chunks. Use malloc(9), because we
 		 * want to traverse user_kfilters as an array.
 		 */
-		user_kfiltermaxc += KFILTER_EXTENT;
-		kfilter = malloc(user_kfiltermaxc * sizeof(struct filter *),
-		    M_KEVENT, M_WAITOK);
+		i->i_kevt->user_kfiltermaxc += KFILTER_EXTENT;
+		kfilter = malloc(i->i_kevt->user_kfiltermaxc * 
+				sizeof(struct filter *),
+				M_KEVENT, M_WAITOK);
 
 		/* copy existing user_kfilters */
-		if (user_kfilters != NULL)
-			memcpy((caddr_t)kfilter, (caddr_t)user_kfilters,
-			    user_kfilterc * sizeof(struct kfilter *));
+		if (i->i_kevt->user_kfilters != NULL)
+			memcpy((caddr_t)kfilter, 
+					(caddr_t)i->i_kevt->user_kfilters,
+					i->i_kevt->user_kfilterc * 
+					sizeof(struct kfilter *));
 					/* zero new sections */
 		memset((caddr_t)kfilter +
-		    user_kfilterc * sizeof(struct kfilter *), 0,
-		    (user_kfiltermaxc - user_kfilterc) *
-		    sizeof(struct kfilter *));
-					/* switch to new kfilter */
-		if (user_kfilters != NULL)
-			free(user_kfilters, M_KEVENT);
-		user_kfilters = kfilter;
+				i->i_kevt->user_kfilterc * 
+				sizeof(struct kfilter *), 0,
+				(i->i_kevt->user_kfiltermaxc - 
+				 i->i_kevt->user_kfilterc) *
+				sizeof(struct kfilter *));
+		/* switch to new kfilter */
+		if (i->i_kevt->user_kfilters != NULL)
+			free(i->i_kevt->user_kfilters, M_KEVENT);
+		i->i_kevt->user_kfilters = kfilter;
 	}
 	len = strlen(name) + 1;		/* copy name */
 	space = malloc(len, M_KEVENT, M_WAITOK);
 	memcpy(space, name, len);
-	user_kfilters[user_kfilterc].name = space;
+	i->i_kevt->user_kfilters[i->i_kevt->user_kfilterc].name = 
+		space;
 
-	user_kfilters[user_kfilterc].filter = user_kfilterc + EVFILT_SYSCOUNT;
+	i->i_kevt->user_kfilters[i->i_kevt->user_kfilterc].filter = 
+		i->i_kevt->user_kfilterc + EVFILT_SYSCOUNT;
 
 	len = sizeof(struct filterops);	/* copy filtops */
 	space = malloc(len, M_KEVENT, M_WAITOK);
 	memcpy(space, filtops, len);
-	user_kfilters[user_kfilterc].filtops = space;
+	i->i_kevt->user_kfilters[i->i_kevt->user_kfilterc].filtops = 
+		space;
 
 	if (retfilter != NULL)
-		*retfilter = user_kfilters[user_kfilterc].filter;
-	user_kfilterc++;		/* finally, increment count */
+		*retfilter = i->i_kevt->user_kfilters
+			[i->i_kevt->user_kfilterc].filter;
+	i->i_kevt->user_kfilterc++;		
+	/* finally, increment count */
 	return (0);
 }
+					
 
 /*
  * Unregister a kfilter previously registered with kfilter_register.
- * This retains the filter id, but clears the name and frees filtops (filter
- * operations), so that the number isn't reused during a boot.
- * Returns 0 if operation succeeded, or an appropriate errno(2) otherwise.
+ * This retains the filter id, but clears the name and frees filtops
+ * (filter operations), so that the number isn't reused during a boot.
+ * Returns 0 if operation succeeded, or an appropriate errno(2)
+ * otherwise.
  */
 int
-kfilter_unregister(const char *name)
+kfilter_unregister(struct inst *i, const char *name)
 {
-	struct kfilter *kfilter;
+	struct kfilter 	*kfilter;
 
-	if (name == NULL || name[0] == '\0')
+	if (i == NULL || name == NULL || name[0] == '\0')
 		return (EINVAL);	/* invalid name */
 
 	if (kfilter_byname_sys(name) != NULL)
 		return (EINVAL);	/* can't detach system filters */
 
-	kfilter = kfilter_byname_user(name);
+	kfilter = kfilter_byname_user(i->i_kevt, name);
 	if (kfilter == NULL)		/* not found */
 		return (ENOENT);
 
@@ -359,7 +409,8 @@
 {
 	struct proc *p;
 
-	p = pfind(kn->kn_id);
+	/* FIXME - instances */
+	p = pfind(NULL, kn->kn_id);
 	if (p == NULL)
 		return (ESRCH);
 
@@ -409,7 +460,8 @@
 		return;
 
 	p = kn->kn_ptr.p_proc;
-	KASSERT(p->p_stat == SZOMB || pfind(kn->kn_id) == p);
+	/* FIXME - instances */
+	KASSERT(p->p_stat == SZOMB || pfind(NULL, kn->kn_id) == p);
 
 	/* XXXSMP lock the process? */
 	SLIST_REMOVE(&p->p_klist, kn, knote, kn_selnext);
@@ -730,11 +782,13 @@
 	struct knote	*kn;
 	int		s, error;
 
+	KASSERT(NULL != p);
+
 	fdp = kq->kq_fdp;
 	fp = NULL;
 	kn = NULL;
 	error = 0;
-	kfilter = kfilter_byfilter(kev->filter);
+	kfilter = kfilter_byfilter(p->p_inst->i_kevt, kev->filter);
 	if (kfilter == NULL || kfilter->filtops == NULL) {
 		/* filter not found nor implemented */
 		return (EINVAL);
@@ -1073,9 +1127,11 @@
 	km = (struct kfilter_mapping *)data;
 	error = 0;
 
+	KASSERT(p->p_inst);
+
 	switch (com) {
 	case KFILTER_BYFILTER:	/* convert filter -> name */
-		kfilter = kfilter_byfilter(km->filter);
+		kfilter = kfilter_byfilter(p->p_inst->i_kevt, km->filter);
 		if (kfilter != NULL)
 			error = copyoutstr(kfilter->name, km->name, km->len,
 			    NULL);
@@ -1090,7 +1146,7 @@
 			FREE(name, M_KEVENT);
 			break;
 		}
-		kfilter = kfilter_byname(name);
+		kfilter = kfilter_byname(p->p_inst->i_kevt, name);
 		if (kfilter != NULL)
 			km->filter = kfilter->filter;
 		else
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_exec.c mult-netbsd-3.1/sys/kern/kern_exec.c
--- NetBSD-3.1/sys/kern/kern_exec.c	2005-10-31 13:25:31.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_exec.c	2007-11-23 10:17:19.000000000 +0000
@@ -69,6 +69,7 @@
 #endif
 
 #include <uvm/uvm_extern.h>
+#include <sys/inst.h>
 
 #include <machine/cpu.h>
 #include <machine/reg.h>
@@ -288,6 +289,7 @@
 	 */
 	epp->ep_vm_minaddr = VM_MIN_ADDRESS;
 	epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
+
 	/*
 	 * set up the vmcmds for creation of the process
 	 * address space
@@ -712,6 +714,7 @@
 
 	p->p_flag |= P_EXEC;
 	if (p->p_flag & P_PPWAIT) {
+		KASSERT(p->p_pptr);
 		p->p_flag &= ~P_PPWAIT;
 		wakeup((caddr_t) p->p_pptr);
 	}
@@ -832,6 +835,7 @@
 		int s;
 
 		sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
+		KASSERT(p->p_pptr);
 		SCHED_LOCK(s);
 		p->p_pptr->p_nstopchild++;
 		p->p_stat = SSTOP;
@@ -996,6 +1000,7 @@
 	struct emul_entry	*it;
 	int			i, error;
 	struct proc		*ptmp;
+	struct inst		*inst;
 
 	error = 0;
 	lockmgr(&exec_lock, LK_SHARED, NULL);
@@ -1028,16 +1033,23 @@
 	 * emul_unregister() is running quite sendomly, it's better
 	 * to do expensive check here than to use any locking.
 	 */
-	proclist_lock_read();
-	for (pd = proclists; pd->pd_list != NULL && !error; pd++) {
-		PROCLIST_FOREACH(ptmp, pd->pd_list) {
-			if (ptmp->p_emul == it->el_emul) {
-				error = EBUSY;
-				break;
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) {
+		proclist_lock_read(inst);
+		for (pd = inst->i_proclists; 
+				pd->pd_list != NULL && !error; pd++) {
+			PROCLIST_FOREACH(ptmp, pd->pd_list) {
+				if (ptmp->p_emul == it->el_emul) {
+					error = EBUSY;
+					break;
+				}
 			}
 		}
+		proclist_unlock_read(inst);
+		if (error)
+			break;
 	}
-	proclist_unlock_read();
+	instlist_unlock_read();
 
 	if (error)
 		goto out;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_exit.c mult-netbsd-3.1/sys/kern/kern_exit.c
--- NetBSD-3.1/sys/kern/kern_exit.c	2005-10-04 15:16:42.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_exit.c	2007-12-18 17:56:36.000000000 +0000
@@ -78,7 +78,6 @@
 
 #include "opt_ktrace.h"
 #include "opt_perfctrs.h"
-#include "opt_systrace.h"
 #include "opt_sysv.h"
 
 #include <sys/param.h>
@@ -112,22 +111,18 @@
 #include <sys/savar.h>
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
-#include <sys/systrace.h>
+#include <sys/inst.h>
 
 #include <machine/cpu.h>
 
 #include <uvm/uvm_extern.h>
 
-#define DEBUG_EXIT
+static POOL_INIT(rusage_pool, sizeof(struct rusage), 
+		0, 0, 0, "rusgepl", &pool_allocator_nointr);
 
-#ifdef DEBUG_EXIT
-int debug_exit = 0;
-#define DPRINTF(x) if (debug_exit) printf x
-#else
-#define DPRINTF(x)
-#endif
+static void 
+lwp_exit_hook(struct lwp *, void *);
 
-static void lwp_exit_hook(struct lwp *, void *);
 
 /*
  * Fill in the appropriate signal information, and signal the parent.
@@ -178,6 +173,76 @@
 	return (0);
 }
 
+
+/*
+ * This is documented in exitinst1(9).
+ */
+static void
+exitinst1(struct inst *i, int rv)
+{
+	int		count, error;
+	struct inst	*p;
+	ksiginfo_t	ksi;
+	struct proc	*child;
+
+	KASSERT(i);
+
+	count = 0;
+	instlist_lock_read();
+	LIST_FOREACH(p, &allinst, i_list)
+		count++;
+	instlist_unlock_read();
+
+	KASSERT(count >= 2);
+	if (2 == count)
+		panic("init died (uuid %u, signal %d, exit %d)",
+			i->i_uuid, WTERMSIG(rv), WEXITSTATUS(rv));
+
+#ifdef DEBUG
+	printf("%s: instance exiting: %u\n", __func__, i->i_uuid);
+#endif
+
+	i->i_state = INST_EXITING;
+
+	/*
+	 * Kill all members of the instance.  This will eventually cause
+	 * the tree to reparent under the instance.
+	 */
+
+	KSI_INIT(&ksi);
+	ksi.ksi_signo = SIGKILL;
+	ksi.ksi_code = SI_NOINFO;
+	ksi.ksi_pid = 1;
+	ksi.ksi_uid = 0;
+
+	(void)killpg1(i->i_initproc, &ksi, 0, 1);
+
+	for (;;) {
+		error = find_stopped_child(i->i_initproc, WAIT_ANY, 0, &child);
+		if (ECHILD == error) {
+#ifdef DEBUG
+			printf("%s: no more children: uuid %u\n", 
+					__func__, i->i_uuid);
+#endif
+			break;
+		} else if (EINTR == error || ERESTART == error)
+			continue;
+		/* What to do here?  FIXME. */
+		KASSERT(0 == error);
+		KASSERT(child);
+#ifdef DEBUG
+		printf("%s: freeing child: %d, %u\n", 
+				__func__, child->p_pid, i->i_uuid);
+#endif
+		uvm_uarea_drain(FALSE);
+		proc_free(child);
+	}
+
+	instdaemon_sem = 1;
+	wakeup((void *)&instdaemon_sem);
+}
+
+
 /*
  * Exit: deallocate address space and other resources, change proc state
  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
@@ -187,20 +252,24 @@
 exit1(struct lwp *l, int rv)
 {
 	struct proc	*p, *q, *nq;
+	struct inst	*inst;
 	int		s, sa;
 	struct plimit	*plim;
 	struct pstats	*pstats;
 	struct sigacts	*ps;
 	ksiginfo_t	ksi;
-	int		do_psignal = 0;
+	int		do_psignal;
 
+	do_psignal = 0;
 	p = l->l_proc;
-
-	if (__predict_false(p == initproc))
-		panic("init died (signal %d, exit %d)",
-		    WTERMSIG(rv), WEXITSTATUS(rv));
+	KASSERT(l->l_inst);
+	inst = l->l_inst;
 
 	p->p_flag |= P_WEXIT;
+	if (p == inst->i_initproc)
+		/* Note that instinit(8) is marked as exiting. */
+		exitinst1(inst, rv);
+
 	if (p->p_flag & P_STOPEXIT) {
 		int s;
 
@@ -214,17 +283,13 @@
 		splx(s);
 	}
 
-	DPRINTF(("exit1: %d.%d exiting.\n", p->p_pid, l->l_lid));
 	/*
-	 * Disable scheduler activation upcalls.
-	 * We're trying to get out of here.
+	 * Disable scheduler activation upcalls.  We're trying to get
+	 * out of here.
 	 */
 	sa = 0;
 	if (p->p_sa != NULL) {
 		l->l_flag &= ~L_SA;
-#if 0
-		p->p_flag &= ~P_SA;
-#endif
 		sa = 1;
 	}
 
@@ -234,11 +299,13 @@
 	if (p->p_flag & P_PROFIL)
 		stopprofclock(p);
 	p->p_ru = pool_get(&rusage_pool, PR_WAITOK);
+
 	/*
-	 * If parent is waiting for us to exit or exec, P_PPWAIT is set; we
-	 * wake up the parent early to avoid deadlock.
+	 * If parent is waiting for us to exit or exec, P_PPWAIT is set;
+	 * we wake up the parent early to avoid deadlock.
 	 */
 	if (p->p_flag & P_PPWAIT) {
+		KASSERT(p->p_pptr);
 		p->p_flag &= ~P_PPWAIT;
 		wakeup(p->p_pptr);
 	}
@@ -249,7 +316,6 @@
 
 	if (sa || (p->p_nlwps > 1)) {
 		exit_lwps(l);
-
 		/*
 		 * Collect thread u-areas.
 		 */
@@ -261,8 +327,8 @@
 #endif
 
 	/*
-	 * Close open files and release open-file table.
-	 * This may block!
+	 * Close open files and release open-file table.  This may
+	 * block!
 	 */
 	fdfree(p);
 	cwdfree(p->p_cwdi);
@@ -277,10 +343,9 @@
 		if (sp->s_ttyvp) {
 			int s;
 			/*
-			 * Controlling process.
-			 * Signal foreground pgrp,
-			 * drain controlling terminal
-			 * and revoke access to controlling terminal.
+			 * Controlling process.  Signal foreground pgrp,
+			 * drain controlling terminal and revoke access
+			 * to controlling terminal.
 			 */
 			tp = sp->s_ttyp;
 			s = spltty();
@@ -288,7 +353,8 @@
 			if (tp->t_session == sp) {
 				if (tp->t_pgrp)
 					pgsignal(tp->t_pgrp, SIGHUP, 1);
-				/* we can't guarantee the revoke will do this */
+				/* We can't guarantee the revoke will do
+				 * this. */
 				tp->t_pgrp = NULL;
 				tp->t_session = NULL;
 				TTY_UNLOCK(tp);
@@ -296,8 +362,8 @@
 				SESSRELE(sp);
 				(void) ttywait(tp);
 				/*
-				 * The tty could have been revoked
-				 * if we blocked.
+				 * The tty could have been revoked if we
+				 * blocked.
 				 */
 				if (sp->s_ttyvp)
 					VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
@@ -310,10 +376,11 @@
 			sp->s_ttyvp = NULL;
 			/*
 			 * s_ttyp is not zero'd; we use this to indicate
-			 * that the session once had a controlling terminal.
-			 * (for logging and informational purposes)
+			 * that the session once had a controlling
+			 * terminal.  (for logging and informational
+			 * purposes)
 			 */
-		}
+		} 
 		sp->s_leader = NULL;
 	}
 	fixjobc(p, p->p_pgrp, 0);
@@ -324,9 +391,6 @@
 	 */
 	ktrderef(p);
 #endif
-#ifdef SYSTRACE
-	systrace_sys_exit(p);
-#endif
 	/*
 	 * If emulation has process exit hook, call it now.
 	 */
@@ -334,21 +398,19 @@
 		(*p->p_emul->e_proc_exit)(p);
 
 	/*
-	 * Free the VM resources we're still holding on to.
-	 * We must do this from a valid thread because doing
-	 * so may block. This frees vmspace, which we don't
-	 * need anymore. The only remaining lwp is the one
-	 * we run at this moment, nothing runs in userland
-	 * anymore.
+	 * Free the VM resources we're still holding on to.  We must do
+	 * this from a valid thread because doing so may block. This
+	 * frees vmspace, which we don't need anymore. The only
+	 * remaining lwp is the one we run at this moment, nothing runs
+	 * in userland anymore.
 	 */
 	uvm_proc_exit(p);
 
 	/*
-	 * Give machine-dependent code a chance to free any
-	 * MD LWP resources while we can still block. This must be done
-	 * before uvm_lwp_exit(), in case these resources are in the
-	 * PCB.
-	 * THIS IS LAST BLOCKING OPERATION.
+	 * Give machine-dependent code a chance to free any MD LWP
+	 * resources while we can still block. This must be done before
+	 * uvm_lwp_exit(), in case these resources are in the PCB.  THIS
+	 * IS LAST BLOCKING OPERATION.
 	 */
 #ifndef __NO_CPU_LWP_FREE
 	cpu_lwp_free(l, 1);
@@ -361,10 +423,10 @@
 	 */
 
 	/*
-	 * Save exit status and final rusage info, adding in child rusage
-	 * info and self times.
-	 * In order to pick up the time for the current execution, we must
-	 * do this before unlinking the lwp from l_list.
+	 * Save exit status and final rusage info, adding in child
+	 * rusage info and self times.  In order to pick up the time for
+	 * the current execution, we must do this before unlinking the
+	 * lwp from l_list.
 	 */
 	p->p_xstat = rv;
 	*p->p_ru = p->p_stats->p_ru;
@@ -380,24 +442,24 @@
 	/*
 	 * Save final PMC information in parent process & clean up.
 	 */
-	if (PMC_ENABLED(p)) {
+	if (PMC_ENABLED(p) && p->p_pptr) {
 		pmc_save_context(p);
 		pmc_accumulate(p->p_pptr, p);
 		pmc_process_exit(p);
 	}
 #endif
 
-	s = proclist_lock_write();
+	s = proclist_lock_write(p->p_inst);
+
 	/*
-	 * Reset p_opptr pointer of all former children which got
-	 * traced by another process and were reparented. We reset
-	 * it to NULL here; the trace detach code then reparents
-	 * the child to initproc. We only check allproc list, since
-	 * eventual former children on zombproc list won't reference
-	 * p_opptr anymore.
+	 * Reset p_opptr pointer of all former children which got traced
+	 * by another process and were reparented. We reset it to NULL
+	 * here; the trace detach code then reparents the child to
+	 * initproc. We only check allproc list, since eventual former
+	 * children on zombproc list won't reference p_opptr anymore.
 	 */
 	if (p->p_flag & P_CHTRACED) {
-		PROCLIST_FOREACH(q, &allproc) {
+		PROCLIST_FOREACH(q, &p->p_inst->i_allproc) {
 			if (q->p_opptr == p)
 				q->p_opptr = NULL;
 		}
@@ -408,7 +470,7 @@
 	 */
 	q = LIST_FIRST(&p->p_children);
 	if (q)		/* only need this if any child is SZOMB */
-		wakeup(initproc);
+		wakeup(inst->i_initproc);
 	for (; q != NULL; q = nq) {
 		nq = LIST_NEXT(q, p_sibling);
 
@@ -420,28 +482,30 @@
 		 * original parent, so we must do this here.
 		 */
 		if (q->p_flag & P_TRACED) {
+			KASSERT(q->p_pptr);
 			if (q->p_opptr != q->p_pptr) {
 				struct proc *t = q->p_opptr;
-				proc_reparent(q, t ? t : initproc);
+				proc_reparent(q, t ? t : 
+					inst->i_initproc);
 				q->p_opptr = NULL;
 			} else
-				proc_reparent(q, initproc);
+				proc_reparent
+					(q, inst->i_initproc);
 			q->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE);
 			psignal(q, SIGKILL);
 		} else {
-			proc_reparent(q, initproc);
+			proc_reparent(q, inst->i_initproc);
 		}
 	}
 
 	/*
-	 * Move proc from allproc to zombproc, it's now ready
-	 * to be collected by parent. Remaining lwp resources
-	 * will be freed in lwp_exit2() once we've switch to idle
-	 * context.
-	 * Changing the state to SZOMB stops it being found by pfind().
+	 * Move proc from allproc to zombproc, it's now ready to be
+	 * collected by parent. Remaining lwp resources will be freed in
+	 * lwp_exit2() once we've switch to idle context.  Changing the
+	 * state to SZOMB stops it being found by pfind().
 	 */
 	LIST_REMOVE(p, p_list);
-	LIST_INSERT_HEAD(&zombproc, p, p_list);
+	LIST_INSERT_HEAD(&p->p_inst->i_zombproc, p, p_list);
 	p->p_stat = SZOMB;
 
 	LIST_REMOVE(l, l_list);
@@ -454,30 +518,35 @@
 	p->p_nrlwps--;
 	p->p_nlwps--;
 
-	/* Put in front of parent's sibling list for parent to collect it */
-	q = p->p_pptr;
-	q->p_nstopchild++;
-	if (LIST_FIRST(&q->p_children) != p) {
-		/* Put child where it can be found quickly */
-		LIST_REMOVE(p, p_sibling);
-		LIST_INSERT_HEAD(&q->p_children, p, p_sibling);
-	}
-
-	/*
-	 * Notify parent that we're gone.  If parent has the P_NOCLDWAIT
-	 * flag set, notify init instead (and hope it will handle
-	 * this situation).
+	/* 
+	 * Put in front of parent's sibling list for parent to collect
+	 * it.  This only occurs if we're not the instance root. 
 	 */
-	if (q->p_flag & P_NOCLDWAIT) {
-		proc_reparent(p, initproc);
+	q = p->p_pptr;
+	if (q) {
+		q->p_nstopchild++;
+		if (LIST_FIRST(&q->p_children) != p) {
+			/* Put child where it can be found quickly */
+			LIST_REMOVE(p, p_sibling);
+			LIST_INSERT_HEAD(&q->p_children, p, p_sibling);
+		}
 
 		/*
-		 * If this was the last child of our parent, notify
-		 * parent, so in case he was wait(2)ing, he will
-		 * continue.
+		 * Notify parent that we're gone.  If parent has the
+		 * P_NOCLDWAIT flag set, notify init instead (and hope
+		 * it will handle this situation).
 		 */
-		if (LIST_FIRST(&q->p_children) == NULL)
-			wakeup(q);
+		if (q->p_flag & P_NOCLDWAIT) {
+			proc_reparent(p, inst->i_initproc);
+	
+			/*
+			 * If this was the last child of our parent,
+			 * notify parent, so in case he was wait(2)ing,
+			 * he will continue.
+			 */
+			if (LIST_FIRST(&q->p_children) == NULL)
+				wakeup(q);
+		}
 	}
 
 	/*
@@ -502,25 +571,36 @@
 	p->p_sigacts = NULL;
 
 	/* Reload parent pointer, since p may have been reparented above */
-	q = p->p_pptr;
 
+	q = p->p_pptr;
 	if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0) {
-		exit_psignal(p, q, &ksi);
+		if (q)
+			exit_psignal(p, q, &ksi);
 		do_psignal = 1;
 	}
 
 	/*
 	 * Once we release the proclist lock, we shouldn't touch the
-	 * process structure anymore, since it's now on the zombie
-	 * list and available for collection by the parent.
+	 * process structure anymore, since it's now on the zombie list
+	 * and available for collection by the parent.
 	 */
-	proclist_unlock_write(s);
-
-	if (do_psignal)
-		kpsignal(q, &ksi, NULL);
+	proclist_unlock_write(p->p_inst, s);
+	
+	if (q) {
+		if (do_psignal)
+			kpsignal(q, &ksi, NULL);
+		/* Wake up the parent so it can get exit status. */
+		wakeup(q);
+	}
 
-	/* Wake up the parent so it can get exit status. */
-	wakeup(q);
+	if (p->p_inst->i_state == INST_EXITING) {
+		/*
+		 * FIXME: we should only do this if we're the last ones
+		 * left.
+		 */
+		instdaemon_sem = 1;
+		wakeup((void *)&instdaemon_sem);
+	}
 
 	/* Release substructures */
 	sigactsfree(ps);
@@ -559,6 +639,7 @@
 	lwpid_t		waited;
 
 	p = l->l_proc;
+	KASSERT(NULL != p);
 
 	/* XXX SMP
 	 * This would be the right place to IPI any LWPs running on
@@ -573,16 +654,12 @@
 			 * Make SA-cached LWPs normal process runnable
 			 * LWPs so that they'll also self-destruct.
 			 */
-			DPRINTF(("exit_lwps: Making cached LWPs of %d on VP %d runnable: ",
-				    p->p_pid, vp->savp_id));
 			SCHED_LOCK(s);
 			while ((l2 = sa_getcachelwp(vp)) != 0) {
 				l2->l_priority = l2->l_usrpri;
 				setrunnable(l2);
-				DPRINTF(("%d ", l2->l_lid));
 			}
 			SCHED_UNLOCK(s);
-			DPRINTF(("\n"));
 
 			/*
 			 * Clear wokenq, the LWPs on the queue will
@@ -605,16 +682,12 @@
 		if ((l2->l_stat == LSSLEEP && (l2->l_flag & L_SINTR)) ||
 		    l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) {
 			setrunnable(l2);
-			DPRINTF(("exit_lwps: Made %d.%d runnable\n",
-			    p->p_pid, l2->l_lid));
 		}
 		SCHED_UNLOCK(s);
 	}
 
 
 	while (p->p_nlwps > 1) {
-		DPRINTF(("exit_lwps: waiting for %d LWPs (%d runnable, %d zombies)\n",
-		    p->p_nlwps, p->p_nrlwps, p->p_nzlwps));
 		error = lwp_wait1(l, 0, &waited, LWPWAIT_EXITCONTROL);
 		if (error == EDEADLK) {
 			/*
@@ -627,7 +700,6 @@
 		if (error)
 			panic("exit_lwps: lwp_wait1 failed with error %d\n",
 			    error);
-		DPRINTF(("exit_lwps: Got LWP %d from lwp_wait1()\n", waited));
 	}
 
 	p->p_userret = NULL;
@@ -711,17 +783,21 @@
 find_stopped_child(struct proc *parent, pid_t pid, int options,
 	struct proc **child_p)
 {
-	struct proc *child;
-	int error;
+	struct proc 	*child;
+	int 		error;
+
+	KASSERT(NULL != parent);
+	KASSERT(NULL != parent->p_inst);
 
 	for (;;) {
-		proclist_lock_read();
+		proclist_lock_read(parent->p_inst);
 		error = ECHILD;
 		LIST_FOREACH(child, &parent->p_children, p_sibling) {
 			if (pid >= 0) {
 				if (child->p_pid != pid) {
-					child = p_find(pid, PFIND_ZOMBIE |
-								PFIND_LOCKED);
+					child = p_find(parent->p_inst, 
+							pid, PFIND_ZOMBIE |
+							PFIND_LOCKED);
 					if (child == NULL
 					    || child->p_pptr != parent) {
 						child = NULL;
@@ -766,7 +842,7 @@
 				break;
 			}
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(parent->p_inst);
 		if (child != NULL || error != 0 || options & WNOHANG) {
 			*child_p = child;
 			return error;
@@ -783,15 +859,21 @@
 void
 proc_free(struct proc *p)
 {
-	struct proc *parent = p->p_pptr;
-	ksiginfo_t ksi;
-	int s;
+	struct proc 	*parent;
+	ksiginfo_t 	ksi;
+	int 		s;
+	struct inst	*i;
 
+	KASSERT(p);
+	KASSERT(p->p_inst);
 	KASSERT(p->p_nlwps == 0);
 	KASSERT(p->p_nzlwps == 0);
 	KASSERT(p->p_nrlwps == 0);
 	KASSERT(LIST_EMPTY(&p->p_lwps));
 
+	parent = p->p_pptr;
+	i = p->p_inst;
+
 	/*
 	 * If we got the child via ptrace(2) or procfs, and
 	 * the parent is different (meaning the process was
@@ -800,10 +882,10 @@
 	 * parent the exit signal.  The rest of the cleanup
 	 * will be done when the old parent waits on the child.
 	 */
-	if ((p->p_flag & P_TRACED) && p->p_opptr != parent){
+	if (parent && (p->p_flag & P_TRACED) && p->p_opptr != parent) {
 		parent = p->p_opptr;
 		if (parent == NULL)
-			parent = initproc;
+			parent = i->i_initproc;
 		proc_reparent(p, parent);
 		p->p_opptr = NULL;
 		p->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE);
@@ -815,10 +897,12 @@
 		return;
 	}
 
-	scheduler_wait_hook(parent, p);
+	if (parent)
+		scheduler_wait_hook(parent, p);
 	p->p_xstat = 0;
 
-	ruadd(&parent->p_stats->p_cru, p->p_ru);
+	if (parent)
+		ruadd(&parent->p_stats->p_cru, p->p_ru);
 
 	/*
 	 * At this point we are going to start freeing the final resources.
@@ -837,24 +921,28 @@
 	 */
 	leavepgrp(p);
 
-	s = proclist_lock_write();
-	LIST_REMOVE(p, p_list);	/* off zombproc */
-	p->p_pptr->p_nstopchild--;
-	LIST_REMOVE(p, p_sibling);
-	proclist_unlock_write(s);
+	if (p->p_pptr) {
+		s = proclist_lock_write(i);
+		LIST_REMOVE(p, p_list);	/* off zombproc */
+		p->p_pptr->p_nstopchild--;
+		LIST_REMOVE(p, p_sibling);
+		proclist_unlock_write(i, s);
+	}
 
 	/*
 	 * Decrement the count of procs running with this uid.
 	 */
-	(void)chgproccnt(p->p_cred->p_ruid, -1);
+	(void)chgproccnt(i, p->p_cred->p_ruid, -1);
 
 	/*
 	 * Free up credentials.
 	 */
+
 	if (--p->p_cred->p_refcnt == 0) {
 		crfree(p->p_cred->pc_ucred);
-		pool_put(&pcred_pool, p->p_cred);
+		pcred_free(p->p_cred);
 	}
+	KASSERT(i->i_refcnt >= 1);
 
 	/*
 	 * Release reference to text vnode
@@ -867,7 +955,7 @@
 		sa_release(p);
 
 	/* Free proc structure and let pid be reallocated */
-	proc_free_mem(p);
+	proc_free_mem(i, p);
 }
 
 /*
@@ -887,7 +975,7 @@
 		child->p_pptr->p_nstopchild--;
 		parent->p_nstopchild++;
 	}
-	if (parent == initproc)
+	if (parent == parent->p_inst->i_initproc)
 		child->p_exitsig = SIGCHLD;
 
 	LIST_REMOVE(child, p_sibling);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_fork.c mult-netbsd-3.1/sys/kern/kern_fork.c
--- NetBSD-3.1/sys/kern/kern_fork.c	2005-05-23 20:09:56.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_fork.c	2007-12-16 14:56:45.000000000 +0000
@@ -79,7 +79,6 @@
 __KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.121.2.2 2005/05/23 19:09:56 riz Exp $");
 
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 #include "opt_multiprocessor.h"
 
 #include <sys/param.h>
@@ -99,21 +98,44 @@
 #include <sys/vmmeter.h>
 #include <sys/sched.h>
 #include <sys/signalvar.h>
-#include <sys/systrace.h>
 
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
 
-int	nprocs = 1;		/* process 0 */
+extern const struct emul emul_netbsd;
+
+struct inst_fork
+{
+	int		forkfsleep;	/* Sleep ticks on fork-fail. */
+};
+
+
+int
+inst_fork_alloc(inst_fork_t *p, int flags)
+{
+	struct inst_fork *i;
+
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_fork), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_fork));
+	*p = i;
+	return(1);
+}
+
+void
+inst_fork_free(inst_fork_t p)
+{
+	KASSERT(p);
+	free(p, M_INST);
+}
 
-/*
- * Number of ticks to sleep if fork() would fail due to process hitting
- * limits. Exported in miliseconds to userland via sysctl.
- */
-int	forkfsleep = 0;
 
 /*ARGSUSED*/
 int
@@ -204,14 +226,212 @@
 /* print the 'table full' message once per 10 seconds */
 struct timeval fork_tfmrate = { 10, 0 };
 
+
+
+int
+forkinst1(void (*func)(void *), void *arg, const char *path, 
+		register_t *retval, struct proc **rnewprocp)
+{
+	struct proc	*p1, *p2;
+	struct lwp	*l2;
+	struct inst	*i1, *i2;
+	uid_t		uid;
+	int		s;
+	vaddr_t		uaddr;
+	boolean_t	inmem;
+
+	p1 = lwp0.l_proc;
+	uid = p1->p_cred->p_ruid;
+	i1 = lwp0.l_inst;
+
+	KASSERT(i1);
+
+	/* Reserve space for U-area (easy abortion). */
+	inmem = uvm_uarea_alloc(&uaddr);
+	if (__predict_false(0 == uaddr))
+		return (ENOMEM);
+
+	/*
+	 * We are now committed to the fork.  From here on, we may
+	 * block on resources, but resource allocation may NOT fail.
+	 */
+
+	/* Allocate new instance and proc. */
+	i2 = inst_alloc(INST_WAIT);
+	p2 = proc_alloc(i2);
+	i2->i_nprocs++;
+	(void)chgproccnt(i2, 0, 1); 
+
+	KASSERT(path);
+
+	strlcpy(i2->i_root, path, MAXPATHLEN);
+
+	/*
+	 * Make a proc table entry for the new process.  Start by
+	 * zeroing the section of proc that is zero-initialized, then
+	 * copy the section that is copied directly from the parent.
+	 */
+	memset(&p2->p_startzero, 0, (unsigned)
+			((caddr_t)&p2->p_endzero - 
+			 (caddr_t)&p2->p_startzero));
+	memcpy(&p2->p_startcopy, &p1->p_startcopy, (unsigned)
+			((caddr_t)&p2->p_endcopy - 
+			 (caddr_t)&p2->p_startcopy));
+
+	simple_lock_init(&p2->p_sigctx.ps_silock);
+	CIRCLEQ_INIT(&p2->p_sigctx.ps_siginfo);
+	simple_lock_init(&p2->p_lock);
+	LIST_INIT(&p2->p_lwps);
+
+	/*
+	 * Duplicate sub-structures as needed.  Increase reference
+	 * counts on shared objects.  The p_stats and p_sigacts
+	 * substructs are set in uvm_fork().  Inherit SUGID, STOPFORK
+	 * and STOPEXEC flags.
+	 */
+	p2->p_flag = p1->p_flag & (P_SUGID | P_STOPFORK | P_STOPEXEC);
+	p2->p_emul = p1->p_emul;
+	p2->p_execsw = p1->p_execsw;
+	p2->p_pptr = NULL;
+
+	p2->p_cred = pcred_alloc();
+	p2->p_cred->p_refcnt = 1;
+	p2->p_cred->pc_ucred = crget(i2);
+
+	LIST_INIT(&p2->p_raslist);
+#if defined(__HAVE_RAS)
+	ras_fork(p1, p2);
+#endif
+
+	/* bump references to the text vnode (for procfs) */
+	p2->p_textvp = p1->p_textvp;
+	if (p2->p_textvp)
+		VREF(p2->p_textvp);
+
+	p2->p_fd = fdinit();
+	p2->p_cwdi = cwdinit(p1);
+	p2->p_limit = limcopy(p1->p_limit);
+
+	if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
+		p2->p_flag |= P_CONTROLT;
+	LIST_INIT(&p2->p_children);
+
+	s = proclist_lock_write(p2->p_inst);
+	LIST_INSERT_AFTER(p1, p2, p_pglist);
+	proclist_unlock_write(p2->p_inst, s);
+
+	scheduler_fork_hook(p1, p2);
+
+	/*
+	 * Create signal actions for the child process.
+	 */
+	sigactsinit(p2, p1, FALSE);
+
+	/*
+	 * p_stats.  Copy parts of p_stats, and zero out the rest.
+	 */
+	p2->p_stats = pstatscopy(p1->p_stats);
+
+	/*
+	 * If emulation has process fork hook, call it now.
+	 */
+	if (p2->p_emul->e_proc_fork)
+		(*p2->p_emul->e_proc_fork)(p2, p1, 0);
+
+	/*
+	 * ...and finally, any other random fork hooks that subsystems
+	 * might have registered.
+	 */
+	doforkhooks(p2, p1);
+
+	/*
+	 * This begins the section where we must prevent the parent
+	 * from being swapped.
+	 */
+	PHOLD(&lwp0);
+
+	uvm_proc_fork(p1, p2, FALSE);
+
+	/*
+	 * Finish creating the child process.  It will return through a
+	 * different path later.
+	 */
+	newlwp(&lwp0, p2, uaddr, inmem, 0, NULL, 0,
+			(func != NULL) ? func : child_return,
+			arg, &l2);
+
+	/* Now safe for scheduler to see child process */
+	s = proclist_lock_write(p2->p_inst);
+	/* Signal for parent on exit. */
+	LIST_INSERT_HEAD(&p2->p_inst->i_allproc, p2, p_list);
+	proclist_unlock_write(p2->p_inst, s);
+
+#ifdef __HAVE_SYSCALL_INTERN
+	(*p2->p_emul->e_syscall_intern)(p2);
+#endif
+
+	/*
+	 * Make child runnable, set start time, and add to run queue
+	 * except if the parent requested the child to start in SSTOP state.
+	 */
+	SCHED_LOCK(s);
+	p2->p_stats->p_start = time;
+	p2->p_acflag = AFORK;
+	p2->p_nrlwps = 1;
+	p2->p_stat = SACTIVE;
+	l2->l_stat = LSRUN;
+	setrunqueue(l2);
+	SCHED_UNLOCK(s);
+
+	/*
+	 * Now can be swapped.
+	 */
+	PRELE(&lwp0);
+
+	/*
+	 * Notify any interested parties about the new process.
+	 */
+	KNOTE(&p1->p_klist, NOTE_FORK | p2->p_pid);
+
+	/*
+	 * Update stats now that we know the fork was successful.
+	 */
+	uvmexp.forks++;
+
+	/*
+	 * Pass a pointer to the new process to the caller.
+	 */
+	if (rnewprocp != NULL)
+		*rnewprocp = p2;
+
+#ifdef KTRACE
+	if (KTRPOINT(p2, KTR_EMUL))
+		p2->p_traceflag |= KTRFAC_TRC_EMUL;
+#endif
+
+	/*
+	 * Return child pid to parent process, marking us as parent via
+	 * retval[1].
+	 */
+	if (retval != NULL) {
+		retval[0] = p2->p_pid;
+		retval[1] = 0;
+	}
+
+	return (0);
+}
+
+
+
 int
 fork1(struct lwp *l1, int flags, int exitsig, void *stack, size_t stacksize,
     void (*func)(void *), void *arg, register_t *retval,
     struct proc **rnewprocp)
 {
 	struct proc	*p1, *p2, *parent;
-	uid_t		uid;
 	struct lwp	*l2;
+	struct inst	*i1;
+	uid_t		uid;
 	int		count, s;
 	vaddr_t		uaddr;
 	boolean_t	inmem;
@@ -225,29 +445,37 @@
 	 */
 	p1 = l1->l_proc;
 	uid = p1->p_cred->p_ruid;
-	if (__predict_false((nprocs >= maxproc - 5 && uid != 0) ||
-			    nprocs >= maxproc)) {
+	i1 = l1->l_inst;
+
+	KASSERT(NULL != i1);
+
+	/* FIXME - instances - lock instance for i_nprocs? */
+
+	if (__predict_false((i1->i_nprocs >= maxproc - 5 && uid != 0) ||
+			    i1->i_nprocs >= maxproc)) {
 		static struct timeval lasttfm;
 
 		if (ratecheck(&lasttfm, &fork_tfmrate))
 			tablefull("proc", "increase kern.maxproc or NPROC");
-		if (forkfsleep)
-			(void)tsleep(&nprocs, PUSER, "forkmx", forkfsleep);
+		if (i1->i_fork->forkfsleep)
+			(void)tsleep(&i1->i_nprocs, PUSER, "forkmx", 
+					i1->i_fork->forkfsleep);
 		return (EAGAIN);
 	}
-	nprocs++;
+	i1->i_nprocs++;
 
 	/*
 	 * Increment the count of procs running with this uid. Don't allow
 	 * a nonprivileged user to exceed their current limit.
 	 */
-	count = chgproccnt(uid, 1);
+	count = chgproccnt(i1, uid, 1);
 	if (__predict_false(uid != 0 && count >
 			    p1->p_rlimit[RLIMIT_NPROC].rlim_cur)) {
-		(void)chgproccnt(uid, -1);
-		nprocs--;
-		if (forkfsleep)
-			(void)tsleep(&nprocs, PUSER, "forkulim", forkfsleep);
+		(void)chgproccnt(i1, uid, -1);
+		i1->i_nprocs--;
+		if (i1->i_fork->forkfsleep)
+			(void)tsleep(&i1->i_nprocs, PUSER, "forkulim", 
+					i1->i_fork->forkfsleep);
 		return (EAGAIN);
 	}
 
@@ -260,8 +488,8 @@
 
 	inmem = uvm_uarea_alloc(&uaddr);
 	if (__predict_false(uaddr == 0)) {
-		(void)chgproccnt(uid, -1);
-		nprocs--;
+		(void)chgproccnt(i1, uid, -1);
+		i1->i_nprocs--;
 		return (ENOMEM);
 	}
 
@@ -271,7 +499,7 @@
 	 */
 
 	/* Allocate new proc. */
-	p2 = proc_alloc();
+	p2 = proc_alloc(l1->l_inst);
 
 	/*
 	 * Make a proc table entry for the new process.
@@ -300,10 +528,20 @@
 
 	if (p1->p_flag & P_PROFIL)
 		startprofclock(p2);
-	p2->p_cred = pool_get(&pcred_pool, PR_WAITOK);
+	p2->p_cred = pcred_alloc();
+
+	/*
+	 * NB: this will copy over the pc_ucred pointer, and thus the
+	 * instance pointer, too.
+	 */
 	memcpy(p2->p_cred, p1->p_cred, sizeof(*p2->p_cred));
 	p2->p_cred->p_refcnt = 1;
+
+	/*
+	 * Bump reference counts on both the user and the instance.
+	 */
 	crhold(p1->p_ucred);
+	inst_hold(p1->p_inst);
 
 	LIST_INIT(&p2->p_raslist);
 #if defined(__HAVE_RAS)
@@ -318,7 +556,7 @@
 	if (flags & FORK_SHAREFILES)
 		fdshare(p1, p2);
 	else if (flags & FORK_CLEANFILES)
-		p2->p_fd = fdinit(p1);
+		p2->p_fd = fdinit();
 	else
 		p2->p_fd = fdcopy(p1);
 
@@ -346,14 +584,15 @@
 		p2->p_flag |= P_CONTROLT;
 	if (flags & FORK_PPWAIT)
 		p2->p_flag |= P_PPWAIT;
-	parent = (flags & FORK_NOWAIT) ? initproc : p1;
+	parent = (flags & FORK_NOWAIT) ? 
+		i1->i_initproc : p1;
 	p2->p_pptr = parent;
 	LIST_INIT(&p2->p_children);
 
-	s = proclist_lock_write();
+	s = proclist_lock_write(p2->p_inst);
 	LIST_INSERT_AFTER(p1, p2, p_pglist);
 	LIST_INSERT_HEAD(&parent->p_children, p2, p_sibling);
-	proclist_unlock_write(s);
+	proclist_unlock_write(p2->p_inst, s);
 
 #ifdef KTRACE
 	/*
@@ -409,16 +648,10 @@
 	    arg, &l2);
 
 	/* Now safe for scheduler to see child process */
-	s = proclist_lock_write();
+	s = proclist_lock_write(p2->p_inst);
 	p2->p_exitsig = exitsig;		/* signal for parent on exit */
-	LIST_INSERT_HEAD(&allproc, p2, p_list);
-	proclist_unlock_write(s);
-
-#ifdef SYSTRACE
-	/* Tell systrace what's happening. */
-	if (ISSET(p1->p_flag, P_SYSTRACE))
-		systrace_sys_fork(p1, p2);
-#endif
+	LIST_INSERT_HEAD(&p2->p_inst->i_allproc, p2, p_list);
+	proclist_unlock_write(p2->p_inst, s);
 
 #ifdef __HAVE_SYSCALL_INTERN
 	(*p2->p_emul->e_syscall_intern)(p2);
@@ -511,3 +744,60 @@
 	KERNEL_PROC_LOCK(l);
 }
 #endif
+
+#include <sys/sysctl.h>
+
+static int sysctl_kern_forkfsleep(SYSCTLFN_PROTO);
+
+/*
+ * sysctl helper routine for kern.forkfsleep node.  ensures that the
+ * given value is not too large or two small, and is at least one timer
+ * tick if not zero.
+ */
+static int
+sysctl_kern_forkfsleep(SYSCTLFN_ARGS)
+{
+	/* userland sees value in ms, internally is in ticks */
+	int error, timo, lsleep;
+	struct sysctlnode node;
+
+	lsleep = l->l_inst->i_fork->forkfsleep * 1000 / hz;
+	node = *rnode;
+	node.sysctl_data = &lsleep;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return (error);
+
+	/* refuse negative values, and overly 'long time' */
+	if (lsleep < 0 || lsleep > MAXSLP * 1000)
+		return (EINVAL);
+
+	timo = mstohz(lsleep);
+
+	/* if the interval is >0 ms && <1 tick, use 1 tick */
+	if (lsleep != 0 && timo == 0)
+		l->l_inst->i_fork->forkfsleep = 1;
+	else
+		l->l_inst->i_fork->forkfsleep = timo;
+
+	return (0);
+}
+
+
+SYSCTL_SETUP(sysctl_kern_forkfsleep_setup, 
+		"sysctl kern.forkfsleep setup")
+{
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "kern", NULL,
+		       NULL, 0, NULL, 0,
+		       CTL_KERN, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "forkfsleep",
+		       SYSCTL_DESCR("Milliseconds to sleep on fork "
+			       "failure due to process limits"),
+		       sysctl_kern_forkfsleep, 0, NULL, 0,
+		       CTL_KERN, KERN_FORKFSLEEP, CTL_EOL);
+}
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_inst.c mult-netbsd-3.1/sys/kern/kern_inst.c
--- NetBSD-3.1/sys/kern/kern_inst.c	1970-01-01 01:00:00.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_inst.c	2007-12-19 13:35:20.000000000 +0000
@@ -0,0 +1,817 @@
+/*
+ * Copyright (c) 2007 Kristaps Dzonsons <kristaps.dzonsons@latnet.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/cdefs.h>
+
+#include <sys/lock.h>
+#include <sys/pool.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/ucred.h>
+#include <sys/lwp.h>
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/inst.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/filedesc.h>
+#include <sys/vnode.h>
+#include <sys/namei.h>
+#include <sys/reboot.h>
+
+#include <sys/syscallargs.h>
+
+#include <dev/cons.h>
+
+#include <uvm/uvm.h>
+
+#include <machine/stdarg.h>
+
+MALLOC_DEFINE(M_INST, "inst", "Instance sub-structures");
+
+static int		inst_debug = 0;
+static struct inst 	*insttbl[INST_MAX];
+static struct lock 	instlist_rw_lock;
+static u_int		instlist_cnt;
+static 			POOL_INIT(inst_pool, sizeof(struct inst), 
+				0, 0, 0, "inst_pool", NULL);
+
+void			instinit(void *);
+static int		instctl_debug(int, struct inst *);
+static int		instctl_create(const struct instctl_create *, 
+				struct inst *);
+static int		instctl_kill(const struct instctl_kill *, 
+				struct inst *);
+static int		instchroot(struct proc *);
+static int		instlist_lock_rw(void);
+static void		instlist_unlock_rw(int);
+static void		inst_log(int lvl, const char *, 
+				const struct inst *, 
+				const char *, ...) 
+				__attribute__((__format__
+					(__printf__, 4, 5)));
+static void		inst_free(struct inst *);
+
+#define inst_refcnt_inc(inst) 					\
+	simple_lock(&(inst)->i_lock);				\
+	(inst)->i_refcnt++;					\
+	inst_log(IC_REFCNT, __func__, (inst), "refcnt: %d", 	\
+			(inst)->i_refcnt);			\
+	simple_unlock(&(inst)->i_lock);
+
+#define inst_refcnt_dec(val, inst) 				\
+	simple_lock(&(inst)->i_lock);				\
+	(val) = --(inst)->i_refcnt;				\
+	inst_log(IC_REFCNT, __func__, (inst), "refcnt: %d", 	\
+			(inst)->i_refcnt);			\
+	simple_unlock(&(inst)->i_lock);
+
+static void
+inst_log(int lvl, const char *func, 
+		const struct inst *inst, const char *fmt, ...)
+{
+	va_list 	ap;
+	size_t		sz;
+	char		dbuf[256], *p;
+	int		uuid;
+
+	if ( ! (inst_debug & lvl))
+		return;
+
+	/* FIXME: this will overflow. */
+	uuid = inst ? (int)inst->i_uuid : -1;
+
+	KASSERT(func);
+	KASSERT(fmt);
+
+	dbuf[255] = 0;
+	snprintf(dbuf, 255, "%s uuid %d: ", func, uuid);
+
+	sz = strlen(dbuf);
+	p = dbuf + sz;
+	va_start(ap, fmt);
+	vsnprintf(p, 255 - sz, fmt, ap);
+	va_end(ap);
+	printf("%s\n", dbuf);
+}
+
+
+void
+inst_init(void)
+{
+	spinlockinit(&instlist_rw_lock, "instlk", 0);
+	LIST_INIT(&allinst);
+	instlist_cnt = 0;
+	memset(insttbl, 0, sizeof(insttbl));
+}
+
+
+void
+inst_get_phostname(struct proc *proc, char *buf, size_t len)
+{
+	KASSERT(NULL != buf);
+
+	if (NULL == proc) {
+		(void)strlcpy(buf, "", len);
+		return;
+	}
+
+	KASSERT(NULL != proc->p_inst);
+
+	simple_lock(&proc->p_inst->i_lock);
+	strlcpy(buf, proc->p_inst->i_host, len);
+	simple_unlock(&proc->p_inst->i_lock);
+}
+
+
+void
+inst_get_hostname(struct lwp *l, char *buf, size_t len)
+{
+	if (NULL == l) {
+		KASSERT(NULL != buf);
+		(void)strlcpy(buf, "", len);
+	} else
+		inst_get_phostname(l->l_proc, buf, len);
+}
+
+
+int
+inst_copyout_hostname(struct lwp *l, void *uaddr, size_t len)
+{
+	char		tmp[MAXHOSTNAMELEN];
+
+	tmp[0] = 0;
+
+	if (NULL != l) {
+		KASSERT(NULL != l->l_inst);
+		simple_lock(&l->l_inst->i_lock);
+		strlcpy(tmp, l->l_inst->i_host, MAXHOSTNAMELEN);
+		simple_unlock(&l->l_inst->i_lock);
+	} 
+
+	return(copyout(tmp, uaddr, len));
+}
+
+
+int
+inst_copyoutstr_hostname(struct lwp *l, 
+		void *uaddr, size_t len, size_t *done)
+{
+	char		tmp[MAXHOSTNAMELEN];
+
+	tmp[0] = 0;
+
+	if (NULL != l) {
+		KASSERT(NULL != l->l_inst);
+		simple_lock(&l->l_inst->i_lock);
+		strlcpy(tmp, l->l_inst->i_host, MAXHOSTNAMELEN);
+		simple_unlock(&l->l_inst->i_lock);
+	} 
+
+	return(copyoutstr(tmp, uaddr, len, done));
+}
+
+
+size_t
+inst_get_phostnamelen(struct proc *proc)
+{
+	size_t		sz;
+
+	if (NULL == proc)
+		return(0);
+
+	KASSERT(NULL != proc->p_inst);
+
+	simple_lock(&proc->p_inst->i_lock);
+	sz = strlen(proc->p_inst->i_host);
+	simple_unlock(&proc->p_inst->i_lock);
+
+	return(sz);
+}
+
+
+size_t
+inst_get_hostnamelen(struct lwp *l)
+{
+	if (NULL == l)
+		return(0);
+
+	return(inst_get_phostnamelen(l->l_proc));
+}
+
+
+void
+inst_get_pdomainname(struct proc *proc, char *buf, size_t len)
+{
+	KASSERT(NULL != buf);
+
+	if (NULL == proc) {
+		(void)strlcpy(buf, "", len);
+		return;
+	}
+
+	KASSERT(NULL != proc->p_inst);
+
+	simple_lock(&proc->p_inst->i_lock);
+	strlcpy(buf, proc->p_inst->i_domain, len);
+	simple_unlock(&proc->p_inst->i_lock);
+}
+
+
+void
+inst_get_domainname(struct lwp *l, char *buf, size_t len)
+{
+	if (NULL == l) {
+		KASSERT(NULL != buf);
+		(void)strlcpy(buf, "", len);
+	} else
+		inst_get_pdomainname(l->l_proc, buf, len);
+}
+
+
+size_t
+inst_get_pdomainnamelen(struct proc *proc)
+{
+	size_t		sz;
+
+	if (NULL == proc)
+		return(0);
+
+	KASSERT(NULL != proc->p_inst);
+
+	simple_lock(&proc->p_inst->i_lock);
+	sz = strlen(proc->p_inst->i_domain);
+	simple_unlock(&proc->p_inst->i_lock);
+
+	return(sz);
+}
+
+
+size_t
+inst_get_domainnamelen(struct lwp *l)
+{
+	if (NULL == l)
+		return(0);
+
+	return(inst_get_pdomainnamelen(l->l_proc));
+}
+
+
+int
+inst_set_hostname(struct lwp *l, const char *buf)
+{
+	if (NULL == l)
+		return(EINVAL);
+
+	KASSERT(l->l_inst);
+	KASSERT(buf);
+
+	simple_lock(&l->l_inst->i_lock);
+	strlcpy(l->l_inst->i_host, buf, MAXHOSTNAMELEN);
+	simple_unlock(&l->l_inst->i_lock);
+
+	return(0);
+}
+
+
+int
+inst_set_domainname(struct lwp *l, const char *buf)
+{
+	if (NULL == l)
+		return(EINVAL);
+
+	KASSERT(NULL != l->l_inst);
+	KASSERT(NULL != buf);
+
+	simple_lock(&l->l_inst->i_lock);
+	strlcpy(l->l_inst->i_domain, buf, MAXHOSTNAMELEN);
+	simple_unlock(&l->l_inst->i_lock);
+
+	return(0);
+}
+
+
+struct inst *
+inst_alloc(int flag)
+{
+	struct inst	*i;
+	int		s, pflag, mflag;
+
+	pflag = flag & INST_WAIT ? PR_WAITOK : PR_NOWAIT;
+	mflag = flag & INST_WAIT ? M_WAITOK : M_NOWAIT;
+
+	i = pool_get(&inst_pool, pflag);
+	(void)memset(i, 0, sizeof(struct inst));
+
+	i->i_refcnt = 1;
+	i->i_state = INST_INIT;
+
+	simple_lock_init(&i->i_lock);
+
+	/*
+	 * Initialise live-in process stuff.
+	 */
+
+	i->i_proclists[0].pd_list = &i->i_allproc;
+	i->i_proclists[1].pd_list = &i->i_zombproc;
+	i->i_proclists[2].pd_list = NULL;
+
+	spinlockinit(&i->i_proclist_lock, "proclk", 0);
+
+	/*
+	 * Initialise live-in file stuff.
+	 */
+
+	simple_lock_init(&i->i_filelist_lock);
+
+	/*
+	 * Initialise sub-structures.
+	 */
+
+	/* TODO: release extant resources. */
+	if ( ! inst_proc_alloc(&i->i_proc, mflag))
+		return(NULL);
+	if ( ! inst_acct_alloc(&i->i_acct, mflag))
+		return(NULL);
+	if ( ! inst_res_alloc(&i->i_res, mflag))
+		return(NULL);
+	if ( ! inst_pipe_alloc(&i->i_pipe, mflag))
+		return(NULL);
+	if ( ! inst_kevt_alloc(&i->i_kevt, mflag))
+		return(NULL);
+	if ( ! inst_fork_alloc(&i->i_fork, mflag))
+		return(NULL);
+	if ( ! inst_ktrc_alloc(&i->i_ktrc, mflag))
+		return(NULL);
+
+	/*
+	 * FIXME.  Use an real method for instance identifiers so that
+	 * we can later do lookups based on instances.  Use the proc
+	 * method or something.  This dies after INSTLIST_MAX tries.
+	 */
+
+	s = instlist_lock_rw();
+	KASSERT(instlist_cnt < INST_MAX);
+	KASSERT(NULL == insttbl[instlist_cnt]);
+	i->i_uuid = instlist_cnt++;
+	insttbl[i->i_uuid] = i;
+	LIST_INSERT_HEAD(&allinst, i, i_list);
+	instlist_unlock_rw(s);
+
+	inst_log(IC_ALLOC, __func__, i, "alloc: %u", i->i_uuid);
+
+	return(i);
+}
+
+
+static void
+inst_free(struct inst *i)
+{
+	int	sp;
+
+	inst_log(IC_ALLOC, __func__, i, "free: %u", i->i_uuid);
+
+	sp = instlist_lock_rw();
+	KASSERT(insttbl[i->i_uuid]);
+	insttbl[i->i_uuid] = NULL;
+	LIST_REMOVE(i, i_list);
+	instlist_unlock_rw(sp);
+
+	if (i->i_ktrc)
+		inst_ktrc_free(i->i_ktrc);
+	if (i->i_fork)
+		inst_fork_free(i->i_fork);
+	if (i->i_kevt)
+		inst_kevt_free(i->i_kevt);
+	if (i->i_acct)
+		inst_acct_free(i->i_acct);
+	if (i->i_res)
+		inst_res_free(i->i_res);
+	if (i->i_proc)
+		inst_proc_free(i->i_proc);
+	if (i->i_proc)
+		inst_pipe_free(i->i_pipe);
+
+	pool_put(&inst_pool, i);
+}
+
+
+void
+inst_hold(struct inst *inst)
+{
+	KASSERT(inst);
+	KASSERT(inst->i_refcnt > 0);
+	inst_refcnt_inc(inst);
+}
+
+
+void
+inst_release(struct inst *inst)
+{
+	uint		refcnt;
+
+	KASSERT(NULL != inst);
+	KASSERT(inst->i_refcnt > 0);
+	inst_refcnt_dec(refcnt, inst);
+	if (0 != refcnt)
+		return;
+	inst_free(inst);
+}
+
+
+static int
+instlist_lock_rw(void)
+{
+	int 		s, error;
+	s = splclock();
+	error = spinlockmgr(&instlist_slock, LK_EXCLUSIVE, NULL);
+	if (__predict_false(0 != error))
+		panic("failed to acquire instance lock");
+	return(s);
+}
+
+
+static void
+instlist_unlock_rw(int s)
+{
+	(void)spinlockmgr(&instlist_slock, LK_RELEASE, NULL);
+	splx(s);
+}
+
+
+void
+instlist_lock_read(void)
+{
+	int 		error;
+	error = spinlockmgr(&instlist_slock, LK_SHARED, NULL);
+	if (__predict_false(0 != error))
+		panic("failed to acquire instance lock");
+}
+
+
+void
+instlist_unlock_read(void)
+{
+	(void)spinlockmgr(&instlist_slock, LK_RELEASE, NULL);
+}
+
+
+static int
+instctl_debug(int ctl, struct inst *i)
+{
+	KASSERT(i);
+	inst_log(IC_SYSCALL, __func__, i,
+			"debug level: %x -> %x", inst_debug, ctl);
+	
+	simple_lock(&i->i_lock);
+	inst_debug = ctl;
+	simple_unlock(&i->i_lock);
+	return(0);
+}
+
+
+static int
+instctl_create(const struct instctl_create *ctl, struct inst *i)
+{
+	char		path[MAXPATHLEN];
+	int		error;
+
+	KASSERT(i);
+	KASSERT(ctl);
+	if (NULL == ctl->root) 
+		return(EINVAL);
+
+	error = copyinstr(ctl->root, path, MAXPATHLEN, NULL);
+	if (error)
+		return(error);
+
+	inst_log(IC_SYSCALL, __func__, i, "fork: %s", path);
+	return(forkinst1(instinit, NULL, path, NULL, NULL));
+}
+
+
+static int
+instctl_kill(const struct instctl_kill *ctl, struct inst *i)
+{
+	struct inst	*ci;
+
+	ci = inst_lookup(ctl->uuid);
+	if (NULL == ci) 
+		return(ESRCH);
+	psignal1(ci->i_initproc, IC_KILLSLOW == ctl->sig ? 
+			SIGTERM : SIGKILL, 1);
+	inst_release(ci);
+	return(0);
+}
+
+
+int
+/* ARGSUSED */
+sys_instctl(struct lwp *l, void *v, register_t *retval)
+{
+	struct sys_instctl_args /* {
+		syscallarg(const struct instctl *) ctl;
+	} */ *uap = v;
+	const struct instctl *ctl;
+	struct inst	*i;
+
+	KASSERT(l);
+	KASSERT(l->l_inst);
+	ctl = SCARG(uap, ctl);
+	
+	i = l->l_inst;
+	switch (ctl->ic_op) {
+	case (IC_CREATE):
+		return(instctl_create(&ctl->ic_data.ic_create, i));
+	case (IC_DEBUG):
+		return(instctl_debug(ctl->ic_data.ic_debug, i));
+	case (IC_KILL):
+		return(instctl_kill(&ctl->ic_data.ic_kill, i));
+	default:
+		break;
+	}
+	return (EINVAL);
+}
+
+
+struct inst *
+inst_lookup(u_int uuid)
+{
+	struct inst	*i;
+
+	if (uuid >= INST_MAX)
+		return(NULL);
+
+	instlist_lock_read();
+	i = insttbl[uuid];
+	if (i)
+		inst_hold(i);
+	instlist_unlock_read();
+
+	return(i);
+}
+
+
+static const char *initpaths[] = {
+	"/sbin/instinit",
+	"/sbin/instinit.bak",
+	NULL,
+};
+
+
+void
+instinit(void *arg)
+{
+	struct lwp 	*l = arg;
+	struct proc 	*p = l->l_proc;
+	vaddr_t 	addr;
+	struct sys_execve_args /* {
+		syscallarg(const char *) path;
+		syscallarg(char * const *) argp;
+		syscallarg(char * const *) envp;
+	} */ args;
+	int 		options, i, error;
+	register_t 	retval[2];
+	char 		flags[4], *flagsp;
+	const char 	*path, *slash;
+	char 		*ucp, **uap, *arg0, *arg1 = NULL;
+	int 		ipx;
+
+	/*
+	 * Now in process 1.
+	 */
+	strncpy(p->p_comm, "init", MAXCOMLEN);
+	p->p_inst->i_initproc = p;
+	p->p_inst->i_state = INST_RUNNING;
+
+	if (0 != (error = instchroot(p))) {
+		inst_log(IC_SYSCALL, __func__, p->p_inst, 
+				"chroot: %s", p->p_inst->i_root);
+		goto out;
+	}
+
+	/*
+	 * Need just enough stack to hold the faked-up "execve()" arguments.
+	 */
+	addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);
+	if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
+                    NULL, UVM_UNKNOWN_OFFSET, 0,
+                    UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
+		    UVM_ADV_NORMAL,
+                    UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
+		panic("init: couldn't allocate argument space");
+	p->p_vmspace->vm_maxsaddr = (caddr_t)STACK_MAX(addr, PAGE_SIZE);
+
+	ipx = 0;
+	for (;; /* Infinite loop. */) {
+		if ((path = initpaths[ipx++]) == NULL)
+			break;
+
+		ucp = (char *)USRSTACK;
+
+		/*
+		 * Construct the boot flag argument.
+		 */
+		flagsp = flags;
+		*flagsp++ = '-';
+		options = 0;
+
+		/*
+		 * Move out the file name (also arg 0).
+		 */
+		i = strlen(path) + 1;
+		arg0 = STACK_ALLOC(ucp, i);
+		ucp = STACK_MAX(arg0, i);
+		(void)copyout((const caddr_t)path, arg0, i);
+
+		/*
+		 * Move out the arg pointers.
+		 */
+		ucp = (caddr_t)STACK_ALIGN(ucp, ALIGNBYTES);
+		uap = (char **)STACK_ALLOC(ucp, sizeof(char *) * 3);
+		SCARG(&args, path) = arg0;
+		SCARG(&args, argp) = uap;
+		SCARG(&args, envp) = NULL;
+		slash = strrchr(path, '/');
+		if (slash)
+			(void)suword((caddr_t)uap++,
+			    (long)arg0 + (slash + 1 - path));
+		else
+			(void)suword((caddr_t)uap++, (long)arg0);
+		if (options != 0)
+			(void)suword((caddr_t)uap++, (long)arg1);
+		(void)suword((caddr_t)uap++, 0);	/* terminator */
+
+		/*
+		 * Now try to exec the program.  If can't for any reason
+		 * other than it doesn't exist, complain.
+		 */
+		error = sys_execve(LIST_FIRST(&p->p_lwps), &args, retval);
+		if (error == 0 || error == EJUSTRETURN) {
+			KERNEL_PROC_UNLOCK(l);
+			return;
+		}
+
+		inst_log(IC_SYSCALL, __func__, p->p_inst, 
+				"exec: %s, %d", path, error);
+	}
+
+out:
+	inst_log(IC_SYSCALL, __func__, p->p_inst, 
+			"instance death: cannot fork");
+
+	p->p_inst->i_state = INST_EXITING;
+	instdaemon_sem = 1;
+	wakeup((void *)&instdaemon_sem);
+
+	exit1(LIST_FIRST(&p->p_lwps), 1);
+}
+
+
+/*
+ * This is yanked from sys_chroot.
+ */
+static int
+instchroot(struct proc *p)
+{
+	int 		error;
+	struct nameidata nd;
+
+	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, 
+			UIO_SYSSPACE, p->p_inst->i_root, p);
+
+	if (0 != (error = namei(&nd)))
+		return (error);
+
+	error = nd.ni_vp->v_type != VDIR ? ENOTDIR :
+		VOP_ACCESS(nd.ni_vp, VEXEC, p->p_ucred, p);
+
+	if (error) {
+		vput(nd.ni_vp);
+		return(error);
+	} else
+		VOP_UNLOCK(nd.ni_vp, 0);
+
+	if (p->p_cwdi->cwdi_rdir != NULL)
+		vrele(p->p_cwdi->cwdi_rdir);
+	p->p_cwdi->cwdi_rdir = nd.ni_vp;
+
+	/*
+	 * Prevent escaping from chroot by putting the root under the
+	 * working directory.  Silently chdir to / if we aren't already
+	 * there.
+	 */
+	if (!vn_isunder(p->p_cwdi->cwdi_cdir, nd.ni_vp, p)) {
+		/*
+		 * XXX would be more failsafe to change directory to a
+		 * deadfs node here instead.
+		 */
+		vrele(p->p_cwdi->cwdi_cdir);
+		VREF(nd.ni_vp);
+		p->p_cwdi->cwdi_cdir = nd.ni_vp;
+	}
+
+	return (0);
+}
+
+
+void
+proclist_lock_read(struct inst *i)
+{
+	int 		error;
+
+	KASSERT(i);
+	error = spinlockmgr
+		(&i->i_proclist_lock, LK_SHARED, NULL);
+#ifdef DIAGNOSTIC
+	if (__predict_false(0 != error))
+		panic("proclist_lock_read: failed to acquire lock");
+#endif
+}
+
+
+void
+proclist_unlock_read(struct inst *i)
+{
+	KASSERT(NULL != i);
+	(void)spinlockmgr(&i->i_proclist_lock, LK_RELEASE, NULL);
+}
+
+
+int
+proclist_lock_write(struct inst *i)
+{
+	int 		s, error;
+
+	s = splclock();
+	KASSERT(i);
+	error = spinlockmgr(&i->i_proclist_lock, LK_EXCLUSIVE, NULL);
+#ifdef DIAGNOSTIC
+	if (__predict_false(0 != error))
+		panic("proclist_lock: failed to acquire lock");
+#endif
+	return(s);
+}
+
+
+void
+proclist_unlock_write(struct inst *i, int s)
+{
+	KASSERT(i);
+	(void)spinlockmgr(&i->i_proclist_lock, LK_RELEASE, NULL);
+	splx(s);
+}
+
+
+/*
+ * This kernel-thread handles exited instinit(8) processes.  See
+ * instdaemon(9).  This should never exit!
+ */
+void
+instdaemon(void *v)
+{
+	struct inst	*i;
+
+	(void)v; /* Stop lint from complaining. */
+
+	for (;;) {
+		while (0 == instdaemon_sem)
+			(void)tsleep((void *)&instdaemon_sem, 
+					PWAIT, "instdaemon", 0);
+		instdaemon_sem = 0;
+
+		inst_log(IC_DAEMON, __func__, NULL, "instdaemon woken");
+
+again:
+		i = NULL;
+		instlist_lock_read();
+		LIST_FOREACH(i, &allinst, i_list) 
+			if (INST_EXITING == i->i_state &&
+					1 == i->i_nprocs)
+				break;
+		instlist_unlock_read();
+		if (NULL == i)
+			continue;
+
+		inst_log(IC_DAEMON, __func__, i,
+				"instdaemon reaping: %d", i->i_uuid);
+
+		i->i_state = INST_REAPED;
+		proc_free(i->i_initproc);
+		goto again;
+	}
+}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_ktrace.c mult-netbsd-3.1/sys/kern/kern_ktrace.c
--- NetBSD-3.1/sys/kern/kern_ktrace.c	2006-10-24 17:33:44.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_ktrace.c	2007-11-27 12:47:32.000000000 +0000
@@ -56,6 +56,8 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #ifdef KTRACE
 
 /*
@@ -136,21 +138,55 @@
 #define	KTD_WAKEDELAY		5000	/* XXX: tune */
 #define	KTD_INTRWAKDL		100	/* XXX: tune */
 
-/*
- * Patchable variables.
- */
-int ktd_maxentry = KTD_MAXENTRY;	/* max # of entry in the queue */
-int ktd_timeout = KTD_TIMEOUT;		/* timeout in seconds */
-int ktd_delayqcnt = KTD_DELAYQCNT;	/* # of entry allowed to delay */
-int ktd_wakedelay = KTD_WAKEDELAY;	/* delay of wakeup in *ms* */
-int ktd_intrwakdl = KTD_INTRWAKDL;	/* ditto, but when interactive */
 
-static struct simplelock ktdq_slock = SIMPLELOCK_INITIALIZER;
-static TAILQ_HEAD(, ktr_desc) ktdq = TAILQ_HEAD_INITIALIZER(ktdq);
+struct inst_ktrc
+{
+	struct simplelock	ktdq_slock;
+	TAILQ_HEAD(, ktr_desc)	ktdq;
+	int 			ktd_maxentry; /* max # of entry in the queue */
+	int			ktd_timeout; /* timeout in seconds */
+	int			ktd_delayqcnt; /* # of entry allowed to delay */
+	int			ktd_wakedelay; /* delay of wakeup in *ms* */
+	int 			ktd_intrwakdl; /* ditto, but when interactive */
+};
+
 
 MALLOC_DEFINE(M_KTRACE, "ktrace", "ktrace data buffer");
+
 POOL_INIT(kte_pool, sizeof(struct ktrace_entry), 0, 0, 0,
-    "ktepl", &pool_allocator_nointr);
+		"ktepl", &pool_allocator_nointr);
+
+
+int
+inst_ktrc_alloc(inst_ktrc_t *p, int flags)
+{
+	struct inst_ktrc *i;
+
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_ktrc), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_ktrc));
+
+	simple_lock_init(&i->ktdq_slock);
+	TAILQ_INIT(&i->ktdq);
+	i->ktd_maxentry = KTD_MAXENTRY;
+	i->ktd_timeout = KTD_TIMEOUT;
+	i->ktd_delayqcnt = KTD_DELAYQCNT;
+	i->ktd_wakedelay = KTD_WAKEDELAY;
+	i->ktd_intrwakdl = KTD_INTRWAKDL;
+
+	*p = i;
+	return(1);
+}
+
+void
+inst_ktrc_free(inst_ktrc_t p)
+{
+	KASSERT(p);
+	free(p, M_INST);
+}
+
 
 static __inline void
 ktd_wakeup(struct ktr_desc *ktd)
@@ -211,8 +247,9 @@
 {
 	struct ktr_desc *ktd;
 
-	simple_lock(&ktdq_slock);
-	for (ktd = TAILQ_FIRST(&ktdq); ktd != NULL;
+	simple_lock(&fp->f_cred->cr_inst->i_ktrc->ktdq_slock);
+	for (ktd = TAILQ_FIRST(&fp->f_cred->cr_inst->i_ktrc->ktdq); 
+			ktd != NULL;
 	    ktd = TAILQ_NEXT(ktd, ktd_list)) {
 		simple_lock(&ktd->ktd_slock);
 		if (ktrsamefile(ktd->ktd_fp, fp)) {
@@ -222,7 +259,7 @@
 		}
 		simple_unlock(&ktd->ktd_slock);
 	}
-	simple_unlock(&ktdq_slock);
+	simple_unlock(&fp->f_cred->cr_inst->i_ktrc->ktdq_slock);
 	return (ktd);
 }
 
@@ -260,7 +297,7 @@
 	if (ktd->ktd_flags & KTDF_DONE)
 		goto relktd;
 
-	if (ktd->ktd_qcount > ktd_maxentry) {
+	if (ktd->ktd_qcount > p->p_inst->i_ktrc->ktd_maxentry) {
 		ktd_logerrl(ktd, KTDE_ENOSPC);
 		goto relktd;
 	}
@@ -271,7 +308,7 @@
 
 	if (flags & KTA_WAITOK &&
 	    (/* flags & KTA_LARGE */0 || ktd->ktd_flags & KTDF_WAIT ||
-	    ktd->ktd_qcount > ktd_maxentry >> 1))
+	    ktd->ktd_qcount > p->p_inst->i_ktrc->ktd_maxentry >> 1))
 		/*
 		 * Sync with writer thread since we're requesting rather
 		 * big one or many requests are pending.
@@ -285,7 +322,8 @@
 			splx(s);
 #endif
 			if (ltsleep(&ktd->ktd_flags, PWAIT, "ktrsync",
-			    ktd_timeout * hz, &ktd->ktd_slock) != 0) {
+						p->p_inst->i_ktrc->ktd_timeout * hz, 
+						&ktd->ktd_slock) != 0) {
 				ktd->ktd_flags |= KTDF_BLOCKING;
 				/*
 				 * Maybe the writer thread is blocking
@@ -738,8 +776,9 @@
 		if (ktd == NULL)
 			goto done;
 
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		KASSERT(NULL != curp->p_inst);
+		proclist_lock_read(curp->p_inst);
+		PROCLIST_FOREACH(p, &curp->p_inst->i_allproc) {
 			if (p->p_tracep == ktd) {
 				if (ktrcanset(curp, p))
 					ktrderef(p);
@@ -747,7 +786,7 @@
 					error = EPERM;
 			}
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(curp->p_inst);
 		goto done;
 
 	case KTROP_SET:
@@ -761,9 +800,9 @@
 			ktd->ktd_flags = ktd->ktd_qcount =
 			    ktd->ktd_error = ktd->ktd_errcnt = 0;
 			ktd->ktd_ref = 1;
-			ktd->ktd_delayqcnt = ktd_delayqcnt;
-			ktd->ktd_wakedelay = mstohz(ktd_wakedelay);
-			ktd->ktd_intrwakdl = mstohz(ktd_intrwakdl);
+			ktd->ktd_delayqcnt = curp->p_inst->i_ktrc->ktd_delayqcnt;
+			ktd->ktd_wakedelay = mstohz(curp->p_inst->i_ktrc->ktd_wakedelay);
+			ktd->ktd_intrwakdl = mstohz(curp->p_inst->i_ktrc->ktd_intrwakdl);
 			/*
 			 * XXX: not correct.  needs an way to detect
 			 * whether ktruss or ktrace.
@@ -783,9 +822,9 @@
 			simple_unlock(&fp->f_slock);
 			ktd->ktd_fp = fp;
 
-			simple_lock(&ktdq_slock);
-			TAILQ_INSERT_TAIL(&ktdq, ktd, ktd_list);
-			simple_unlock(&ktdq_slock);
+			simple_lock(&curp->p_inst->i_ktrc->ktdq_slock);
+			TAILQ_INSERT_TAIL(&curp->p_inst->i_ktrc->ktdq, ktd, ktd_list);
+			simple_unlock(&curp->p_inst->i_ktrc->ktdq_slock);
 		}
 		break;
 
@@ -808,7 +847,7 @@
 		/*
 		 * by process group
 		 */
-		pg = pg_find(-pid, PFIND_UNLOCK_FAIL);
+		pg = pg_find(curp->p_inst, -pid, PFIND_UNLOCK_FAIL);
 		if (pg == NULL) {
 			error = ESRCH;
 			goto done;
@@ -824,7 +863,7 @@
 		/*
 		 * by pid
 		 */
-		p = p_find(pid, PFIND_UNLOCK_FAIL);
+		p = p_find(curp->p_inst, pid, PFIND_UNLOCK_FAIL);
 		if (p == NULL) {
 			error = ESRCH;
 			goto done;
@@ -834,7 +873,8 @@
 		else
 			ret |= ktrops(curp, p, ops, facs, ktd);
 	}
-	proclist_unlock_read();	/* taken by p{g}_find */
+	/* taken by p{g}_find */
+	proclist_unlock_read(curp->p_inst);	
 	if (!ret)
 		error = EPERM;
 done:
@@ -1023,7 +1063,7 @@
 			continue;
 		}
 		for (;;) {
-			if (p == top)
+			if (NULL == p || p == top)
 				return (ret);
 			if (LIST_NEXT(p, p_sibling) != NULL) {
 				p = LIST_NEXT(p, p_sibling);
@@ -1100,12 +1140,13 @@
 			log(LOG_NOTICE,
 			    "ktrace write failed, errno %d, tracing stopped\n",
 			    error);
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		KASSERT(NULL != ktd->ktd_proc->p_inst);
+		proclist_lock_read(ktd->ktd_proc->p_inst);
+		PROCLIST_FOREACH(p, &ktd->ktd_proc->p_inst->i_allproc) {
 			if (p->p_tracep == ktd)
 				ktrderef(p);
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(ktd->ktd_proc->p_inst);
 	}
 
 	while ((kte = top) != NULL) {
@@ -1152,9 +1193,9 @@
 	}
 	simple_unlock(&ktd->ktd_slock);
 
-	simple_lock(&ktdq_slock);
-	TAILQ_REMOVE(&ktdq, ktd, ktd_list);
-	simple_unlock(&ktdq_slock);
+	simple_lock(&fp->f_cred->cr_inst->i_ktrc->ktdq_slock);
+	TAILQ_REMOVE(&fp->f_cred->cr_inst->i_ktrc->ktdq, ktd, ktd_list);
+	simple_unlock(&fp->f_cred->cr_inst->i_ktrc->ktdq_slock);
 
 	simple_lock(&fp->f_slock);
 	FILE_USE(fp);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_lwp.c mult-netbsd-3.1/sys/kern/kern_lwp.c
--- NetBSD-3.1/sys/kern/kern_lwp.c	2005-11-13 13:56:02.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_lwp.c	2007-11-23 10:17:19.000000000 +0000
@@ -54,18 +54,18 @@
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
-struct lwplist alllwp;
 
-#define LWP_DEBUG
+POOL_INIT(lwp_uc_pool, sizeof(ucontext_t), 
+		0, 0, 0, "lwpucpl", &pool_allocator_nointr);
+
+static POOL_INIT(lwp_pool, sizeof(struct lwp), 
+		0, 0, 0, "lwppl", &pool_allocator_nointr);
+
 
-#ifdef LWP_DEBUG
-int lwp_debug = 0;
-#define DPRINTF(x) if (lwp_debug) printf x
-#else
-#define DPRINTF(x)
-#endif
 /* ARGSUSED */
 int
 sys__lwp_create(struct lwp *l, void *v, register_t *retval)
@@ -85,6 +85,8 @@
 	if (p->p_flag & P_SA)
 		return EINVAL;
 
+	KASSERT(NULL != l->l_inst);
+
 	newuc = pool_get(&lwp_uc_pool, PR_WAITOK);
 
 	error = copyin(SCARG(uap, ucp), newuc, sizeof(*newuc));
@@ -284,11 +286,6 @@
 void
 lwp_continue(struct lwp *l)
 {
-
-	DPRINTF(("lwp_continue of %d.%d (%s), state %d, wchan %p\n",
-	    l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, l->l_stat,
-	    l->l_wchan));
-
 	if (l->l_stat != LSSUSPENDED)
 		return;
 
@@ -383,8 +380,7 @@
 	static const char waitstr1[] = "lwpwait";
 	static const char waitstr2[] = "lwpwait2";
 
-	DPRINTF(("lwp_wait1: %d.%d waiting for %d.\n",
-	    p->p_pid, l->l_lid, lid));
+	KASSERT(NULL != p->p_inst);
 
 	if (lid == l->l_lid)
 		return (EDEADLK); /* Waiting for ourselves makes no sense. */
@@ -466,6 +462,9 @@
 	struct lwp *l2;
 	int s;
 
+	KASSERT(NULL != l1);
+	KASSERT(NULL != l1->l_inst);
+
 	l2 = pool_get(&lwp_pool, PR_WAITOK);
 
 	l2->l_stat = LSIDL;
@@ -515,9 +514,10 @@
 	simple_unlock(&p2->p_lock);
 
 	/* XXX should be locked differently... */
-	s = proclist_lock_write();
-	LIST_INSERT_HEAD(&alllwp, l2, l_list);
-	proclist_unlock_write(s);
+	KASSERT(NULL != l1->l_inst);
+	s = proclist_lock_write(l1->l_inst);
+	LIST_INSERT_HEAD(&l1->l_inst->i_alllwp, l2, l_list);
+	proclist_unlock_write(l1->l_inst, s);
 
 	if (p2->p_emul->e_lwp_fork)
 		(*p2->p_emul->e_lwp_fork)(l1, l2);
@@ -527,19 +527,21 @@
 
 
 /*
- * Quit the process. This will call cpu_exit, which will call cpu_switch,
- * so this can only be used meaningfully if you're willing to switch away.
+ * Quit the process. This will call cpu_exit, which will call cpu_switch, so
+ * this can only be used meaningfully if you're willing to switch away.
  * Calling with l!=curlwp would be weird.
  */
 void
 lwp_exit(struct lwp *l)
 {
-	struct proc *p = l->l_proc;
-	int s;
+	struct proc 	*p;
+	struct inst	*i;
+	int 		s;
 
-	DPRINTF(("lwp_exit: %d.%d exiting.\n", p->p_pid, l->l_lid));
-	DPRINTF((" nlwps: %d nrlwps %d nzlwps: %d\n",
-	    p->p_nlwps, p->p_nrlwps, p->p_nzlwps));
+	p = l->l_proc;
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+	i = p->p_inst;
 
 	if (p->p_emul->e_lwp_exit)
 		(*p->p_emul->e_lwp_exit)(l);
@@ -551,15 +553,13 @@
 	 * exit, and because that's what Solaris does.
 	 */
 	if (((p->p_nlwps - p->p_nzlwps) == 1) && ((p->p_flag & P_WEXIT) == 0)) {
-		DPRINTF(("lwp_exit: %d.%d calling exit1()\n",
-		    p->p_pid, l->l_lid));
 		exit1(l, 0);
 		/* NOTREACHED */
 	}
 
-	s = proclist_lock_write();
+	s = proclist_lock_write(i);
 	LIST_REMOVE(l, l_list);
-	proclist_unlock_write(s);
+	proclist_unlock_write(i, s);
 
 	/* Free MD LWP resources */
 #ifndef __NO_CPU_LWP_FREE
@@ -592,7 +592,7 @@
 void
 lwp_exit2(struct lwp *l)
 {
-	struct proc *p;
+	struct proc 	*p;
 
 	KERNEL_LOCK(LK_EXCLUSIVE);
 	/*
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_proc.c mult-netbsd-3.1/sys/kern/kern_proc.c
--- NetBSD-3.1/sys/kern/kern_proc.c	2004-10-03 23:26:35.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_proc.c	2007-12-09 20:42:25.000000000 +0000
@@ -95,305 +95,249 @@
 #include <sys/savar.h>
 #include <uvm/uvm_extern.h>
 
-/*
- * Other process lists
- */
-
-struct proclist allproc;
-struct proclist zombproc;	/* resources have been freed */
+#include <sys/inst.h>
 
 
-/*
- * Process list locking:
- *
- * We have two types of locks on the proclists: read locks and write
- * locks.  Read locks can be used in interrupt context, so while we
- * hold the write lock, we must also block clock interrupts to
- * lock out any scheduling changes that may happen in interrupt
- * context.
- *
- * The proclist lock locks the following structures:
- *
- *	allproc
- *	zombproc
- *	pid_table
- */
-struct lock proclist_lock;
-
-/*
- * pid to proc lookup is done by indexing the pid_table array.
- * Since pid numbers are only allocated when an empty slot
- * has been found, there is no need to search any lists ever.
- * (an orphaned pgrp will lock the slot, a session will lock
- * the pgrp with the same number.)
- * If the table is too small it is reallocated with twice the
- * previous size and the entries 'unzipped' into the two halves.
- * A linked list of free entries is passed through the pt_proc
- * field of 'free' items - set odd to be an invalid ptr.
- */
-
-struct pid_table {
+struct pid_table
+{
 	struct proc	*pt_proc;
 	struct pgrp	*pt_pgrp;
 };
-#if 1	/* strongly typed cast - should be a noop */
-static __inline uint p2u(struct proc *p) { return (uint)(uintptr_t)p; }
-#else
-#define p2u(p) ((uint)p)
-#endif
-#define P_VALID(p) (!(p2u(p) & 1))
-#define P_NEXT(p) (p2u(p) >> 1)
-#define P_FREE(pid) ((struct proc *)(uintptr_t)((pid) << 1 | 1))
-
-#define INITIAL_PID_TABLE_SIZE	(1 << 5)
-static struct pid_table *pid_table;
-static uint pid_tbl_mask = INITIAL_PID_TABLE_SIZE - 1;
-static uint pid_alloc_lim;	/* max we allocate before growing table */
-static uint pid_alloc_cnt;	/* number of allocated pids */
-
-/* links through free slots - never empty! */
-static uint next_free_pt, last_free_pt;
-static pid_t pid_max = PID_MAX;		/* largest value we allocate */
-
-POOL_INIT(proc_pool, sizeof(struct proc), 0, 0, 0, "procpl",
-    &pool_allocator_nointr);
-POOL_INIT(lwp_pool, sizeof(struct lwp), 0, 0, 0, "lwppl",
-    &pool_allocator_nointr);
-POOL_INIT(lwp_uc_pool, sizeof(ucontext_t), 0, 0, 0, "lwpucpl",
-    &pool_allocator_nointr);
-POOL_INIT(pgrp_pool, sizeof(struct pgrp), 0, 0, 0, "pgrppl",
-    &pool_allocator_nointr);
-POOL_INIT(pcred_pool, sizeof(struct pcred), 0, 0, 0, "pcredpl",
-    &pool_allocator_nointr);
-POOL_INIT(plimit_pool, sizeof(struct plimit), 0, 0, 0, "plimitpl",
-    &pool_allocator_nointr);
-POOL_INIT(pstats_pool, sizeof(struct pstats), 0, 0, 0, "pstatspl",
-    &pool_allocator_nointr);
-POOL_INIT(rusage_pool, sizeof(struct rusage), 0, 0, 0, "rusgepl",
-    &pool_allocator_nointr);
-POOL_INIT(ras_pool, sizeof(struct ras), 0, 0, 0, "raspl",
-    &pool_allocator_nointr);
-POOL_INIT(sadata_pool, sizeof(struct sadata), 0, 0, 0, "sadatapl",
-    &pool_allocator_nointr);
-POOL_INIT(saupcall_pool, sizeof(struct sadata_upcall), 0, 0, 0, "saupcpl",
-    &pool_allocator_nointr);
-POOL_INIT(sastack_pool, sizeof(struct sastack), 0, 0, 0, "sastackpl",
-    &pool_allocator_nointr);
-POOL_INIT(savp_pool, sizeof(struct sadata_vp), 0, 0, 0, "savppl",
-    &pool_allocator_nointr);
-POOL_INIT(ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl",
-    &pool_allocator_nointr);
-POOL_INIT(session_pool, sizeof(struct session), 0, 0, 0, "sessionpl",
-    &pool_allocator_nointr);
+
+struct inst_proc
+{
+	uint		pid_alloc_lim; /* XXX */
+	uint		pid_alloc_cnt; /* XXX */
+	struct pid_table *pid_table;	/* Master table of processes. */
+	uint		pid_tbl_mask;	/* XXX */
+	uint		next_free_pt;	/* XXX */
+	uint		last_free_pt;	/* XXX */
+	pid_t 		pid_max;	/* Maximum pid. */
+};
+
+static POOL_INIT(pcred_pool, sizeof(struct pcred), 
+		0, 0, 0, "pcredpl", &pool_allocator_nointr);
+
+static POOL_INIT(proc_pool, sizeof(struct proc), 
+		0, 0, 0, "procpl", &pool_allocator_nointr);
+
+static POOL_INIT(pgrp_pool, sizeof(struct pgrp), 
+		0, 0, 0, "pgrppl", &pool_allocator_nointr);
+
+static POOL_INIT(session_pool, sizeof(struct session), 
+		0, 0, 0, "sessionpl", &pool_allocator_nointr);
+
+
+#define P_VALID(p) 	(!(p2u(p) & 1))
+#define P_NEXT(p) 	(p2u(p) >> 1)
+#define P_FREE(pid) 	((struct proc *)(uintptr_t)((pid) << 1 | 1))
+#define PID_INITTBL_SZ	(1 << 5)
 
 MALLOC_DEFINE(M_EMULDATA, "emuldata", "Per-process emulation data");
 MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
 MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
 
+
 /*
- * The process list descriptors, used during pid allocation and
- * by sysctl.  No locking on this data structure is needed since
- * it is completely static.
+ * A process group has become orphaned; if there are any stopped
+ * processes in the group, hang-up all process in that group.  Call with
+ * proclist_lock held.
  */
-const struct proclist_desc proclists[] = {
-	{ &allproc	},
-	{ &zombproc	},
-	{ NULL		},
-};
-
-static void orphanpg(struct pgrp *);
-static void pg_delete(pid_t);
+static void 
+orphanpg(struct pgrp *);
 
 /*
- * Initialize global process hashing structures.
+ * Return a process group to the pool.
  */
-void
-procinit(void)
-{
-	const struct proclist_desc *pd;
-	int i;
-#define	LINK_EMPTY ((PID_MAX + INITIAL_PID_TABLE_SIZE) & ~(INITIAL_PID_TABLE_SIZE - 1))
-
-	for (pd = proclists; pd->pd_list != NULL; pd++)
-		LIST_INIT(pd->pd_list);
-
-	spinlockinit(&proclist_lock, "proclk", 0);
-
-	pid_table = malloc(INITIAL_PID_TABLE_SIZE * sizeof *pid_table,
-			    M_PROC, M_WAITOK);
-	/* Set free list running through table...
-	   Preset 'use count' above PID_MAX so we allocate pid 1 next. */
-	for (i = 0; i <= pid_tbl_mask; i++) {
-		pid_table[i].pt_proc = P_FREE(LINK_EMPTY + i + 1);
-		pid_table[i].pt_pgrp = 0;
-	}
-	/* slot 0 is just grabbed */
-	next_free_pt = 1;
-	/* Need to fix last entry. */
-	last_free_pt = pid_tbl_mask;
-	pid_table[last_free_pt].pt_proc = P_FREE(LINK_EMPTY);
-	/* point at which we grow table - to avoid reusing pids too often */
-	pid_alloc_lim = pid_tbl_mask - 1;
-#undef LINK_EMPTY
-
-	LIST_INIT(&alllwp);
-
-	uihashtbl =
-	    hashinit(maxproc / 16, HASH_LIST, M_PROC, M_WAITOK, &uihash);
-}
+static void 
+pg_delete(struct inst *i, pid_t pgid);
 
 /*
- * Acquire a read lock on the proclist.
+ * Free up the resources of a process group.
  */
-void
-proclist_lock_read(void)
-{
-	int error;
+static void 
+pg_free(struct inst *i, pid_t pgid);
 
-	error = spinlockmgr(&proclist_lock, LK_SHARED, NULL);
-#ifdef DIAGNOSTIC
-	if (__predict_false(error != 0))
-		panic("proclist_lock_read: failed to acquire lock");
-#endif
-}
+/*
+ * This is fairly self-explanatory.
+ */
+static void 
+expand_pid_table(struct inst *inst);
 
 /*
- * Release a read lock on the proclist.
+ * Create a session with a valid parent (leader) process.
  */
-void
-proclist_unlock_read(void)
-{
+static void
+sesscreate(struct proc *p, struct session *session);
 
-	(void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL);
+#if 1
+static __inline uint 
+p2u(struct proc *p) 
+{ 
+	return((uint)(uintptr_t)p);
 }
+#else
+# define p2u(p) 	((uint)p)
+#endif
+
 
-/*
- * Acquire a write lock on the proclist.
- */
 int
-proclist_lock_write(void)
+inst_proc_alloc(inst_proc_t *p, int flags)
 {
-	int s, error;
+	struct inst_proc *i;
+	int 		j;
 
-	s = splclock();
-	error = spinlockmgr(&proclist_lock, LK_EXCLUSIVE, NULL);
-#ifdef DIAGNOSTIC
-	if (__predict_false(error != 0))
-		panic("proclist_lock: failed to acquire lock");
-#endif
-	return (s);
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_proc), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_proc));
+
+	i->pid_tbl_mask = PID_INITTBL_SZ - 1;
+	i->pid_max = PID_MAX;
+	i->pid_table = malloc(PID_INITTBL_SZ * 
+			sizeof(*i->pid_table), M_PROC, flags);
+	if (NULL == i->pid_table)
+		return(0);
+
+#define	LINK_EMPTY \
+	((PID_MAX + PID_INITTBL_SZ) & ~(PID_INITTBL_SZ - 1))
+
+	/* Set free list running through table...  Preset 'use count'
+	 * above PID_MAX so we allocate pid 1 next. */
+
+	for (j = 0; j <= i->pid_tbl_mask; j++) {
+		i->pid_table[j].pt_proc = P_FREE(LINK_EMPTY + j + 1);
+		i->pid_table[j].pt_pgrp = 0;
+	}
+
+	i->next_free_pt = 1;
+	i->last_free_pt = i->pid_tbl_mask;
+	i->pid_table[i->last_free_pt].pt_proc = P_FREE(LINK_EMPTY);
+	i->pid_alloc_lim = i->pid_tbl_mask - 1;
+
+#undef LINK_EMPTY
+	*p = i;
+	return(1);
 }
 
-/*
- * Release a write lock on the proclist.
- */
+
 void
-proclist_unlock_write(int s)
+inst_proc_free(inst_proc_t p)
 {
-
-	(void) spinlockmgr(&proclist_lock, LK_RELEASE, NULL);
-	splx(s);
+	KASSERT(p);
+	if (p->pid_table)
+		free(p->pid_table, M_PROC);
 }
 
-/*
- * Check that the specified process group is in the session of the
- * specified process.
- * Treats -ve ids as process ids.
- * Used to validate TIOCSPGRP requests.
- */
+
 int
 pgid_in_session(struct proc *p, pid_t pg_id)
 {
-	struct pgrp *pgrp;
+	struct pgrp 	*pgrp;
+	struct proc	*p1;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
 
 	if (pg_id < 0) {
-		struct proc *p1 = pfind(-pg_id);
+		p1 = pfind(p->p_inst, -pg_id);
 		if (p1 == NULL)
-			return EINVAL;
+			return(EINVAL);
 		pgrp = p1->p_pgrp;
 	} else {
-		pgrp = pgfind(pg_id);
+		pgrp = pgfind(p->p_inst, pg_id);
 		if (pgrp == NULL)
-			return EINVAL;
+			return(EINVAL);
 	}
 	if (pgrp->pg_session != p->p_pgrp->pg_session)
-		return EPERM;
-	return 0;
+		return(EPERM);
+	return(0);
 }
 
-/*
- * Is p an inferior of q?
- */
+
 int
 inferior(struct proc *p, struct proc *q)
 {
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+	KASSERT(NULL != q);
+	KASSERT(NULL != q->p_inst);
+
+	if (p->p_inst->i_uuid != q->p_inst->i_uuid)
+		return(0);
 
 	for (; p != q; p = p->p_pptr)
 		if (p->p_pid == 0)
-			return (0);
-	return (1);
+			return(0);
+	return(1);
 }
 
-/*
- * Locate a process by number
- */
+
 struct proc *
-p_find(pid_t pid, uint flags)
+p_find(struct inst *i, pid_t pid, uint flags)
 {
-	struct proc *p;
-	char stat;
+	struct proc 	*p;
+	char 		stat;
+
+	KASSERT(NULL != i);
 
 	if (!(flags & PFIND_LOCKED))
-		proclist_lock_read();
-	p = pid_table[pid & pid_tbl_mask].pt_proc;
+		proclist_lock_read(i);
+	p = i->i_proc->pid_table[pid & i->i_proc->pid_tbl_mask].pt_proc;
 	/* Only allow live processes to be found by pid. */
 	if (P_VALID(p) && p->p_pid == pid &&
 	    ((stat = p->p_stat) == SACTIVE || stat == SSTOP
 		    || (stat == SZOMB && (flags & PFIND_ZOMBIE)))) {
 		if (flags & PFIND_UNLOCK_OK)
-			 proclist_unlock_read();
-		return p;
+			 proclist_unlock_read(i);
+		return(p);
 	}
 	if (flags & PFIND_UNLOCK_FAIL)
-		 proclist_unlock_read();
-	return NULL;
+		 proclist_unlock_read(i);
+	return(NULL);
 }
 
 
-/*
- * Locate a process group by number
- */
 struct pgrp *
-pg_find(pid_t pgid, uint flags)
+pg_find(struct inst *i, pid_t pgid, uint flags)
 {
-	struct pgrp *pg;
+	struct pgrp 	*pg;
+
+	KASSERT(NULL != i);
 
 	if (!(flags & PFIND_LOCKED))
-		proclist_lock_read();
-	pg = pid_table[pgid & pid_tbl_mask].pt_pgrp;
+		proclist_lock_read(i);
+	pg = i->i_proc->pid_table[pgid & i->i_proc->pid_tbl_mask].pt_pgrp;
+
 	/*
 	 * Can't look up a pgrp that only exists because the session
-	 * hasn't died yet (traditional)
+	 * hasn't died yet (traditional).
 	 */
-	if (pg == NULL || pg->pg_id != pgid || LIST_EMPTY(&pg->pg_members)) {
+	if (pg == NULL || pg->pg_id != pgid || 
+			LIST_EMPTY(&pg->pg_members)) {
 		if (flags & PFIND_UNLOCK_FAIL)
-			 proclist_unlock_read();
-		return NULL;
+			 proclist_unlock_read(i);
+		return(NULL);
 	}
 
 	if (flags & PFIND_UNLOCK_OK)
-		proclist_unlock_read();
-	return pg;
+		proclist_unlock_read(i);
+	return(pg);
 }
 
-/*
- * Set entry for process 0
- */
+
 void
-proc0_insert(struct proc *p, struct lwp *l, struct pgrp *pgrp,
-	struct session *sess)
+proc0_insert(struct proc *p, struct lwp *l, 
+		struct pgrp *pgrp, struct session *sess)
 {
-	int s;
+	int 		s;
+	struct inst	*i;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
+	i = p->p_inst;
 
 	simple_lock_init(&p->p_lock);
 	LIST_INIT(&p->p_lwps);
@@ -402,62 +346,63 @@
 	simple_lock_init(&p->p_sigctx.ps_silock);
 	CIRCLEQ_INIT(&p->p_sigctx.ps_siginfo);
 
-	s = proclist_lock_write();
+	s = proclist_lock_write(i);
 
-	pid_table[0].pt_proc = p;
-	LIST_INSERT_HEAD(&allproc, p, p_list);
-	LIST_INSERT_HEAD(&alllwp, l, l_list);
+	i->i_proc->pid_table[0].pt_proc = p;
+	LIST_INSERT_HEAD(&i->i_allproc, p, p_list);
+	LIST_INSERT_HEAD(&i->i_alllwp, l, l_list);
 
 	p->p_pgrp = pgrp;
-	pid_table[0].pt_pgrp = pgrp;
+	i->i_proc->pid_table[0].pt_pgrp = pgrp;
 	LIST_INIT(&pgrp->pg_members);
 	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
 
+	sesscreate(p, sess);
 	pgrp->pg_session = sess;
-	sess->s_count = 1;
-	sess->s_sid = 0;
-	sess->s_leader = p;
 
-	proclist_unlock_write(s);
+	proclist_unlock_write(i, s);
 }
 
+
 static void
-expand_pid_table(void)
+expand_pid_table(struct inst *in)
 {
-	uint pt_size = pid_tbl_mask + 1;
+	uint 		pt_size;
 	struct pid_table *n_pt, *new_pt;
-	struct proc *proc;
-	struct pgrp *pgrp;
-	int i;
-	int s;
-	pid_t pid;
+	struct proc	*proc;
+	struct pgrp	*pgrp;
+	int 		i, s;
+	pid_t		pid;
+
+	KASSERT(in);
+
+	pt_size = in->i_proc->pid_tbl_mask + 1;
+	new_pt = malloc(pt_size * 2 * sizeof(*new_pt), 
+			M_PROC, M_WAITOK);
 
-	new_pt = malloc(pt_size * 2 * sizeof *new_pt, M_PROC, M_WAITOK);
-
-	s = proclist_lock_write();
-	if (pt_size != pid_tbl_mask + 1) {
+	s = proclist_lock_write(in);
+	if (pt_size != in->i_proc->pid_tbl_mask + 1) {
 		/* Another process beat us to it... */
-		proclist_unlock_write(s);
+		proclist_unlock_write(in, s);
 		FREE(new_pt, M_PROC);
 		return;
 	}
 
 	/*
-	 * Copy entries from old table into new one.
-	 * If 'pid' is 'odd' we need to place in the upper half,
-	 * even pid's to the lower half.
-	 * Free items stay in the low half so we don't have to
-	 * fixup the reference to them.
-	 * We stuff free items on the front of the freelist
-	 * because we can't write to unmodified entries.
-	 * Processing the table backwards maintains a semblance
-	 * of issueing pid numbers that increase with time.
+	 * Copy entries from old table into new one.  If 'pid' is 'odd'
+	 * we need to place in the upper half, even pid's to the lower
+	 * half.  Free items stay in the low half so we don't have to
+	 * fixup the reference to them.  We stuff free items on the
+	 * front of the freelist because we can't write to unmodified
+	 * entries.  Processing the table backwards maintains a
+	 * semblance of issueing pid numbers that increase with time.
 	 */
 	i = pt_size - 1;
 	n_pt = new_pt + i;
+
 	for (; ; i--, n_pt--) {
-		proc = pid_table[i].pt_proc;
-		pgrp = pid_table[i].pt_pgrp;
+		proc = in->i_proc->pid_table[i].pt_proc;
+		pgrp = in->i_proc->pid_table[i].pt_pgrp;
 		if (!P_VALID(proc)) {
 			/* Up 'use count' so that link is valid */
 			pid = (P_NEXT(proc) + pt_size) & ~pt_size;
@@ -472,167 +417,185 @@
 		n_pt[pid & pt_size].pt_pgrp = pgrp;
 
 		/* Put other piece on start of free list */
-		pid = (pid ^ pt_size) & ~pid_tbl_mask;
-		n_pt[pid & pt_size].pt_proc =
-				    P_FREE((pid & ~pt_size) | next_free_pt);
+		pid = (pid ^ pt_size) & ~in->i_proc->pid_tbl_mask;
+		n_pt[pid & pt_size].pt_proc = P_FREE((pid & ~pt_size) 
+				| in->i_proc->next_free_pt);
 		n_pt[pid & pt_size].pt_pgrp = 0;
-		next_free_pt = i | (pid & pt_size);
+		in->i_proc->next_free_pt = i | (pid & pt_size);
 		if (i == 0)
 			break;
 	}
 
 	/* Switch tables */
-	n_pt = pid_table;
-	pid_table = new_pt;
-	pid_tbl_mask = pt_size * 2 - 1;
+	n_pt = in->i_proc->pid_table;
+	in->i_proc->pid_table = new_pt;
+	in->i_proc->pid_tbl_mask = pt_size * 2 - 1;
 
 	/*
 	 * pid_max starts as PID_MAX (= 30000), once we have 16384
 	 * allocated pids we need it to be larger!
 	 */
-	if (pid_tbl_mask > PID_MAX) {
-		pid_max = pid_tbl_mask * 2 + 1;
-		pid_alloc_lim |= pid_alloc_lim << 1;
-	} else
-		pid_alloc_lim <<= 1;	/* doubles number of free slots... */
-
-	proclist_unlock_write(s);
+	if (in->i_proc->pid_tbl_mask > PID_MAX) {
+		in->i_proc->pid_max = in->i_proc->pid_tbl_mask * 2 + 1;
+		in->i_proc->pid_alloc_lim |= in->i_proc->pid_alloc_lim << 1;
+	} else /* double number of free slots... */
+		in->i_proc->pid_alloc_lim <<= 1;
+			
+	proclist_unlock_write(in, s);
 	FREE(n_pt, M_PROC);
 }
 
+
 struct proc *
-proc_alloc(void)
+proc_alloc(struct inst *i)
 {
-	struct proc *p;
-	int s;
-	int nxt;
-	pid_t pid;
+	struct proc 	*p;
+	int 		s, nxt;
+	pid_t 		pid;
 	struct pid_table *pt;
 
+	KASSERT(i);
+
 	p = pool_get(&proc_pool, PR_WAITOK);
-	p->p_stat = SIDL;			/* protect against others */
+	p->p_stat = SIDL;
 
 	/* allocate next free pid */
 
-	for (;;expand_pid_table()) {
-		if (__predict_false(pid_alloc_cnt >= pid_alloc_lim))
+	for (;;expand_pid_table(i)) {
+		if (__predict_false(i->i_proc->pid_alloc_cnt >= 
+					i->i_proc->pid_alloc_lim))
 			/* ensure pids cycle through 2000+ values */
 			continue;
-		s = proclist_lock_write();
-		pt = &pid_table[next_free_pt];
+		s = proclist_lock_write(i);
+		pt = &i->i_proc->pid_table[i->i_proc->next_free_pt];
 #ifdef DIAGNOSTIC
 		if (__predict_false(P_VALID(pt->pt_proc) || pt->pt_pgrp))
 			panic("proc_alloc: slot busy");
 #endif
 		nxt = P_NEXT(pt->pt_proc);
-		if (nxt & pid_tbl_mask)
+		if (nxt & i->i_proc->pid_tbl_mask)
 			break;
 		/* Table full - expand (NB last entry not used....) */
-		proclist_unlock_write(s);
+		proclist_unlock_write(i, s);
 	}
 
 	/* pid is 'saved use count' + 'size' + entry */
-	pid = (nxt & ~pid_tbl_mask) + pid_tbl_mask + 1 + next_free_pt;
-	if ((uint)pid > (uint)pid_max)
-		pid &= pid_tbl_mask;
+	pid = (nxt & ~i->i_proc->pid_tbl_mask) + 
+		i->i_proc->pid_tbl_mask + 1 + i->i_proc->next_free_pt;
+	if ((uint)pid > (uint)i->i_proc->pid_max)
+		pid &= i->i_proc->pid_tbl_mask;
 	p->p_pid = pid;
-	next_free_pt = nxt & pid_tbl_mask;
+	i->i_proc->next_free_pt = nxt & i->i_proc->pid_tbl_mask;
 
 	/* Grab table slot */
 	pt->pt_proc = p;
-	pid_alloc_cnt++;
+	i->i_proc->pid_alloc_cnt++;
 
-	proclist_unlock_write(s);
+	proclist_unlock_write(i, s);
 
-	return p;
+	return(p);
 }
 
-/*
- * Free last resources of a process - called from proc_free (in kern_exit.c)
- */
+
 void
-proc_free_mem(struct proc *p)
+proc_free_mem(struct inst *i, struct proc *p)
 {
-	int s;
-	pid_t pid = p->p_pid;
+	int 		s;
+	pid_t 		pid;
 	struct pid_table *pt;
 
-	s = proclist_lock_write();
+	KASSERT(p);
+	KASSERT(i);
+
+	pid = p->p_pid;
+
+	s = proclist_lock_write(i);
 
-	pt = &pid_table[pid & pid_tbl_mask];
+	pt = &i->i_proc->pid_table[pid & i->i_proc->pid_tbl_mask];
 #ifdef DIAGNOSTIC
 	if (__predict_false(pt->pt_proc != p))
 		panic("proc_free: pid_table mismatch, pid %x, proc %p",
 			pid, p);
 #endif
 	/* save pid use count in slot */
-	pt->pt_proc = P_FREE(pid & ~pid_tbl_mask);
+	pt->pt_proc = P_FREE(pid & ~i->i_proc->pid_tbl_mask);
 
 	if (pt->pt_pgrp == NULL) {
 		/* link last freed entry onto ours */
-		pid &= pid_tbl_mask;
-		pt = &pid_table[last_free_pt];
+		pid &= i->i_proc->pid_tbl_mask;
+		pt = &i->i_proc->pid_table[i->i_proc->last_free_pt];
 		pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pid);
-		last_free_pt = pid;
-		pid_alloc_cnt--;
+		i->i_proc->last_free_pt = pid;
+		i->i_proc->pid_alloc_cnt--;
 	}
 
-	nprocs--;
-	proclist_unlock_write(s);
-
+	i->i_nprocs--;
+	proclist_unlock_write(i, s);
 	pool_put(&proc_pool, p);
+
+	inst_release(i);
 }
 
-/*
- * Move p to a new or existing process group (and session)
- *
- * If we are creating a new pgrp, the pgid should equal
- * the calling process' pid.
- * If is only valid to enter a process group that is in the session
- * of the process.
- * Also mksess should only be set if we are creating a process group
- *
- * Only called from sys_setsid, sys_setpgid/sys_setpgrp and the
- * SYSV setpgrp support for hpux == enterpgrp(curproc, curproc->p_pid)
- */
+
 int
 enterpgrp(struct proc *p, pid_t pgid, int mksess)
 {
-	struct pgrp *new_pgrp, *pgrp;
-	struct session *sess;
-	struct proc *curp = curproc;
-	pid_t pid = p->p_pid;
-	int rval;
-	int s;
-	pid_t pg_id = NO_PGID;
-
-	/* Allocate data areas we might need before doing any validity checks */
-	proclist_lock_read();		/* Because pid_table might change */
-	if (pid_table[pgid & pid_tbl_mask].pt_pgrp == 0) {
-		proclist_unlock_read();
+	struct pgrp	*new_pgrp, *pgrp;
+	struct session	*sess;
+	struct inst	*i;
+	struct proc	*curp;
+	pid_t 		pid;
+	int 		rval, s;
+	pid_t 		pg_id = NO_PGID;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
+	curp = curproc;
+	i = p->p_inst;
+	pid = p->p_pid;
+
+	KASSERT(NULL != curp->p_inst);
+
+	if (i->i_uuid != curp->p_inst->i_uuid)
+		return(ESRCH);
+
+	/* 
+	 * Allocate data areas we might need before doing any validity
+	 * checks 
+	 */
+
+	proclist_lock_read(i);
+
+	if (i->i_proc->pid_table[pgid & i->i_proc->pid_tbl_mask].pt_pgrp == 0) {
+		proclist_unlock_read(i);
 		new_pgrp = pool_get(&pgrp_pool, PR_WAITOK);
 	} else {
-		proclist_unlock_read();
+		proclist_unlock_read(i);
 		new_pgrp = NULL;
 	}
+
 	if (mksess)
 		sess = pool_get(&session_pool, M_WAITOK);
 	else
 		sess = NULL;
 
-	s = proclist_lock_write();
+	s = proclist_lock_write(i);
 	rval = EPERM;	/* most common error (to save typing) */
 
 	/* Check pgrp exists or can be created */
-	pgrp = pid_table[pgid & pid_tbl_mask].pt_pgrp;
+
+	pgrp = i->i_proc->pid_table[pgid & i->i_proc->pid_tbl_mask].pt_pgrp;
 	if (pgrp != NULL && pgrp->pg_id != pgid)
 		goto done;
 
-	/* Can only set another process under restricted circumstances. */
+	/* Can set another process under restricted circumstances. */
+
 	if (p != curp) {
 		/* must exist and be one of our children... */
-		if (p != pid_table[pid & pid_tbl_mask].pt_proc
-		    || !inferior(p, curp)) {
+		if (p != i->i_proc->pid_table[pid & 
+				i->i_proc->pid_tbl_mask].pt_proc || 
+				! inferior(p, curp)) {
 			rval = ESRCH;
 			goto done;
 		}
@@ -686,14 +649,12 @@
 		pgrp = new_pgrp;
 		new_pgrp = 0;
 		if (sess != NULL) {
-			sess->s_sid = p->p_pid;
-			sess->s_leader = p;
-			sess->s_count = 1;
+			sesscreate(p, sess);
 			sess->s_ttyvp = NULL;
 			sess->s_ttyp = NULL;
 			sess->s_flags = p->p_session->s_flags & ~S_LOGIN_SET;
 			memcpy(sess->s_login, p->p_session->s_login,
-			    sizeof(sess->s_login));
+					sizeof(sess->s_login));
 			p->p_flag &= ~P_CONTROLT;
 		} else {
 			sess = p->p_pgrp->pg_session;
@@ -705,24 +666,27 @@
 		pgrp->pg_id = pgid;
 		LIST_INIT(&pgrp->pg_members);
 #ifdef DIAGNOSTIC
-		if (__predict_false(pid_table[pgid & pid_tbl_mask].pt_pgrp))
+		if (__predict_false(i->i_proc->pid_table[pgid & 
+					i->i_proc->pid_tbl_mask].pt_pgrp))
 			panic("enterpgrp: pgrp table slot in use");
 		if (__predict_false(mksess && p != curp))
 			panic("enterpgrp: mksession and p != curproc");
 #endif
-		pid_table[pgid & pid_tbl_mask].pt_pgrp = pgrp;
+		i->i_proc->pid_table[pgid & i->i_proc->pid_tbl_mask].pt_pgrp = pgrp;
 		pgrp->pg_jobc = 0;
 	}
 
 	/*
-	 * Adjust eligibility of affected pgrps to participate in job control.
-	 * Increment eligibility counts before decrementing, otherwise we
-	 * could reach 0 spuriously during the first call.
+	 * Adjust eligibility of affected pgrps to participate in job
+	 * control.  Increment eligibility counts before decrementing,
+	 * otherwise we could reach 0 spuriously during the first call.
 	 */
+
 	fixjobc(p, pgrp, 1);
 	fixjobc(p, p->p_pgrp, 0);
 
 	/* Move process to requested group */
+
 	LIST_REMOVE(p, p_pglist);
 	if (LIST_EMPTY(&p->p_pgrp->pg_members))
 		/* defer delete until we've dumped the lock */
@@ -731,94 +695,103 @@
 	LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
 
     done:
-	proclist_unlock_write(s);
-	if (sess != NULL)
+	proclist_unlock_write(i, s);
+	if (sess != NULL) 
 		pool_put(&session_pool, sess);
-	if (new_pgrp != NULL)
+	if (new_pgrp != NULL) 
 		pool_put(&pgrp_pool, new_pgrp);
 	if (pg_id != NO_PGID)
-		pg_delete(pg_id);
+		pg_delete(i, pg_id);
 #ifdef DEBUG_PGRP
 	if (__predict_false(rval))
 		printf("enterpgrp(%d,%d,%d), curproc %d, rval %d\n",
 			pid, pgid, mksess, curp->p_pid, rval);
 #endif
-	return rval;
+	return(rval);
 }
 
-/*
- * remove process from process group
- */
+
 int
 leavepgrp(struct proc *p)
 {
-	int s;
-	struct pgrp *pgrp;
-	pid_t pg_id;
+	int 		s;
+	struct pgrp 	*pgrp;
+	pid_t 		pg_id;
+
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	s = proclist_lock_write(p->p_inst);
 
-	s = proclist_lock_write();
 	pgrp = p->p_pgrp;
 	LIST_REMOVE(p, p_pglist);
 	p->p_pgrp = 0;
 	pg_id = LIST_EMPTY(&pgrp->pg_members) ? pgrp->pg_id : NO_PGID;
-	proclist_unlock_write(s);
+	proclist_unlock_write(p->p_inst, s);
 
 	if (pg_id != NO_PGID)
-		pg_delete(pg_id);
-	return 0;
+		pg_delete(p->p_inst, pg_id);
+	return(0);
 }
 
+
 static void
-pg_free(pid_t pg_id)
+pg_free(struct inst *i, pid_t pg_id)
 {
-	struct pgrp *pgrp;
+	struct pgrp 	*pgrp;
 	struct pid_table *pt;
-	int s;
+	int 		s;
+
+	KASSERT(NULL != i);
 
-	s = proclist_lock_write();
-	pt = &pid_table[pg_id & pid_tbl_mask];
+	s = proclist_lock_write(i);
+	pt = &i->i_proc->pid_table[pg_id & i->i_proc->pid_tbl_mask];
 	pgrp = pt->pt_pgrp;
 #ifdef DIAGNOSTIC
 	if (__predict_false(!pgrp || pgrp->pg_id != pg_id
 	    || !LIST_EMPTY(&pgrp->pg_members)))
-		panic("pg_free: process group absent or has members");
+		panic("pg_free: process group absent or has members "
+				"%p, %d != %d, %d",
+				pgrp, pgrp->pg_id, pg_id, 
+				LIST_EMPTY(&pgrp->pg_members));
 #endif
 	pt->pt_pgrp = 0;
 
 	if (!P_VALID(pt->pt_proc)) {
 		/* orphaned pgrp, put slot onto free list */
 #ifdef DIAGNOSTIC
-		if (__predict_false(P_NEXT(pt->pt_proc) & pid_tbl_mask))
+		if (__predict_false(P_NEXT(pt->pt_proc) & 
+					i->i_proc->pid_tbl_mask))
 			panic("pg_free: process slot on free list");
 #endif
 
-		pg_id &= pid_tbl_mask;
-		pt = &pid_table[last_free_pt];
+		pg_id &= i->i_proc->pid_tbl_mask;
+		pt = &i->i_proc->pid_table[i->i_proc->last_free_pt];
 		pt->pt_proc = P_FREE(P_NEXT(pt->pt_proc) | pg_id);
-		last_free_pt = pg_id;
-		pid_alloc_cnt--;
+		i->i_proc->last_free_pt = pg_id;
+		i->i_proc->pid_alloc_cnt--;
 	}
-	proclist_unlock_write(s);
-
+	proclist_unlock_write(i, s);
 	pool_put(&pgrp_pool, pgrp);
 }
 
-/*
- * delete a process group
- */
+
 static void
-pg_delete(pid_t pg_id)
+pg_delete(struct inst *i, pid_t pg_id)
 {
-	struct pgrp *pgrp;
-	struct tty *ttyp;
-	struct session *ss;
-	int s, is_pgrp_leader;
+	struct pgrp	*pgrp;
+	struct tty	*ttyp;
+	struct session	*ss;
+	int 		s, is_pgrp_leader;
+
+	KASSERT(i);
+
+	s = proclist_lock_write(i);
+	pgrp = i->i_proc->pid_table[pg_id & i->i_proc->pid_tbl_mask].pt_pgrp;
 
-	s = proclist_lock_write();
-	pgrp = pid_table[pg_id & pid_tbl_mask].pt_pgrp;
 	if (pgrp == NULL || pgrp->pg_id != pg_id ||
 	    !LIST_EMPTY(&pgrp->pg_members)) {
-		proclist_unlock_write(s);
+		proclist_unlock_write(i, s);
 		return;
 	}
 
@@ -835,66 +808,80 @@
 	}
 
 	/*
-	 * The leading process group in a session is freed
-	 * by sessdelete() if last reference.
+	 * The leading process group in a session is freed by
+	 * sessdelete() if last reference.
 	 */
 	is_pgrp_leader = (ss->s_sid == pgrp->pg_id);
-	proclist_unlock_write(s);
+	proclist_unlock_write(i, s);
 	SESSRELE(ss);
 
 	if (is_pgrp_leader)
 		return;
+	pg_free(i, pg_id);
+}
+
+
+static void
+sesscreate(struct proc *p, struct session *sess)
+{
+	KASSERT(p);
+	KASSERT(sess);
+	KASSERT(p->p_inst);
 
-	pg_free(pg_id);
+	/*
+	 * Note that the session also holds a reference to the instance,
+	 * as a session is deleted only when the last process is already
+	 * deleted, and we need a context to put the reaped session data
+	 * back into.
+	 */
+	sess->s_inst = p->p_inst;
+	sess->s_count = 1;
+	sess->s_sid = p->p_pid;
+	sess->s_leader = p;
+	p->p_inst->i_nsess++;
 }
 
-/*
- * Delete session - called from SESSRELE when s_count becomes zero.
- */
+
 void
 sessdelete(struct session *ss)
 {
 	/*
-	 * We keep the pgrp with the same id as the session in
-	 * order to stop a process being given the same pid.
-	 * Since the pgrp holds a reference to the session, it
-	 * must be a 'zombie' pgrp by now.
+	 * We keep the pgrp with the same id as the session in order to
+	 * stop a process being given the same pid.  Since the pgrp
+	 * holds a reference to the session, it must be a 'zombie' pgrp
+	 * by now.
 	 */
-
-	pg_free(ss->s_sid);
-
+	pg_free(ss->s_inst, ss->s_sid);
+	ss->s_inst->i_nsess--;
 	pool_put(&session_pool, ss);
 }
 
-/*
- * Adjust pgrp jobc counters when specified process changes process group.
- * We count the number of processes in each process group that "qualify"
- * the group for terminal job control (those with a parent in a different
- * process group of the same session).  If that count reaches zero, the
- * process group becomes orphaned.  Check both the specified process'
- * process group and that of its children.
- * entering == 0 => p is leaving specified group.
- * entering == 1 => p is entering specified group.
- *
- * Call with proclist_lock held.
- */
+
 void
 fixjobc(struct proc *p, struct pgrp *pgrp, int entering)
 {
-	struct pgrp *hispgrp;
-	struct session *mysession = pgrp->pg_session;
-	struct proc *child;
+	struct pgrp 	*hispgrp;
+	struct session	*mysession;
+	struct proc	*child;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != pgrp);
+
+	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.
 	 */
-	hispgrp = p->p_pptr->p_pgrp;
-	if (hispgrp != pgrp && hispgrp->pg_session == mysession) {
-		if (entering)
-			pgrp->pg_jobc++;
-		else if (--pgrp->pg_jobc == 0)
-			orphanpg(pgrp);
+	if (NULL != p->p_pptr) {
+		hispgrp = p->p_pptr->p_pgrp;
+		if (hispgrp != pgrp && 
+				hispgrp->pg_session == mysession) {
+			if (entering)
+				pgrp->pg_jobc++;
+			else if (--pgrp->pg_jobc == 0)
+				orphanpg(pgrp);
+		}
 	}
 
 	/*
@@ -914,17 +901,13 @@
 	}
 }
 
-/*
- * A process group has become orphaned;
- * if there are any stopped processes in the group,
- * hang-up all process in that group.
- *
- * Call with proclist_lock held.
- */
+
 static void
 orphanpg(struct pgrp *pg)
 {
-	struct proc *p;
+	struct proc 	*p;
+
+	KASSERT(NULL != pg);
 
 	LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 		if (p->p_stat == SSTOP) {
@@ -937,12 +920,15 @@
 	}
 }
 
-/* mark process as suid/sgid, reset some values to defaults */
+
 void
 p_sugid(struct proc *p)
 {
-	struct plimit *lim;
-	char *cn;
+	struct plimit	*lim;
+	char		*cn;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
 
 	p->p_flag |= P_SUGID;
 	/* reset what needs to be reset in plimit */
@@ -963,7 +949,12 @@
 	}
 }
 
-#ifdef DDB
+
+/*
+ * FIXME - the following section assumes a global context, which is no
+ * longer correct.  Byeeeee!
+ */
+#if 0  /* Was "if DDB" */
 #include <ddb/db_output.h>
 void pidtbl_dump(void);
 void
@@ -975,9 +966,9 @@
 	int id;
 
 	db_printf("pid table %p size %x, next %x, last %x\n",
-		pid_table, pid_tbl_mask+1,
+		pid_table, PID_TBL_MASK+1,
 		next_free_pt, last_free_pt);
-	for (pt = pid_table, id = 0; id <= pid_tbl_mask; id++, pt++) {
+	for (pt = pid_table, id = 0; id <= PID_TBL_MASK; id++, pt++) {
 		p = pt->pt_proc;
 		if (!P_VALID(p) && !pt->pt_pgrp)
 			continue;
@@ -987,8 +978,8 @@
 				p, p->p_pid, p->p_pid, p->p_comm);
 		else
 			db_printf("next %x use %x\n",
-				P_NEXT(p) & pid_tbl_mask,
-				P_NEXT(p) & ~pid_tbl_mask);
+				P_NEXT(p) & PID_TBL_MASK,
+				P_NEXT(p) & ~PID_TBL_MASK);
 		if ((pgrp = pt->pt_pgrp)) {
 			db_printf("\tsession %p, sid %d, count %d, login %s\n",
 			    pgrp->pg_session, pgrp->pg_session->s_sid,
@@ -1085,6 +1076,12 @@
 }
 #endif /* KSTACK_CHECK_MAGIC */
 
+
+/*
+ * FIXME: (or not)  This is getting removed along with procfs, which
+ * doesn't play nicely with instances.  Byeeee!
+ */
+#if 0
 /* XXX shouldn't be here */
 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
 #define	PROCLIST_ASSERT_LOCKED_READ()	\
@@ -1121,3 +1118,21 @@
 
 	return ret;
 }
+#endif
+
+
+void
+pcred_free(struct pcred *p)
+{
+	pool_put(&pcred_pool, p);
+}
+
+
+struct pcred *
+pcred_alloc(void)
+{
+	struct pcred	*pc;
+	pc = pool_get(&pcred_pool, PR_WAITOK);
+	memset(pc, 0, sizeof(struct pcred));
+	return(pc);
+}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_prot.c mult-netbsd-3.1/sys/kern/kern_prot.c
--- NetBSD-3.1/sys/kern/kern_prot.c	2004-05-04 22:27:28.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_prot.c	2007-11-23 10:17:19.000000000 +0000
@@ -60,6 +60,8 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 POOL_INIT(cred_pool, sizeof(struct ucred), 0, 0, 0, "credpl",
     &pool_allocator_nointr);
 
@@ -86,8 +88,11 @@
 {
 	struct proc *p = l->l_proc;
 
+	KASSERT(l);
+	KASSERT(p);
+
 	retval[0] = p->p_pid;
-	retval[1] = p->p_pptr->p_pid;
+	retval[1] = p->p_pptr ? p->p_pptr->p_pid : 0;
 	return (0);
 }
 
@@ -97,7 +102,7 @@
 {
 	struct proc *p = l->l_proc;
 
-	*retval = p->p_pptr->p_pid;
+	*retval = p->p_pptr ? p->p_pptr->p_pid : 0;
 	return (0);
 }
 
@@ -123,9 +128,12 @@
 	} */ *uap = v;
 	struct proc *p = l->l_proc;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	if (SCARG(uap, pid) == 0)
 		goto found;
-	if ((p = pfind(SCARG(uap, pid))) == 0)
+	if ((p = pfind(p->p_inst, SCARG(uap, pid))) == 0)
 		return (ESRCH);
 found:
 	*retval = p->p_session->s_sid;
@@ -140,9 +148,12 @@
 	} */ *uap = v;
 	struct proc *p = l->l_proc;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	if (SCARG(uap, pid) == 0)
 		goto found;
-	if ((p = pfind(SCARG(uap, pid))) == 0)
+	if ((p = pfind(p->p_inst, SCARG(uap, pid))) == 0)
 		return (ESRCH);
 found:
 	*retval = p->p_pgid;
@@ -251,7 +262,10 @@
 {
 	struct proc *p = l->l_proc;
 
-	if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
+	if (p->p_pgid == p->p_pid || pgfind(p->p_inst, p->p_pid)) {
 		return (EPERM);
 	} else {
 		(void)enterpgrp(p, p->p_pid, 1);
@@ -287,12 +301,15 @@
 	struct proc *curp = l->l_proc;
 	struct proc *targp;			/* target process */
 
+	KASSERT(NULL != curp);
+	KASSERT(NULL != curp->p_inst);
+
 	if (SCARG(uap, pgid) < 0)
 		return EINVAL;
 
 	/* XXX MP - there is a horrid race here with targp exiting! */
 	if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != curp->p_pid) {
-		targp = pfind(SCARG(uap, pid));
+		targp = pfind(curp->p_inst, SCARG(uap, pid));
 		if (targp == NULL)
 			return ESRCH;
 	} else
@@ -313,10 +330,14 @@
 int
 do_setresuid(struct lwp *l, uid_t r, uid_t e, uid_t sv, u_int flags)
 {
-	int error;
-	struct proc *p = l->l_proc;
-	struct pcred *pcred = p->p_cred;
-	struct ucred *cred = pcred->pc_ucred;
+	int 		error;
+	struct proc 	*p = l->l_proc;
+	struct pcred 	*pcred = p->p_cred;
+	struct ucred 	*cred = pcred->pc_ucred;
+	struct inst	*i;
+
+	KASSERT(NULL != p->p_inst);
+	i = p->p_inst;
 
 	/* Superuser can do anything it wants to.... */
 	error = suser(cred, &p->p_acflag);
@@ -347,8 +368,8 @@
 	/* The pcred structure is not actually shared... */
 	if (r != -1 && r != pcred->p_ruid) {
 		/* Update count of processes for this user */
-		(void)chgproccnt(pcred->p_ruid, -1);
-		(void)chgproccnt(r, 1);
+		(void)chgproccnt(i, pcred->p_ruid, -1);
+		(void)chgproccnt(i, r, 1);
 		pcred->p_ruid = r;
 	}
 	if (sv != -1)
@@ -585,6 +606,9 @@
 	const gid_t *gp;
 	const gid_t *egp;
 
+	KASSERT(NULL != cred);
+	KASSERT(NULL != cred->cr_inst);
+
 	egp = &(cred->cr_groups[cred->cr_ngroups]);
 	for (gp = cred->cr_groups; gp < egp; gp++)
 		if (*gp == gid)
@@ -614,15 +638,22 @@
  * Allocate a zeroed cred structure.
  */
 struct ucred *
-crget(void)
+crget(struct inst *i)
 {
 	struct ucred *cr;
 
+	KASSERT(i);
+
 	cr = pool_get(&cred_pool, PR_WAITOK);
-	memset(cr, 0, sizeof(*cr));
+	memset(cr, 0, sizeof(struct ucred));
 	simple_lock_init(&cr->cr_lock);
 	cr->cr_ref = 1;
-	return (cr);
+	cr->cr_inst = i;
+	inst_hold(i);
+
+	/* FIXME - instance - locking */
+	i->i_ncreds++;
+	return(cr);
 }
 
 /*
@@ -634,11 +665,18 @@
 {
 	int n;
 
+	KASSERT(cr);
+	KASSERT(cr->cr_inst);
+
 	simple_lock(&cr->cr_lock);
 	n = --cr->cr_ref;
 	simple_unlock(&cr->cr_lock);
-	if (n == 0)
-		pool_put(&cred_pool, cr);
+	if (n > 0)
+		return;
+
+	cr->cr_inst->i_ncreds--;
+	inst_release(cr->cr_inst);
+	pool_put(&cred_pool, cr);
 }
 
 /*
@@ -661,16 +699,37 @@
 {
 	struct ucred *newcr;
 
+	KASSERT(cr);
+	KASSERT(cr->cr_inst);
+
 	if (cr->cr_ref == 1)
 		return (cr);
 
-	newcr = crget();
+	newcr = crget(cr->cr_inst);
 	memcpy(&newcr->cr_startcopy, &cr->cr_startcopy,
 		sizeof(struct ucred) - offsetof(struct ucred, cr_startcopy));
+
 	crfree(cr);
 	return (newcr);
 }
 
+
+/*
+ * Dup cred struct to a new held one, but inherit only the instance.
+ */
+struct ucred *
+crdupinst(const struct ucred *cr)
+{
+	struct ucred *newcr;
+
+	KASSERT(cr);
+	KASSERT(cr->cr_inst);
+
+	newcr = crget(cr->cr_inst);
+
+	return (newcr);
+}
+
 /*
  * Dup cred struct to a new held one.
  */
@@ -679,9 +738,13 @@
 {
 	struct ucred *newcr;
 
-	newcr = crget();
+	KASSERT(cr);
+	KASSERT(cr->cr_inst);
+
+	newcr = crget(cr->cr_inst);
 	memcpy(&newcr->cr_startcopy, &cr->cr_startcopy,
 		sizeof(struct ucred) - offsetof(struct ucred, cr_startcopy));
+
 	return (newcr);
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_ras.c mult-netbsd-3.1/sys/kern/kern_ras.c
--- NetBSD-3.1/sys/kern/kern_ras.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_ras.c	2007-11-13 18:31:33.000000000 +0000
@@ -47,6 +47,7 @@
 #include <sys/ras.h>
 #include <sys/sa.h>
 #include <sys/savar.h>
+#include <sys/inst.h>
 
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
@@ -55,6 +56,10 @@
 
 #define MAX_RAS_PER_PROC	16
 
+
+static POOL_INIT(ras_pool, sizeof(struct ras), 
+		0, 0, 0, "raspl", &pool_allocator_nointr);
+
 u_int ras_per_proc = MAX_RAS_PER_PROC;
 
 #ifdef DEBUG
@@ -64,8 +69,13 @@
 #define DPRINTF(x)	/* nothing */
 #endif
 
-int ras_install(struct proc *, caddr_t, size_t);
-int ras_purge(struct proc *, caddr_t, size_t);
+
+int 
+ras_install(struct proc *, caddr_t, size_t);
+
+int 
+ras_purge(struct proc *, caddr_t, size_t);
+
 
 /*
  * Check the specified address to see if it is within the
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_resource.c mult-netbsd-3.1/sys/kern/kern_resource.c
--- NetBSD-3.1/sys/kern/kern_resource.c	2005-09-18 21:09:50.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_resource.c	2007-11-23 10:17:19.000000000 +0000
@@ -53,38 +53,88 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
+
+struct inst_res
+{
+	struct uihashhead *uihashtbl;
+	u_long		uihash;
+};
+
+static POOL_INIT(plimit_pool, sizeof(struct plimit), 
+		0, 0, 0, "plimitpl", &pool_allocator_nointr);
+
+static POOL_INIT(pstats_pool, sizeof(struct pstats), 
+		0, 0, 0, "pststpl", &pool_allocator_nointr);
+
+
+#define UIHASH(res, uid) \
+	(&(res)->uihashtbl[(uid) & (res)->uihash])
+
 /*
- * Maximum process data and stack limits.
- * They are variables so they are patchable.
+ * Maximum process data and stack limits.  They are variables so they
+ * are patchable.  These don't change, so they're save not to put into
+ * the instance context.
  */
-rlim_t maxdmap = MAXDSIZ;
-rlim_t maxsmap = MAXSSIZ;
+rlim_t 			maxdmap = MAXDSIZ;
+rlim_t 			maxsmap = MAXSSIZ;
+
+static void 		freeuidinfo(struct uidinfo *);
+static struct uidinfo	*allocuidinfo(struct inst *i, uid_t uid);
+static struct uidinfo	*getuidinfo(struct inst *i, uid_t uid);
+
+
+int
+inst_res_alloc(inst_res_t *p, int flags)
+{
+	struct inst_res *i;
+
+	KASSERT(p);
+
+	i = malloc(sizeof(struct inst_res), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_res));
+
+	i->uihash = 0;
+	i->uihashtbl = hashinit(maxproc / 16, HASH_LIST, 
+			M_INST, flags, &i->uihash);
+	*p = i;
+	return(1);
+}
+
 
-struct uihashhead *uihashtbl;
-u_long uihash;		/* size of hash table - 1 */
+void
+inst_res_free(inst_res_t p)
+{
+	KASSERT(p);
+	if (p->uihashtbl)
+		free(p->uihashtbl, M_INST);
+	free(p, M_INST);
+}
 
-static struct uidinfo *getuidinfo(uid_t);
-static void freeuidinfo(struct uidinfo *);
-static struct uidinfo *allocuidinfo(uid_t);
 
 /*
  * Resource controls and accounting.
  */
-
 int
-sys_getpriority(l, v, retval)
-	struct lwp *l;
-	void *v;
-	register_t *retval;
+sys_getpriority(struct lwp *l, void *v, register_t *retval)
 {
 	struct sys_getpriority_args /* {
 		syscallarg(int) which;
 		syscallarg(id_t) who;
 	} */ *uap = v;
-	struct proc *curp = l->l_proc, *p;
-	int low = NZERO + PRIO_MAX + 1;
+	struct proc 	*curp, *p;
+	int 		low;
+
+	curp = l->l_proc;
+	low = NZERO + PRIO_MAX + 1;
+
+	KASSERT(curp);
+	KASSERT(curp->p_inst);
 
 	switch (SCARG(uap, which)) {
 
@@ -92,7 +142,7 @@
 		if (SCARG(uap, who) == 0)
 			p = curp;
 		else
-			p = pfind(SCARG(uap, who));
+			p = pfind(curp->p_inst, SCARG(uap, who));
 		if (p == 0)
 			break;
 		low = p->p_nice;
@@ -103,7 +153,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, SCARG(uap, who))) == NULL)
 			break;
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 			if (p->p_nice < low)
@@ -115,13 +165,13 @@
 	case PRIO_USER:
 		if (SCARG(uap, who) == 0)
 			SCARG(uap, who) = curp->p_ucred->cr_uid;
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		proclist_lock_read(curp->p_inst);
+		PROCLIST_FOREACH(p, &curp->p_inst->i_allproc) {
 			if (p->p_ucred->cr_uid == (uid_t) SCARG(uap, who) &&
 			    p->p_nice < low)
 				low = p->p_nice;
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(curp->p_inst);
 		break;
 
 	default:
@@ -133,6 +183,7 @@
 	return (0);
 }
 
+
 /* ARGSUSED */
 int
 sys_setpriority(l, v, retval)
@@ -148,13 +199,16 @@
 	struct proc *curp = l->l_proc, *p;
 	int found = 0, error = 0;
 
+	KASSERT(curp);
+	KASSERT(curp->p_inst);
+
 	switch (SCARG(uap, which)) {
 
 	case PRIO_PROCESS:
 		if (SCARG(uap, who) == 0)
 			p = curp;
 		else
-			p = pfind(SCARG(uap, who));
+			p = pfind(curp->p_inst, SCARG(uap, who));
 		if (p == 0)
 			break;
 		error = donice(curp, p, SCARG(uap, prio));
@@ -166,7 +220,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, SCARG(uap, who))) == NULL)
 			break;
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 			error = donice(curp, p, SCARG(uap, prio));
@@ -178,14 +232,14 @@
 	case PRIO_USER:
 		if (SCARG(uap, who) == 0)
 			SCARG(uap, who) = curp->p_ucred->cr_uid;
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		proclist_lock_read(curp->p_inst);
+		PROCLIST_FOREACH(p, &curp->p_inst->i_allproc) {
 			if (p->p_ucred->cr_uid == (uid_t) SCARG(uap, who)) {
 				error = donice(curp, p, SCARG(uap, prio));
 				found++;
 			}
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(curp->p_inst);
 		break;
 
 	default:
@@ -196,13 +250,14 @@
 	return (error);
 }
 
+
 int
-donice(curp, chgp, n)
-	struct proc *curp, *chgp;
-	int n;
+donice(struct proc *curp, struct proc *chgp, int n)
 {
-	struct pcred *pcred = curp->p_cred;
-	int s;
+	struct pcred 	*pcred;
+	int 		s;
+
+	pcred = curp->p_cred;
 
 	if (pcred->pc_ucred->cr_uid && pcred->p_ruid &&
 	    pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid &&
@@ -222,21 +277,22 @@
 	return (0);
 }
 
+
 /* ARGSUSED */
 int
-sys_setrlimit(l, v, retval)
-	struct lwp *l;
-	void *v;
-	register_t *retval;
+sys_setrlimit(struct lwp *l, void *v, register_t *retval)
 {
 	struct sys_setrlimit_args /* {
 		syscallarg(int) which;
 		syscallarg(const struct rlimit *) rlp;
 	} */ *uap = v;
-	struct proc *p = l->l_proc;
-	int which = SCARG(uap, which);
-	struct rlimit alim;
-	int error;
+	struct proc 	*p;
+	int 		which;
+	struct rlimit	alim;
+	int 		error;
+
+	p = l->l_proc;
+	which = SCARG(uap, which);
 
 	error = copyin(SCARG(uap, rlp), &alim, sizeof(struct rlimit));
 	if (error)
@@ -244,16 +300,14 @@
 	return (dosetrlimit(p, p->p_cred, which, &alim));
 }
 
+
 int
-dosetrlimit(p, cred, which, limp)
-	struct proc *p;
-	struct  pcred *cred;
-	int which;
-	struct rlimit *limp;
-{
-	struct rlimit *alimp;
-	struct plimit *oldplim;
-	int error;
+dosetrlimit(struct proc *p, struct  pcred *cred, int which,
+		struct rlimit *limp)
+{
+	struct rlimit	*alimp;
+	struct plimit	*oldplim;
+	int 		error;
 
 	if ((u_int)which >= RLIM_NLIMITS)
 		return (EINVAL);
@@ -280,6 +334,7 @@
 
 	if (p->p_limit->p_refcnt > 1 &&
 	    (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
+		KASSERT(NULL != p->p_inst);
 		p->p_limit = limcopy(oldplim = p->p_limit);
 		limfree(oldplim);
 		alimp = &p->p_rlimit[which];
@@ -361,19 +416,20 @@
 	return (0);
 }
 
+
 /* ARGSUSED */
 int
-sys_getrlimit(l, v, retval)
-	struct lwp *l;
-	void *v;
-	register_t *retval;
+sys_getrlimit(struct lwp *l, void *v, register_t *retval)
 {
 	struct sys_getrlimit_args /* {
 		syscallarg(int) which;
 		syscallarg(struct rlimit *) rlp;
 	} */ *uap = v;
-	struct proc *p = l->l_proc;
-	int which = SCARG(uap, which);
+	struct proc	*p;
+	int 		which;
+
+	p = l->l_proc;
+	which = SCARG(uap, which);
 
 	if ((u_int)which >= RLIM_NLIMITS)
 		return (EINVAL);
@@ -381,23 +437,21 @@
 	    sizeof(struct rlimit)));
 }
 
+
 /*
  * Transform the running time and tick information in proc p into user,
  * system, and interrupt time usage.
  */
 void
-calcru(p, up, sp, ip)
-	struct proc *p;
-	struct timeval *up;
-	struct timeval *sp;
-	struct timeval *ip;
-{
-	u_quad_t u, st, ut, it, tot;
-	unsigned long sec;
-	long usec;
-	int s;
-	struct timeval tv;
-	struct lwp *l;
+calcru(struct proc *p, struct timeval *up, struct timeval *sp,
+		struct timeval *ip)
+{
+	u_quad_t 	u, st, ut, it, tot;
+	unsigned long 	sec;
+	long 		usec;
+	int 		s;
+	struct timeval	tv;
+	struct lwp 	*l;
 
 	s = splstatclock();
 	st = p->p_sticks;
@@ -449,6 +503,7 @@
 	}
 }
 
+
 /* ARGSUSED */
 int
 sys_getrusage(l, v, retval)
@@ -496,18 +551,21 @@
 		*ip++ += *ip2++;
 }
 
+
 /*
  * Make a copy of the plimit structure.
  * We share these structures copy-on-write after fork,
  * and copy when a limit is changed.
  */
 struct plimit *
-limcopy(lim)
-	struct plimit *lim;
+limcopy(struct plimit *lim)
 {
-	struct plimit *newlim;
-	size_t l = 0;
+	struct plimit	*newlim;
+	size_t 		l;
+
+	KASSERT(lim);
 
+	l = 0;
 	simple_lock(&lim->p_slock);
 	if (lim->pl_corename != defcorename)
 		l = strlen(lim->pl_corename) + 1;
@@ -532,11 +590,13 @@
 	return (newlim);
 }
 
+
 void
-limfree(lim)
-	struct plimit *lim;
+limfree(struct plimit *lim)
 {
-	int n;
+	int 		n;
+
+	KASSERT(lim);
 
 	simple_lock(&lim->p_slock);
 	n = --lim->p_refcnt;
@@ -552,31 +612,31 @@
 	pool_put(&plimit_pool, lim);
 }
 
+
 struct pstats *
-pstatscopy(ps)
-	struct pstats *ps;
+pstatscopy(struct pstats *ps)
 {
+	struct pstats	*newps;
 
-	struct pstats *newps;
+	KASSERT(NULL != ps);
 
 	newps = pool_get(&pstats_pool, PR_WAITOK);
 
 	memset(&newps->pstat_startzero, 0,
-	(unsigned) ((caddr_t)&newps->pstat_endzero -
-		    (caddr_t)&newps->pstat_startzero));
+			(unsigned) ((caddr_t)&newps->pstat_endzero -
+				(caddr_t)&newps->pstat_startzero));
 	memcpy(&newps->pstat_startcopy, &ps->pstat_startcopy,
-	((caddr_t)&newps->pstat_endcopy -
-	 (caddr_t)&newps->pstat_startcopy));
-
-	return (newps);
+			((caddr_t)&newps->pstat_endcopy -
+			 (caddr_t)&newps->pstat_startcopy));
 
+	return(newps);
 }
 
+
 void
-pstatsfree(ps)
-	struct pstats *ps;
+pstatsfree(struct pstats *ps)
 {
-
+	KASSERT(NULL != ps);
 	pool_put(&pstats_pool, ps);
 }
 
@@ -594,9 +654,12 @@
 	struct proc *ptmp;
 	int i, error = 0;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	if (pid == PROC_CURPROC)
 		ptmp = p;
-	else if ((ptmp = pfind(pid)) == NULL)
+	else if ((ptmp = pfind(p->p_inst, pid)) == NULL)
 		error = ESRCH;
 	else {
 		/*
@@ -700,6 +763,7 @@
 
 	lim = ptmp->p_limit;
 	if (lim->p_refcnt > 1 && (lim->p_lflags & PL_SHAREMOD) == 0) {
+		KASSERT(NULL != l->l_inst);
 		ptmp->p_limit = limcopy(lim);
 		limfree(lim);
 		lim = ptmp->p_limit;
@@ -894,12 +958,13 @@
 }
 
 static struct uidinfo *
-getuidinfo(uid_t uid)
+getuidinfo(struct inst *i, uid_t uid)
 {
 	struct uidinfo *uip;
 	struct uihashhead *uipp;
 
-	uipp = UIHASH(uid);
+	KASSERT(NULL != i);
+	uipp = UIHASH(i->i_res, uid);
 
 	LIST_FOREACH(uip, uipp, ui_hash)
 		if (uip->ui_uid == uid)
@@ -915,12 +980,14 @@
 }
 
 static struct uidinfo *
-allocuidinfo(uid_t uid)
+allocuidinfo(struct inst *i, uid_t uid)
 {
 	struct uidinfo *uip;
 	struct uihashhead *uipp;
 
-	uipp = UIHASH(uid);
+	KASSERT(NULL != i);
+
+	uipp = UIHASH(i->i_res, uid);
 	MALLOC(uip, struct uidinfo *, sizeof(*uip), M_PROC, M_WAITOK);
 	LIST_INSERT_HEAD(uipp, uip, ui_hash);
 	uip->ui_uid = uid;
@@ -929,23 +996,23 @@
 	return uip;
 }
 
+
 /*
- * Change the count associated with number of processes
- * a given user is using.
+ * Change the count associated with number of processes a given user is using.
  */
 int
-chgproccnt(uid_t uid, int diff)
+chgproccnt(struct inst *i, uid_t uid, int diff)
 {
 	struct uidinfo *uip;
 
 	if (diff == 0)
 		return 0;
 
-	if ((uip = getuidinfo(uid)) != NULL) {
+	if ((uip = getuidinfo(i, uid)) != NULL) {
 		uip->ui_proccnt += diff;
 		KASSERT(uip->ui_proccnt >= 0);
 		if (uip->ui_proccnt > 0)
-			return uip->ui_proccnt;
+			return(uip->ui_proccnt);
 		else {
 			if (uip->ui_sbsize == 0)
 				freeuidinfo(uip);
@@ -954,9 +1021,9 @@
 	} else {
 		if (diff < 0)
 			panic("chgproccnt: lost user %lu", (unsigned long)uid);
-		uip = allocuidinfo(uid);
+		uip = allocuidinfo(i, uid);
 		uip->ui_proccnt = diff;
-		return uip->ui_proccnt;
+		return(uip->ui_proccnt);
 	}
 }
 
@@ -965,23 +1032,4 @@
 {
 	*hiwat = to;
 	return 1;
-#ifdef notyet
-	struct uidinfo *uip;
-	rlim_t nsb;
-	int rv = 0;
-
-	if ((uip = getuidinfo(uid)) == NULL)
-		uip = allocuidinfo(uid);
-	nsb = uip->ui_sbsize + to - *hiwat;
-	if (to > *hiwat && nsb > max)
-		goto done;
-	*hiwat = to;
-	uip->ui_sbsize = nsb;
-	rv = 1;
-	KASSERT(uip->ui_sbsize >= 0);
-done:
-	if (uip->ui_sbsize == 0 && uip->ui_proccnt == 0)
-		freeuidinfo(uip);
-	return rv;
-#endif
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_sa.c mult-netbsd-3.1/sys/kern/kern_sa.c
--- NetBSD-3.1/sys/kern/kern_sa.c	2005-10-28 21:07:02.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_sa.c	2007-11-23 17:59:22.000000000 +0000
@@ -50,9 +50,20 @@
 #include <sys/sa.h>
 #include <sys/savar.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 #include <uvm/uvm_extern.h>
 
+
+static POOL_INIT(sadata_pool, sizeof(struct sadata), 
+		0, 0, 0, "sadatapl", &pool_allocator_nointr);
+
+static POOL_INIT(sastack_pool, sizeof(struct sastack), 
+		0, 0, 0, "sastackpl", &pool_allocator_nointr);
+
+static POOL_INIT(savp_pool, sizeof(struct sadata_vp), 
+		0, 0, 0, "savppl", &pool_allocator_nointr);
+
 static struct sadata_vp *sa_newsavp(struct sadata *);
 static __inline int sa_stackused(struct sastack *, struct sadata *);
 static __inline void sa_setstackfree(struct sastack *, struct sadata *);
@@ -74,6 +85,9 @@
     size_t, void *, void (*)(void *));
 static void sa_upcall_getstate(union sau_state *, struct lwp *);
 
+static POOL_INIT(saupcall_pool, sizeof(struct sadata_upcall), 
+		0, 0, 0, "plimitpl", &pool_allocator_nointr);
+
 MALLOC_DEFINE(M_SA, "sa", "Scheduler activations");
 
 #define SA_DEBUG
@@ -97,6 +111,8 @@
 	(l)->l_flag |= (f) & L_SA;				\
 } while (/*CONSTCOND*/ 0)
 
+
+/* FIXME - instances? */
 SPLAY_PROTOTYPE(sasttree, sastack, sast_node, sast_compare);
 SPLAY_GENERATE(sasttree, sastack, sast_node, sast_compare);
 
@@ -111,11 +127,11 @@
 {
 	struct sadata_upcall *sau;
 
-	sau = pool_get(&saupcall_pool, waitok ? PR_WAITOK : PR_NOWAIT);
-	if (sau) {
+	sau = pool_get(&saupcall_pool, 
+			waitok ? PR_WAITOK : PR_NOWAIT);
+	if (sau)
 		sau->sau_arg = NULL;
-	}
-	return sau;
+	return(sau);
 }
 
 /*
@@ -126,7 +142,6 @@
 void
 sadata_upcall_free(struct sadata_upcall *sau)
 {
-
 	if (sau == NULL) {
 		return;
 	}
@@ -631,8 +646,9 @@
 	if (vp->savp_lwp != l) {
 		/*
 		 * We lost the VP on our way here, this happens for
-		 * instance when we sleep in systrace.  This will end
-		 * in an SA_UNBLOCKED_UPCALL in sa_setwoken().
+		 * instance when we sleep in systrace (which has since
+		 * been removed).  This will end in an
+		 * SA_UNBLOCKED_UPCALL in sa_setwoken().
 		 */
 		DPRINTFN(1,("sa_yield(%d.%d) lost VP\n",
 			     p->p_pid, l->l_lid));
@@ -1682,21 +1698,6 @@
 #ifdef DEBUG
 int debug_print_sa(struct proc *);
 int debug_print_lwp(struct lwp *);
-int debug_print_proc(int);
-
-int
-debug_print_proc(int pid)
-{
-	struct proc *p;
-
-	p = pfind(pid);
-	if (p == NULL)
-		printf("No process %d\n", pid);
-	else
-		debug_print_sa(p);
-
-	return 0;
-}
 
 int
 debug_print_sa(struct proc *p)
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_sig.c mult-netbsd-3.1/sys/kern/kern_sig.c
--- NetBSD-3.1/sys/kern/kern_sig.c	2005-11-13 13:55:27.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_sig.c	2007-11-23 10:17:19.000000000 +0000
@@ -74,6 +74,8 @@
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <machine/cpu.h>
 
 #include <sys/user.h>		/* for coredump */
@@ -86,7 +88,9 @@
 static void	ksiginfo_exithook(struct proc *, void *);
 static void	ksiginfo_put(struct proc *, const ksiginfo_t *);
 static ksiginfo_t *ksiginfo_get(struct proc *, int);
-static void	kpsignal2(struct proc *, const ksiginfo_t *, int);
+
+static void
+kpsignal2(struct proc *p, const ksiginfo_t *, int);
 
 sigset_t	contsigmask, stopsigmask, sigcantmask;
 
@@ -124,11 +128,11 @@
  */
 #define	CANSIGNAL(p, pc, q, signum) \
 	((pc)->pc_ucred->cr_uid == 0 || \
-	    (pc)->p_ruid == (q)->p_cred->p_ruid || \
-	    (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
-	    (pc)->p_ruid == (q)->p_ucred->cr_uid || \
-	    (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
-	    ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
+	 (pc)->p_ruid == (q)->p_cred->p_ruid || \
+	 (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
+	 (pc)->p_ruid == (q)->p_ucred->cr_uid || \
+	 (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
+	 ((signum) == SIGCONT && (q)->p_session == (p)->p_session))
 
 /*
  * Remove and return the first ksiginfo element that matches our requested
@@ -264,6 +268,7 @@
 	}
 }
 
+
 /*
  * Make this process not share its sigctx, maintaining all
  * signal state.
@@ -762,6 +767,9 @@
 	struct pcred	*pc;
 	ksiginfo_t	ksi;
 
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_proc->p_inst);
+
 	cp = l->l_proc;
 	pc = cp->p_cred;
 	if ((u_int)SCARG(uap, signum) >= NSIG)
@@ -773,7 +781,7 @@
 	ksi.ksi_uid = cp->p_ucred->cr_uid;
 	if (SCARG(uap, pid) > 0) {
 		/* kill single process */
-		if ((p = pfind(SCARG(uap, pid))) == NULL)
+		if ((p = pfind(cp->p_inst, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 		if (!CANSIGNAL(cp, pc, p, SCARG(uap, signum)))
 			return (EPERM);
@@ -792,27 +800,28 @@
 	/* NOTREACHED */
 }
 
-/*
- * Common code for kill process group/broadcast kill.
- * cp is calling process.
- */
+
 int
 killpg1(struct proc *cp, ksiginfo_t *ksi, int pgid, int all)
 {
 	struct proc	*p;
 	struct pcred	*pc;
 	struct pgrp	*pgrp;
-	int		nfound;
-	int		signum = ksi->ksi_signo;
+	int		nfound, signum;
+	struct inst	*i;
 
+	signum = ksi->ksi_signo;
 	pc = cp->p_cred;
+	i = cp->p_inst;
+	KASSERT(NULL != i);
 	nfound = 0;
+
 	if (all) {
 		/*
 		 * broadcast
 		 */
-		proclist_lock_read();
-		PROCLIST_FOREACH(p, &allproc) {
+		proclist_lock_read(i);
+		PROCLIST_FOREACH(p, &i->i_allproc) {
 			if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
 			    p == cp || !CANSIGNAL(cp, pc, p, signum))
 				continue;
@@ -820,7 +829,7 @@
 			if (signum)
 				kpsignal2(p, ksi, 1);
 		}
-		proclist_unlock_read();
+		proclist_unlock_read(i);
 	} else {
 		if (pgid == 0)
 			/*
@@ -828,7 +837,7 @@
 			 */
 			pgrp = cp->p_pgrp;
 		else {
-			pgrp = pgfind(pgid);
+			pgrp = pgfind(i, pgid);
 			if (pgrp == NULL)
 				return (ESRCH);
 		}
@@ -844,31 +853,31 @@
 	return (nfound ? 0 : ESRCH);
 }
 
-/*
- * Send a signal to a process group.
- */
+
 void
-gsignal(int pgid, int signum)
+gsignal(struct inst *i, int pgid, int signum)
 {
-	ksiginfo_t ksi;
+	ksiginfo_t 	ksi;
+
+	KASSERT(NULL != i);
+
 	KSI_INIT_EMPTY(&ksi);
 	ksi.ksi_signo = signum;
-	kgsignal(pgid, &ksi, NULL);
+	kgsignal(i, pgid, &ksi, NULL);
 }
 
 void
-kgsignal(int pgid, ksiginfo_t *ksi, void *data)
+kgsignal(struct inst *i, int pgid, ksiginfo_t *ksi, void *data)
 {
-	struct pgrp *pgrp;
+	struct pgrp 	*pgrp;
+
+	KASSERT(NULL != i);
 
-	if (pgid && (pgrp = pgfind(pgid)))
+	if (pgid && (pgrp = pgfind(i, pgid)))
 		kpgsignal(pgrp, ksi, data, 0);
 }
 
-/*
- * Send a signal to a process group. If checktty is 1,
- * limit to members which have a controlling terminal.
- */
+
 void
 pgsignal(struct pgrp *pgrp, int sig, int checkctty)
 {
@@ -878,17 +887,20 @@
 	kpgsignal(pgrp, &ksi, NULL, checkctty);
 }
 
+
 void
 kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
 {
-	struct proc *p;
+	struct proc 	*p;
 
-	if (pgrp)
-		LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
-			if (checkctty == 0 || p->p_flag & P_CONTROLT)
-				kpsignal(p, ksi, data);
+	if ( ! pgrp)
+		return;
+	LIST_FOREACH(p, &pgrp->pg_members, p_pglist)
+		if (checkctty == 0 || p->p_flag & P_CONTROLT)
+			kpsignal(p, ksi, data);
 }
 
+
 /*
  * Send a signal caused by a trap to the current process.
  * If it will be caught immediately, deliver it with correct code.
@@ -950,7 +962,8 @@
 	ksi.ksi_status = p->p_xstat;
 	ksi.ksi_utime = p->p_stats->p_ru.ru_utime.tv_sec;
 	ksi.ksi_stime = p->p_stats->p_ru.ru_stime.tv_sec;
-	kpsignal2(p->p_pptr, &ksi, dolock);
+	if (p->p_pptr)
+		kpsignal2(p->p_pptr, &ksi, dolock);
 }
 
 /*
@@ -981,7 +994,6 @@
 void
 kpsignal1(struct proc *p, ksiginfo_t *ksi, void *data, int dolock)
 {
-
 	if ((p->p_flag & P_WEXIT) == 0 && data) {
 		size_t fd;
 		struct filedesc *fdp = p->p_fd;
@@ -999,14 +1011,22 @@
 	kpsignal2(p, ksi, dolock);
 }
 
+
 static void
 kpsignal2(struct proc *p, const ksiginfo_t *ksi, int dolock)
 {
-	struct lwp *l, *suspended = NULL;
+	struct lwp 	*l, *suspended;
 	struct sadata_vp *vp;
-	int	s = 0, prop, allsusp;
-	sig_t	action;
-	int	signum = ksi->ksi_signo;
+	int		s, prop, allsusp;
+	sig_t		action;
+	int		signum;
+
+	signum = ksi->ksi_signo;
+	suspended = NULL;
+	s = 0;
+
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
 
 #ifdef DIAGNOSTIC
 	if (signum <= 0 || signum >= NSIG)
@@ -1228,7 +1248,8 @@
 			}
 			sigdelset(&p->p_sigctx.ps_siglist, signum);
 			p->p_xstat = signum;
-			if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0) {
+			if (p->p_pptr && 
+				((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)) {
 				/*
 				 * XXXSMP: recursive call; don't lock
 				 * the second time around.
@@ -1580,7 +1601,7 @@
 				    prop & SA_TTYSTOP))
 					break;	/* == ignore */
 				p->p_xstat = signum;
-				if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
+				if (p->p_pptr && ((p->p_pptr->p_flag & P_NOCLDSTOP)) == 0)
 					child_psignal(p, dolock);
 				if (dolock)
 					SCHED_LOCK(s);
@@ -1644,7 +1665,6 @@
 proc_stop(struct proc *p, int wakeup)
 {
 	struct lwp *l;
-	struct proc *parent;
 	struct sadata_vp *vp;
 
 	SCHED_ASSERT_LOCKED();
@@ -1652,8 +1672,8 @@
 	/* XXX lock process LWP state */
 	p->p_flag &= ~P_WAITED;
 	p->p_stat = SSTOP;
-	parent = p->p_pptr;
-	parent->p_nstopchild++;
+	if (p->p_pptr)
+		p->p_pptr->p_nstopchild++;
 
 	if (p->p_flag & P_SA) {
 		/*
@@ -1735,7 +1755,7 @@
  out:
 	/* XXX unlock process LWP state */
 
-	if (wakeup)
+	if (wakeup && p->p_pptr)
 		sched_wakeup((caddr_t)p->p_pptr);
 }
 
@@ -1763,7 +1783,7 @@
 	 * interruptable LWPs if this is the case.
 	 */
 
-	if (!(p->p_flag & P_WAITED))
+	if (p->p_pptr && !(p->p_flag & P_WAITED))
 		p->p_pptr->p_nstopchild--;
 	p->p_stat = SACTIVE;
 	LIST_FOREACH(l, &p->p_lwps, l_sibling) {
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_subr.c mult-netbsd-3.1/sys/kern/kern_subr.c
--- NetBSD-3.1/sys/kern/kern_subr.c	2005-12-29 20:00:12.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_subr.c	2007-11-10 19:27:11.000000000 +0000
@@ -92,7 +92,6 @@
 #include "opt_md.h"
 #include "opt_syscall_debug.h"
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -104,7 +103,6 @@
 #include <sys/conf.h>
 #include <sys/disklabel.h>
 #include <sys/queue.h>
-#include <sys/systrace.h>
 #include <sys/ktrace.h>
 
 #include <uvm/uvm_extern.h>
@@ -1344,7 +1342,7 @@
 trace_enter(struct lwp *l, register_t code,
 	register_t realcode, const struct sysent *callp, void *args)
 {
-#if defined(KTRACE) || defined(SYSTRACE)
+#if defined(KTRACE) 
 	struct proc *p = l->l_proc;
 #endif
 
@@ -1357,10 +1355,6 @@
 		ktrsyscall(p, code, realcode, callp, args);
 #endif /* KTRACE */
 
-#ifdef SYSTRACE
-	if (ISSET(p->p_flag, P_SYSTRACE))
-		return systrace_enter(p, code, args);
-#endif
 	return 0;
 }
 
@@ -1375,7 +1369,7 @@
 trace_exit(struct lwp *l, register_t code, void *args, register_t rval[],
     int error)
 {
-#if defined(KTRACE) || defined(SYSTRACE)
+#if defined(KTRACE) 
 	struct proc *p = l->l_proc;
 #endif
 
@@ -1390,12 +1384,4 @@
 		KERNEL_PROC_UNLOCK(l);
 	}
 #endif /* KTRACE */
-
-#ifdef SYSTRACE
-	if (ISSET(p->p_flag, P_SYSTRACE)) {
-		KERNEL_PROC_LOCK(l);
-		systrace_exit(p, code, args, rval, error);
-		KERNEL_PROC_UNLOCK(l);
-	}
-#endif
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_synch.c mult-netbsd-3.1/sys/kern/kern_synch.c
--- NetBSD-3.1/sys/kern/kern_synch.c	2005-10-21 18:39:40.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_synch.c	2007-11-23 10:17:19.000000000 +0000
@@ -100,6 +100,8 @@
 #include <sys/sa.h>
 #include <sys/savar.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
 #ifdef KTRACE
@@ -242,6 +244,7 @@
  */
 #define	CCPU_SHIFT	11
 
+
 /*
  * Recompute process priorities, every hz ticks.
  */
@@ -249,74 +252,95 @@
 void
 schedcpu(void *arg)
 {
-	fixpt_t loadfac = loadfactor(averunnable.ldavg[0]);
-	struct lwp *l;
-	struct proc *p;
-	int s, minslp;
-	unsigned int newcpu;
-	int clkhz;
+	fixpt_t 	loadfac = loadfactor(averunnable.ldavg[0]);
+	struct lwp 	*l;
+	struct proc 	*p;
+	struct inst	*i;
+	int 		s, minslp, clkhz;
+	unsigned int 	newcpu;
+
+	instlist_lock_read();
+
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		PROCLIST_FOREACH(p, &i->i_allproc) {
+			/*
+			 * 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.
+			 */
+			minslp = 2;
+			LIST_FOREACH(l, &p->p_lwps, l_sibling) {
+				l->l_swtime++;
+				if (l->l_stat == LSSLEEP || 
+						l->l_stat == LSSTOP ||
+						l->l_stat == LSSUSPENDED) {
+					l->l_slptime++;
+					minslp = min(minslp, l->l_slptime);
+				} else
+					minslp = 0;
+			}
+			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 (minslp > 1)
+				continue;
+
+			/* Prevent state changes */
+			s = splstatclock();	
+
+			/*
+			 * p_pctcpu is only for ps.
+			 */
+			clkhz = stathz != 0 ? stathz : hz;
 
-	proclist_lock_read();
-	PROCLIST_FOREACH(p, &allproc) {
-		/*
-		 * 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.
-		 */
-		minslp = 2;
-		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
-			l->l_swtime++;
-			if (l->l_stat == LSSLEEP || l->l_stat == LSSTOP ||
-			    l->l_stat == LSSUSPENDED) {
-				l->l_slptime++;
-				minslp = min(minslp, l->l_slptime);
-			} else
-				minslp = 0;
-		}
-		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 (minslp > 1)
-			continue;
-		s = splstatclock();	/* prevent state changes */
-		/*
-		 * p_pctcpu is only for ps.
-		 */
-		clkhz = stathz != 0 ? stathz : hz;
 #if	(FSHIFT >= CCPU_SHIFT)
-		p->p_pctcpu += (clkhz == 100)?
-			((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT):
-                	100 * (((fixpt_t) p->p_cpticks)
+			p->p_pctcpu += (clkhz == 100) ?
+				((fixpt_t) p->p_cpticks) << 
+				(FSHIFT - CCPU_SHIFT) :
+	                	100 * (((fixpt_t) p->p_cpticks)
 				<< (FSHIFT - CCPU_SHIFT)) / clkhz;
 #else
-		p->p_pctcpu += ((FSCALE - ccpu) *
-			(p->p_cpticks * FSCALE / clkhz)) >> FSHIFT;
+			p->p_pctcpu += ((FSCALE - ccpu) *
+				(p->p_cpticks * FSCALE / clkhz)) >> FSHIFT;
 #endif
-		p->p_cpticks = 0;
-		newcpu = (u_int)decay_cpu(loadfac, p->p_estcpu);
-		p->p_estcpu = newcpu;
-		splx(s);	/* Done with the process CPU ticks update */
-		SCHED_LOCK(s);
-		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
-			if (l->l_slptime > 1)
-				continue;
-			resetpriority(l);
-			if (l->l_priority >= PUSER) {
-				if (l->l_stat == LSRUN &&
-				    (l->l_flag & L_INMEM) &&
-				    (l->l_priority / PPQ) != (l->l_usrpri / PPQ)) {
-					remrunqueue(l);
-					l->l_priority = l->l_usrpri;
-					setrunqueue(l);
-				} else
-					l->l_priority = l->l_usrpri;
+
+			p->p_cpticks = 0;
+			newcpu = (u_int)decay_cpu
+				(loadfac, p->p_estcpu);
+			p->p_estcpu = newcpu;
+
+			/* Done with the process CPU ticks update */
+			splx(s);	
+			SCHED_LOCK(s);
+			LIST_FOREACH(l, &p->p_lwps, l_sibling) {
+				if (l->l_slptime > 1)
+					continue;
+				resetpriority(l);
+				if (l->l_priority >= PUSER) {
+					if (l->l_stat == LSRUN &&
+					    (l->l_flag & L_INMEM) &&
+					    (l->l_priority / PPQ) != 
+					    (l->l_usrpri / PPQ)) {
+						remrunqueue(l);
+						l->l_priority = l->l_usrpri;
+						setrunqueue(l);
+					} else
+						l->l_priority = l->l_usrpri;
+				}
 			}
+			SCHED_UNLOCK(s);
 		}
-		SCHED_UNLOCK(s);
+		proclist_unlock_read(i);
 	}
-	proclist_unlock_read();
+
+	instlist_unlock_read();
+
 	uvm_meter();
 	wakeup((caddr_t)&lbolt);
 	callout_schedule(&schedcpu_ch, hz);
@@ -1155,42 +1179,49 @@
 void
 suspendsched()
 {
-	struct lwp *l;
-	int s;
+	struct lwp 	*l;
+	struct inst	*i;
+	int 		s;
 
 	/*
 	 * Convert all non-P_SYSTEM LSSLEEP or LSRUN processes to
 	 * LSSUSPENDED.
 	 */
-	proclist_lock_read();
+	instlist_lock_read();
 	SCHED_LOCK(s);
-	LIST_FOREACH(l, &alllwp, l_list) {
-		if ((l->l_proc->p_flag & P_SYSTEM) != 0)
-			continue;
-
-		switch (l->l_stat) {
-		case LSRUN:
-			l->l_proc->p_nrlwps--;
-			if ((l->l_flag & L_INMEM) != 0)
-				remrunqueue(l);
-			/* FALLTHROUGH */
-		case LSSLEEP:
-			l->l_stat = LSSUSPENDED;
-			break;
-		case LSONPROC:
-			/*
-			 * XXX SMP: we need to deal with processes on
-			 * others CPU !
-			 */
-			break;
-		default:
-			break;
+
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			if ((l->l_proc->p_flag & P_SYSTEM) != 0)
+				continue;
+	
+			switch (l->l_stat) {
+			case LSRUN:
+				l->l_proc->p_nrlwps--;
+				if ((l->l_flag & L_INMEM) != 0)
+					remrunqueue(l);
+				/* FALLTHROUGH */
+			case LSSLEEP:
+				l->l_stat = LSSUSPENDED;
+				break;
+			case LSONPROC:
+				/*
+				 * XXX SMP: we need to deal with
+				 * processes on others CPU !
+				 */
+				break;
+			default:
+				break;
+			}
 		}
+		proclist_unlock_read(i);
 	}
 	SCHED_UNLOCK(s);
-	proclist_unlock_read();
+	instlist_unlock_read();
 }
 
+
 /*
  * Low-level routines to access the run queue.  Optimised assembler
  * routines can override these.
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_sysctl.c mult-netbsd-3.1/sys/kern/kern_sysctl.c
--- NetBSD-3.1/sys/kern/kern_sysctl.c	2006-03-24 22:44:29.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_sysctl.c	2007-11-26 15:42:56.000000000 +0000
@@ -152,17 +152,9 @@
 caddr_t sysctl_memaddr;
 size_t sysctl_memsize;
 
-/*
- * Attributes stored in the kernel.
- */
-char hostname[MAXHOSTNAMELEN];
-int hostnamelen;
-
-char domainname[MAXHOSTNAMELEN];
-int domainnamelen;
-
 long hostid;
 
+/* FIXME - instances (maybe not...) */
 #ifdef INSECURE
 int securelevel = -1;
 #else
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_systrace.c mult-netbsd-3.1/sys/kern/kern_systrace.c
--- NetBSD-3.1/sys/kern/kern_systrace.c	2006-10-16 21:36:50.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_systrace.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1733 +0,0 @@
-/*	$NetBSD: kern_systrace.c,v 1.44.2.4 2006/10/16 20:36:50 ghen Exp $	*/
-
-/*
- * Copyright 2002, 2003 Niels Provos <provos@citi.umich.edu>
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Niels Provos.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_systrace.c,v 1.44.2.4 2006/10/16 20:36:50 ghen Exp $");
-
-#include "opt_systrace.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/tree.h>
-#include <sys/malloc.h>
-#include <sys/syscall.h>
-#include <sys/vnode.h>
-#include <sys/errno.h>
-#include <sys/conf.h>
-#include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/filio.h>
-#include <sys/signalvar.h>
-#include <sys/lock.h>
-#include <sys/pool.h>
-#include <sys/mount.h>
-#include <sys/poll.h>
-#include <sys/ptrace.h>
-#include <sys/namei.h>
-#include <sys/systrace.h>
-#include <sys/sa.h>
-#include <sys/savar.h>
-
-#include <compat/common/compat_util.h>
-
-#ifdef __NetBSD__
-#define	SYSTRACE_LOCK(fst, p)	lockmgr(&fst->lock, LK_EXCLUSIVE, NULL)
-#define	SYSTRACE_UNLOCK(fst, p)	lockmgr(&fst->lock, LK_RELEASE, NULL)
-#else
-#define	SYSTRACE_LOCK(fst, p)	lockmgr(&fst->lock, LK_EXCLUSIVE, NULL, p)
-#define	SYSTRACE_UNLOCK(fst, p)	lockmgr(&fst->lock, LK_RELEASE, NULL, p)
-#endif
-#ifndef	M_XDATA
-MALLOC_DEFINE(M_SYSTR, "systrace", "systrace");
-#define	M_XDATA		M_SYSTR
-#endif
-
-#ifdef __NetBSD__
-dev_type_open(systraceopen);
-#else
-cdev_decl(systrace);
-#endif
-
-#ifdef __NetBSD__
-int	systracef_read(struct file *, off_t *, struct uio *, struct ucred *,
-		int);
-int	systracef_write(struct file *, off_t *, struct uio *, struct ucred *,
-		int);
-int	systracef_poll(struct file *, int, struct proc *);
-#else
-int	systracef_read(struct file *, off_t *, struct uio *, struct ucred *);
-int	systracef_write(struct file *, off_t *, struct uio *, struct ucred *);
-int	systracef_select(struct file *, int, struct proc *);
-#endif
-int	systracef_ioctl(struct file *, u_long, void *, struct proc *);
-int	systracef_close(struct file *, struct proc *);
-
-struct str_policy {
-	TAILQ_ENTRY(str_policy) next;
-
-	int nr;
-
-	const struct emul *emul;	/* Is only valid for this emulation */
-
-	int refcount;
-
-	int nsysent;
-	u_char *sysent;
-};
-
-#define STR_PROC_ONQUEUE	0x01
-#define STR_PROC_WAITANSWER	0x02
-#define STR_PROC_SYSCALLRES	0x04
-#define STR_PROC_REPORT		0x08	/* Report emulation */
-#define STR_PROC_NEEDSEQNR	0x10	/* Answer must quote seqnr */
-#define STR_PROC_SETEUID	0x20	/* Elevate privileges */
-#define STR_PROC_SETEGID	0x40
-#define STR_PROC_DIDSETUGID	0x80
-
-struct str_process {
-	TAILQ_ENTRY(str_process) next;
-
-	struct proc *proc;
-	const struct emul *oldemul;
-	uid_t olduid;
-	gid_t oldgid;
-
-	pid_t pid;
-
-	struct fsystrace *parent;
-	struct str_policy *policy;
-
-	struct systrace_replace *replace;
-	char *fname[SYSTR_MAXFNAME];
-	size_t nfname;
-
-	int flags;
-	short answer;
-	short error;
-	u_int16_t seqnr;	/* expected reply sequence number */
-
-	uid_t seteuid;
-	uid_t saveuid;
-	gid_t setegid;
-	gid_t savegid;
-};
-
-uid_t	systrace_seteuid(struct proc *,  uid_t);
-gid_t	systrace_setegid(struct proc *,  gid_t);
-void systrace_lock(void);
-void systrace_unlock(void);
-
-/* Needs to be called with fst locked */
-
-int	systrace_attach(struct fsystrace *, pid_t);
-int	systrace_detach(struct str_process *);
-int	systrace_answer(struct str_process *, struct systrace_answer *);
-int	systrace_io(struct str_process *, struct systrace_io *);
-int	systrace_policy(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 *);
-int	systrace_fname(struct str_process *, caddr_t, size_t);
-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);
-void	systrace_wakeup(struct fsystrace *);
-void	systrace_closepolicy(struct fsystrace *, struct str_policy *);
-int	systrace_insert_process(struct fsystrace *, struct proc *,
-	    struct str_process **);
-struct str_policy *systrace_newpolicy(struct fsystrace *, int);
-int	systrace_msg_child(struct fsystrace *, struct str_process *, pid_t);
-int	systrace_msg_policyfree(struct fsystrace *, struct str_policy *);
-int	systrace_msg_ask(struct fsystrace *, struct str_process *,
-	    int, size_t, register_t []);
-int	systrace_msg_result(struct fsystrace *, struct str_process *,
-	    int, int, size_t, register_t [], register_t []);
-int	systrace_msg_emul(struct fsystrace *, struct str_process *);
-int	systrace_msg_ugid(struct fsystrace *, struct str_process *);
-int	systrace_make_msg(struct str_process *, int, struct str_message *);
-
-static const struct fileops systracefops = {
-	systracef_read,
-	systracef_write,
-	systracef_ioctl,
-	fnullop_fcntl,
-	systracef_poll,
-	fbadop_stat,
-	systracef_close,
-	fnullop_kqfilter
-};
-
-#ifdef __NetBSD__
-POOL_INIT(systr_proc_pl, sizeof(struct str_process), 0, 0, 0, "strprocpl",
-    NULL);
-POOL_INIT(systr_policy_pl, sizeof(struct str_policy), 0, 0, 0, "strpolpl",
-    NULL);
-POOL_INIT(systr_msgcontainer_pl, sizeof(struct str_msgcontainer), 0, 0, 0,
-    "strmsgpl", NULL);
-#else
-struct pool systr_proc_pl;
-struct pool systr_policy_pl;
-struct pool systr_msgcontainer_pl;
-#endif
-
-int systrace_debug = 0;
-struct lock systrace_lck;
-
-#ifdef __NetBSD__
-const struct cdevsw systrace_cdevsw = {
-	systraceopen, noclose, noread, nowrite, noioctl,
-	nostop, notty, nopoll, nommap, nokqfilter,
-};
-#endif
-
-#define DPRINTF(y)	if (systrace_debug) printf y;
-
-/* ARGSUSED */
-int
-systracef_read(struct file *fp, off_t *poff, struct uio *uio,
-    struct ucred *cred
-#ifdef __NetBSD__
-    , int flags
-#endif
-)
-{
-	struct fsystrace *fst = (struct fsystrace *)fp->f_data;
-	struct str_msgcontainer *cont;
-	int error = 0;
-
-	if (uio->uio_resid != sizeof(struct str_message))
-		return (EINVAL);
-
- again:
-	systrace_lock();
-	SYSTRACE_LOCK(fst, curlwp);
-	systrace_unlock();
-	if ((cont = TAILQ_FIRST(&fst->messages)) != NULL) {
-		error = uiomove((caddr_t)&cont->msg,
-		    sizeof(struct str_message), uio);
-		if (!error) {
-			TAILQ_REMOVE(&fst->messages, cont, next);
-			if (!SYSTR_MSG_NOPROCESS(cont))
-				CLR(cont->strp->flags, STR_PROC_ONQUEUE);
-			pool_put(&systr_msgcontainer_pl, cont);
-
-		}
-	} else if (TAILQ_FIRST(&fst->processes) == NULL) {
-		/* EOF situation */
-		;
-	} else {
-		if (fp->f_flag & FNONBLOCK)
-			error = EAGAIN;
-		else {
-			SYSTRACE_UNLOCK(fst, curlwp);
-			error = tsleep(fst, PWAIT|PCATCH, "systrrd", 0);
-			if (error)
-				goto out;
-			goto again;
-		}
-
-	}
-
-	SYSTRACE_UNLOCK(fst, curlwp);
- out:
-	return (error);
-}
-
-/* ARGSUSED */
-int
-systracef_write(struct file *fp, off_t *poff, struct uio *uio,
-    struct ucred *cred
-#ifdef __NetBSD__
-    , int flags
-#endif
-)
-{
-	return (EIO);
-}
-
-#define POLICY_VALID(x)	((x) == SYSTR_POLICY_PERMIT || \
-			 (x) == SYSTR_POLICY_ASK || \
-			 (x) == SYSTR_POLICY_NEVER)
-
-/* ARGSUSED */
-int
-systracef_ioctl(struct file *fp, u_long cmd, void *data, struct proc *p)
-{
-	int ret = 0;
-	struct fsystrace *fst = (struct fsystrace *)fp->f_data;
-#ifdef __NetBSD__
-	struct cwdinfo *cwdp;
-#else
-	struct filedesc *fdp;
-#endif
-	struct str_process *strp = NULL;
-	pid_t pid = 0;
-
-	switch (cmd) {
-	case FIONBIO:
-	case FIOASYNC:
-		return (0);
-
-	case STRIOCDETACH:
-	case STRIOCREPORT:
-		pid = *(pid_t *)data;
-		if (!pid)
-			ret = EINVAL;
-		break;
-	case STRIOCANSWER:
-		pid = ((struct systrace_answer *)data)->stra_pid;
-		if (!pid)
-			ret = EINVAL;
-		break;
-	case STRIOCIO:
-		pid = ((struct systrace_io *)data)->strio_pid;
-		if (!pid)
-			ret = EINVAL;
-		break;
-	case STRIOCGETCWD:
-		pid = *(pid_t *)data;
-		if (!pid)
-			ret = EINVAL;
-		break;
-	case STRIOCATTACH:
-	case STRIOCRESCWD:
-	case STRIOCPOLICY:
-		break;
-	case STRIOCREPLACE:
-		pid = ((struct systrace_replace *)data)->strr_pid;
-		if (!pid)
-			ret = EINVAL;
-		break;
-	default:
-		ret = EINVAL;
-		break;
-	}
-
-	if (ret)
-		return (ret);
-
-	systrace_lock();
-	SYSTRACE_LOCK(fst, curlwp);
-	systrace_unlock();
-	if (pid) {
-		strp = systrace_findpid(fst, pid);
-		if (strp == NULL) {
-			ret = ESRCH;
-			goto unlock;
-		}
-	}
-
-	switch (cmd) {
-	case STRIOCATTACH:
-		pid = *(pid_t *)data;
-		if (!pid)
-			ret = EINVAL;
-		else
-			ret = systrace_attach(fst, pid);
-		DPRINTF(("%s: attach to %u: %d\n", __func__, pid, ret));
-		break;
-	case STRIOCDETACH:
-		ret = systrace_detach(strp);
-		break;
-	case STRIOCREPORT:
-		SET(strp->flags, STR_PROC_REPORT);
-		break;
-	case STRIOCANSWER:
-		ret = systrace_answer(strp, (struct systrace_answer *)data);
-		break;
-	case STRIOCIO:
-		ret = systrace_io(strp, (struct systrace_io *)data);
-		break;
-	case STRIOCPOLICY:
-		ret = systrace_policy(fst, (struct systrace_policy *)data);
-		break;
-	case STRIOCREPLACE:
-		ret = systrace_preprepl(strp, (struct systrace_replace *)data);
-		break;
-	case STRIOCRESCWD:
-		if (!fst->fd_pid) {
-			ret = EINVAL;
-			break;
-		}
-#ifdef __NetBSD__
-		cwdp = p->p_cwdi;
-
-		/* Release cwd from other process */
-		if (cwdp->cwdi_cdir)
-			vrele(cwdp->cwdi_cdir);
-		if (cwdp->cwdi_rdir)
-			vrele(cwdp->cwdi_rdir);
-		cwdp->cwdi_cdir = fst->fd_cdir;
-		cwdp->cwdi_rdir = fst->fd_rdir;
-#else
-		fdp = p->p_fd;
-
-		/* Release cwd from other process */
-		if (fdp->fd_cdir)
-			vrele(fdp->fd_cdir);
-		if (fdp->fd_rdir)
-			vrele(fdp->fd_rdir);
-		/* This restores the cwd we had before */
-		fdp->fd_cdir = fst->fd_cdir;
-		fdp->fd_rdir = fst->fd_rdir;
-#endif
-		/* Note that we are normal again */
-		fst->fd_pid = 0;
-		fst->fd_cdir = fst->fd_rdir = NULL;
-		break;
-	case STRIOCGETCWD:
-		ret = systrace_getcwd(fst, strp);
-		break;
-	default:
-		ret = EINVAL;
-		break;
-	}
-
- unlock:
-	SYSTRACE_UNLOCK(fst, curlwp);
-
-	return (ret);
-}
-
-#ifdef __NetBSD__
-int
-systracef_poll(struct file *fp, int events, struct proc *p)
-{
-	struct fsystrace *fst = (struct fsystrace *)fp->f_data;
-	int revents = 0;
-
-	if ((events & (POLLIN | POLLRDNORM)) == 0)
-		return (revents);
-
-	systrace_lock();
-	SYSTRACE_LOCK(fst, p);
-	systrace_unlock();
-	if (!TAILQ_EMPTY(&fst->messages))
-		revents |= events & (POLLIN | POLLRDNORM);
-	if (revents == 0)
-		selrecord(p, &fst->si);
-	SYSTRACE_UNLOCK(fst, p);
-
-	return (revents);
-}
-#else
-int
-systracef_select(struct file *fp, int which, struct proc *p)
-{
-	struct fsystrace *fst = (struct fsystrace *)fp->f_data;
-	int ready = 0;
-
-	if (which != FREAD)
-		return (0);
-
-	systrace_lock();
-	SYSTRACE_LOCK(fst, p);
-	systrace_unlock();
-	ready = TAILQ_FIRST(&fst->messages) != NULL;
-	if (!ready)
-		selrecord(p, &fst->si);
-	SYSTRACE_UNLOCK(fst, p);
-
-	return (ready);
-}
-#endif /* __NetBSD__ */
-
-/* ARGSUSED */
-int
-systracef_close(struct file *fp, struct proc *p)
-{
-	struct fsystrace *fst = (struct fsystrace *)fp->f_data;
-	struct str_process *strp;
-	struct str_msgcontainer *cont;
-	struct str_policy *strpol;
-
-	systrace_lock();
-	SYSTRACE_LOCK(fst, curlwp);
-	systrace_unlock();
-
-	/* Untrace all processes */
-	for (strp = TAILQ_FIRST(&fst->processes); strp;
-	    strp = TAILQ_FIRST(&fst->processes)) {
-		struct proc *q = strp->proc;
-
-		systrace_detach(strp);
-		psignal(q, SIGKILL);
-	}
-
-	/* Clean up fork and exit messages */
-	for (cont = TAILQ_FIRST(&fst->messages); cont;
-	    cont = TAILQ_FIRST(&fst->messages)) {
-		TAILQ_REMOVE(&fst->messages, cont, next);
-		pool_put(&systr_msgcontainer_pl, cont);
-	}
-
-	/* Clean up all policies */
-	for (strpol = TAILQ_FIRST(&fst->policies); strpol;
-	    strpol = TAILQ_FIRST(&fst->policies))
-		systrace_closepolicy(fst, strpol);
-
-	/* Release vnodes */
-	if (fst->fd_cdir)
-		vrele(fst->fd_cdir);
-	if (fst->fd_rdir)
-		vrele(fst->fd_rdir);
-	SYSTRACE_UNLOCK(fst, curlwp);
-
-	FREE(fp->f_data, M_XDATA);
-	fp->f_data = NULL;
-
-	return (0);
-}
-
-void
-systrace_lock(void)
-{
-#ifdef __NetBSD__
-	lockmgr(&systrace_lck, LK_EXCLUSIVE, NULL);
-#else
-	lockmgr(&systrace_lck, LK_EXCLUSIVE, NULL, curlwp);
-#endif
-}
-
-void
-systrace_unlock(void)
-{
-#ifdef __NetBSD__
-	lockmgr(&systrace_lck, LK_RELEASE, NULL);
-#else
-	lockmgr(&systrace_lck, LK_RELEASE, NULL, curlwp);
-#endif
-}
-
-void
-systrace_init(void)
-{
-
-#ifndef __NetBSD__
-	pool_init(&systr_proc_pl, sizeof(struct str_process), 0, 0, 0,
-	    "strprocpl", NULL);
-	pool_init(&systr_policy_pl, sizeof(struct str_policy), 0, 0, 0,
-	    "strpolpl", NULL);
-	pool_init(&systr_msgcontainer_pl, sizeof(struct str_msgcontainer),
-	    0, 0, 0, "strmsgpl", NULL);
-#endif
-	lockinit(&systrace_lck, PLOCK, "systrace", 0, 0);
-}
-
-int
-systraceopen(dev_t dev, int flag, int mode, struct proc *p)
-{
-	struct fsystrace *fst;
-	struct file *fp;
-	int error, fd;
-
-	/* falloc() will use the descriptor for us. */
-	if ((error = falloc(p, &fp, &fd)) != 0)
-		return (error);
-
-	MALLOC(fst, struct fsystrace *, sizeof(*fst), M_XDATA, M_WAITOK);
-
-	memset(fst, 0, sizeof(struct fsystrace));
-	lockinit(&fst->lock, PLOCK, "systrace", 0, 0);
-
-	TAILQ_INIT(&fst->processes);
-	TAILQ_INIT(&fst->messages);
-	TAILQ_INIT(&fst->policies);
-
-	if (suser(p->p_ucred, &p->p_acflag) == 0)
-		fst->issuser = 1;
-	fst->p_ruid = p->p_cred->p_ruid;
-	fst->p_rgid = p->p_cred->p_rgid;
-
-	return fdclone(p, fp, fd, flag, &systracefops, fst);
-}
-
-void
-systrace_wakeup(struct fsystrace *fst)
-{
-	wakeup((caddr_t)fst);
-	selwakeup(&fst->si);
-}
-
-struct proc *
-systrace_find(struct str_process *strp)
-{
-	struct proc *proc;
-
-	if ((proc = pfind(strp->pid)) == NULL)
-		return (NULL);
-
-	if (proc != strp->proc)
-		return (NULL);
-
-	if (!ISSET(proc->p_flag, P_SYSTRACE))
-		return (NULL);
-
-	return (proc);
-}
-
-void
-systrace_sys_exit(struct proc *proc)
-{
-	struct str_process *strp;
-	struct fsystrace *fst;
-
-	systrace_lock();
-	strp = proc->p_systrace;
-	if (strp != NULL) {
-		fst = strp->parent;
-		SYSTRACE_LOCK(fst, curlwp);
-		systrace_unlock();
-
-		/* Insert Exit message */
-		systrace_msg_child(fst, strp, -1);
-
-		systrace_detach(strp);
-		SYSTRACE_UNLOCK(fst, curlwp);
-	} else
-		systrace_unlock();
-	CLR(proc->p_flag, P_SYSTRACE);
-}
-
-void
-systrace_sys_fork(struct proc *oldproc, struct proc *p)
-{
-	struct str_process *oldstrp, *strp;
-	struct fsystrace *fst;
-
-	systrace_lock();
-	oldstrp = oldproc->p_systrace;
-	if (oldstrp == NULL) {
-		systrace_unlock();
-		return;
-	}
-
-	fst = oldstrp->parent;
-	SYSTRACE_LOCK(fst, curlwp);
-	systrace_unlock();
-
-	if (systrace_insert_process(fst, p, &strp)) {
-		/* We need to kill the child */
-		psignal(p, SIGKILL);
-		goto out;
-	}
-
-	/* Reference policy */
-	if ((strp->policy = oldstrp->policy) != NULL)
-		strp->policy->refcount++;
-
-	/* Insert fork message */
-	systrace_msg_child(fst, oldstrp, p->p_pid);
- out:
-	SYSTRACE_UNLOCK(fst, curlwp);
-}
-
-int
-systrace_enter(struct proc *p, register_t code, void *v)
-{
-	const struct sysent *callp;
-	struct str_process *strp;
-	struct str_policy *strpolicy;
-	struct fsystrace *fst;
-	struct pcred *pc;
-	int policy, error = 0, maycontrol = 0, issuser = 0;
-	size_t argsize;
-
-	systrace_lock();
-	strp = p->p_systrace;
-	if (strp == NULL) {
-		systrace_unlock();
-		return (EINVAL);
-	}
-
-	KASSERT(strp->proc == p);
-
-	fst = strp->parent;
-
-	SYSTRACE_LOCK(fst, p);
-	systrace_unlock();
-
-	/*
-	 * We can not monitor a SUID process unless we are root,
-	 * but we wait until it executes something unprivileged.
-	 * A non-root user may only monitor if the real uid and
-	 * real gid match the monitored process.  Changing the
-	 * uid or gid causes P_SUGID to be set.
-	 */
-	if (fst->issuser) {
-		maycontrol = 1;
-		issuser = 1;
-	} else if (!(p->p_flag & P_SUGID)) {
-		maycontrol = fst->p_ruid == p->p_cred->p_ruid &&
-		    fst->p_rgid == p->p_cred->p_rgid;
-	}
-
-	if (!maycontrol) {
-		policy = SYSTR_POLICY_PERMIT;
-	} else {
-		/* Find out current policy */
-		if ((strpolicy = strp->policy) == NULL)
-			policy = SYSTR_POLICY_ASK;
-		else {
-			if (code >= strpolicy->nsysent)
-				policy = SYSTR_POLICY_NEVER;
-			else
-				policy = strpolicy->sysent[code];
-		}
-	}
-
-	callp = p->p_emul->e_sysent + code;
-
-	/* Fast-path */
-	if (policy != SYSTR_POLICY_ASK) {
-		if (policy != SYSTR_POLICY_PERMIT) {
-			if (policy > 0)
-				error = policy;
-			else
-				error = EPERM;
-		}
-		strp->oldemul = NULL;
-		systrace_replacefree(strp);
-		SYSTRACE_UNLOCK(fst, p);
-		return (error);
-	}
-
-	/* Get the (adjusted) argsize */
-	argsize = callp->sy_argsize;
-#ifdef _LP64
-	if (p->p_flag & P_32)
-		argsize = argsize << 1;
-#endif
-
-	/* Puts the current process to sleep, return unlocked */
-	error = systrace_msg_ask(fst, strp, code, argsize, v);
-
-	/* lock has been released in systrace_msg_ask() */
-	fst = NULL;
-	/* We might have detached by now for some reason */
-	if (!error && (strp = p->p_systrace) != NULL) {
-		/* XXX - do I need to lock here? */
-		if (strp->answer == SYSTR_POLICY_NEVER) {
-			error = strp->error;
-			systrace_replacefree(strp);
-		} else {
-			if (ISSET(strp->flags, STR_PROC_SYSCALLRES)) {
-#ifndef __NetBSD__
-				CLR(strp->flags, STR_PROC_SYSCALLRES);
-#endif
-			}
-			/* Replace the arguments if necessary */
-			if (strp->replace != NULL) {
-				error = systrace_replace(strp, argsize, v);
-			}
-		}
-	}
-
-	systrace_lock();
-	if ((strp = p->p_systrace) == NULL)
-		goto out;
-
-	if (error) {
-		strp->oldemul = NULL;
-		goto out;
-	}
-
-	pc = p->p_cred;
-	strp->oldemul = p->p_emul;
-	strp->olduid = pc->p_ruid;
-	strp->oldgid = pc->p_rgid;
-
-	/* Elevate privileges as desired */
-	if (issuser) {
-		if (ISSET(strp->flags, STR_PROC_SETEUID)) {
-			strp->saveuid = systrace_seteuid(p, strp->seteuid);
-			SET(strp->flags, STR_PROC_DIDSETUGID);
-		}
-		if (ISSET(strp->flags, STR_PROC_SETEGID)) {
-			strp->savegid = systrace_setegid(p, strp->setegid);
-			SET(strp->flags, STR_PROC_DIDSETUGID);
-		}
-	} else
-		CLR(strp->flags,
-		    STR_PROC_SETEUID|STR_PROC_SETEGID|STR_PROC_DIDSETUGID);
-
- out:
-	systrace_unlock();
-	return (error);
-}
-
-void
-systrace_exit(struct proc *p, register_t code, void *v, register_t retval[],
-    int error)
-{
-	const struct sysent *callp;
-	struct str_process *strp;
-	struct fsystrace *fst;
-	struct pcred *pc;
-
-	/* Report change in emulation */
-	systrace_lock();
-	strp = p->p_systrace;
-	if (strp == NULL || strp->oldemul == NULL) {
-		systrace_unlock();
-		return;
-	}
-	DPRINTF(("exit syscall %lu, oldemul %p\n", (u_long)code, strp->oldemul));
-
-	/* Return to old privileges */
-	pc = p->p_cred;
-	if (ISSET(strp->flags, STR_PROC_DIDSETUGID)) {
-		if (ISSET(strp->flags, STR_PROC_SETEUID)) {
-			if (pc->pc_ucred->cr_uid == strp->seteuid)
-				systrace_seteuid(p, strp->saveuid);
-		}
-		if (ISSET(strp->flags, STR_PROC_SETEGID)) {
-			if (pc->pc_ucred->cr_gid == strp->setegid)
-				systrace_setegid(p, strp->savegid);
-		}
-	}
-	CLR(strp->flags,
-	    STR_PROC_SETEUID|STR_PROC_SETEGID|STR_PROC_DIDSETUGID);
-
-	systrace_replacefree(strp);
-
-	if (p->p_flag & P_SUGID) {
-		if ((fst = strp->parent) == NULL || !fst->issuser) {
-			systrace_unlock();
-			return;
-		}
-	}
-
-	/* See if we should force a report */
-	if (ISSET(strp->flags, STR_PROC_REPORT)) {
-		CLR(strp->flags, STR_PROC_REPORT);
-		strp->oldemul = NULL;
-	}
-
-	if (p->p_emul != strp->oldemul && strp != NULL) {
-		fst = strp->parent;
-		SYSTRACE_LOCK(fst, p);
-		systrace_unlock();
-
-		/* Old policy is without meaning now */
-		if (strp->policy) {
-			systrace_closepolicy(fst, strp->policy);
-			strp->policy = NULL;
-		}
-		systrace_msg_emul(fst, strp);
-	} else
-		systrace_unlock();
-
-	/* Report if effective uid or gid changed */
-	systrace_lock();
-	strp = p->p_systrace;
-	if (strp != NULL && (strp->olduid != p->p_cred->p_ruid ||
-	    strp->oldgid != p->p_cred->p_rgid)) {
-
-		fst = strp->parent;
-		SYSTRACE_LOCK(fst, p);
-		systrace_unlock();
-
-		systrace_msg_ugid(fst, strp);
-	} else
-		systrace_unlock();
-
-	/* Report result from system call */
-	systrace_lock();
-	strp = p->p_systrace;
-	if (strp != NULL && ISSET(strp->flags, STR_PROC_SYSCALLRES)) {
-		size_t argsize;
-
-		CLR(strp->flags, STR_PROC_SYSCALLRES);
-		fst = strp->parent;
-		SYSTRACE_LOCK(fst, p);
-		systrace_unlock();
-		DPRINTF(("will ask syscall %lu, strp %p\n", (u_long)code, strp));
-
-		/* Get the (adjusted) argsize */
-		callp = p->p_emul->e_sysent + code;
-		argsize = callp->sy_argsize;
-#ifdef _LP64
-		if (p->p_flag & P_32)
-			argsize = argsize << 1;
-#endif
-
-		systrace_msg_result(fst, strp, error, code, argsize, v, retval);
-	} else {
-		DPRINTF(("will not ask syscall %lu, strp %p\n", (u_long)code, strp));
-		systrace_unlock();
-	}
-}
-
-uid_t
-systrace_seteuid(struct proc *p,  uid_t euid)
-{
-	struct pcred *pc = p->p_cred;
-	uid_t oeuid = pc->pc_ucred->cr_uid;
-
-	if (pc->pc_ucred->cr_uid == euid)
-		return (oeuid);
-
-	/*
-	 * Copy credentials so other references do not see our changes.
-	 */
-	pc->pc_ucred = crcopy(pc->pc_ucred);
-	pc->pc_ucred->cr_uid = euid;
-	p_sugid(p);
-
-	return (oeuid);
-}
-
-gid_t
-systrace_setegid(struct proc *p,  gid_t egid)
-{
-	struct pcred *pc = p->p_cred;
-	gid_t oegid = pc->pc_ucred->cr_gid;
-
-	if (pc->pc_ucred->cr_gid == egid)
-		return (oegid);
-
-	/*
-	 * Copy credentials so other references do not see our changes.
-	 */
-	pc->pc_ucred = crcopy(pc->pc_ucred);
-	pc->pc_ucred->cr_gid = egid;
-	p_sugid(p);
-
-	return (oegid);
-}
-
-/* Called with fst locked */
-
-int
-systrace_answer(struct str_process *strp, struct systrace_answer *ans)
-{
-	int error = 0;
-
-	DPRINTF(("%s: %u: policy %d\n", __func__,
-	    ans->stra_pid, ans->stra_policy));
-
-	if (!POLICY_VALID(ans->stra_policy)) {
-		error = EINVAL;
-		goto out;
-	}
-
-	/* Check if answer is in sync with us */
-	if (ans->stra_seqnr != strp->seqnr) {
-		error = ESRCH;
-		goto out;
-	}
-
-	if ((error = systrace_processready(strp)) != 0)
-		goto out;
-
-	strp->answer = ans->stra_policy;
-	strp->error = ans->stra_error;
-	if (!strp->error)
-		strp->error = EPERM;
-	if (ISSET(ans->stra_flags, SYSTR_FLAGS_RESULT))
-		SET(strp->flags, STR_PROC_SYSCALLRES);
-
-	/* See if we should elevate privileges for this system call */
-	if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEUID)) {
-		SET(strp->flags, STR_PROC_SETEUID);
-		strp->seteuid = ans->stra_seteuid;
-	}
-	if (ISSET(ans->stra_flags, SYSTR_FLAGS_SETEGID)) {
-		SET(strp->flags, STR_PROC_SETEGID);
-		strp->setegid = ans->stra_setegid;
-	}
-
-
-	/* Clearing the flag indicates to the process that it woke up */
-	CLR(strp->flags, STR_PROC_WAITANSWER);
-	wakeup(strp);
- out:
-
-	return (error);
-}
-
-int
-systrace_policy(struct fsystrace *fst, struct systrace_policy *pol)
-{
-	struct str_policy *strpol;
-	struct str_process *strp;
-
-	switch(pol->strp_op) {
-	case SYSTR_POLICY_NEW:
-		DPRINTF(("%s: new, ents %d\n", __func__,
-			    pol->strp_maxents));
-		if (pol->strp_maxents <= 0 || pol->strp_maxents > 1024)
-			return (EINVAL);
-		strpol = systrace_newpolicy(fst, pol->strp_maxents);
-		if (strpol == NULL)
-			return (ENOBUFS);
-		pol->strp_num = strpol->nr;
-		break;
-	case SYSTR_POLICY_ASSIGN:
-		DPRINTF(("%s: %d -> pid %d\n", __func__,
-			    pol->strp_num, pol->strp_pid));
-
-		/* Find right policy by number */
-		TAILQ_FOREACH(strpol, &fst->policies, next)
-		    if (strpol->nr == pol->strp_num)
-			    break;
-		if (strpol == NULL)
-			return (EINVAL);
-
-		strp = systrace_findpid(fst, pol->strp_pid);
-		if (strp == NULL)
-			return (EINVAL);
-
-		/* Check that emulation matches */
-		if (strpol->emul && strpol->emul != strp->proc->p_emul)
-			return (EINVAL);
-
-		if (strp->policy)
-			systrace_closepolicy(fst, strp->policy);
-		strp->policy = strpol;
-		strpol->refcount++;
-
-		/* Record emulation for this policy */
-		if (strpol->emul == NULL)
-			strpol->emul = strp->proc->p_emul;
-
-		break;
-	case SYSTR_POLICY_MODIFY:
-		DPRINTF(("%s: %d: code %d -> policy %d\n", __func__,
-		    pol->strp_num, pol->strp_code, pol->strp_policy));
-		if (!POLICY_VALID(pol->strp_policy))
-			return (EINVAL);
-		TAILQ_FOREACH(strpol, &fst->policies, next)
-		    if (strpol->nr == pol->strp_num)
-			    break;
-		if (strpol == NULL)
-			return (EINVAL);
-		if (pol->strp_code < 0 || pol->strp_code >= strpol->nsysent)
-			return (EINVAL);
-		strpol->sysent[pol->strp_code] = pol->strp_policy;
-		break;
-	default:
-		return (EINVAL);
-	}
-
-	return (0);
-}
-
-int
-systrace_processready(struct str_process *strp)
-{
-	if (ISSET(strp->flags, STR_PROC_ONQUEUE))
-		return (EBUSY);
-
-	if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
-		return (EBUSY);
-
-	/* XXX - ignore until systrace knows about lwps. :-(
-	if (strp->proc->p_stat != LSSLEEP)
-		return (EBUSY);
-	*/
-	return (0);
-}
-
-int
-systrace_getcwd(struct fsystrace *fst, struct str_process *strp)
-{
-#ifdef __NetBSD__
-	struct cwdinfo *mycwdp, *cwdp;
-#else
-	struct filedesc *myfdp, *fdp;
-#endif
-	int error;
-
-	DPRINTF(("%s: %d\n", __func__, strp->pid));
-
-	error = systrace_processready(strp);
-	if (error)
-		return (error);
-
-#ifdef __NetBSD__
-	mycwdp = curproc->p_cwdi;
-	cwdp = strp->proc->p_cwdi;
-	if (mycwdp == NULL || cwdp == NULL)
-		return (EINVAL);
-
-	/* Store our current values */
-	fst->fd_pid = strp->pid;
-	fst->fd_cdir = mycwdp->cwdi_cdir;
-	fst->fd_rdir = mycwdp->cwdi_rdir;
-
-	if ((mycwdp->cwdi_cdir = cwdp->cwdi_cdir) != NULL)
-		VREF(mycwdp->cwdi_cdir);
-	if ((mycwdp->cwdi_rdir = cwdp->cwdi_rdir) != NULL)
-		VREF(mycwdp->cwdi_rdir);
-#else
-	myfdp = curlwp->p_fd;
-	fdp = strp->proc->p_fd;
-	if (myfdp == NULL || fdp == NULL)
-		return (EINVAL);
-
-	/* Store our current values */
-	fst->fd_pid = strp->pid;
-	fst->fd_cdir = myfdp->fd_cdir;
-	fst->fd_rdir = myfdp->fd_rdir;
-
-	if ((myfdp->fd_cdir = fdp->fd_cdir) != NULL)
-		VREF(myfdp->fd_cdir);
-	if ((myfdp->fd_rdir = fdp->fd_rdir) != NULL)
-		VREF(myfdp->fd_rdir);
-#endif
-
-	return (0);
-}
-
-int
-systrace_io(struct str_process *strp, struct systrace_io *io)
-{
-	struct proc *p = curproc, *t = strp->proc;
-	struct uio uio;
-	struct iovec iov;
-	int error = 0;
-
-	DPRINTF(("%s: %u: %p(%lu)\n", __func__,
-	    io->strio_pid, io->strio_offs, (u_long)io->strio_len));
-
-	switch (io->strio_op) {
-	case SYSTR_READ:
-		uio.uio_rw = UIO_READ;
-		break;
-	case SYSTR_WRITE:
-		uio.uio_rw = UIO_WRITE;
-		break;
-	default:
-		return (EINVAL);
-	}
-
-	error = systrace_processready(strp);
-	if (error)
-		goto out;
-
-	iov.iov_base = io->strio_addr;
-	iov.iov_len = io->strio_len;
-	uio.uio_iov = &iov;
-	uio.uio_iovcnt = 1;
-	uio.uio_offset = (off_t)(unsigned long)io->strio_offs;
-	uio.uio_resid = io->strio_len;
-	uio.uio_segflg = UIO_USERSPACE;
-	uio.uio_procp = p;
-
-#ifdef __NetBSD__
-	error = process_domem(p, t, &uio);
-#else
-	error = procfs_domem(p, t, NULL, &uio);
-#endif
-	io->strio_len -= uio.uio_resid;
- out:
-
-	return (error);
-}
-
-int
-systrace_attach(struct fsystrace *fst, pid_t pid)
-{
-	int error = 0;
-	struct proc *proc, *p = curproc;
-
-	if ((proc = pfind(pid)) == NULL) {
-		error = ESRCH;
-		goto out;
-	}
-
-	if (ISSET(proc->p_flag, P_INEXEC)) {
-		error = EAGAIN;
-		goto out;
-	}
-
-	/*
-	 * You can't attach to a process if:
-	 *	(1) it's the process that's doing the attaching,
-	 */
-	if (proc->p_pid == p->p_pid) {
-		error = EINVAL;
-		goto out;
-	}
-
-	/*
-	 *	(2) it's a system process
-	 */
-	if (ISSET(proc->p_flag, P_SYSTEM)) {
-		error = EPERM;
-		goto out;
-	}
-
-	/*
-	 *	(3) it's being traced already
-	 */
-	if (ISSET(proc->p_flag, P_SYSTRACE)) {
-		error = EBUSY;
-		goto out;
-	}
-
-	/*
-	 *	(4) it's not owned by you, or the last exec
-	 *	    gave us setuid/setgid privs (unless
-	 *	    you're root), or...
-	 *
-	 *      [Note: once P_SUGID gets set in execve(), it stays
-	 *	set until the process does another execve(). Hence
-	 *	this prevents a setuid process which revokes its
-	 *	special privileges using setuid() from being
-	 *	traced. This is good security.]
-	 */
-	if ((proc->p_cred->p_ruid != p->p_cred->p_ruid ||
-		ISSET(proc->p_flag, P_SUGID)) &&
-	    (error = suser(p->p_ucred, &p->p_acflag)) != 0)
-		goto out;
-
-	/*
-	 *	(5) ...it's init, which controls the security level
-	 *	    of the entire system, and the system was not
-	 *          compiled with permanently insecure mode turned
-	 *	    on.
-	 */
-	if ((proc->p_pid == 1) && (securelevel > -1)) {
-		error = EPERM;
-		goto out;
-	}
-
-	error = systrace_insert_process(fst, proc, NULL);
-
-#if defined(__NetBSD__) && defined(__HAVE_SYSCALL_INTERN)
-	/*
-	 * Make sure we're using the version of the syscall handler that
-	 * has systrace hooks.
-	 */
-	if (!error)
-		(*proc->p_emul->e_syscall_intern)(proc);
-#endif
- out:
-	return (error);
-}
-
-/* Prepare to replace arguments */
-
-int
-systrace_preprepl(struct str_process *strp, struct systrace_replace *repl)
-{
-	size_t len;
-	int i, ret = 0;
-
-	ret = systrace_processready(strp);
-	if (ret)
-		return (ret);
-
-	systrace_replacefree(strp);
-
-	if (repl->strr_nrepl < 0 || repl->strr_nrepl > SYSTR_MAXARGS)
-		return (EINVAL);
-
-	for (i = 0, len = 0; i < repl->strr_nrepl; i++) {
-		if (repl->strr_argind[i] < 0 ||
-		    repl->strr_argind[i] >= SYSTR_MAXARGS)
-			return (EINVAL);
-		if (repl->strr_offlen[i] == 0)
-			continue;
-		len += repl->strr_offlen[i];
-		if (repl->strr_offlen[i] > SYSTR_MAXREPLEN ||
-		    repl->strr_off[i] > SYSTR_MAXREPLEN ||
-		    len > SYSTR_MAXREPLEN)
-			return (EINVAL);
-		if (repl->strr_offlen[i] + repl->strr_off[i] > len)
-			return (EINVAL);
-	}
-
-	/* Make sure that the length adds up */
-	if (repl->strr_len != len)
-		return (EINVAL);
-
-	/* Check against a maximum length */
-	if (repl->strr_len > SYSTR_MAXREPLEN)
-		return (EINVAL);
-
-	strp->replace = (struct systrace_replace *)
-	    malloc(sizeof(struct systrace_replace) + len, M_XDATA, M_WAITOK);
-
-	memcpy(strp->replace, repl, sizeof(struct systrace_replace));
-	ret = copyin(repl->strr_base, strp->replace + 1, len);
-	if (ret) {
-		free(strp->replace, M_XDATA);
-		strp->replace = NULL;
-		return (ret);
-	}
-
-	/* Adjust the offset */
-	repl = strp->replace;
-	repl->strr_base = (caddr_t)(repl + 1);
-
-	return (0);
-}
-
-/*
- * Replace the arguments with arguments from the monitoring process.
- */
-
-int
-systrace_replace(struct str_process *strp, size_t argsize, register_t args[])
-{
-	struct proc *p = strp->proc;
-	struct systrace_replace *repl = strp->replace;
-	caddr_t sg, kdata, udata, kbase, ubase;
-	int i, maxarg, ind, ret = 0;
-
-	maxarg = argsize/sizeof(register_t);
-#ifdef __NetBSD__
-	sg = stackgap_init(p, 0);
-	ubase = stackgap_alloc(p, &sg, repl->strr_len);
-#else
-	sg = stackgap_init(p->p_emul);
-	ubase = stackgap_alloc(&sg, repl->strr_len);
-#endif
-	if (ubase == NULL) {
-		ret = EINVAL;
-		goto out;
-	}
-
-	kbase = repl->strr_base;
-	for (i = 0; i < maxarg && i < repl->strr_nrepl; i++) {
-		ind = repl->strr_argind[i];
-		if (ind < 0 || ind >= maxarg) {
-			ret = EINVAL;
-			goto out;
-		}
-		if (repl->strr_offlen[i] == 0) {
-			args[ind] = repl->strr_off[i];
-			continue;
-		}
-		kdata = kbase + repl->strr_off[i];
-		udata = ubase + repl->strr_off[i];
-		if (repl->strr_flags[i] & SYSTR_NOLINKS) {
-			ret = systrace_fname(strp, kdata, repl->strr_offlen[i]);
-			if (ret != 0)
-				goto out;
-		}
-		if (copyout(kdata, udata, repl->strr_offlen[i])) {
-			ret = EINVAL;
-			goto out;
-		}
-
-		/* Replace the argument with the new address */
-		args[ind] = (register_t)(intptr_t)udata;
-	}
-
- out:
-	return (ret);
-}
-
-int
-systrace_fname(struct str_process *strp, caddr_t kdata, size_t len)
-{
-
-	if (strp->nfname >= SYSTR_MAXFNAME || len < 2)
-		return EINVAL;
-
-	strp->fname[strp->nfname] = kdata;
-	strp->fname[strp->nfname][len - 1] = '\0';
-	strp->nfname++;
-
-	return 0;
-}
-
-void
-systrace_replacefree(struct str_process *strp)
-{
-
-	if (strp->replace != NULL) {
-		free(strp->replace, M_XDATA);
-		strp->replace = NULL;
-	}
-	while (strp->nfname > 0) {
-		strp->nfname--;
-		strp->fname[strp->nfname] = NULL;
-	}
-}
-
-void
-systrace_namei(struct nameidata *ndp)
-{
-	struct str_process *strp;
-	struct fsystrace *fst;
-	struct componentname *cnp = &ndp->ni_cnd;
-	size_t i;
-
-	systrace_lock();
-	strp = cnp->cn_proc->p_systrace;
-	if (strp != NULL) {
-		fst = strp->parent;
-		SYSTRACE_LOCK(fst, curlwp);
-		systrace_unlock();
-
-		for (i = 0; i < strp->nfname; i++) {
-			if (strcmp(cnp->cn_pnbuf, strp->fname[i]) == 0) {
-				/* ELOOP if namei() tries to readlink */
-				ndp->ni_loopcnt = MAXSYMLINKS;
-				cnp->cn_flags &= ~FOLLOW;
-				cnp->cn_flags |= NOFOLLOW;
-				break;
-			}
-		}
-		SYSTRACE_UNLOCK(fst, curlwp);
-	} else
-		systrace_unlock();
-}
-
-struct str_process *
-systrace_findpid(struct fsystrace *fst, pid_t pid)
-{
-	struct str_process *strp;
-	struct proc *proc = NULL;
-
-	TAILQ_FOREACH(strp, &fst->processes, next)
-	    if (strp->pid == pid)
-		    break;
-
-	if (strp == NULL)
-		return (NULL);
-
-	proc = systrace_find(strp);
-
-	return (proc ? strp : NULL);
-}
-
-int
-systrace_detach(struct str_process *strp)
-{
-	struct proc *proc;
-	struct fsystrace *fst = NULL;
-	int error = 0;
-
-	DPRINTF(("%s: Trying to detach from %d\n", __func__, strp->pid));
-
-	if ((proc = systrace_find(strp)) != NULL) {
-		CLR(proc->p_flag, P_SYSTRACE);
-		proc->p_systrace = NULL;
-	} else
-		error = ESRCH;
-
-	if (ISSET(strp->flags, STR_PROC_WAITANSWER)) {
-		CLR(strp->flags, STR_PROC_WAITANSWER);
-		wakeup(strp);
-	}
-
-	fst = strp->parent;
-	systrace_wakeup(fst);
-
-	TAILQ_REMOVE(&fst->processes, strp, next);
-	fst->nprocesses--;
-
-	if (strp->policy)
-		systrace_closepolicy(fst, strp->policy);
-	systrace_replacefree(strp);
-	pool_put(&systr_proc_pl, strp);
-
-	return (error);
-}
-
-void
-systrace_closepolicy(struct fsystrace *fst, struct str_policy *policy)
-{
-	if (--policy->refcount)
-		return;
-
-	fst->npolicies--;
-
-	if (policy->nsysent)
-		free(policy->sysent, M_XDATA);
-
-	TAILQ_REMOVE(&fst->policies, policy, next);
-
-	pool_put(&systr_policy_pl, policy);
-}
-
-
-int
-systrace_insert_process(struct fsystrace *fst, struct proc *proc,
-    struct str_process **pstrp)
-{
-	struct str_process *strp;
-
-	strp = pool_get(&systr_proc_pl, PR_NOWAIT);
-	if (strp == NULL)
-		return (ENOBUFS);
-
-	memset((caddr_t)strp, 0, sizeof(struct str_process));
-	strp->pid = proc->p_pid;
-	strp->proc = proc;
-	strp->parent = fst;
-
-	TAILQ_INSERT_TAIL(&fst->processes, strp, next);
-	fst->nprocesses++;
-
-	proc->p_systrace = strp;
-	SET(proc->p_flag, P_SYSTRACE);
-
-	/* Pass the new pointer back to the caller */
-	if (pstrp != NULL)
-		*pstrp = strp;
-
-	return (0);
-}
-
-struct str_policy *
-systrace_newpolicy(struct fsystrace *fst, int maxents)
-{
-	struct str_policy *pol;
-	int i;
-
-	if (fst->npolicies > SYSTR_MAX_POLICIES && !fst->issuser) {
-		struct str_policy *tmp;
-
-		/* Try to find a policy for freeing */
-		TAILQ_FOREACH(tmp, &fst->policies, next) {
-			if (tmp->refcount == 1)
-				break;
-		}
-
-		if (tmp == NULL)
-			return (NULL);
-
-		/* Notify userland about freed policy */
-		systrace_msg_policyfree(fst, tmp);
-		/* Free this policy */
-		systrace_closepolicy(fst, tmp);
-	}
-
-	pol = pool_get(&systr_policy_pl, PR_NOWAIT);
-	if (pol == NULL)
-		return (NULL);
-
-	DPRINTF(("%s: allocating %d -> %lu\n", __func__,
-		     maxents, (u_long)maxents * sizeof(int)));
-
-	memset((caddr_t)pol, 0, sizeof(struct str_policy));
-
-	pol->sysent = (u_char *)malloc(maxents * sizeof(u_char),
-	    M_XDATA, M_WAITOK);
-	pol->nsysent = maxents;
-	for (i = 0; i < maxents; i++)
-		pol->sysent[i] = SYSTR_POLICY_ASK;
-
-	fst->npolicies++;
-	pol->nr = fst->npolicynr++;
-	pol->refcount = 1;
-
-	TAILQ_INSERT_TAIL(&fst->policies, pol, next);
-
-	return (pol);
-}
-
-int
-systrace_msg_ask(struct fsystrace *fst, struct str_process *strp,
-    int code, size_t argsize, register_t args[])
-{
-	struct str_message msg;
-	struct str_msg_ask *msg_ask = &msg.msg_data.msg_ask;
-	int i;
-
-	msg_ask->code = code;
-	msg_ask->argsize = argsize;
-	for (i = 0; i < (argsize/sizeof(register_t)) && i < SYSTR_MAXARGS; i++)
-		msg_ask->args[i] = args[i];
-
-	return (systrace_make_msg(strp, SYSTR_MSG_ASK, &msg));
-}
-
-int
-systrace_msg_result(struct fsystrace *fst, struct str_process *strp,
-    int error, int code, size_t argsize, register_t args[], register_t rval[])
-{
-	struct str_message msg;
-	struct str_msg_ask *msg_ask = &msg.msg_data.msg_ask;
-	int i;
-
-	msg_ask->code = code;
-	msg_ask->argsize = argsize;
-	msg_ask->result = error;
-	for (i = 0; i < (argsize/sizeof(register_t)) && i < SYSTR_MAXARGS; i++)
-		msg_ask->args[i] = args[i];
-
-	msg_ask->rval[0] = rval[0];
-	msg_ask->rval[1] = rval[1];
-
-	return (systrace_make_msg(strp, SYSTR_MSG_RES, &msg));
-}
-
-int
-systrace_msg_emul(struct fsystrace *fst, struct str_process *strp)
-{
-	struct str_message msg;
-	struct str_msg_emul *msg_emul = &msg.msg_data.msg_emul;
-	struct proc *p = strp->proc;
-
-	memcpy(msg_emul->emul, p->p_emul->e_name, SYSTR_EMULEN);
-
-	return (systrace_make_msg(strp, SYSTR_MSG_EMUL, &msg));
-}
-
-int
-systrace_msg_ugid(struct fsystrace *fst, struct str_process *strp)
-{
-	struct str_message msg;
-	struct str_msg_ugid *msg_ugid = &msg.msg_data.msg_ugid;
-	struct proc *p = strp->proc;
-
-	msg_ugid->uid = p->p_cred->p_ruid;
-	msg_ugid->gid = p->p_cred->p_rgid;
-
-	return (systrace_make_msg(strp, SYSTR_MSG_UGID, &msg));
-}
-
-int
-systrace_make_msg(struct str_process *strp, int type, struct str_message *tmsg)
-{
-	struct str_msgcontainer *cont;
-	struct str_message *msg;
-	struct fsystrace *fst = strp->parent;
-	int st;
-
-	cont = pool_get(&systr_msgcontainer_pl, PR_WAITOK);
-	memset(cont, 0, sizeof(struct str_msgcontainer));
-	cont->strp = strp;
-
-	msg = &cont->msg;
-
-	/* Copy the already filled in fields */
-	memcpy(&msg->msg_data, &tmsg->msg_data, sizeof(msg->msg_data));
-
-	/* Add the extra fields to the message */
-	msg->msg_seqnr = ++strp->seqnr;
-	msg->msg_type = type;
-	msg->msg_pid = strp->pid;
-	if (strp->policy)
-		msg->msg_policy = strp->policy->nr;
-	else
-		msg->msg_policy = -1;
-
-	SET(strp->flags, STR_PROC_WAITANSWER);
-	if (ISSET(strp->flags, STR_PROC_ONQUEUE))
-		goto out;
-
-	TAILQ_INSERT_TAIL(&fst->messages, cont, next);
-	SET(strp->flags, STR_PROC_ONQUEUE);
-
- out:
-	systrace_wakeup(fst);
-
-	/* Release the lock - XXX */
-	SYSTRACE_UNLOCK(fst, strp->proc);
-
-	while (1) {
-		int f;
-		f = curlwp->l_flag & L_SA;
-		curlwp->l_flag &= ~L_SA;
-		st = tsleep(strp, PWAIT, "systrmsg", 0);
-		curlwp->l_flag |= f;
-		if (st != 0)
-			return (ERESTART);
-		/* If we detach, then everything is permitted */
-		if ((strp = curproc->p_systrace) == NULL)
-			return (0);
-		if (!ISSET(strp->flags, STR_PROC_WAITANSWER))
-			break;
-	}
-
-	return (0);
-}
-
-int
-systrace_msg_child(struct fsystrace *fst, struct str_process *strp, pid_t npid)
-{
-	struct str_msgcontainer *cont;
-	struct str_message *msg;
-	struct str_msg_child *msg_child;
-
-	cont = pool_get(&systr_msgcontainer_pl, PR_WAITOK);
-	memset(cont, 0, sizeof(struct str_msgcontainer));
-	cont->strp = strp;
-
-	msg = &cont->msg;
-
-	DPRINTF(("%s: %p: pid %d -> pid %d\n", __func__,
-		    msg, strp->pid, npid));
-
-	msg_child = &msg->msg_data.msg_child;
-
-	msg->msg_type = SYSTR_MSG_CHILD;
-	msg->msg_pid = strp->pid;
-	if (strp->policy)
-		msg->msg_policy = strp->policy->nr;
-	else
-		msg->msg_policy = -1;
-	msg_child->new_pid = npid;
-
-	TAILQ_INSERT_TAIL(&fst->messages, cont, next);
-
-	systrace_wakeup(fst);
-
-	return (0);
-}
-
-int
-systrace_msg_policyfree(struct fsystrace *fst, struct str_policy *strpol)
-{
-	struct str_msgcontainer *cont;
-	struct str_message *msg;
-
-	cont = pool_get(&systr_msgcontainer_pl, PR_WAITOK);
-	memset(cont, 0, sizeof(struct str_msgcontainer));
-
-	msg = &cont->msg;
-
-	DPRINTF(("%s: free %d\n", __func__, strpol->nr));
-
-	msg->msg_type = SYSTR_MSG_POLICYFREE;
-	msg->msg_policy = strpol->nr;
-
-	TAILQ_INSERT_TAIL(&fst->messages, cont, next);
-
-	systrace_wakeup(fst);
-
-	return (0);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_time.c mult-netbsd-3.1/sys/kern/kern_time.c
--- NetBSD-3.1/sys/kern/kern_time.c	2005-12-07 09:53:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/kern_time.c	2007-11-18 14:10:51.000000000 +0000
@@ -89,6 +89,8 @@
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
 #if defined(NFS) || defined(NFSSERVER)
@@ -99,7 +101,14 @@
 
 #include <machine/cpu.h>
 
-static void timerupcall(struct lwp *, void *);
+
+POOL_INIT(ptimer_pool, sizeof(struct ptimer), 
+		0, 0, 0, "ptimerpl", &pool_allocator_nointr);
+
+
+static void 
+timerupcall(struct lwp *, void *);
+
 
 /* Time of day and interval timer support.
  *
@@ -134,10 +143,13 @@
 		struct proc *p = curproc;
 		struct proc *pp = p->p_pptr;
 		log(LOG_WARNING, "pid %d (%s) "
-		    "invoked by uid %d ppid %d (%s) "
-		    "tried to set clock forward to %ld\n",
-		    p->p_pid, p->p_comm, pp->p_ucred->cr_uid,
-		    pp->p_pid, pp->p_comm, (long)tv->tv_sec);
+				"invoked by uid %d ppid %d (%s) "
+				"tried to set clock forward to %ld\n",
+				p->p_pid, p->p_comm, 
+				pp ? pp->p_ucred->cr_uid : 0,
+				pp ? pp->p_pid : 0,
+				pp ? pp->p_comm : "(null)",
+				(long)tv->tv_sec);
 		return (EPERM);
 	}
 	/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/kern_verifiedexec.c mult-netbsd-3.1/sys/kern/kern_verifiedexec.c
--- NetBSD-3.1/sys/kern/kern_verifiedexec.c	2005-10-15 18:33:31.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/kern_verifiedexec.c	2007-11-23 17:59:22.000000000 +0000
@@ -59,6 +59,8 @@
 int veriexec_verbose = 0;
 int veriexec_strict = 0;
 
+/* FIXME - instances */
+
 char *veriexec_fp_names = NULL;
 unsigned int veriexec_name_max = 0;
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/subr_log.c mult-netbsd-3.1/sys/kern/subr_log.c
--- NetBSD-3.1/sys/kern/subr_log.c	2003-09-22 13:59:57.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/subr_log.c	2007-11-14 17:12:02.000000000 +0000
@@ -281,7 +281,8 @@
 		return;
 	selnotify(&logsoftc.sc_selp, 0);
 	if (logsoftc.sc_state & LOG_ASYNC)
-		fownsignal(logsoftc.sc_pgid, SIGIO, 0, 0, NULL);
+		/* FIXME - instance */
+		fownsignal(proc0.p_inst, logsoftc.sc_pgid, SIGIO, 0, 0, NULL);
 	if (logsoftc.sc_state & LOG_RDWAIT) {
 		wakeup((caddr_t)msgbufp);
 		logsoftc.sc_state &= ~LOG_RDWAIT;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/subr_prf.c mult-netbsd-3.1/sys/kern/subr_prf.c
--- NetBSD-3.1/sys/kern/subr_prf.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/subr_prf.c	2007-11-12 16:59:26.000000000 +0000
@@ -449,24 +449,22 @@
  *   when done, do a "tprintf_close" to drop the handle
  */
 
-/*
- * tprintf_open: get a tprintf handle on a process "p"
- *
- * => returns NULL if process can't be printed to
- */
 
 tpr_t
-tprintf_open(p)
-	struct proc *p;
+tprintf_open(struct proc *p)
 {
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
 
 	if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
 		SESSHOLD(p->p_session);
-		return ((tpr_t) p->p_session);
+		return((tpr_t)p->p_session);
 	}
-	return ((tpr_t) NULL);
+
+	return((tpr_t)NULL);
 }
 
+
 /*
  * tprintf_close: dispose of a tprintf handle obtained with tprintf_open
  */
@@ -475,7 +473,6 @@
 tprintf_close(sess)
 	tpr_t sess;
 {
-
 	if (sess)
 		SESSRELE((struct session *) sess);
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/sys_generic.c mult-netbsd-3.1/sys/kern/sys_generic.c
--- NetBSD-3.1/sys/kern/sys_generic.c	2005-02-25 19:56:07.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/sys_generic.c	2007-12-16 14:56:45.000000000 +0000
@@ -62,8 +62,14 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
-int selscan(struct proc *, fd_mask *, fd_mask *, int, register_t *);
-int pollscan(struct proc *, struct pollfd *, int, register_t *);
+#include <sys/inst.h>
+
+int 		selscan(struct proc *, fd_mask *, 
+			fd_mask *, int, register_t *);
+int 		pollscan(struct proc *, struct pollfd *, 
+			int, register_t *);
+
+int		selwait, nselcoll;
 
 
 /*
@@ -102,6 +108,7 @@
 	    &fp->f_offset, FOF_UPDATE_OFFSET, retval));
 }
 
+
 int
 dofileread(struct proc *p, int fd, struct file *fp, void *buf, size_t nbyte,
 	off_t *offset, int flags, register_t *retval)
@@ -115,6 +122,8 @@
 #endif
 	error = 0;
 
+	/* FIXME - instances - cross-check credentials? */
+
 	aiov.iov_base = (caddr_t)buf;
 	aiov.iov_len = nbyte;
 	auio.uio_iov = &aiov;
@@ -158,6 +167,7 @@
 	return (error);
 }
 
+
 /*
  * Scatter read system call.
  */
@@ -193,6 +203,7 @@
 	    &fp->f_offset, FOF_UPDATE_OFFSET, retval));
 }
 
+
 int
 dofilereadv(struct proc *p, int fd, struct file *fp, const struct iovec *iovp,
 	int iovcnt, off_t *offset, int flags, register_t *retval)
@@ -206,6 +217,8 @@
 	struct iovec	*ktriov;
 #endif
 
+	/* FIXME - instances - cross-check credentials */
+
 	error = 0;
 #ifdef KTRACE
 	ktriov = NULL;
@@ -281,6 +294,7 @@
 	return (error);
 }
 
+
 /*
  * Write system call
  */
@@ -311,11 +325,15 @@
 
 	FILE_USE(fp);
 
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+
 	/* dofilewrite() will unuse the descriptor for us */
 	return (dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
 	    &fp->f_offset, FOF_UPDATE_OFFSET, retval));
 }
 
+
 int
 dofilewrite(struct proc *p, int fd, struct file *fp, const void *buf,
 	size_t nbyte, off_t *offset, int flags, register_t *retval)
@@ -405,6 +423,10 @@
 
 	FILE_USE(fp);
 
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+
 	/* dofilewritev() will unuse the descriptor for us */
 	return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
 	    &fp->f_offset, FOF_UPDATE_OFFSET, retval));
@@ -649,8 +671,6 @@
 	}
 }
 
-int	selwait, nselcoll;
-
 /*
  * Select system call.
  */
@@ -699,8 +719,13 @@
 		syscallarg(fd_set *)		ex;
 		syscallarg(struct timeval *)	tv;
 	} */ * const uap = v;
-	struct timeval atv, *tv = NULL;
-	int error;
+	struct timeval 	atv, *tv;
+	int 		error;
+
+	tv = NULL;
+
+	KASSERT(l);
+	KASSERT(l->l_inst);
 
 	if (SCARG(uap, tv)) {
 		error = copyin(SCARG(uap, tv), (caddr_t)&atv,
@@ -710,13 +735,16 @@
 		tv = &atv;
 	}
 
-	return selcommon(l, retval, SCARG(uap, nd), SCARG(uap, in),
-	    SCARG(uap, ou), SCARG(uap, ex), tv, NULL);
+	return(selcommon(l, retval, SCARG(uap, nd), 
+				SCARG(uap, in), SCARG(uap, ou), 
+				SCARG(uap, ex), tv, NULL));
 }
 
+
 int
 selcommon(struct lwp *l, register_t *retval, int nd, fd_set *u_in,
-	fd_set *u_ou, fd_set *u_ex, struct timeval *tv, sigset_t *mask)
+		fd_set *u_ou, fd_set *u_ex, struct timeval *tv, 
+		sigset_t *mask)
 {
 	struct proc	* const p = l->l_proc;
 	caddr_t		bits;
@@ -817,6 +845,7 @@
 	return (error);
 }
 
+
 int
 selscan(struct proc *p, fd_mask *ibitp, fd_mask *obitp, int nfd,
 	register_t *retval)
@@ -853,6 +882,7 @@
 	return (0);
 }
 
+
 /*
  * Poll system call.
  */
@@ -876,6 +906,7 @@
 		tv, NULL);
 }
 
+
 /*
  * Poll system call.
  */
@@ -912,6 +943,7 @@
 		tv, mask);
 }
 
+
 int
 pollcommon(struct lwp *l, register_t *retval,
 	struct pollfd *u_fds, u_int nfds,
@@ -995,6 +1027,7 @@
 	return (error);
 }
 
+
 int
 pollscan(struct proc *p, struct pollfd *fds, int nfd, register_t *retval)
 {
@@ -1002,6 +1035,8 @@
 	int		i, n;
 	struct file	*fp;
 
+	/* FIXME - instances - cross-check ownership */
+
 	fdp = p->p_fd;
 	n = 0;
 	for (i = 0; i < nfd; i++, fds++) {
@@ -1028,6 +1063,7 @@
 	return (0);
 }
 
+
 /*ARGSUSED*/
 int
 seltrue(dev_t dev, int events, struct proc *p)
@@ -1036,6 +1072,7 @@
 	return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
 }
 
+
 /*
  * Record a select request.
  */
@@ -1044,33 +1081,48 @@
 {
 	struct lwp	*l;
 	struct proc	*p;
+	struct inst	*i;
+	u_int		myiid;
 	pid_t		mypid;
 
+	KASSERT(selector);
+	KASSERT(selector->p_inst);
+
 	mypid = selector->p_pid;
-	if (sip->sel_pid == mypid)
+	myiid = selector->p_inst->i_uuid;
+
+	if (sip->sel_pid == mypid && sip->sel_iid == myiid)
 		return;
-	if (sip->sel_pid && (p = pfind(sip->sel_pid))) {
+
+	if (NULL == (i = inst_lookup(sip->sel_iid)))
+		goto out;
+	if (sip->sel_pid && (p = pfind(i, sip->sel_pid))) {
 		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
 			if (l->l_wchan == (caddr_t)&selwait) {
 				sip->sel_collision = 1;
+				inst_release(i);
 				return;
 			}
 		}
 	}
+	inst_release(i);
 
+out:
 	sip->sel_pid = mypid;
+	sip->sel_iid = myiid;
 }
 
+
 /*
  * Do a wakeup when a selectable event occurs.
  */
 void
-selwakeup(sip)
-	struct selinfo *sip;
+selwakeup(struct selinfo *sip)
 {
-	struct lwp *l;
-	struct proc *p;
-	int s;
+	struct lwp	*l;
+	struct proc	*p;
+	int		s;
+	struct inst	*i;
 
 	if (sip->sel_pid == 0)
 		return;
@@ -1081,9 +1133,12 @@
 		wakeup((caddr_t)&selwait);
 		return;
 	}
-	p = pfind(sip->sel_pid);
+
+	if (NULL == (i = inst_lookup(sip->sel_iid)))
+		return;
+	p = pfind(i, sip->sel_pid);
 	sip->sel_pid = 0;
-	if (p != NULL) {
+	if (NULL != p) {
 		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
 			SCHED_LOCK(s);
 			if (l->l_wchan == (caddr_t)&selwait) {
@@ -1096,4 +1151,6 @@
 			SCHED_UNLOCK(s);
 		}
 	}
+	inst_release(i);
 }
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/sys_pipe.c mult-netbsd-3.1/sys/kern/sys_pipe.c
--- NetBSD-3.1/sys/kern/sys_pipe.c	2005-09-14 21:35:05.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/sys_pipe.c	2007-11-23 10:17:19.000000000 +0000
@@ -1,3 +1,4 @@
+/* $Id: sys_pipe.c,v 1.8 2007/11/23 10:17:19 kristaps Exp $ */
 /*	$NetBSD: sys_pipe.c,v 1.64.2.1 2005/09/14 20:35:05 tron Exp $	*/
 
 /*-
@@ -109,98 +110,140 @@
 #include <uvm/uvm.h>
 #include <sys/sysctl.h>
 #include <sys/kernel.h>
+#include <sys/inst.h>
 
 #include <sys/pipe.h>
 
-/*
- * Avoid microtime(9), it's slow. We don't guard the read from time(9)
- * with splclock(9) since we don't actually need to be THAT sure the access
- * is atomic.
+/* 
+ * Limit for direct transfers; we annot limit the amount of kva for
+ * pipes in general. 
  */
-#define PIPE_TIMESTAMP(tvp)	(*(tvp) = time)
+#define LIMPIPEKVA	(16 * 1024 * 1024)
 
-
-/*
- * Use this define if you want to disable *fancy* VM things.  Expect an
- * approx 30% decrease in transfer rate.
+/* 
+ * Soft limit for pipe kva, but we don't want to exhaust it on large
+ * system. 
  */
-/* #define PIPE_NODIRECT */
+#define MAXPIPEKVA	(8 * 1024 * 1024)
 
 /*
- * interfaces to the outside world
+ * Avoid microtime(9), it's slow. We don't guard the read from time(9)
+ * with splclock(9) since we don't actually need to be THAT sure the
+ * access is atomic.
  */
-static int pipe_read(struct file *fp, off_t *offset, struct uio *uio,
-		struct ucred *cred, int flags);
-static int pipe_write(struct file *fp, off_t *offset, struct uio *uio,
-		struct ucred *cred, int flags);
-static int pipe_close(struct file *fp, struct proc *p);
-static int pipe_poll(struct file *fp, int events, struct proc *p);
-static int pipe_kqfilter(struct file *fp, struct knote *kn);
-static int pipe_stat(struct file *fp, struct stat *sb, struct proc *p);
-static int pipe_ioctl(struct file *fp, u_long cmd, void *data,
-		struct proc *p);
-
-static const struct fileops pipeops = {
-	pipe_read, pipe_write, pipe_ioctl, fnullop_fcntl, pipe_poll,
-	pipe_stat, pipe_close, pipe_kqfilter
-};
+#define PIPE_TIMESTAMP(tvp) (*(tvp) = time)
 
-/*
- * Default pipe buffer size(s), this can be kind-of large now because pipe
- * space is pageable.  The pipe code will try to maintain locality of
- * reference for performance reasons, so small amounts of outstanding I/O
- * will not wipe the cache.
+/* 
+ * Limit the number of "big" pipes. 
  */
-#define MINPIPESIZE (PIPE_SIZE/3)
-#define MAXPIPESIZE (2*PIPE_SIZE/3)
+#define MAXBIGPIPE	(32)
 
 /*
- * Maximum amount of kva for pipes -- this is kind-of a soft limit, but
- * is there so that on large systems, we don't exhaust it.
+ * Default pipe buffer size(s), this can be kind-of large now because
+ * pipe space is pageable.  The pipe code will try to maintain locality
+ * of reference for performance reasons, so small amounts of outstanding
+ * I/O will not wipe the cache.
  */
-#define MAXPIPEKVA (8*1024*1024)
-static int maxpipekva = MAXPIPEKVA;
+#define MINPIPESIZE	(PIPE_SIZE / 3)
+#define MAXPIPESIZE	(2 * PIPE_SIZE / 3)
 
 /*
- * Limit for direct transfers, we cannot, of course limit
- * the amount of kva for pipes in general though.
+ * Use this define if you want to disable *fancy* VM things.  Expect an
+ * approx 30% decrease in transfer rate.
  */
-#define LIMITPIPEKVA (16*1024*1024)
-static int limitpipekva = LIMITPIPEKVA;
+#if 0
+# define PIPE_NODIRECT
+#endif
 
-/*
- * Limit the number of "big" pipes
- */
-#define LIMITBIGPIPES  32
-static int maxbigpipes = LIMITBIGPIPES;
-static int nbigpipe = 0;
 
-/*
- * Amount of KVA consumed by pipe buffers.
- */
-static int amountpipekva = 0;
+struct inst_pipe
+{
+	int	maxpipekva;	/* Max (soft-limit) pipe kva. */
+	int	limpipekva;	/* Max transfer kva. */
+	int	maxbigpipe;	/* Max count of big pipes. */
+	int	nbigpipe;	/* Number of allocated bpipes. */
+	int	amountpipekva;	/* Amount of active kva. */
+};
+
+
+static POOL_INIT(pipe_pool, sizeof(struct pipe), 
+		0, 0, 0, "pipepl", &pool_allocator_nointr);
+
 
 MALLOC_DEFINE(M_PIPE, "pipe", "Pipe structures");
 
-static void pipeclose(struct file *fp, struct pipe *pipe);
-static void pipe_free_kmem(struct pipe *pipe);
-static int pipe_create(struct pipe **pipep, int allockva);
-static int pipelock(struct pipe *pipe, int catch);
+static int	sysctl_maxpipekva(SYSCTLFN_PROTO);
+static int	sysctl_limpipekva(SYSCTLFN_PROTO);
+static int	sysctl_maxbigpipe(SYSCTLFN_PROTO);
+static int	sysctl_nbigpipe(SYSCTLFN_PROTO);
+static int	sysctl_amountpipekva(SYSCTLFN_PROTO);
+
+static int	pipe_read(struct file *fp, off_t *offset, 
+			struct uio *uio, struct ucred *cred, 
+			int flags);
+static int 	pipe_write(struct file *fp, off_t *offset, 
+			struct uio *uio, struct ucred *cred, 
+			int flags);
+static int	pipe_close(struct file *fp, struct proc *p);
+static int	pipe_poll(struct file *fp, int events, struct proc *p);
+static int	pipe_kqfilter(struct file *fp, struct knote *kn);
+static int	pipe_stat(struct file *fp, struct stat *sb, 
+			struct proc *p);
+static int	pipe_ioctl(struct file *fp, u_long cmd, void *data,
+			struct proc *p);
+static void	pipeclose(struct file *fp, struct pipe *pipe);
+static void	pipe_free_kmem(struct pipe *pipe);
+static int	pipe_create(struct proc *proc, 
+			struct pipe **pipep, int allockva);
+static int	pipelock(struct pipe *pipe, int catch);
 static __inline void pipeunlock(struct pipe *pipe);
-static void pipeselwakeup(struct pipe *pipe, struct pipe *sigp, int code);
+static void	pipeselwakeup(struct pipe *pipe, 
+			struct pipe *sigp, int code);
 #ifndef PIPE_NODIRECT
-static int pipe_direct_write(struct file *fp, struct pipe *wpipe,
-    struct uio *uio);
+static int	pipe_direct_write(struct file *fp, struct pipe *wpipe,
+			struct uio *uio);
 #endif
-static int pipespace(struct pipe *pipe, int size);
-
+static int	pipespace(struct pipe *pipe, int size);
 #ifndef PIPE_NODIRECT
-static int pipe_loan_alloc(struct pipe *, int);
-static void pipe_loan_free(struct pipe *);
+static int	pipe_loan_alloc(struct pipe *, int);
+static void	pipe_loan_free(struct pipe *);
 #endif /* PIPE_NODIRECT */
 
-static POOL_INIT(pipe_pool, sizeof(struct pipe), 0, 0, 0, "pipepl",
-    &pool_allocator_nointr);
+
+static const struct fileops pipeops = {
+	pipe_read, pipe_write, pipe_ioctl, 
+	fnullop_fcntl, pipe_poll, pipe_stat, 
+	pipe_close, pipe_kqfilter
+};
+
+
+int
+inst_pipe_alloc(inst_pipe_t *p, int flags)
+{
+	struct inst_pipe *i;
+
+	KASSERT(p);
+	i = malloc(sizeof(struct inst_pipe), M_INST, flags);
+	if (NULL == i)
+		return(0);
+	memset(i, 0, sizeof(struct inst_pipe));
+
+	i->maxpipekva = MAXPIPEKVA;
+	i->limpipekva = LIMPIPEKVA;
+	i->maxbigpipe = MAXBIGPIPE;
+
+	*p = i;
+	return(1);
+}
+
+
+void
+inst_pipe_free(inst_pipe_t p)
+{
+	KASSERT(p);
+	free(p, M_INST);
+}
+
 
 /*
  * The pipe system call for the DTYPE_PIPE type of pipes
@@ -208,19 +251,20 @@
 
 /* ARGSUSED */
 int
-sys_pipe(l, v, retval)
-	struct lwp *l;
-	void *v;
-	register_t *retval;
-{
-	struct file *rf, *wf;
-	struct pipe *rpipe, *wpipe;
-	int fd, error;
-	struct proc *p;
+sys_pipe(struct lwp *l, void *v, register_t *retval)
+{
+	struct file 	*rf, *wf;
+	struct pipe 	*rpipe, *wpipe;
+	int 		fd, error;
+	struct proc 	*p;
 
 	p = l->l_proc;
 	rpipe = wpipe = NULL;
-	if (pipe_create(&rpipe, 1) || pipe_create(&wpipe, 0)) {
+
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	if (pipe_create(p, &rpipe, 1) || pipe_create(p, &wpipe, 0)) {
 		pipeclose(NULL, rpipe);
 		pipeclose(NULL, wpipe);
 		return (ENFILE);
@@ -234,18 +278,18 @@
 	 * file descriptor races if we block in the second falloc().
 	 */
 
-	error = falloc(p, &rf, &fd);
-	if (error)
+	if ((error = falloc(p, &rf, &fd)))
 		goto free2;
+
 	retval[0] = fd;
 	rf->f_flag = FREAD;
 	rf->f_type = DTYPE_PIPE;
 	rf->f_data = (caddr_t)rpipe;
 	rf->f_ops = &pipeops;
 
-	error = falloc(p, &wf, &fd);
-	if (error)
+	if ((error = falloc(p, &wf, &fd)))
 		goto free3;
+
 	retval[1] = fd;
 	wf->f_flag = FWRITE;
 	wf->f_type = DTYPE_PIPE;
@@ -260,10 +304,12 @@
 	FILE_UNUSE(rf, p);
 	FILE_UNUSE(wf, p);
 	return (0);
+
 free3:
 	FILE_UNUSE(rf, p);
 	ffree(rf);
 	fdremove(p->p_fd, retval[0]);
+
 free2:
 	pipeclose(NULL, wpipe);
 	pipeclose(NULL, rpipe);
@@ -271,18 +317,20 @@
 	return (error);
 }
 
+
 /*
- * Allocate kva for pipe circular buffer, the space is pageable
- * This routine will 'realloc' the size of a pipe safely, if it fails
- * it will retain the old buffer.
- * If it fails it will return ENOMEM.
+ * Allocate kva for pipe circular buffer, the space is pageable This
+ * routine will 'realloc' the size of a pipe safely, if it fails it will
+ * retain the old buffer.  If it fails it will return ENOMEM.
  */
 static int
-pipespace(pipe, size)
-	struct pipe *pipe;
-	int size;
+pipespace(struct pipe *pipe, int size)
 {
-	caddr_t buffer;
+	caddr_t 	buffer;
+
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
+
 	/*
 	 * Allocate pageable virtual address space. Physical memory is
 	 * allocated on demand.
@@ -298,26 +346,30 @@
 	pipe->pipe_buffer.in = 0;
 	pipe->pipe_buffer.out = 0;
 	pipe->pipe_buffer.cnt = 0;
-	amountpipekva += pipe->pipe_buffer.size;
+	pipe->pipe_inst->i_pipe->amountpipekva += pipe->pipe_buffer.size;
 	return (0);
 }
 
+
 /*
  * Initialize and allocate VM and memory for pipe.
  */
 static int
-pipe_create(pipep, allockva)
-	struct pipe **pipep;
-	int allockva;
+pipe_create(struct proc *p, struct pipe **pipep, int allockva)
 {
-	struct pipe *pipe;
-	int error;
+	struct pipe 	*pipe;
+	int 		error;
 
-	pipe = *pipep = pool_get(&pipe_pool, PR_WAITOK);
+	KASSERT(p);
+	KASSERT(p->p_inst);
 
-	/* Initialize */
+	pipe = *pipep = pool_get(&pipe_pool, PR_WAITOK);
 	memset(pipe, 0, sizeof(struct pipe));
+
 	pipe->pipe_state = PIPE_SIGNALR;
+	pipe->pipe_inst = p->p_inst;
+	inst_hold(p->p_inst);
+	p->p_inst->i_npipes++;
 
 	PIPE_TIMESTAMP(&pipe->pipe_ctime);
 	pipe->pipe_atime = pipe->pipe_ctime;
@@ -333,16 +385,16 @@
 
 
 /*
- * Lock a pipe for I/O, blocking other access
- * Called with pipe spin lock held.
- * Return with pipe spin lock released on success.
+ * Lock a pipe for I/O, blocking other access Called with pipe spin lock
+ * held.  Return with pipe spin lock released on success.
  */
 static int
-pipelock(pipe, catch)
-	struct pipe *pipe;
-	int catch;
+pipelock(struct pipe *pipe, int catch)
 {
-	int error;
+	int 		error;
+
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
 
 	LOCK_ASSERT(simple_lock_held(&pipe->pipe_slock));
 
@@ -373,38 +425,47 @@
 		 * beneficial.
 		 */
 		(void) ltsleep(&lbolt, PSOCK, "rstrtpipelock", hz,
-		    &pipe->pipe_slock);
+				&pipe->pipe_slock);
 	}
 	return (error);
 }
 
+
 /*
  * unlock a pipe I/O lock
  */
 static __inline void
-pipeunlock(pipe)
-	struct pipe *pipe;
+pipeunlock(struct pipe *pipe)
 {
-
 	lockmgr(&pipe->pipe_lock, LK_RELEASE, NULL);
 }
 
+
 /*
  * Select/poll wakup. This also sends SIGIO to peer connected to
  * 'sigpipe' side of pipe.
  */
 static void
-pipeselwakeup(selp, sigp, code)
-	struct pipe *selp, *sigp;
-	int code;
+pipeselwakeup(struct pipe *selp, struct pipe *sigp, int code)
 {
-	int band;
+	int 		band;
+
+	KASSERT(selp);
+	KASSERT(selp->pipe_inst);
 
 	selnotify(&selp->pipe_sel, NOTE_SUBMIT);
 
 	if (sigp == NULL || (sigp->pipe_state & PIPE_ASYNC) == 0)
 		return;
 
+	KASSERT(sigp->pipe_inst);
+
+	if (selp->pipe_inst != sigp->pipe_inst)
+		printf("error: selp->pipe_inst = %d, "
+				"sigp->pipe_inst = %d\n",
+				selp->pipe_inst->i_uuid, 
+				sigp->pipe_inst->i_uuid);
+
 	switch (code) {
 	case POLL_IN:
 		band = POLLIN|POLLRDNORM;
@@ -428,24 +489,33 @@
 		break;
 	}
 
-	fownsignal(sigp->pipe_pgid, SIGIO, code, band, selp);
+	fownsignal(sigp->pipe_inst, sigp->pipe_pgid, 
+			SIGIO, code, band, selp);
 }
 
+
 /* ARGSUSED */
 static int
-pipe_read(fp, offset, uio, cred, flags)
-	struct file *fp;
-	off_t *offset;
-	struct uio *uio;
-	struct ucred *cred;
-	int flags;
-{
-	struct pipe *rpipe = (struct pipe *) fp->f_data;
-	struct pipebuf *bp = &rpipe->pipe_buffer;
-	int error;
-	size_t nread = 0;
-	size_t size;
-	size_t ocnt;
+pipe_read(struct file *fp, off_t *offset, struct uio *uio,
+		struct ucred *cred, int flags)
+{
+	struct pipe 	*rpipe;
+	struct pipebuf	*bp;
+	int 		error;
+	size_t 		nread, size, ocnt;
+
+	nread = 0;
+	rpipe = (struct pipe *) fp->f_data;
+	bp = &rpipe->pipe_buffer;
+
+	KASSERT(rpipe->pipe_inst);
+	KASSERT(cred->cr_inst);
+
+	if (rpipe->pipe_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: rpipe->pipe_inst = %d, "
+				"cred->cr_inst->i_uuid = %d\n",
+				rpipe->pipe_inst->i_uuid,
+				cred->cr_inst->i_uuid);
 
 	PIPE_LOCK(rpipe);
 	++rpipe->pipe_busy;
@@ -620,70 +690,90 @@
 	return (error);
 }
 
+
 #ifndef PIPE_NODIRECT
 /*
  * Allocate structure for loan transfer.
  */
 static int
-pipe_loan_alloc(wpipe, npages)
-	struct pipe *wpipe;
-	int npages;
+pipe_loan_alloc(struct pipe *wpipe, int npages)
 {
-	vsize_t len;
+	vsize_t 	len;
+
+	KASSERT(wpipe);
+	KASSERT(wpipe->pipe_inst);
 
 	len = (vsize_t)npages << PAGE_SHIFT;
 	wpipe->pipe_map.kva = uvm_km_valloc_wait(kernel_map, len);
 	if (wpipe->pipe_map.kva == 0)
 		return (ENOMEM);
 
-	amountpipekva += len;
+	wpipe->pipe_inst->i_pipe->amountpipekva += len;
 	wpipe->pipe_map.npages = npages;
 	wpipe->pipe_map.pgs = malloc(npages * sizeof(struct vm_page *), M_PIPE,
 	    M_WAITOK);
 	return (0);
 }
 
+
 /*
  * Free resources allocated for loan transfer.
  */
 static void
-pipe_loan_free(wpipe)
-	struct pipe *wpipe;
+pipe_loan_free(struct pipe *wpipe)
 {
-	vsize_t len;
+	vsize_t 	len;
+
+	KASSERT(wpipe);
+	KASSERT(wpipe->pipe_inst);
 
 	len = (vsize_t)wpipe->pipe_map.npages << PAGE_SHIFT;
 	uvm_km_free(kernel_map, wpipe->pipe_map.kva, len);
 	wpipe->pipe_map.kva = 0;
-	amountpipekva -= len;
+	wpipe->pipe_inst->i_pipe->amountpipekva -= len;
 	free(wpipe->pipe_map.pgs, M_PIPE);
 	wpipe->pipe_map.pgs = NULL;
 }
 
+
 /*
- * NetBSD direct write, using uvm_loan() mechanism.
- * This implements the pipe buffer write mechanism.  Note that only
- * a direct write OR a normal pipe write can be pending at any given time.
- * If there are any characters in the pipe buffer, the direct write will
- * be deferred until the receiving process grabs all of the bytes from
- * the pipe buffer.  Then the direct mapping write is set-up.
+ * NetBSD direct write, using uvm_loan() mechanism.  This implements the
+ * pipe buffer write mechanism.  Note that only a direct write OR a
+ * normal pipe write can be pending at any given time.  If there are any
+ * characters in the pipe buffer, the direct write will be deferred
+ * until the receiving process grabs all of the bytes from the pipe
+ * buffer.  Then the direct mapping write is set-up.
  *
  * Called with the long-term pipe lock held.
  */
 static int
-pipe_direct_write(fp, wpipe, uio)
-	struct file *fp;
-	struct pipe *wpipe;
-	struct uio *uio;
-{
-	int error, npages, j;
-	struct vm_page **pgs;
-	vaddr_t bbase, kva, base, bend;
-	vsize_t blen, bcnt;
-	voff_t bpos;
+pipe_direct_write(struct file *fp, struct pipe *wpipe, 
+		struct uio *uio)
+{
+	int 		error, npages, j, maxpipekva;
+	struct vm_page	**pgs;
+	vaddr_t 	bbase, kva, base, bend;
+	vsize_t 	blen, bcnt;
+	voff_t 		bpos;
 
+	KASSERT(wpipe);
+	KASSERT(wpipe->pipe_inst);
 	KASSERT(wpipe->pipe_map.cnt == 0);
 
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+
+	maxpipekva = wpipe->pipe_inst->i_pipe->maxpipekva;
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != wpipe->pipe_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"wpipe->pipe_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				wpipe->pipe_inst->i_uuid);
+
 	/*
 	 * Handle first PIPE_CHUNK_SIZE bytes of buffer. Deal with buffers
 	 * not aligned to PAGE_SIZE.
@@ -785,7 +875,8 @@
 		pmap_kremove(wpipe->pipe_map.kva, blen);
 		uvm_unloan(pgs, npages, UVM_LOAN_TOPAGE);
 	}
-	if (error || amountpipekva > maxpipekva)
+	if (error || wpipe->pipe_inst->i_pipe->amountpipekva > 
+			maxpipekva)
 		pipe_loan_free(wpipe);
 
 	if (error) {
@@ -820,21 +911,37 @@
 }
 #endif /* !PIPE_NODIRECT */
 
+
 static int
-pipe_write(fp, offset, uio, cred, flags)
-	struct file *fp;
-	off_t *offset;
-	struct uio *uio;
-	struct ucred *cred;
-	int flags;
-{
-	struct pipe *wpipe, *rpipe;
-	struct pipebuf *bp;
-	int error;
+pipe_write(struct file *fp, off_t *offset, struct uio *uio, 
+		struct ucred *cred, int flags)
+{
+	struct pipe 	*wpipe, *rpipe;
+	struct pipebuf	*bp;
+	int 		error, limpipekva, maxbigpipe, amtpipekva;
 
 	/* We want to write to our peer */
 	rpipe = (struct pipe *) fp->f_data;
+	KASSERT(rpipe);
+	KASSERT(rpipe->pipe_inst);
 
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+
+	KASSERT(cred);
+	KASSERT(cred->cr_inst);
+
+	limpipekva = rpipe->pipe_inst->i_pipe->limpipekva;
+	maxbigpipe = rpipe->pipe_inst->i_pipe->maxbigpipe;
+	amtpipekva = rpipe->pipe_inst->i_pipe->amountpipekva;
+
+	/* FIXME - instance protection */
+
+	if (fp->f_cred->cr_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"cred->cr_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				cred->cr_inst->i_uuid);
 retry:
 	error = 0;
 	PIPE_LOCK(rpipe);
@@ -854,10 +961,18 @@
 		error = EPIPE;
 	}
 
+	/* FIXME - instance protection */
+
 	PIPE_UNLOCK(rpipe);
 	if (error != 0)
 		return (error);
 
+	if (wpipe->pipe_inst->i_uuid != rpipe->pipe_inst->i_uuid)
+		printf("error: wpipe->pipe_inst = %d, "
+				"rpipe->pipe_inst = %d\n",
+				wpipe->pipe_inst->i_uuid,
+				rpipe->pipe_inst->i_uuid);
+
 	++wpipe->pipe_busy;
 
 	/* Aquire the long-term pipe lock */
@@ -878,14 +993,14 @@
 	 * If it is advantageous to resize the pipe buffer, do so.
 	 */
 	if ((uio->uio_resid > PIPE_SIZE) &&
-	    (nbigpipe < maxbigpipes) &&
+	    (wpipe->pipe_inst->i_pipe->nbigpipe < maxbigpipe) &&
 #ifndef PIPE_NODIRECT
 	    (wpipe->pipe_state & PIPE_DIRECTW) == 0 &&
 #endif
 	    (bp->size <= PIPE_SIZE) && (bp->cnt == 0)) {
 
 		if (pipespace(wpipe, BIG_PIPE_SIZE) == 0)
-			nbigpipe++;
+			wpipe->pipe_inst->i_pipe->nbigpipe++;
 	}
 
 	while (uio->uio_resid) {
@@ -928,7 +1043,7 @@
 		 */
 		if ((uio->uio_iov->iov_len >= PIPE_MINDIRECT) &&
 		    (fp->f_flag & FNONBLOCK) == 0 &&
-		    (wpipe->pipe_map.kva || (amountpipekva < limitpipekva))) {
+		    (wpipe->pipe_map.kva || (amtpipekva < limpipekva))) {
 			error = pipe_direct_write(fp, wpipe, uio);
 
 			/*
@@ -1097,17 +1212,38 @@
 	return (error);
 }
 
+
 /*
  * we implement a very minimal set of ioctls for compatibility with sockets.
  */
 int
-pipe_ioctl(fp, cmd, data, p)
-	struct file *fp;
-	u_long cmd;
-	void *data;
-	struct proc *p;
+pipe_ioctl(struct file *fp, u_long cmd, void *data, struct proc *p)
 {
-	struct pipe *pipe = (struct pipe *)fp->f_data;
+	struct pipe 	*pipe;
+
+	pipe = (struct pipe *)fp->f_data;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(p);
+	KASSERT(p->p_inst);
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
+
+	/* FIXME - instance protection */
+
+	if (fp->f_cred->cr_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"p->p_inst = %d\n", 
+				fp->f_cred->cr_inst->i_uuid,
+				p->p_inst->i_uuid);
+
+	if (pipe->pipe_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: pipe->pipe_inst = %d, "
+				"p->p_inst = %d\n", 
+				pipe->pipe_inst->i_uuid,
+				p->p_inst->i_uuid);
 
 	switch (cmd) {
 
@@ -1179,20 +1315,52 @@
 	return (EPASSTHROUGH);
 }
 
+
 int
-pipe_poll(fp, events, td)
-	struct file *fp;
-	int events;
-	struct proc *td;
-{
-	struct pipe *rpipe = (struct pipe *)fp->f_data;
-	struct pipe *wpipe;
-	int eof = 0;
-	int revents = 0;
+pipe_poll(struct file *fp, int events, struct proc *td)
+{
+	struct pipe	*rpipe, *wpipe;
+	int 		eof;
+	int 		revents;
+
+	eof = revents = 0;
+	rpipe = (struct pipe *)fp->f_data;
+
+	/* FIXME - instance protection */
+
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(td);
+	KASSERT(td->p_inst);
+	KASSERT(rpipe);
+	KASSERT(rpipe->pipe_inst);
+
+	if (fp->f_cred->cr_inst->i_uuid != td->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"td->p_inst = %d\n", 
+				fp->f_cred->cr_inst->i_uuid,
+				td->p_inst->i_uuid);
+
+	if (rpipe->pipe_inst->i_uuid != td->p_inst->i_uuid)
+		printf("error: rpipe->pipe_inst = %d, "
+				"td->p_inst = %d\n", 
+				rpipe->pipe_inst->i_uuid,
+				td->p_inst->i_uuid);
 
 retry:
 	PIPE_LOCK(rpipe);
 	wpipe = rpipe->pipe_peer;
+
+	if (wpipe) {
+		KASSERT(wpipe->pipe_inst);
+		if (wpipe->pipe_inst->i_uuid != 
+				rpipe->pipe_inst->i_uuid)
+			printf("error: rpipe->pipe_inst = %d, "
+					"wpipe->p_inst = %d\n", 
+					rpipe->pipe_inst->i_uuid,
+					wpipe->pipe_inst->i_uuid);
+	}
+
 	if (wpipe != NULL && simple_lock_try(&wpipe->pipe_slock) == 0) {
 		/* Deal with race for peer */
 		PIPE_UNLOCK(rpipe);
@@ -1239,13 +1407,33 @@
 	return (revents);
 }
 
+
 static int
-pipe_stat(fp, ub, td)
-	struct file *fp;
-	struct stat *ub;
-	struct proc *td;
+pipe_stat(struct file *fp, struct stat *ub, struct proc *td)
 {
-	struct pipe *pipe = (struct pipe *)fp->f_data;
+	struct pipe	*pipe;
+
+	pipe = (struct pipe *)fp->f_data;
+
+	/* FIXME - instance protection */
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(td);
+	KASSERT(td->p_inst);
+
+	if (td->p_inst->i_uuid != fp->f_cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"td->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				td->p_inst->i_uuid);
+
+	if (td->p_inst->i_uuid != pipe->pipe_inst->i_uuid)
+		printf("error: pipe->pipe_inst = %d, "
+				"td->p_inst = %d\n",
+				pipe->pipe_inst->i_uuid,
+				td->p_inst->i_uuid);
 
 	memset((caddr_t)ub, 0, sizeof(*ub));
 	ub->st_mode = S_IFIFO | S_IRUSR | S_IWUSR;
@@ -1260,34 +1448,58 @@
 	ub->st_uid = fp->f_cred->cr_uid;
 	ub->st_gid = fp->f_cred->cr_gid;
 	/*
-	 * Left as 0: st_dev, st_ino, st_nlink, st_rdev, st_flags, st_gen.
-	 * XXX (st_dev, st_ino) should be unique.
+	 * Left as 0: st_dev, st_ino, st_nlink, st_rdev, st_flags,
+	 * st_gen.  XXX (st_dev, st_ino) should be unique.
 	 */
 	return (0);
 }
 
+
 /* ARGSUSED */
 static int
-pipe_close(fp, td)
-	struct file *fp;
-	struct proc *td;
+pipe_close(struct file *fp, struct proc *td)
 {
-	struct pipe *pipe = (struct pipe *)fp->f_data;
+	struct pipe	*pipe;
+
+	pipe = (struct pipe *)fp->f_data;
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(td);
+	KASSERT(td->p_inst);
+
+	if (td->p_inst->i_uuid != fp->f_cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"td->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				td->p_inst->i_uuid);
+
+	if (td->p_inst->i_uuid != pipe->pipe_inst->i_uuid)
+		printf("error: pipe->pipe_inst = %d, "
+				"td->p_inst = %d\n",
+				pipe->pipe_inst->i_uuid,
+				td->p_inst->i_uuid);
+
 
 	fp->f_data = NULL;
 	pipeclose(fp, pipe);
 	return (0);
 }
 
+
 static void
-pipe_free_kmem(pipe)
-	struct pipe *pipe;
+pipe_free_kmem(struct pipe *pipe)
 {
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
 
 	if (pipe->pipe_buffer.buffer != NULL) {
 		if (pipe->pipe_buffer.size > PIPE_SIZE)
-			--nbigpipe;
-		amountpipekva -= pipe->pipe_buffer.size;
+			--pipe->pipe_inst->i_pipe->nbigpipe;
+		pipe->pipe_inst->i_pipe->amountpipekva -= 
+			pipe->pipe_buffer.size;
 		uvm_km_free(kernel_map,
 			(vaddr_t)pipe->pipe_buffer.buffer,
 			pipe->pipe_buffer.size);
@@ -1304,19 +1516,29 @@
 #endif /* !PIPE_NODIRECT */
 }
 
+
 /*
  * shutdown the pipe
  */
 static void
-pipeclose(fp, pipe)
-	struct file *fp;
-	struct pipe *pipe;
+pipeclose(struct file *fp, struct pipe *pipe)
 {
-	struct pipe *ppipe;
+	struct pipe	*ppipe;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
 
 	if (pipe == NULL)
 		return;
 
+	KASSERT(pipe->pipe_inst);
+	if (pipe->pipe_inst->i_uuid != fp->f_cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"pipe->pipe_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				pipe->pipe_inst->i_uuid);
+
 retry:
 	PIPE_LOCK(pipe);
 
@@ -1353,17 +1575,21 @@
 	(void)lockmgr(&pipe->pipe_lock, LK_DRAIN | LK_INTERLOCK,
 			&pipe->pipe_slock);
 
-	/*
-	 * free resources
-	 */
+	pipe->pipe_inst->i_npipes--;
+	inst_release(pipe->pipe_inst);
 	pipe_free_kmem(pipe);
 	pool_put(&pipe_pool, pipe);
 }
 
+
 static void
 filt_pipedetach(struct knote *kn)
 {
-	struct pipe *pipe = (struct pipe *)kn->kn_fp->f_data;
+	struct pipe	*pipe;
+
+	pipe = (struct pipe *)kn->kn_fp->f_data;
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
 
 	switch(kn->kn_filter) {
 	case EVFILT_WRITE:
@@ -1391,12 +1617,28 @@
 	PIPE_UNLOCK(pipe);
 }
 
+
 /*ARGSUSED*/
 static int
 filt_piperead(struct knote *kn, long hint)
 {
-	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
-	struct pipe *wpipe = rpipe->pipe_peer;
+	struct pipe	*rpipe, *wpipe;
+
+	rpipe = (struct pipe *)kn->kn_fp->f_data;
+	wpipe = rpipe->pipe_peer;
+
+	KASSERT(rpipe);
+	KASSERT(rpipe->pipe_inst);
+	KASSERT(wpipe);
+	KASSERT(wpipe->pipe_inst);
+
+	/* FIXME - instances - cross-check */
+
+	if (rpipe->pipe_inst->i_uuid != wpipe->pipe_inst->i_uuid)
+		printf("error: rpipe->pipe_inst = %d, "
+				"wpipe->pipe_inst = %d\n",
+				rpipe->pipe_inst->i_uuid,
+				wpipe->pipe_inst->i_uuid);
 
 	if ((hint & NOTE_SUBMIT) == 0)
 		PIPE_LOCK(rpipe);
@@ -1417,6 +1659,7 @@
 	return (kn->kn_data > 0);
 }
 
+
 /*ARGSUSED*/
 static int
 filt_pipewrite(struct knote *kn, long hint)
@@ -1424,6 +1667,23 @@
 	struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data;
 	struct pipe *wpipe = rpipe->pipe_peer;
 
+	rpipe = (struct pipe *)kn->kn_fp->f_data;
+	wpipe = rpipe->pipe_peer;
+
+	KASSERT(rpipe);
+	KASSERT(rpipe->pipe_inst);
+	KASSERT(wpipe);
+	KASSERT(wpipe->pipe_inst);
+
+	/* FIXME - instances - cross-check */
+
+	if (rpipe->pipe_inst->i_uuid != wpipe->pipe_inst->i_uuid)
+		printf("error: rpipe->pipe_inst = %d, "
+				"wpipe->pipe_inst = %d\n",
+				rpipe->pipe_inst->i_uuid,
+				wpipe->pipe_inst->i_uuid);
+
+
 	if ((hint & NOTE_SUBMIT) == 0)
 		PIPE_LOCK(rpipe);
 	/* XXXSMP: race for peer */
@@ -1443,18 +1703,23 @@
 	return (kn->kn_data >= PIPE_BUF);
 }
 
+
 static const struct filterops pipe_rfiltops =
 	{ 1, NULL, filt_pipedetach, filt_piperead };
 static const struct filterops pipe_wfiltops =
 	{ 1, NULL, filt_pipedetach, filt_pipewrite };
 
+
 /*ARGSUSED*/
 static int
 pipe_kqfilter(struct file *fp, struct knote *kn)
 {
-	struct pipe *pipe;
+	struct pipe	*pipe;
 
 	pipe = (struct pipe *)kn->kn_fp->f_data;
+	KASSERT(pipe);
+	KASSERT(pipe->pipe_inst);
+
 	switch (kn->kn_filter) {
 	case EVFILT_READ:
 		kn->kn_fop = &pipe_rfiltops;
@@ -1479,6 +1744,7 @@
 	return (0);
 }
 
+
 /*
  * Handle pipe sysctls.
  */
@@ -1502,31 +1768,56 @@
 		       CTLTYPE_INT, "maxkvasz",
 		       SYSCTL_DESCR("Maximum amount of kernel memory to be "
 				    "used for pipes"),
-		       NULL, 0, &maxpipekva, 0,
+		       sysctl_maxpipekva, 0, NULL, 0,
 		       CTL_KERN, KERN_PIPE, KERN_PIPE_MAXKVASZ, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_INT, "maxloankvasz",
 		       SYSCTL_DESCR("Limit for direct transfers via page loan"),
-		       NULL, 0, &limitpipekva, 0,
+		       sysctl_limpipekva, 0, NULL, 0,
 		       CTL_KERN, KERN_PIPE, KERN_PIPE_LIMITKVA, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_INT, "maxbigpipes",
 		       SYSCTL_DESCR("Maximum number of \"big\" pipes"),
-		       NULL, 0, &maxbigpipes, 0,
+		       sysctl_maxbigpipe, 0, NULL, 0,
 		       CTL_KERN, KERN_PIPE, KERN_PIPE_MAXBIGPIPES, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT,
 		       CTLTYPE_INT, "nbigpipes",
 		       SYSCTL_DESCR("Number of \"big\" pipes"),
-		       NULL, 0, &nbigpipe, 0,
+		       sysctl_nbigpipe, 0, NULL, 0,
 		       CTL_KERN, KERN_PIPE, KERN_PIPE_NBIGPIPES, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT,
 		       CTLTYPE_INT, "kvasize",
 		       SYSCTL_DESCR("Amount of kernel memory consumed by pipe "
 				    "buffers"),
-		       NULL, 0, &amountpipekva, 0,
+		       sysctl_amountpipekva, 0, NULL, 0,
 		       CTL_KERN, KERN_PIPE, KERN_PIPE_KVASIZE, CTL_EOL);
 }
+
+
+#define sysctl_impl(name, val) 				\
+static int						\
+name(SYSCTLFN_ARGS)					\
+{							\
+	int 		nval, error;			\
+	struct sysctlnode node;				\
+							\
+	nval = l->l_inst->i_pipe->val;			\
+	node = *rnode;					\
+	node.sysctl_data = &nval;			\
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));	\
+	if (error || newp == NULL)			\
+		return (error);				\
+	l->l_inst->i_pipe->val = nval;			\
+	return (error);					\
+}
+
+sysctl_impl(sysctl_maxpipekva, maxpipekva)
+sysctl_impl(sysctl_limpipekva, limpipekva)
+sysctl_impl(sysctl_maxbigpipe, maxbigpipe)
+sysctl_impl(sysctl_nbigpipe, nbigpipe)
+sysctl_impl(sysctl_amountpipekva, amountpipekva)
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/sys_process.c mult-netbsd-3.1/sys/kern/sys_process.c
--- NetBSD-3.1/sys/kern/sys_process.c	2006-10-26 11:23:11.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/sys_process.c	2007-11-23 10:17:19.000000000 +0000
@@ -105,6 +105,8 @@
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
 
+#include <sys/inst.h>
+
 #include <uvm/uvm_extern.h>
 
 #include <machine/reg.h>
@@ -139,13 +141,16 @@
 	int s, error, write, tmp;
 	char *path;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	/* "A foolish consistency..." XXX */
 	if (SCARG(uap, req) == PT_TRACE_ME)
 		t = p;
 	else {
 
 		/* Find the process we're supposed to be operating on. */
-		if ((t = pfind(SCARG(uap, pid))) == NULL)
+		if ((t = pfind(p->p_inst, SCARG(uap, pid))) == NULL)
 			return (ESRCH);
 	}
 
@@ -194,7 +199,7 @@
 		 *	    of the entire system, and the system was not
 		 *	    compiled with permanently insecure mode turned on
 		 */
-		if (t == initproc && securelevel > -1)
+		if (t == p->p_inst->i_initproc && securelevel > -1)
 			return (EPERM);
 
 		/*
@@ -417,15 +422,16 @@
 
 		if (SCARG(uap, req) == PT_DETACH) {
 			/* give process back to original parent or init */
-			s = proclist_lock_write();
-			if (t->p_opptr != t->p_pptr) {
+			s = proclist_lock_write(p->p_inst);
+			if (t->p_opptr && t->p_opptr != t->p_pptr) {
 				struct proc *pp = t->p_opptr;
-				proc_reparent(t, pp ? pp : initproc);
+				proc_reparent(t, pp ? pp : 
+					p->p_inst->i_initproc);
 			}
 
 			/* not being traced any more */
 			t->p_opptr = NULL;
-			proclist_unlock_write(s);
+			proclist_unlock_write(p->p_inst, s);
 			CLR(t->p_flag, P_TRACED|P_WAITED);
 		}
 
@@ -469,13 +475,13 @@
 		 * Stop the target.
 		 */
 		SET(t->p_flag, P_TRACED);
-		s = proclist_lock_write();
+		s = proclist_lock_write(p->p_inst);
 		t->p_opptr = t->p_pptr;
-		if (t->p_pptr != p) {
+		if (t->p_pptr && t->p_pptr != p) {
 			t->p_pptr->p_flag |= P_CHTRACED;
 			proc_reparent(t, p);
 		}
-		proclist_unlock_write(s);
+		proclist_unlock_write(p->p_inst, s);
 		SCARG(uap, data) = SIGSTOP;
 		goto sendsig;
 
@@ -784,7 +790,7 @@
 	 *	    of the entire system, and the system was not
 	 *	    compiled with permanetly insecure mode turned on.
 	 */
-	if (t == initproc && securelevel > -1)
+	if (t == p->p_inst->i_initproc && securelevel > -1)
 		return (EPERM);
 
 	/*
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/sys_socket.c mult-netbsd-3.1/sys/kern/sys_socket.c
--- NetBSD-3.1/sys/kern/sys_socket.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/sys_socket.c	2007-11-18 18:59:49.000000000 +0000
@@ -45,51 +45,120 @@
 #include <sys/stat.h>
 #include <sys/poll.h>
 #include <sys/proc.h>
+#include <sys/inst.h>
 
 #include <net/if.h>
 #include <net/route.h>
 
+
 struct	fileops socketops = {
 	soo_read, soo_write, soo_ioctl, soo_fcntl, soo_poll,
 	soo_stat, soo_close, soo_kqfilter
 };
 
+
 /* ARGSUSED */
 int
-soo_read(fp, offset, uio, cred, flags)
-	struct file *fp;
-	off_t *offset;
-	struct uio *uio;
-	struct ucred *cred;
-	int flags;
+soo_read(struct file *fp, off_t *offset, struct uio *uio,
+		struct ucred *cred, int flags)
 {
-	struct socket *so = (struct socket *) fp->f_data;
+	struct socket	*so;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(cred);
+	KASSERT(cred->cr_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"cred->cr_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				cred->cr_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"cred->cr_inst = %d\n",
+				so->so_inst->i_uuid,
+				cred->cr_inst->i_uuid);
+
 	return ((*so->so_receive)(so, (struct mbuf **)0,
-		uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0));
+				uio, (struct mbuf **)0, 
+				(struct mbuf **)0, (int *)0));
 }
 
+
 /* ARGSUSED */
 int
-soo_write(fp, offset, uio, cred, flags)
-	struct file *fp;
-	off_t *offset;
-	struct uio *uio;
-	struct ucred *cred;
-	int flags;
+soo_write(struct file *fp, off_t *offset, struct uio *uio,
+		struct ucred *cred, int flags)
 {
-	struct socket *so = (struct socket *) fp->f_data;
+	struct socket	*so;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(cred);
+	KASSERT(cred->cr_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"cred->cr_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				cred->cr_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != cred->cr_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"cred->cr_inst = %d\n",
+				so->so_inst->i_uuid,
+				cred->cr_inst->i_uuid);
+
 	return ((*so->so_send)(so, (struct mbuf *)0,
-		uio, (struct mbuf *)0, (struct mbuf *)0, 0, uio->uio_procp));
+				uio, (struct mbuf *)0, 
+				(struct mbuf *)0, 0, uio->uio_procp));
 }
 
+
 int
-soo_ioctl(fp, cmd, data, p)
-	struct file *fp;
-	u_long cmd;
-	void *data;
-	struct proc *p;
+soo_ioctl(struct file *fp, u_long cmd, void *data, struct proc *p)
 {
-	struct socket *so = (struct socket *)fp->f_data;
+	struct socket	*so;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"p->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				p->p_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"p->p_inst = %d\n",
+				so->so_inst->i_uuid,
+				p->p_inst->i_uuid);
 
 	switch (cmd) {
 
@@ -161,12 +230,9 @@
 	    (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0, p));
 }
 
+
 int
-soo_fcntl(fp, cmd, data, p)
-	struct file *fp;
-	u_int cmd;
-	void *data;
-	struct proc *p;
+soo_fcntl(struct file *fp, u_int cmd, void *data, struct proc *p)
 {
 	if (cmd == F_SETFL)
 		return (0);
@@ -174,15 +240,40 @@
 		return (EOPNOTSUPP);
 }
 
+
 int
-soo_poll(fp, events, p)
-	struct file *fp;
-	int events;
-	struct proc *p;
-{
-	struct socket *so = (struct socket *)fp->f_data;
-	int revents = 0;
-	int s = splsoftnet();
+soo_poll(struct file *fp, int events, struct proc *p)
+{
+	struct socket	*so;
+	int 		s, revents;
+
+	revents = 0;
+	s = splsoftnet();
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"p->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				p->p_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"p->p_inst = %d\n",
+				so->so_inst->i_uuid,
+				p->p_inst->i_uuid);
+
 
 	if (events & (POLLIN | POLLRDNORM))
 		if (soreadable(so))
@@ -212,30 +303,80 @@
 	return (revents);
 }
 
+
 int
-soo_stat(fp, ub, p)
-	struct file *fp;
-	struct stat *ub;
-	struct proc *p;
+soo_stat(struct file *fp, struct stat *ub, struct proc *p)
 {
-	struct socket *so = (struct socket *)fp->f_data;
+	struct socket	*so;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"p->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				p->p_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"p->p_inst = %d\n",
+				so->so_inst->i_uuid,
+				p->p_inst->i_uuid);
 
 	memset((caddr_t)ub, 0, sizeof(*ub));
 	ub->st_mode = S_IFSOCK;
 	return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
-	    (struct mbuf *)ub, (struct mbuf *)0, (struct mbuf *)0, p));
+				(struct mbuf *)ub, (struct mbuf *)0, 
+				(struct mbuf *)0, p));
 }
 
+
 /* ARGSUSED */
 int
-soo_close(fp, p)
-	struct file *fp;
-	struct proc *p;
+soo_close(struct file *fp, struct proc *p)
 {
-	int error = 0;
+	struct socket	*so;
+	int		error;
+
+	error = 0;
+
+	KASSERT(fp);
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	/* FIXME - instance - cross-check */
+
+	if (fp->f_cred->cr_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: fp->f_cred->cr_inst = %d, "
+				"p->p_inst = %d\n",
+				fp->f_cred->cr_inst->i_uuid,
+				p->p_inst->i_uuid);
+
+	so = (struct socket *) fp->f_data;
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	if (so->so_inst->i_uuid != p->p_inst->i_uuid)
+		printf("error: so->so_inst = %d, "
+				"p->p_inst = %d\n",
+				so->so_inst->i_uuid,
+				p->p_inst->i_uuid);
+
 
 	if (fp->f_data)
-		error = soclose((struct socket *)fp->f_data);
+		error = soclose(so);
 	fp->f_data = 0;
 	return (error);
 }
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/syscalls.c mult-netbsd-3.1/sys/kern/syscalls.c
--- NetBSD-3.1/sys/kern/syscalls.c	2005-02-27 00:02:40.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/syscalls.c	2007-11-15 13:34:52.000000000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscalls.c,v 1.158 2005/02/27 00:02:40 perry Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call names.
@@ -8,7 +8,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.158 2005/02/27 00:02:40 perry Exp $");
+__KERNEL_RCSID(0, "$NetBSD$");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ktrace.h"
@@ -26,6 +26,7 @@
 #include <sys/mount.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 #endif /* _KERNEL_OPT */
 
 const char *const syscallnames[] = {
@@ -510,4 +511,5 @@
 	"extattr_list_link",			/* 372 = extattr_list_link */
 	"pselect",			/* 373 = pselect */
 	"pollts",			/* 374 = pollts */
+	"instctl",			/* 375 = instctl */
 };
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/syscalls.master mult-netbsd-3.1/sys/kern/syscalls.master
--- NetBSD-3.1/sys/kern/syscalls.master	2005-02-25 19:53:56.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/syscalls.master	2007-11-15 13:34:52.000000000 +0000
@@ -54,6 +54,7 @@
 #include <sys/mount.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 
 %%
 
@@ -751,3 +752,6 @@
 			    const sigset_t *mask); }
 374	STD		{ int sys_pollts(struct pollfd *fds, u_int nfds, \
 			    const struct timespec *ts, const sigset_t *mask); }
+375	STD		{ int sys_instctl(struct instctl *ctl); }
+
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/tty.c mult-netbsd-3.1/sys/kern/tty.c
--- NetBSD-3.1/sys/kern/tty.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/tty.c	2007-12-09 13:38:53.000000000 +0000
@@ -61,6 +61,7 @@
 #include <sys/kprintf.h>
 #include <sys/namei.h>
 #include <sys/sysctl.h>
+#include <sys/inst.h>
 
 #include <machine/stdarg.h>
 
@@ -224,9 +225,11 @@
 int
 ttyopen(struct tty *tp, int dialout, int nonblock)
 {
-	int	s, error;
+	int		s, error;
+	struct proc	*p;
 
 	error = 0;
+	p = curproc;
 
 	s = spltty();
 	TTY_LOCK(tp);
@@ -815,6 +818,9 @@
 	int		s, error;
 	struct nameidata nd;
 
+	KASSERT(NULL != p);
+	KASSERT(NULL != p->p_inst);
+
 	/* If the ioctl involves modification, hang if in the background. */
 	switch (cmd) {
 	case  TIOCFLUSH:
@@ -1167,9 +1173,9 @@
 			return (ENOTTY);
 
 		if (pgid < 0)
-			pgrp = pgfind(-pgid);
+			pgrp = pgfind(p->p_inst, -pgid);
 		else {
-			struct proc *p1 = pfind(pgid);
+			struct proc *p1 = pfind(p->p_inst, pgid);
 			if (!p1)
 				return (ESRCH);
 			pgrp = p1->p_pgrp;
@@ -1183,7 +1189,7 @@
 		break;
 	}
 	case TIOCSPGRP: {		/* set pgrp of tty */
-		struct pgrp *pgrp = pgfind(*(int *)data);
+		struct pgrp *pgrp = pgfind(p->p_inst, *(int *)data);
 
 		if (!isctty(p, tp))
 			return (ENOTTY);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/tty_ptm.c mult-netbsd-3.1/sys/kern/tty_ptm.c
--- NetBSD-3.1/sys/kern/tty_ptm.c	2004-11-30 04:25:44.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/tty_ptm.c	2007-11-27 12:47:33.000000000 +0000
@@ -111,6 +111,7 @@
 	return pty_makedev('t', i);
 }
 
+
 /*
  * Hacked up version of vn_open. We _only_ handle ptys and only open
  * them with FREAD|FWRITE and never deal with creat or stuff like that.
@@ -129,9 +130,10 @@
 	}
 
 	/*
-	 * Get us a fresh cred with root privileges.
+	 * Get us a fresh cred with root privileges.  Copy over the
+	 * instance of the caller.
 	 */
-	cred = crget();
+	cred = crdupinst(p->p_ucred);
 	error = VOP_OPEN(vp, FREAD|FWRITE, cred, p);
 	crfree(cred);
 
@@ -145,6 +147,7 @@
 	return 0;
 }
 
+
 static int
 pty_alloc_master(struct proc *p, int *fd, dev_t *dev)
 {
@@ -193,6 +196,7 @@
 	FILE_SET_MATURE(fp);
 	FILE_UNUSE(fp, p);
 	return 0;
+
 bad:
 	FILE_UNUSE(fp, p);
 	fdremove(p->p_fd, *fd);
@@ -200,6 +204,7 @@
 	return error;
 }
 
+
 int
 pty_grant_slave(struct proc *p, dev_t dev)
 {
@@ -225,10 +230,14 @@
 		struct vattr vattr;
 		struct ucred *cred;
 		(*ptm->getvattr)(ptm, p, &vattr);
-		/* Get a fake cred to pretend we're root. */
-		cred = crget();
+		/* 
+		 * Get a fake cred to pretend we're root.  Copy over the
+		 * instance of the caller.
+		 */
+		cred = crdupinst(p->p_ucred);
 		error = VOP_SETATTR(vp, &vattr, cred, p);
 		crfree(cred);
+
 		if (error) {
 			DPRINTF(("setattr %d\n", error));
 			VOP_UNLOCK(vp, 0);
@@ -248,6 +257,7 @@
 	return 0;
 }
 
+
 static int
 pty_alloc_slave(struct proc *p, int *fd, dev_t dev)
 {
@@ -286,6 +296,7 @@
 	return error;
 }
 
+
 struct ptm_pty *
 pty_sethandler(struct ptm_pty *nptm)
 {
@@ -294,6 +305,7 @@
 	return optm;
 }
 
+
 int
 pty_fill_ptmget(dev_t dev, int cfd, int sfd, void *data)
 {
@@ -313,6 +325,7 @@
 	return (*ptm->makename)(ptm, ptmg->sn, sizeof(ptmg->sn), dev, 't');
 }
 
+
 void
 /*ARGSUSED*/
 ptmattach(int n)
@@ -328,6 +341,7 @@
 #endif
 }
 
+
 int
 /*ARGSUSED*/
 ptmopen(dev_t dev, int flag, int mode, struct proc *p)
@@ -355,6 +369,7 @@
 	return (0);
 }
 
+
 int
 /*ARGSUSED*/
 ptmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
@@ -389,3 +404,4 @@
 	return error;
 }
 #endif
+
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/tty_pty.c mult-netbsd-3.1/sys/kern/tty_pty.c
--- NetBSD-3.1/sys/kern/tty_pty.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/tty_pty.c	2007-11-27 12:47:33.000000000 +0000
@@ -60,6 +60,7 @@
 #include <sys/poll.h>
 #include <sys/malloc.h>
 #include <sys/pty.h>
+#include <sys/inst.h>
 
 #define	DEFAULT_NPTYS		16	/* default number of initial ptys */
 #define DEFAULT_MAXPTYS		992	/* default maximum number of ptys */
@@ -71,14 +72,18 @@
 
 #define BUFSIZ 100		/* Chunk size iomoved to/from user */
 
+
 struct	pt_softc {
-	struct	tty *pt_tty;
-	int	pt_flags;
-	struct	selinfo pt_selr, pt_selw;
-	u_char	pt_send;
-	u_char	pt_ucntl;
+	struct tty	*pt_tty;
+	int 		pt_flags;
+	struct selinfo	pt_selr;
+	struct selinfo	pt_selw;
+	u_char		pt_send;
+	u_char		pt_ucntl;
+	uint		pt_iuuid;
 };
 
+
 static struct pt_softc **pt_softc = NULL;	/* pty array */
 static int maxptys = DEFAULT_MAXPTYS;	/* maximum number of ptys (sysctable) */
 struct simplelock pt_softc_mutex = SIMPLELOCK_INITIALIZER;
@@ -336,8 +341,11 @@
 		tp->t_cflag = TTYDEF_CFLAG;
 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
 		ttsetwater(tp);		/* would be done in xxparam() */
-	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
+	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) 
 		return (EBUSY);
+	else if (pti->pt_iuuid != p->p_inst->i_uuid) 
+		return (EBUSY);
+
 	if (tp->t_oproc)			/* Ctrlr still around. */
 		SET(tp->t_state, TS_CARR_ON);
 
@@ -556,18 +564,16 @@
 	splx(s);
 }
 
+
 /*ARGSUSED*/
 int
-ptcopen(dev, flag, devtype, p)
-	dev_t dev;
-	int flag, devtype;
-	struct proc *p;
+ptcopen(dev_t dev, int flag, int devtype, struct proc *p)
 {
-	struct pt_softc *pti;
-	struct tty *tp;
-	int error;
-	int ptn = minor(dev);
-	int s;
+	struct pt_softc	*pti;
+	struct tty	*tp;
+	int		error, ptn, s;
+
+	ptn = minor(dev);
 
 	if ((error = pty_check(ptn)) != 0)
 		return (error);
@@ -590,6 +596,7 @@
 	pti->pt_flags = 0;
 	pti->pt_send = 0;
 	pti->pt_ucntl = 0;
+	pti->pt_iuuid = p->p_inst->i_uuid;
 	return (0);
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/tty_tty.c mult-netbsd-3.1/sys/kern/tty_tty.c
--- NetBSD-3.1/sys/kern/tty_tty.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/tty_tty.c	2007-12-09 13:38:53.000000000 +0000
@@ -46,6 +46,7 @@
 #include <sys/vnode.h>
 #include <sys/file.h>
 #include <sys/conf.h>
+#include <sys/inst.h>
 
 
 #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/uipc_domain.c mult-netbsd-3.1/sys/kern/uipc_domain.c
--- NetBSD-3.1/sys/kern/uipc_domain.c	2005-03-09 05:07:19.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/uipc_domain.c	2007-11-23 10:17:19.000000000 +0000
@@ -50,6 +50,7 @@
 #include <sys/un.h>
 #include <sys/unpcb.h>
 #include <sys/file.h>
+#include <sys/inst.h>
 
 void	pffasttimo(void *);
 void	pfslowtimo(void *);
@@ -248,6 +249,10 @@
 	size_t len, needed, elem_size, out_size;
 	int error, elem_count, pf, type, pf2;
 
+	KASSERT(NULL != l);
+	KASSERT(NULL != l->l_proc);
+	KASSERT(NULL != l->l_inst);
+
 	if (namelen == 1 && name[0] == CTL_QUERY)
 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
 
@@ -278,7 +283,7 @@
 	 * there's no "list" of local domain sockets, so we have
 	 * to walk the file list looking for them.  :-/
 	 */
-	LIST_FOREACH(fp, &filehead, f_list) {
+	LIST_FOREACH(fp, &l->l_inst->i_filehead, f_list) {
 		if (fp->f_type != DTYPE_SOCKET)
 			continue;
 		so = (struct socket *)fp->f_data;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/uipc_socket.c mult-netbsd-3.1/sys/kern/uipc_socket.c
--- NetBSD-3.1/sys/kern/uipc_socket.c	2006-10-25 13:58:56.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/uipc_socket.c	2007-12-18 10:59:49.000000000 +0000
@@ -91,14 +91,19 @@
 #include <sys/pool.h>
 #include <sys/event.h>
 #include <sys/poll.h>
+#include <sys/inst.h>
 
 #include <uvm/uvm.h>
 
-POOL_INIT(socket_pool, sizeof(struct socket), 0, 0, 0, "sockpl", NULL);
+
+POOL_INIT(socket_pool, sizeof(struct socket), 
+		0, 0, 0, "sockpl", NULL);
+
 
 MALLOC_DEFINE(M_SOOPTS, "soopts", "socket options");
 MALLOC_DEFINE(M_SONAME, "soname", "socket name");
 
+
 extern int	somaxconn;			/* patchable (XXX sysctl) */
 int		somaxconn = SOMAXCONN;
 
@@ -129,7 +134,6 @@
 void
 soinit(void)
 {
-
 	/* Set the initial adjusted socket buffer size. */
 	if (sb_max_set(sb_max))
 		panic("bad initial sb_max value: %lu\n", sb_max);
@@ -163,8 +167,11 @@
 static __inline vsize_t
 sokvareserve(struct socket *so, vsize_t len)
 {
-	int s;
-	int error;
+	int 		s;
+	int 		error;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
 
 	s = splvm();
 	simple_lock(&so_pendfree_slock);
@@ -200,10 +207,11 @@
 	return len;
 }
 
+
 static __inline void
 sokvaunreserve(vsize_t len)
 {
-	int s;
+	int 		s;
 
 	s = splvm();
 	simple_lock(&so_pendfree_slock);
@@ -214,56 +222,42 @@
 	splx(s);
 }
 
+
 /*
  * sokvaalloc: allocate kva for loan.
  */
-
 vaddr_t
 sokvaalloc(vsize_t len, struct socket *so)
 {
 	vaddr_t lva;
 
-	/*
-	 * reserve kva.
-	 */
+	KASSERT(so);
+	KASSERT(so->so_inst);
 
 	if (sokvareserve(so, len) == 0)
-		return 0;
-
-	/*
-	 * allocate kva.
-	 */
+		return(0);
 
 	lva = uvm_km_valloc_wait(kernel_map, len);
 	if (lva == 0) {
 		sokvaunreserve(len);
-		return (0);
+		return(0);
 	}
 
-	return lva;
+	return(lva);
 }
 
+
 /*
  * sokvafree: free kva for loan.
  */
-
 void
 sokvafree(vaddr_t sva, vsize_t len)
 {
-
-	/*
-	 * free kva.
-	 */
-
 	uvm_km_free(kernel_map, sva, len);
-
-	/*
-	 * unreserve kva.
-	 */
-
 	sokvaunreserve(len);
 }
 
+
 static void
 sodoloanfree(struct vm_page **pgs, caddr_t buf, size_t size)
 {
@@ -293,11 +287,15 @@
 	sokvafree(sva, len);
 }
 
+
 static size_t
 sodopendfree(struct socket *so)
 {
-	int s;
-	size_t rv;
+	int 		s;
+	size_t 		rv;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
 
 	s = splvm();
 	simple_lock(&so_pendfree_slock);
@@ -308,19 +306,22 @@
 	return rv;
 }
 
+
 /*
- * sodopendfreel: free mbufs on "pendfree" list.
- * unlock and relock so_pendfree_slock when freeing mbufs.
+ * sodopendfreel: free mbufs on "pendfree" list.  unlock and relock
+ * so_pendfree_slock when freeing mbufs.
  *
  * => called with so_pendfree_slock held.
  * => called at splvm.
  */
-
 static size_t
 sodopendfreel(struct socket *so)
 {
 	size_t rv = 0;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	LOCK_ASSERT(simple_lock_held(&so_pendfree_slock));
 
 	for (;;) {
@@ -351,17 +352,16 @@
 	return (rv);
 }
 
+
 void
 soloanfree(struct mbuf *m, caddr_t buf, size_t size, void *arg)
 {
 	int s;
 
 	if (m == NULL) {
-
 		/*
 		 * called from MEXTREMOVE.
 		 */
-
 		sodoloanfree(NULL, buf, size);
 		return;
 	}
@@ -372,7 +372,6 @@
 	 * we can't do it in interrupt context
 	 * because we need to put kva back to kernel_map.
 	 */
-
 	s = splvm();
 	simple_lock(&so_pendfree_slock);
 	m->m_next = so_pendfree;
@@ -383,6 +382,7 @@
 	splx(s);
 }
 
+
 static long
 sosend_loan(struct socket *so, struct uio *uio, struct mbuf *m, long space)
 {
@@ -392,6 +392,9 @@
 	vaddr_t lva, va;
 	int npgs, i, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	if (uio->uio_segflg != UIO_USERSPACE)
 		return (0);
 
@@ -442,12 +445,12 @@
 	return (space);
 }
 
+
 /*
- * Socket operation routines.
- * These routines are called by the routines in
- * sys_socket.c or from a system process, and
- * implement the semantics of socket operations by
- * switching out to the protocol specific routines.
+ * Socket operation routines.  These routines are called by the routines
+ * in sys_socket.c or from a system process, and implement the semantics
+ * of socket operations by switching out to the protocol specific
+ * routines.
  */
 /*ARGSUSED*/
 int
@@ -465,6 +468,11 @@
 		return (EPROTONOSUPPORT);
 	if (prp->pr_type != type)
 		return (EPROTOTYPE);
+
+	/* XXX - at one time, this switched on p being null. */
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
 	s = splsoftnet();
 	so = pool_get(&socket_pool, PR_WAITOK);
 	memset((caddr_t)so, 0, sizeof(*so));
@@ -479,10 +487,12 @@
 	so->so_snd.sb_mowner = &prp->pr_domain->dom_mowner;
 	so->so_mowner = &prp->pr_domain->dom_mowner;
 #endif
-	if (p != 0)
-		so->so_uid = p->p_ucred->cr_uid;
-	else
-		so->so_uid = UID_MAX;
+	so->so_inst = p->p_inst;
+	so->so_uid = p->p_ucred->cr_uid;
+
+	inst_hold(so->so_inst);
+	so->so_inst->i_nsocks++;
+
 	error = (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0,
 	    (struct mbuf *)(long)proto, (struct mbuf *)0, p);
 	if (error) {
@@ -496,11 +506,18 @@
 	return (0);
 }
 
+
 int
 sobind(struct socket *so, struct mbuf *nam, struct proc *p)
 {
 	int	s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+	KASSERT(p);
+
+	/* FIXME - instances - cross-check p_inst/so_inst? */
+
 	s = splsoftnet();
 	error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, (struct mbuf *)0,
 	    nam, (struct mbuf *)0, p);
@@ -508,11 +525,15 @@
 	return (error);
 }
 
+
 int
 solisten(struct socket *so, int backlog)
 {
 	int	s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	s = splsoftnet();
 	error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, (struct mbuf *)0,
 	    (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);
@@ -529,10 +550,10 @@
 	return (0);
 }
 
+
 void
 sofree(struct socket *so)
 {
-
 	if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
 		return;
 	if (so->so_head) {
@@ -544,21 +565,25 @@
 		if (!soqremque(so, 0))
 			return;
 	}
+
 	if (so->so_rcv.sb_hiwat)
-		(void)chgsbsize(so->so_uid, &so->so_rcv.sb_hiwat, 0,
-		    RLIM_INFINITY);
+		(void)chgsbsize(so->so_uid, 
+				&so->so_rcv.sb_hiwat, 0, RLIM_INFINITY);
 	if (so->so_snd.sb_hiwat)
-		(void)chgsbsize(so->so_uid, &so->so_snd.sb_hiwat, 0,
-		    RLIM_INFINITY);
+		(void)chgsbsize(so->so_uid, 
+				&so->so_snd.sb_hiwat, 0, RLIM_INFINITY);
 	sbrelease(&so->so_snd, so);
 	sorflush(so);
+
+	so->so_inst->i_nsocks--;
+	inst_release(so->so_inst);
 	pool_put(&socket_pool, so);
 }
 
+
 /*
- * Close a socket on last file table reference removal.
- * Initiate disconnect if connected.
- * Free socket when disconnect complete.
+ * Close a socket on last file table reference removal.  Initiate
+ * disconnect if connected.  Free socket when disconnect complete.
  */
 int
 soclose(struct socket *so)
@@ -566,6 +591,9 @@
 	struct socket	*so2;
 	int		s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	error = 0;
 	s = splsoftnet();		/* conservative */
 	if (so->so_options & SO_ACCEPTCONN) {
@@ -616,13 +644,15 @@
 	return (error);
 }
 
+
 /*
  * Must be called at splsoftnet...
  */
 int
 soabort(struct socket *so)
 {
-
+	KASSERT(so);
+	KASSERT(so->so_inst);
 	return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, (struct mbuf *)0,
 	    (struct mbuf *)0, (struct mbuf *)0, (struct proc *)0);
 }
@@ -632,6 +662,9 @@
 {
 	int	s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	error = 0;
 	s = splsoftnet();
 	if ((so->so_state & SS_NOFDREF) == 0)
@@ -648,11 +681,15 @@
 	return (error);
 }
 
+
 int
 soconnect(struct socket *so, struct mbuf *nam, struct proc *p)
 {
 	int		s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	if (so->so_options & SO_ACCEPTCONN)
 		return (EOPNOTSUPP);
 	s = splsoftnet();
@@ -663,21 +700,29 @@
 	 * a null address.
 	 */
 	if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
-	    ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
-	    (error = sodisconnect(so))))
+			((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
+			 (error = sodisconnect(so))))
 		error = EISCONN;
-	else
+	else {
 		error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
-		    (struct mbuf *)0, nam, (struct mbuf *)0, p);
+				(struct mbuf *)0, nam, 
+				(struct mbuf *)0, p);
+	}
 	splx(s);
 	return (error);
 }
 
+
 int
 soconnect2(struct socket *so1, struct socket *so2)
 {
 	int	s, error;
 
+	KASSERT(so1);
+	KASSERT(so1->so_inst);
+	KASSERT(so2);
+	KASSERT(so2->so_inst);
+
 	s = splsoftnet();
 	error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
 	    (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0,
@@ -686,11 +731,15 @@
 	return (error);
 }
 
+
 int
 sodisconnect(struct socket *so)
 {
 	int	s, error;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	s = splsoftnet();
 	if ((so->so_state & SS_ISCONNECTED) == 0) {
 		error = ENOTCONN;
@@ -709,32 +758,36 @@
 	return (error);
 }
 
+
 #define	SBLOCKWAIT(f)	(((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
 /*
- * Send on a socket.
- * If send must go all at once and message is larger than
- * send buffering, then hard error.
- * Lock against other senders.
- * If must go all at once and not enough room now, then
- * inform user that this would block and do nothing.
- * Otherwise, if nonblocking, send as much as possible.
- * The data to be sent is described by "uio" if nonzero,
- * otherwise by the mbuf chain "top" (which must be null
- * if uio is not).  Data provided in mbuf chain must be small
- * enough to send all at once.
+ * Send on a socket.  If send must go all at once and message is larger
+ * than send buffering, then hard error.  Lock against other senders.
+ * If must go all at once and not enough room now, then inform user that
+ * this would block and do nothing.  Otherwise, if nonblocking, send as
+ * much as possible.  The data to be sent is described by "uio" if
+ * nonzero, otherwise by the mbuf chain "top" (which must be null if uio
+ * is not).  Data provided in mbuf chain must be small enough to send
+ * all at once.
  *
- * Returns nonzero on error, timeout or signal; callers
- * must check for short counts if EINTR/ERESTART are returned.
- * Data and control buffers are freed on return.
+ * Returns nonzero on error, timeout or signal; callers must check for
+ * short counts if EINTR/ERESTART are returned.  Data and control
+ * buffers are freed on return.
  */
 int
-sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
-	struct mbuf *control, int flags, struct proc *p)
+sosend(struct socket *so, struct mbuf *addr, struct uio *uio, 
+		struct mbuf *top, struct mbuf *control, 
+		int flags, struct proc *p)
 {
 	struct mbuf	**mp, *m;
 	long		space, len, resid, clen, mlen;
 	int		error, s, dontroute, atomic;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	/* FIXME - instance - cross-check p_inst/so_inst */
+
 	sodopendfree(so);
 
 	clen = 0;
@@ -911,17 +964,17 @@
 	return (error);
 }
 
+
 /*
- * Implement receive operations on a socket.
- * We depend on the way that records are added to the sockbuf
- * by sbappend*.  In particular, each record (mbufs linked through m_next)
- * must begin with an address if the protocol so specifies,
- * followed by an optional mbuf or mbufs containing ancillary data,
- * and then zero or more mbufs of data.
- * In order to avoid blocking network interrupts for the entire time here,
- * we splx() while doing the actual copy to user space.
- * Although the sockbuf is locked, new data may still be appended,
- * and thus we must maintain consistency of the sockbuf during that time.
+ * Implement receive operations on a socket.  We depend on the way that
+ * records are added to the sockbuf by sbappend*.  In particular, each
+ * record (mbufs linked through m_next) must begin with an address if
+ * the protocol so specifies, followed by an optional mbuf or mbufs
+ * containing ancillary data, and then zero or more mbufs of data.  In
+ * order to avoid blocking network interrupts for the entire time here,
+ * we splx() while doing the actual copy to user space.  Although the
+ * sockbuf is locked, new data may still be appended, and thus we must
+ * maintain consistency of the sockbuf during that time.
  *
  * The caller may receive the data as a single mbuf chain by supplying
  * an mbuf **mp0 for use in returning the chain.  The uio is then used
@@ -929,21 +982,29 @@
  */
 int
 soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
-	struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
+		struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
 {
-	struct proc * p;
+	struct proc 	*p;
 	struct mbuf	*m, **mp;
 	int		flags, len, error, s, offset, moff, type, orig_resid;
 	const struct protosw	*pr;
 	struct mbuf	*nextrecord;
 	int		mbuf_removed = 0;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	pr = so->so_proto;
 	mp = mp0;
 	type = 0;
 	orig_resid = uio->uio_resid;
 	p = uio->uio_procp;
 
+	KASSERT(p);
+	KASSERT(p->p_inst);
+
+	/* FIXME - instance - cross check ui->p_inst/so_inst */
+
 	if (paddr)
 		*paddr = 0;
 	if (controlp)
@@ -1340,11 +1401,15 @@
 	return (error);
 }
 
+
 int
 soshutdown(struct socket *so, int how)
 {
 	const struct protosw	*pr;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	pr = so->so_proto;
 	if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
 		return (EINVAL);
@@ -1357,6 +1422,7 @@
 	return (0);
 }
 
+
 void
 sorflush(struct socket *so)
 {
@@ -1364,6 +1430,9 @@
 	const struct protosw	*pr;
 	int		s;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	sb = &so->so_rcv;
 	pr = so->so_proto;
 	sb->sb_flags |= SB_NOINTR;
@@ -1384,12 +1453,16 @@
 	sbrelease(&asb, so);
 }
 
+
 int
 sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
 {
 	int		error;
 	struct mbuf	*m;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	error = 0;
 	m = m0;
 	if (level != SOL_SOCKET) {
@@ -1531,11 +1604,15 @@
 	return (error);
 }
 
+
 int
 sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
 {
 	struct mbuf	*m;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	if (level != SOL_SOCKET) {
 		if (so->so_proto && so->so_proto->pr_ctloutput) {
 			return ((*so->so_proto->pr_ctloutput)
@@ -1618,10 +1695,12 @@
 	}
 }
 
+
 void
 sohasoutofband(struct socket *so)
 {
-	fownsignal(so->so_pgid, SIGURG, POLL_PRI, POLLPRI|POLLRDBAND, so);
+	fownsignal(so->so_inst, so->so_pgid, 
+			SIGURG, POLL_PRI, POLLPRI|POLLRDBAND, so);
 	selwakeup(&so->so_rcv.sb_sel);
 }
 
@@ -1631,6 +1710,10 @@
 	struct socket	*so;
 
 	so = (struct socket *)kn->kn_fp->f_data;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
 	if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
 		so->so_rcv.sb_flags &= ~SB_KNOTE;
@@ -1643,6 +1726,10 @@
 	struct socket	*so;
 
 	so = (struct socket *)kn->kn_fp->f_data;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	kn->kn_data = so->so_rcv.sb_cc;
 	if (so->so_state & SS_CANTRCVMORE) {
 		kn->kn_flags |= EV_EOF;
@@ -1662,6 +1749,10 @@
 	struct socket	*so;
 
 	so = (struct socket *)kn->kn_fp->f_data;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
 	if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
 		so->so_snd.sb_flags &= ~SB_KNOTE;
@@ -1674,6 +1765,10 @@
 	struct socket	*so;
 
 	so = (struct socket *)kn->kn_fp->f_data;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	kn->kn_data = sbspace(&so->so_snd);
 	if (so->so_state & SS_CANTSENDMORE) {
 		kn->kn_flags |= EV_EOF;
@@ -1698,6 +1793,9 @@
 
 	so = (struct socket *)kn->kn_fp->f_data;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	/*
 	 * Set kn_data to number of incoming connections, not
 	 * counting partial (incomplete) connections.
@@ -1713,6 +1811,7 @@
 static const struct filterops sowrite_filtops =
 	{ 1, NULL, filt_sowdetach, filt_sowrite };
 
+
 int
 soo_kqfilter(struct file *fp, struct knote *kn)
 {
@@ -1720,6 +1819,10 @@
 	struct sockbuf	*sb;
 
 	so = (struct socket *)kn->kn_fp->f_data;
+
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	switch (kn->kn_filter) {
 	case EVFILT_READ:
 		if (so->so_options & SO_ACCEPTCONN)
@@ -1744,6 +1847,7 @@
 
 static int sysctl_kern_somaxkva(SYSCTLFN_PROTO);
 
+
 /*
  * sysctl helper routine for kern.somaxkva.  ensures that the given
  * value is not too small.
@@ -1756,6 +1860,8 @@
 	struct sysctlnode node;
 	int s;
 
+	/* FIXME - instance - values should be per-instance */
+
 	new_somaxkva = somaxkva;
 	node = *rnode;
 	node.sysctl_data = &new_somaxkva;
@@ -1776,9 +1882,9 @@
 	return (error);
 }
 
+
 SYSCTL_SETUP(sysctl_kern_somaxkva_setup, "sysctl kern.somaxkva setup")
 {
-
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT,
 		       CTLTYPE_NODE, "kern", NULL,
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/uipc_socket2.c mult-netbsd-3.1/sys/kern/uipc_socket2.c
--- NetBSD-3.1/sys/kern/uipc_socket2.c	2005-02-26 21:34:55.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/uipc_socket2.c	2007-11-23 10:17:19.000000000 +0000
@@ -49,6 +49,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/signalvar.h>
+#include <sys/inst.h>
 
 /*
  * Primitive routines for operating on sockets and socket buffers
@@ -60,6 +61,7 @@
 const char	netio[] = "netio";
 const char	netlck[] = "netlck";
 
+/* FIXME - instance appropriation? */
 u_long	sb_max = SB_MAX;	/* maximum socket buffer size */
 static u_long sb_max_adj;	/* adjusted sb_max */
 
@@ -96,7 +98,6 @@
 void
 soisconnecting(struct socket *so)
 {
-
 	so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
 	so->so_state |= SS_ISCONNECTING;
 }
@@ -159,6 +160,9 @@
 	struct socket	*so;
 	int		soqueue;
 
+	KASSERT(head);
+	KASSERT(head->so_inst);
+
 	soqueue = connstatus ? 1 : 0;
 	if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
 		return ((struct socket *)0);
@@ -176,17 +180,24 @@
 	so->so_send = head->so_send;
 	so->so_receive = head->so_receive;
 	so->so_uid = head->so_uid;
+	so->so_inst = head->so_inst;
 #ifdef MBUFTRACE
 	so->so_mowner = head->so_mowner;
 	so->so_rcv.sb_mowner = head->so_rcv.sb_mowner;
 	so->so_snd.sb_mowner = head->so_snd.sb_mowner;
 #endif
+
+	inst_hold(so->so_inst);
+	so->so_inst->i_nsocks++;
+
 	(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
 	soqinsque(head, so, soqueue);
 	if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
 	    (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,
 	    (struct proc *)0)) {
 		(void) soqremque(so, soqueue);
+		so->so_inst->i_nsocks--;
+		inst_release(so->so_inst);
 		pool_put(&socket_pool, so);
 		return (NULL);
 	}
@@ -307,6 +318,9 @@
 void
 sowakeup(struct socket *so, struct sockbuf *sb, int code)
 {
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
 	selnotify(&sb->sb_sel, 0);
 	sb->sb_flags &= ~SB_SEL;
 	if (sb->sb_flags & SB_WAIT) {
@@ -319,7 +333,9 @@
 			band = POLLIN|POLLRDNORM;
 		else
 			band = POLLOUT|POLLWRNORM;
-		fownsignal(so->so_pgid, SIGIO, code, band, so);
+
+		fownsignal(so->so_inst, so->so_pgid, 
+				SIGIO, code, band, so);
 	}
 	if (sb->sb_flags & SB_UPCALL)
 		(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
@@ -402,23 +418,28 @@
 int
 sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
 {
-	struct proc *p = curproc; /* XXX */
-	rlim_t maxcc;
-	uid_t uid;
+	struct proc 	*p = curproc; /* XXX */
+	rlim_t 		maxcc;
+	uid_t 		uid;
+
+	/* FIXME - instance - cross-check so_inst/p_inst */
 
 	KDASSERT(sb_max_adj != 0);
 	if (cc == 0 || cc > sb_max_adj)
 		return (0);
 	if (so) {
-		if (p && p->p_ucred->cr_uid == so->so_uid)
+		KASSERT(so->so_inst);
+		if (p && p->p_ucred->cr_uid == so->so_uid) {
+			KASSERT(p->p_inst);
 			maxcc = p->p_rlimit[RLIMIT_SBSIZE].rlim_cur;
-		else
+		} else
 			maxcc = RLIM_INFINITY;
 		uid = so->so_uid;
 	} else {
 		uid = 0;	/* XXX: nothing better */
 		maxcc = RLIM_INFINITY;
 	}
+
 	if (!chgsbsize(uid, &sb->sb_hiwat, cc, maxcc))
 		return 0;
 	sb->sb_mbmax = min(cc * 2, sb_max);
@@ -433,10 +454,8 @@
 void
 sbrelease(struct sockbuf *sb, struct socket *so)
 {
-
 	sbflush(sb);
-	(void)chgsbsize(so->so_uid, &sb->sb_hiwat, 0,
-	    RLIM_INFINITY);
+	(void)chgsbsize(so->so_uid, &sb->sb_hiwat, 0, RLIM_INFINITY);
 	sb->sb_mbmax = 0;
 }
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/uipc_syscalls.c mult-netbsd-3.1/sys/kern/uipc_syscalls.c
--- NetBSD-3.1/sys/kern/uipc_syscalls.c	2006-10-24 17:59:08.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/uipc_syscalls.c	2007-11-19 14:26:40.000000000 +0000
@@ -282,11 +282,18 @@
 	/* getsock() will use the descriptor for us */
 	if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
 		return (error);
+
+	KASSERT(fp->f_cred);
+	KASSERT(fp->f_cred->cr_inst);
+
 	so = (struct socket *)fp->f_data;
 	if (so->so_state & SS_ISCONNECTING) {
 		error = EALREADY;
 		goto out;
 	}
+
+	KASSERT(so->so_inst);
+
 	error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
 	    MT_SONAME);
 	if (error)
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/uipc_usrreq.c mult-netbsd-3.1/sys/kern/uipc_usrreq.c
--- NetBSD-3.1/sys/kern/uipc_usrreq.c	2006-09-08 11:38:10.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/uipc_usrreq.c	2007-11-23 10:17:20.000000000 +0000
@@ -120,6 +120,7 @@
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/mbuf.h>
+#include <sys/inst.h>
 
 /*
  * Unix communications domain.
@@ -200,6 +201,13 @@
 	u_int newhiwat;
 	int error = 0;
 
+	KASSERT(so);
+	KASSERT(so->so_inst);
+
+	/* 
+	 * XXX - instance - struct ps can be NULL (see uipc_socket.c).
+	 */
+
 	if (req == PRU_CONTROL)
 		return (EOPNOTSUPP);
 
@@ -285,7 +293,7 @@
 			unp->unp_mbcnt = rcv->sb_mbcnt;
 			newhiwat = snd->sb_hiwat + unp->unp_cc - rcv->sb_cc;
 			(void)chgsbsize(so2->so_uid,
-			    &snd->sb_hiwat, newhiwat, RLIM_INFINITY);
+					&snd->sb_hiwat, newhiwat, RLIM_INFINITY);
 			unp->unp_cc = rcv->sb_cc;
 			sowwakeup(so2);
 #undef snd
@@ -1110,27 +1118,33 @@
 void
 unp_gc(void)
 {
-	struct file *fp, *nextfp;
-	struct socket *so, *so1;
-	struct file **extra_ref, **fpp;
-	int nunref, i;
+	struct file 	*fp, *nextfp;
+	struct socket 	*so, *so1;
+	struct file 	**extra_ref, **fpp;
+	struct inst	*inst;
+	int 		nunref, i;
 
 	if (unp_gcing)
 		return;
+
 	unp_gcing = 1;
 	unp_defer = 0;
 
 	/* Clear mark bits */
-	LIST_FOREACH(fp, &filehead, f_list)
-		fp->f_flag &= ~(FMARK|FDEFER);
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list)
+		LIST_FOREACH(fp, &inst->i_filehead, f_list)
+			fp->f_flag &= ~(FMARK|FDEFER);
+	instlist_unlock_read();
 
 	/*
 	 * Iterate over the set of descriptors, marking ones believed
 	 * (based on refcount) to be referenced from a process, and
 	 * marking for rescan descriptors which are queued on a socket.
 	 */
-	do {
-		LIST_FOREACH(fp, &filehead, f_list) {
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) do {
+		LIST_FOREACH(fp, &inst->i_filehead, f_list) {
 			if (fp->f_flag & FDEFER) {
 				fp->f_flag &= ~FDEFER;
 				unp_defer--;
@@ -1185,6 +1199,8 @@
 
 		}
 	} while (unp_defer);
+	instlist_unlock_read();
+
 	/*
 	 * Sweep pass.  Find unmarked descriptors, and free them.
 	 *
@@ -1227,37 +1243,46 @@
 	 *
 	 * 91/09/19, bsy@cs.cmu.edu
 	 */
-	extra_ref = malloc(nfiles * sizeof(struct file *), M_FILE, M_WAITOK);
-	for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; fp != 0;
-	    fp = nextfp) {
-		nextfp = LIST_NEXT(fp, f_list);
-		simple_lock(&fp->f_slock);
-		if (fp->f_count != 0 &&
-		    fp->f_count == fp->f_msgcount && !(fp->f_flag & FMARK)) {
-			*fpp++ = fp;
-			nunref++;
-			fp->f_count++;
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) {
+		extra_ref = malloc(inst->i_nfiles * 
+				sizeof(struct file *), M_FILE, M_WAITOK);
+		for (nunref = 0, fp = LIST_FIRST
+				(&inst->i_filehead), 
+				fpp = extra_ref; fp != 0;
+				fp = nextfp) {
+			nextfp = LIST_NEXT(fp, f_list);
+			simple_lock(&fp->f_slock);
+			if (fp->f_count != 0 && fp->f_count == 
+					fp->f_msgcount && 
+					!(fp->f_flag & FMARK)) {
+				*fpp++ = fp;
+				nunref++;
+				fp->f_count++;
+			}
+			simple_unlock(&fp->f_slock);
 		}
-		simple_unlock(&fp->f_slock);
-	}
-	for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
-		fp = *fpp;
-		simple_lock(&fp->f_slock);
-		FILE_USE(fp);
-		if (fp->f_type == DTYPE_SOCKET)
-			sorflush((struct socket *)fp->f_data);
-		FILE_UNUSE(fp, NULL);
-	}
-	for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
-		fp = *fpp;
-		simple_lock(&fp->f_slock);
-		FILE_USE(fp);
-		(void) closef(fp, (struct proc *)0);
+		for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
+			fp = *fpp;
+			simple_lock(&fp->f_slock);
+			FILE_USE(fp);
+			if (fp->f_type == DTYPE_SOCKET)
+				sorflush((struct socket *)fp->f_data);
+			FILE_UNUSE(fp, NULL);
+		}
+		for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
+			fp = *fpp;
+			simple_lock(&fp->f_slock);
+			FILE_USE(fp);
+			(void) closef(fp, (struct proc *)0);
+		}
+		free((caddr_t)extra_ref, M_FILE);
 	}
-	free((caddr_t)extra_ref, M_FILE);
+	instlist_unlock_read();
 	unp_gcing = 0;
 }
 
+
 void
 unp_dispose(struct mbuf *m)
 {
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/vfs_lookup.c mult-netbsd-3.1/sys/kern/vfs_lookup.c
--- NetBSD-3.1/sys/kern/vfs_lookup.c	2006-01-20 20:48:41.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/vfs_lookup.c	2007-11-09 18:08:21.000000000 +0000
@@ -40,7 +40,6 @@
 __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.57.2.3 2006/01/20 20:48:41 riz Exp $");
 
 #include "opt_ktrace.h"
-#include "opt_systrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -59,9 +58,6 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
-#ifdef SYSTRACE
-#include <sys/systrace.h>
-#endif
 
 struct pool pnbuf_pool;		/* pathname buffer pool */
 struct pool_cache pnbuf_cache;	/* pathname buffer cache */
@@ -140,10 +136,6 @@
 	if (KTRPOINT(cnp->cn_proc, KTR_NAMEI))
 		ktrnamei(cnp->cn_proc, cnp->cn_pnbuf);
 #endif
-#ifdef SYSTRACE
-	if (ISSET(cnp->cn_proc->p_flag, P_SYSTRACE))
-		systrace_namei(ndp);
-#endif
 
 	/*
 	 * Get starting point for the translation.
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/vfs_subr.c mult-netbsd-3.1/sys/kern/vfs_subr.c
--- NetBSD-3.1/sys/kern/vfs_subr.c	2006-09-02 21:48:57.000000000 +0100
+++ mult-netbsd-3.1/sys/kern/vfs_subr.c	2007-11-11 13:27:02.000000000 +0000
@@ -2379,10 +2379,13 @@
 	np->netc_anon.cr_ref = 1;
 	return 0;
 check:
+	/* FIXME - instances */
+#if 0
 	if (enp->netc_exflags != argp->ex_flags ||
 	    crcmp(&enp->netc_anon, &argp->ex_anon) != 0)
 		error = EPERM;
 	else
+#endif
 		error = 0;
 out:
 	free(np, M_NETADDR);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/kern/vfs_syscalls.c mult-netbsd-3.1/sys/kern/vfs_syscalls.c
--- NetBSD-3.1/sys/kern/vfs_syscalls.c	2006-01-20 20:48:41.000000000 +0000
+++ mult-netbsd-3.1/sys/kern/vfs_syscalls.c	2007-11-23 10:17:20.000000000 +0000
@@ -62,6 +62,7 @@
 #include <sys/sysctl.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/inst.h>
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
@@ -414,8 +415,10 @@
 		return;
 	if (VFS_ROOT(olddp->v_mountedhere, &newdp))
 		panic("mount: lost mount");
-	proclist_lock_read();
-	PROCLIST_FOREACH(p, &allproc) {
+	/* FIXME - instance */
+	KASSERT(NULL != proc0.p_inst);
+	proclist_lock_read(proc0.p_inst);
+	PROCLIST_FOREACH(p, &proc0.p_inst->i_allproc) {
 		cwdi = p->p_cwdi;
 		if (!cwdi)
 			continue;
@@ -430,7 +433,7 @@
 			cwdi->cwdi_rdir = newdp;
 		}
 	}
-	proclist_unlock_read();
+	proclist_unlock_read(proc0.p_inst);
 	if (rootvnode == olddp) {
 		vrele(rootvnode);
 		VREF(newdp);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/Makefile mult-netbsd-3.1/sys/miscfs/Makefile
--- NetBSD-3.1/sys/miscfs/Makefile	2004-11-11 18:57:21.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/Makefile	2007-11-10 19:27:11.000000000 +0000
@@ -1,7 +1,7 @@
 #	$NetBSD: Makefile,v 1.7 2004/11/11 18:57:21 jdolecek Exp $
 
-SUBDIR=	fdesc fifofs genfs kernfs nullfs overlay portal
-SUBDIR+= procfs specfs syncfs umapfs
+SUBDIR=	fdesc fifofs genfs nullfs overlay portal
+SUBDIR+= specfs syncfs umapfs
 
 INCSDIR= /usr/include/miscfs
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/Makefile mult-netbsd-3.1/sys/miscfs/kernfs/Makefile
--- NetBSD-3.1/sys/miscfs/kernfs/Makefile	1998-06-13 00:23:02.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/kernfs/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-#	$NetBSD: Makefile,v 1.1 1998/06/12 23:23:02 cgd Exp $
-
-INCSDIR= /usr/include/miscfs/kernfs
-
-INCS=	kernfs.h
-
-.include <bsd.kinc.mk>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/files.kernfs mult-netbsd-3.1/sys/miscfs/kernfs/files.kernfs
--- NetBSD-3.1/sys/miscfs/kernfs/files.kernfs	2003-09-08 07:51:53.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/kernfs/files.kernfs	1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-#	$NetBSD: files.kernfs,v 1.2 2003/09/08 06:51:53 itojun Exp $
-
-deffs	fs_kernfs.h			KERNFS		# XXX
-
-file	miscfs/kernfs/kernfs_subr.c	kernfs
-file	miscfs/kernfs/kernfs_vfsops.c	kernfs
-file	miscfs/kernfs/kernfs_vnops.c	kernfs
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/kernfs.h mult-netbsd-3.1/sys/miscfs/kernfs/kernfs.h
--- NetBSD-3.1/sys/miscfs/kernfs/kernfs.h	2005-05-28 13:39:14.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/kernfs/kernfs.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,198 +0,0 @@
-/*	$NetBSD: kernfs.h,v 1.23.10.1 2005/05/28 12:39:14 tron Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)kernfs.h	8.6 (Berkeley) 3/29/95
- */
-
-#define	_PATH_KERNFS	"/kern"		/* Default mountpoint */
-
-#ifdef _KERNEL
-#include <sys/queue.h>
-
-/*
- * The different types of node in a kernfs filesystem
- */
-typedef enum {
-	KFSkern,		/* the filesystem itself (.) */
-	KFSroot,		/* the filesystem root (..) */
-	KFSnull,		/* none aplicable */
-	KFStime,		/* boottime */
-	KFSint,			/* integer */
-	KFSstring,		/* string */
-	KFShostname,	/* hostname */
-	KFSavenrun,		/* loadavg */
-	KFSdevice,		/* device file (rootdev/rrootdev) */
-	KFSmsgbuf,		/* msgbuf */
-	KFSipsecsadir,	/* ipsec security association (top dir) */
-	KFSipsecspdir,	/* ipsec security policy (top dir) */
-	KFSipsecsa,		/* ipsec security association entry */
-	KFSipsecsp,		/* ipsec security policy entry */
-	KFSsubdir,		/* directory */
-	KFSlasttype,		/* last used type */
-	KFSmaxtype = (1<<6) - 1	/* last possible type */
-} kfstype;
-
-/*
- * Control data for the kern file system.
- */
-struct kern_target {
-	u_char		kt_type;
-	u_char		kt_namlen;
-	const char	*kt_name;
-	void		*kt_data;
-	kfstype		kt_tag;
-	u_char		kt_vtype;
-	mode_t		kt_mode;
-};
-
-struct dyn_kern_target {
-	struct kern_target		dkt_kt;
-	SIMPLEQ_ENTRY(dyn_kern_target)	dkt_queue;
-};
-
-struct kernfs_subdir {
-	SIMPLEQ_HEAD(,dyn_kern_target)	ks_entries;
-	unsigned int			ks_nentries;
-	unsigned int			ks_dirs;
-	const struct kern_target	*ks_parent;
-};
-
-struct kernfs_node {
-	LIST_ENTRY(kernfs_node) kfs_hash; /* hash chain */
-	TAILQ_ENTRY(kernfs_node) kfs_list; /* flat list */
-	struct vnode	*kfs_vnode;	/* vnode associated with this pfsnode */
-	kfstype		kfs_type;	/* type of procfs node */
-	mode_t		kfs_mode;	/* mode bits for stat() */
-	long		kfs_fileno;	/* unique file id */
-	u_int32_t	kfs_value;	/* SA id or SP id (KFSint) */
-	const struct kern_target *kfs_kt;
-	void		*kfs_v;		/* pointer to secasvar/secpolicy/mbuf */
-	long		kfs_cookie;	/* fileno cookie */
-};
-
-struct kernfs_mount {
-	TAILQ_HEAD(, kernfs_node) nodelist;
-	long fileno_cookie;
-};
-
-#define UIO_MX	32
-
-#define KERNFS_FILENO(kt, typ, cookie) \
-	((kt >= &kern_targets[0] && kt < &kern_targets[static_nkern_targets]) \
-	    ? 2 + ((kt) - &kern_targets[0]) \
-	      : (((cookie + 1) << 6) | (typ)))
-#define KERNFS_TYPE_FILENO(typ, cookie) \
-	(((cookie + 1) << 6) | (typ))
-
-#define VFSTOKERNFS(mp)	((struct kernfs_mount *)((mp)->mnt_data))
-#define	VTOKERN(vp)	((struct kernfs_node *)(vp)->v_data)
-#define KERNFSTOV(kfs)	((kfs)->kfs_vnode)
-
-extern const struct kern_target kern_targets[];
-extern int nkern_targets;
-extern const int static_nkern_targets;
-extern int (**kernfs_vnodeop_p) __P((void *));
-extern struct vfsops kernfs_vfsops;
-extern dev_t rrootdev;
-
-struct secasvar;
-struct secpolicy;
-
-int kernfs_root __P((struct mount *, struct vnode **));
-
-void kernfs_hashinit __P((void));
-void kernfs_hashreinit __P((void));
-void kernfs_hashdone __P((void));
-int kernfs_freevp __P((struct vnode *));
-int kernfs_allocvp __P((struct mount *, struct vnode **, kfstype,
-	const struct kern_target *, u_int32_t));
-
-void kernfs_revoke_sa __P((struct secasvar *));
-void kernfs_revoke_sp __P((struct secpolicy *));
-
-/*
- * Data types for the kernfs file operations.
- */
-typedef enum {
-	KERNFS_XWRITE,
-	KERNFS_FILEOP_CLOSE,
-	KERNFS_FILEOP_GETATTR,
-	KERNFS_FILEOP_IOCTL,
-	KERNFS_FILEOP_OPEN,
-	KERNFS_FILEOP_WRITE,
-} kfsfileop;
-
-struct kernfs_fileop {
-	kfstype				kf_type;
-	kfsfileop			kf_fileop;
-	union {
-		void			*_kf_genop;
-		int			(*_kf_vop)(void *);
-		int			(*_kf_xwrite)
-			(const struct kernfs_node *, char *, size_t);
-	} _kf_opfn;
-	SPLAY_ENTRY(kernfs_fileop)	kf_node;
-};
-#define	kf_genop	_kf_opfn
-#define	kf_vop		_kf_opfn._kf_vop
-#define	kf_xwrite	_kf_opfn._kf_xwrite
-
-typedef struct kern_target kernfs_parentdir_t;
-typedef struct dyn_kern_target kernfs_entry_t;
-
-/*
- * Functions for adding kernfs datatypes and nodes.
- */
-kfstype kernfs_alloctype(int, const struct kernfs_fileop *);
-#define	KERNFS_ALLOCTYPE(kf) kernfs_alloctype(sizeof((kf)) / \
-	sizeof((kf)[0]), (kf))
-#define	KERNFS_ALLOCENTRY(dkt, m_type, m_flags)				\
-	dkt = (struct dyn_kern_target *)malloc(				\
-		sizeof(struct dyn_kern_target), (m_type), (m_flags))
-#define	KERNFS_INITENTRY(dkt, type, name, data, tag, vtype, mode) do {	\
-	(dkt)->dkt_kt.kt_type = (type);					\
-	(dkt)->dkt_kt.kt_namlen = strlen((name));			\
-	(dkt)->dkt_kt.kt_name = (name);					\
-	(dkt)->dkt_kt.kt_data = (data);					\
-	(dkt)->dkt_kt.kt_tag = (tag);					\
-	(dkt)->dkt_kt.kt_vtype = (vtype);				\
-	(dkt)->dkt_kt.kt_mode = (mode);					\
-} while (/*CONSTCOND*/0)
-#define	KERNFS_ENTOPARENTDIR(dkt) &(dkt)->dkt_kt
-int kernfs_addentry __P((kernfs_parentdir_t *, kernfs_entry_t *));
-
-#ifdef SYSCTL_SETUP_PROTO
-SYSCTL_SETUP_PROTO(sysctl_vfs_kernfs_setup);
-#endif /* SYSCTL_SETUP_PROTO */
-
-#endif /* _KERNEL */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/kernfs_subr.c mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_subr.c
--- NetBSD-3.1/sys/miscfs/kernfs/kernfs_subr.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_subr.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,407 +0,0 @@
-/*	$NetBSD: kernfs_subr.c,v 1.7 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)kernfs_subr.c	8.6 (Berkeley) 5/14/95
- */
-
-/*
- * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)kernfs_subr.c	8.6 (Berkeley) 5/14/95
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.7 2005/02/26 22:59:00 perry Exp $");
-
-#ifdef _KERNEL_OPT
-#include "opt_ipsec.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/mount.h>
-
-#include <miscfs/kernfs/kernfs.h>
-
-#ifdef IPSEC
-#include <sys/mbuf.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet6/ipsec.h>
-#include <netkey/keydb.h>
-#include <netkey/key.h>
-#endif
-
-void kernfs_hashins __P((struct kernfs_node *));
-void kernfs_hashrem __P((struct kernfs_node *));
-struct vnode *kernfs_hashget __P((kfstype, struct mount *,
-    const struct kern_target *, u_int32_t));
-
-static LIST_HEAD(kfs_hashhead, kernfs_node) *kfs_hashtbl;
-static u_long	kfs_ihash;	/* size of hash table - 1 */
-#define KFSVALUEHASH(v)	((v) & kfs_ihash)
-
-static struct lock kfs_hashlock;
-static struct simplelock kfs_hash_slock;
-
-#define	ISSET(t, f)	((t) & (f))
-
-/*
- * allocate a kfsnode/vnode pair.  the vnode is
- * referenced, and locked.
- *
- * the kfs_type, kfs_value and mount point uniquely
- * identify a kfsnode.  the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all kfsnodes are maintained on a singly-linked
- * list.  new nodes are only allocated when they cannot
- * be found on this list.  entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list.  this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one process trying to get the same
- * vnode.  this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference.  this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
- */
-int
-kernfs_allocvp(mp, vpp, kfs_type, kt, value)
-	struct mount *mp;
-	struct vnode **vpp;
-	kfstype kfs_type;
-	const struct kern_target *kt;
-	u_int32_t value;
-{
-	struct kernfs_node *kfs = NULL, *kfsp;
-	struct vnode *vp = NULL;
-	int error;
-	long *cookie;
-
-	do {
-		if ((*vpp = kernfs_hashget(kfs_type, mp, kt, value)) != NULL)
-			return (0);
-	} while (lockmgr(&kfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
-
-	if (kfs_type == KFSdevice) {
-			/* /kern/rootdev = look for device and obey */
-			/* /kern/rrootdev = look for device and obey */
-		dev_t *dp;
-		struct vnode *fvp;
-
-#ifdef DIAGNOSTIC
-		if (!kt)
-			panic("kernfs: kt == NULL for KFSdevice");
-#endif
-		dp = kt->kt_data;
-	loop:
-		if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp)) {
-			lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
-			return (ENOENT);
-		}
-		vp = fvp;
-		if (vget(fvp, LK_EXCLUSIVE))
-			goto loop;
-		*vpp = vp;
-		lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
-		return (0);
-	}
-
-	if ((error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &vp)) != 0) {
-		*vpp = NULL;
-		lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
-		return (error);
-	}
-
-	MALLOC(kfs, void *, sizeof(struct kernfs_node), M_TEMP, M_WAITOK);
-	memset(kfs, 0, sizeof(*kfs));
-	vp->v_data = kfs;
-	cookie = &(VFSTOKERNFS(mp)->fileno_cookie);
-again:
-	TAILQ_FOREACH(kfsp, &VFSTOKERNFS(mp)->nodelist, kfs_list) {
-		if (kfsp->kfs_cookie == *cookie) {
-			(*cookie) ++;
-			goto again;
-		}
-		if (TAILQ_NEXT(kfsp, kfs_list)) {
-			if (kfsp->kfs_cookie < *cookie &&
-			    *cookie < TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie)
-				break;
-			if (kfsp->kfs_cookie + 1 <
-			    TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie) {
-				*cookie = kfsp->kfs_cookie + 1;
-				break;
-			}
-		}
-	}
-
-	kfs->kfs_cookie = *cookie;
-
-	if (kfsp)
-		TAILQ_INSERT_AFTER(&VFSTOKERNFS(mp)->nodelist, kfsp, kfs,
-		    kfs_list);
-	else
-		TAILQ_INSERT_TAIL(&VFSTOKERNFS(mp)->nodelist, kfs, kfs_list);
-
-	kfs->kfs_type = kfs_type;
-	kfs->kfs_vnode = vp;
-	kfs->kfs_fileno = KERNFS_FILENO(kt, kfs_type, kfs->kfs_cookie);
-	kfs->kfs_value = value;
-	kfs->kfs_kt = kt;
-	kfs->kfs_mode = kt->kt_mode;
-	vp->v_type = kt->kt_vtype;
-
-	if (kfs_type == KFSkern)
-		vp->v_flag = VROOT;
-
-	kernfs_hashins(kfs);
-	uvm_vnp_setsize(vp, 0);
-	lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
-
-	*vpp = vp;
-	return (0);
-}
-
-int
-kernfs_freevp(vp)
-	struct vnode *vp;
-{
-	struct kernfs_node *kfs = VTOKERN(vp);
-
-	kernfs_hashrem(kfs);
-	TAILQ_REMOVE(&VFSTOKERNFS(vp->v_mount)->nodelist, kfs, kfs_list);
-
-	FREE(vp->v_data, M_TEMP);
-	vp->v_data = 0;
-	return (0);
-}
-
-/*
- * Initialize kfsnode hash table.
- */
-void
-kernfs_hashinit()
-{
-
-	lockinit(&kfs_hashlock, PINOD, "kfs_hashlock", 0, 0);
-	kfs_hashtbl = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT,
-	    M_WAITOK, &kfs_ihash);
-	simple_lock_init(&kfs_hash_slock);
-}
-
-void
-kernfs_hashreinit()
-{
-	struct kernfs_node *pp;
-	struct kfs_hashhead *oldhash, *hash;
-	u_long i, oldmask, mask, val;
-
-	hash = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT, M_WAITOK,
-	    &mask);
-
-	simple_lock(&kfs_hash_slock);
-	oldhash = kfs_hashtbl;
-	oldmask = kfs_ihash;
-	kfs_hashtbl = hash;
-	kfs_ihash = mask;
-	for (i = 0; i <= oldmask; i++) {
-		while ((pp = LIST_FIRST(&oldhash[i])) != NULL) {
-			LIST_REMOVE(pp, kfs_hash);
-			val = KFSVALUEHASH(pp->kfs_value);
-			LIST_INSERT_HEAD(&hash[val], pp, kfs_hash);
-		}
-	}
-	simple_unlock(&kfs_hash_slock);
-	hashdone(oldhash, M_UFSMNT);
-}
-
-/*
- * Free kfsnode hash table.
- */
-void
-kernfs_hashdone()
-{
-
-	hashdone(kfs_hashtbl, M_UFSMNT);
-}
-
-struct vnode *
-kernfs_hashget(type, mp, kt, value)
-	kfstype type;
-	struct mount *mp;
-	const struct kern_target *kt;
-	u_int32_t value;
-{
-	struct kfs_hashhead *ppp;
-	struct kernfs_node *pp;
-	struct vnode *vp;
-
-loop:
-	simple_lock(&kfs_hash_slock);
-	ppp = &kfs_hashtbl[KFSVALUEHASH(value)];
-	LIST_FOREACH(pp, ppp, kfs_hash) {
-		vp = KERNFSTOV(pp);
-		if (pp->kfs_type == type && vp->v_mount == mp &&
-		    pp->kfs_kt == kt && pp->kfs_value == value) {
-			simple_lock(&vp->v_interlock);
-			simple_unlock(&kfs_hash_slock);
-			if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
-				goto loop;
-			return (vp);
-		}
-	}
-	simple_unlock(&kfs_hash_slock);
-	return (NULL);
-}
-
-/*
- * Insert the kfsnode into the hash table and lock it.
- */
-void
-kernfs_hashins(pp)
-	struct kernfs_node *pp;
-{
-	struct kfs_hashhead *ppp;
-
-	/* lock the kfsnode, then put it on the appropriate hash list */
-	lockmgr(&pp->kfs_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
-
-	simple_lock(&kfs_hash_slock);
-	ppp = &kfs_hashtbl[KFSVALUEHASH(pp->kfs_value)];
-	LIST_INSERT_HEAD(ppp, pp, kfs_hash);
-	simple_unlock(&kfs_hash_slock);
-}
-
-/*
- * Remove the kfsnode from the hash table.
- */
-void
-kernfs_hashrem(pp)
-	struct kernfs_node *pp;
-{
-	simple_lock(&kfs_hash_slock);
-	LIST_REMOVE(pp, kfs_hash);
-	simple_unlock(&kfs_hash_slock);
-}
-
-#ifdef IPSEC
-void
-kernfs_revoke_sa(sav)
-	struct secasvar *sav;
-{
-	struct kernfs_node *kfs, *pnext;
-	struct vnode *vp;
-	struct kfs_hashhead *ppp;
-	struct mbuf *m;
-
-	ppp = &kfs_hashtbl[KFSVALUEHASH(ntohl(sav->spi))];
-	for (kfs = LIST_FIRST(ppp); kfs; kfs = pnext) {
-		vp = KERNFSTOV(kfs);
-		pnext = LIST_NEXT(kfs, kfs_hash);
-		if (vp->v_usecount > 0 && kfs->kfs_type == KFSipsecsa &&
-		    kfs->kfs_value == ntohl(sav->spi)) {
-			m = key_setdumpsa_spi(sav->spi);
-			if (!m)
-				VOP_REVOKE(vp, REVOKEALL);
-			else
-				m_freem(m);
-			break;
-		}
-	}
-}
-
-void
-kernfs_revoke_sp(sp)
-	struct secpolicy *sp;
-{
-	struct kernfs_node *kfs, *pnext;
-	struct vnode *vp;
-	struct kfs_hashhead *ppp;
-
-	ppp = &kfs_hashtbl[KFSVALUEHASH(sp->id)];
-	for (kfs = LIST_FIRST(ppp); kfs; kfs = pnext) {
-		vp = KERNFSTOV(kfs);
-		pnext = LIST_NEXT(kfs, kfs_hash);
-		if (vp->v_usecount > 0 && kfs->kfs_type == KFSipsecsa &&
-		    kfs->kfs_value == sp->id)
-			VOP_REVOKE(vp, REVOKEALL);
-	}
-}
-#endif
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/kernfs_vfsops.c mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_vfsops.c
--- NetBSD-3.1/sys/miscfs/kernfs/kernfs_vfsops.c	2005-01-02 16:08:29.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_vfsops.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,361 +0,0 @@
-/*	$NetBSD: kernfs_vfsops.c,v 1.66 2005/01/02 16:08:29 thorpej Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993, 1995
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)kernfs_vfsops.c	8.10 (Berkeley) 5/14/95
- */
-
-/*
- * Kernel params Filesystem
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.66 2005/01/02 16:08:29 thorpej Exp $");
-
-#ifdef _KERNEL_OPT
-#include "opt_compat_netbsd.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <sys/conf.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/dirent.h>
-#include <sys/malloc.h>
-#include <sys/syslog.h>
-
-#include <miscfs/specfs/specdev.h>
-#include <miscfs/kernfs/kernfs.h>
-
-MALLOC_DEFINE(M_KERNFSMNT, "kernfs mount", "kernfs mount structures");
-
-dev_t rrootdev = NODEV;
-
-void	kernfs_init __P((void));
-void	kernfs_reinit __P((void));
-void	kernfs_done __P((void));
-void	kernfs_get_rrootdev __P((void));
-int	kernfs_mount __P((struct mount *, const char *, void *,
-	    struct nameidata *, struct proc *));
-int	kernfs_start __P((struct mount *, int, struct proc *));
-int	kernfs_unmount __P((struct mount *, int, struct proc *));
-int	kernfs_statvfs __P((struct mount *, struct statvfs *, struct proc *));
-int	kernfs_quotactl __P((struct mount *, int, uid_t, void *,
-			     struct proc *));
-int	kernfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
-int	kernfs_vget __P((struct mount *, ino_t, struct vnode **));
-int	kernfs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
-int	kernfs_checkexp __P((struct mount *, struct mbuf *, int *,
-			   struct ucred **));
-int	kernfs_vptofh __P((struct vnode *, struct fid *));
-
-void
-kernfs_init()
-{
-#ifdef _LKM
-	malloc_type_attach(M_KERNFSMNT);
-#endif
-	kernfs_hashinit();
-}
-
-void
-kernfs_reinit()
-{
-	kernfs_hashreinit();
-}
-
-void
-kernfs_done()
-{
-#ifdef _LKM
-	malloc_type_detach(M_KERNFSMNT);
-#endif
-	kernfs_hashdone();
-}
-
-void
-kernfs_get_rrootdev()
-{
-	static int tried = 0;
-
-	if (tried) {
-		/* Already did it once. */
-		return;
-	}
-	tried = 1;
-
-	if (rootdev == NODEV)
-		return;
-	rrootdev = devsw_blk2chr(rootdev);
-	if (rrootdev != NODEV)
-		return;
-	rrootdev = NODEV;
-	printf("kernfs_get_rrootdev: no raw root device\n");
-}
-
-/*
- * Mount the Kernel params filesystem
- */
-int
-kernfs_mount(mp, path, data, ndp, p)
-	struct mount *mp;
-	const char *path;
-	void *data;
-	struct nameidata *ndp;
-	struct proc *p;
-{
-	int error = 0;
-	struct kernfs_mount *fmp;
-
-	if (UIO_MX & (UIO_MX - 1)) {
-		log(LOG_ERR, "kernfs: invalid directory entry size");
-		return (EINVAL);
-	}
-
-	if (mp->mnt_flag & MNT_GETARGS)
-		return 0;
-	/*
-	 * Update is a no-op
-	 */
-	if (mp->mnt_flag & MNT_UPDATE)
-		return (EOPNOTSUPP);
-
-	MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount),
-	    M_KERNFSMNT, M_WAITOK);
-	memset(fmp, 0, sizeof(*fmp));
-	TAILQ_INIT(&fmp->nodelist);
-
-	mp->mnt_stat.f_namemax = MAXNAMLEN;
-	mp->mnt_flag |= MNT_LOCAL;
-	mp->mnt_data = fmp;
-	vfs_getnewfsid(mp);
-
-	if ((error = set_statvfs_info(path, UIO_USERSPACE, "kernfs",
-	    UIO_SYSSPACE, mp, p)) != 0) {
-		free(fmp, M_KERNFSMNT);
-		return error;
-	}
-
-	kernfs_get_rrootdev();
-	return 0;
-}
-
-int
-kernfs_start(mp, flags, p)
-	struct mount *mp;
-	int flags;
-	struct proc *p;
-{
-
-	return (0);
-}
-
-int
-kernfs_unmount(mp, mntflags, p)
-	struct mount *mp;
-	int mntflags;
-	struct proc *p;
-{
-	int error;
-	int flags = 0;
-
-	if (mntflags & MNT_FORCE)
-		flags |= FORCECLOSE;
-
-	if ((error = vflush(mp, 0, flags)) != 0)
-		return (error);
-
-	/*
-	 * Finally, throw away the kernfs_mount structure
-	 */
-	free(mp->mnt_data, M_KERNFSMNT);
-	mp->mnt_data = NULL;
-	return (0);
-}
-
-int
-kernfs_root(mp, vpp)
-	struct mount *mp;
-	struct vnode **vpp;
-{
-
-	/* setup "." */
-	return (kernfs_allocvp(mp, vpp, KFSkern, &kern_targets[0], 0));
-}
-
-int
-kernfs_quotactl(mp, cmd, uid, arg, p)
-	struct mount *mp;
-	int cmd;
-	uid_t uid;
-	void *arg;
-	struct proc *p;
-{
-
-	return (EOPNOTSUPP);
-}
-
-int
-kernfs_statvfs(mp, sbp, p)
-	struct mount *mp;
-	struct statvfs *sbp;
-	struct proc *p;
-{
-
-	sbp->f_bsize = DEV_BSIZE;
-	sbp->f_frsize = DEV_BSIZE;
-	sbp->f_iosize = DEV_BSIZE;
-	sbp->f_blocks = 2;		/* 1K to keep df happy */
-	sbp->f_bfree = 0;
-	sbp->f_bavail = 0;
-	sbp->f_bresvd = 0;
-	sbp->f_files = 1024;	/* XXX lie */
-	sbp->f_ffree = 128;	/* XXX lie */
-	sbp->f_favail = 128;	/* XXX lie */
-	sbp->f_fresvd = 0;
-	copy_statvfs_info(sbp, mp);
-	return (0);
-}
-
-/*ARGSUSED*/
-int
-kernfs_sync(mp, waitfor, uc, p)
-	struct mount *mp;
-	int waitfor;
-	struct ucred *uc;
-	struct proc *p;
-{
-
-	return (0);
-}
-
-/*
- * Kernfs flat namespace lookup.
- * Currently unsupported.
- */
-int
-kernfs_vget(mp, ino, vpp)
-	struct mount *mp;
-	ino_t ino;
-	struct vnode **vpp;
-{
-
-	return (EOPNOTSUPP);
-}
-
-/*ARGSUSED*/
-int
-kernfs_fhtovp(mp, fhp, vpp)
-	struct mount *mp;
-	struct fid *fhp;
-	struct vnode **vpp;
-{
-
-	return (EOPNOTSUPP);
-}
-
-/*ARGSUSED*/
-int
-kernfs_checkexp(mp, mb, what, anon)
-	struct mount *mp;
-	struct mbuf *mb;
-	int *what;
-	struct ucred **anon;
-{
-
-	return (EOPNOTSUPP);
-}
-
-/*ARGSUSED*/
-int
-kernfs_vptofh(vp, fhp)
-	struct vnode *vp;
-	struct fid *fhp;
-{
-
-	return (EOPNOTSUPP);
-}
-
-SYSCTL_SETUP(sysctl_vfs_kernfs_setup, "sysctl vfs.kern subtree setup")
-{
-
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_NODE, "vfs", NULL,
-		       NULL, 0, NULL, 0,
-		       CTL_VFS, CTL_EOL);
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_NODE, "kernfs",
-		       SYSCTL_DESCR("/kern file system"),
-		       NULL, 0, NULL, 0,
-		       CTL_VFS, 11, CTL_EOL);
-	/*
-	 * XXX the "11" above could be dynamic, thereby eliminating one
-	 * more instance of the "number to vfs" mapping problem, but
-	 * "11" is the order as taken from sys/mount.h
-	 */
-}
-
-extern const struct vnodeopv_desc kernfs_vnodeop_opv_desc;
-
-const struct vnodeopv_desc * const kernfs_vnodeopv_descs[] = {
-	&kernfs_vnodeop_opv_desc,
-	NULL,
-};
-
-struct vfsops kernfs_vfsops = {
-	MOUNT_KERNFS,
-	kernfs_mount,
-	kernfs_start,
-	kernfs_unmount,
-	kernfs_root,
-	kernfs_quotactl,
-	kernfs_statvfs,
-	kernfs_sync,
-	kernfs_vget,
-	kernfs_fhtovp,
-	kernfs_vptofh,
-	kernfs_init,
-	kernfs_reinit,
-	kernfs_done,
-	NULL,
-	NULL,				/* vfs_mountroot */
-	kernfs_checkexp,
-	(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
-	vfs_stdextattrctl,
-	kernfs_vnodeopv_descs,
-};
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/kernfs/kernfs_vnops.c mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_vnops.c
--- NetBSD-3.1/sys/miscfs/kernfs/kernfs_vnops.c	2005-11-24 22:11:11.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/kernfs/kernfs_vnops.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1524 +0,0 @@
-/*	$NetBSD: kernfs_vnops.c,v 1.107.2.4 2005/11/24 22:11:11 tron Exp $	*/
-
-/*
- * Copyright (c) 1992, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software donated to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)kernfs_vnops.c	8.15 (Berkeley) 5/21/95
- */
-
-/*
- * Kernel parameter filesystem (/kern)
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.107.2.4 2005/11/24 22:11:11 tron Exp $");
-
-#ifdef _KERNEL_OPT
-#include "opt_ipsec.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/vmmeter.h>
-#include <sys/time.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/buf.h>
-#include <sys/dirent.h>
-#include <sys/msgbuf.h>
-
-#include <miscfs/genfs/genfs.h>
-#include <miscfs/kernfs/kernfs.h>
-
-#ifdef IPSEC
-#include <sys/mbuf.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet6/ipsec.h>
-#include <netkey/key.h>
-#endif
-
-#include <uvm/uvm_extern.h>
-
-#define KSTRING	256		/* Largest I/O available via this filesystem */
-#define	UIO_MX 32
-
-#define	READ_MODE	(S_IRUSR|S_IRGRP|S_IROTH)
-#define	WRITE_MODE	(S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
-#define	UREAD_MODE	(S_IRUSR)
-#define	DIR_MODE	(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
-#define	UDIR_MODE	(S_IRUSR|S_IXUSR)
-
-#define N(s) sizeof(s)-1, s
-const struct kern_target kern_targets[] = {
-/* NOTE: The name must be less than UIO_MX-16 chars in length */
-     /*        name            data          tag           type  ro/rw */
-     { DT_DIR, N("."),         0,            KFSkern,        VDIR, DIR_MODE   },
-     { DT_DIR, N(".."),        0,            KFSroot,        VDIR, DIR_MODE   },
-     { DT_REG, N("boottime"),  &boottime.tv_sec, KFSint,     VREG, READ_MODE  },
-			/* XXX cast away const */
-     { DT_REG, N("copyright"), (void *)copyright,
-     					     KFSstring,      VREG, READ_MODE  },
-     { DT_REG, N("hostname"),  0,            KFShostname,    VREG, WRITE_MODE },
-     { DT_REG, N("hz"),        &hz,          KFSint,         VREG, READ_MODE  },
-#ifdef IPSEC
-     { DT_DIR, N("ipsecsa"),   0,	     KFSipsecsadir,  VDIR, UDIR_MODE  },
-     { DT_DIR, N("ipsecsp"),   0,	     KFSipsecspdir,  VDIR, UDIR_MODE  },
-#endif
-     { DT_REG, N("loadavg"),   0,            KFSavenrun,     VREG, READ_MODE  },
-     { DT_REG, N("msgbuf"),    0,	     KFSmsgbuf,      VREG, READ_MODE  },
-     { DT_REG, N("pagesize"),  &uvmexp.pagesize, KFSint,     VREG, READ_MODE  },
-     { DT_REG, N("physmem"),   &physmem,     KFSint,         VREG, READ_MODE  },
-#if 0
-     { DT_DIR, N("root"),      0,            KFSnull,        VDIR, DIR_MODE   },
-#endif
-     { DT_BLK, N("rootdev"),   &rootdev,     KFSdevice,      VBLK, READ_MODE  },
-     { DT_CHR, N("rrootdev"),  &rrootdev,    KFSdevice,      VCHR, READ_MODE  },
-     { DT_REG, N("time"),      0,            KFStime,        VREG, READ_MODE  },
-			/* XXX cast away const */
-     { DT_REG, N("version"),   (void *)version,
-     					     KFSstring,      VREG, READ_MODE  },
-};
-const struct kern_target subdir_targets[] = {
-/* NOTE: The name must be less than UIO_MX-16 chars in length */
-     /*        name            data          tag           type  ro/rw */
-     { DT_DIR, N("."),         0,            KFSsubdir,      VDIR, DIR_MODE   },
-     { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
-};
-#ifdef IPSEC
-const struct kern_target ipsecsa_targets[] = {
-/* NOTE: The name must be less than UIO_MX-16 chars in length */
-     /*        name            data          tag           type  ro/rw */
-     { DT_DIR, N("."),         0,            KFSipsecsadir,  VDIR, DIR_MODE   },
-     { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
-};
-const struct kern_target ipsecsp_targets[] = {
-/* NOTE: The name must be less than UIO_MX-16 chars in length */
-     /*        name            data          tag           type  ro/rw */
-     { DT_DIR, N("."),         0,            KFSipsecspdir,  VDIR, DIR_MODE   },
-     { DT_DIR, N(".."),        0,            KFSkern,        VDIR, DIR_MODE   },
-};
-const struct kern_target ipsecsa_kt =
-     { DT_DIR, N(""),          0,            KFSipsecsa,     VREG, UREAD_MODE };
-const struct kern_target ipsecsp_kt =
-     { DT_DIR, N(""),          0,            KFSipsecsp,     VREG, UREAD_MODE };
-#endif
-#undef N
-SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets =
-	SIMPLEQ_HEAD_INITIALIZER(dyn_kern_targets);
-int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
-const int static_nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
-#ifdef IPSEC
-int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]);
-int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]);
-int nkern_dirs = 4; /* 2 extra subdirs */
-#else
-int nkern_dirs = 2;
-#endif
-
-int kernfs_try_fileop(kfstype, kfsfileop, void *, int);
-int kernfs_try_xwrite(kfstype, const struct kernfs_node *, char *,
-    size_t, int);
-
-static int kernfs_default_xwrite(void *v);
-static int kernfs_default_fileop_getattr(void *);
-
-/* must include all fileop's */
-const struct kernfs_fileop kernfs_default_fileops[] = {
-  { .kf_fileop = KERNFS_XWRITE },
-  { .kf_fileop = KERNFS_FILEOP_OPEN },
-  { .kf_fileop = KERNFS_FILEOP_GETATTR,
-    .kf_genop = {kernfs_default_fileop_getattr} },
-  { .kf_fileop = KERNFS_FILEOP_IOCTL },
-  { .kf_fileop = KERNFS_FILEOP_CLOSE },
-  { .kf_fileop = KERNFS_FILEOP_WRITE, .kf_genop = {kernfs_default_xwrite} },
-};
-
-int	kernfs_lookup	__P((void *));
-#define	kernfs_create	genfs_eopnotsupp
-#define	kernfs_mknod	genfs_eopnotsupp
-int	kernfs_open	__P((void *));
-int	kernfs_close	__P((void *));
-int	kernfs_access	__P((void *));
-int	kernfs_getattr	__P((void *));
-int	kernfs_setattr	__P((void *));
-int	kernfs_read	__P((void *));
-int	kernfs_write	__P((void *));
-#define	kernfs_fcntl	genfs_fcntl
-int	kernfs_ioctl	__P((void *));
-#define	kernfs_poll	genfs_poll
-#define kernfs_revoke	genfs_revoke
-#define	kernfs_fsync	genfs_nullop
-#define	kernfs_seek	genfs_nullop
-#define	kernfs_remove	genfs_eopnotsupp
-int	kernfs_link	__P((void *));
-#define	kernfs_rename	genfs_eopnotsupp
-#define	kernfs_mkdir	genfs_eopnotsupp
-#define	kernfs_rmdir	genfs_eopnotsupp
-int	kernfs_symlink	__P((void *));
-int	kernfs_readdir	__P((void *));
-#define	kernfs_readlink	genfs_eopnotsupp
-#define	kernfs_abortop	genfs_abortop
-int	kernfs_inactive	__P((void *));
-int	kernfs_reclaim	__P((void *));
-#define	kernfs_lock	genfs_lock
-#define	kernfs_unlock	genfs_unlock
-#define	kernfs_bmap	genfs_badop
-#define	kernfs_strategy	genfs_badop
-int	kernfs_print	__P((void *));
-#define	kernfs_islocked	genfs_islocked
-int	kernfs_pathconf	__P((void *));
-#define	kernfs_advlock	genfs_einval
-#define	kernfs_blkatoff	genfs_eopnotsupp
-#define	kernfs_valloc	genfs_eopnotsupp
-#define	kernfs_vfree	genfs_nullop
-#define	kernfs_truncate	genfs_eopnotsupp
-#define	kernfs_update	genfs_nullop
-#define	kernfs_bwrite	genfs_eopnotsupp
-#define	kernfs_putpages	genfs_putpages
-
-static int	kernfs_xread __P((struct kernfs_node *, int, char **, size_t, size_t *));
-static int	kernfs_xwrite __P((const struct kernfs_node *, char *, size_t));
-
-int (**kernfs_vnodeop_p) __P((void *));
-const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
-	{ &vop_default_desc, vn_default_error },
-	{ &vop_lookup_desc, kernfs_lookup },		/* lookup */
-	{ &vop_create_desc, kernfs_create },		/* create */
-	{ &vop_mknod_desc, kernfs_mknod },		/* mknod */
-	{ &vop_open_desc, kernfs_open },		/* open */
-	{ &vop_close_desc, kernfs_close },		/* close */
-	{ &vop_access_desc, kernfs_access },		/* access */
-	{ &vop_getattr_desc, kernfs_getattr },		/* getattr */
-	{ &vop_setattr_desc, kernfs_setattr },		/* setattr */
-	{ &vop_read_desc, kernfs_read },		/* read */
-	{ &vop_write_desc, kernfs_write },		/* write */
-	{ &vop_fcntl_desc, kernfs_fcntl },		/* fcntl */
-	{ &vop_ioctl_desc, kernfs_ioctl },		/* ioctl */
-	{ &vop_poll_desc, kernfs_poll },		/* poll */
-	{ &vop_revoke_desc, kernfs_revoke },		/* revoke */
-	{ &vop_fsync_desc, kernfs_fsync },		/* fsync */
-	{ &vop_seek_desc, kernfs_seek },		/* seek */
-	{ &vop_remove_desc, kernfs_remove },		/* remove */
-	{ &vop_link_desc, kernfs_link },		/* link */
-	{ &vop_rename_desc, kernfs_rename },		/* rename */
-	{ &vop_mkdir_desc, kernfs_mkdir },		/* mkdir */
-	{ &vop_rmdir_desc, kernfs_rmdir },		/* rmdir */
-	{ &vop_symlink_desc, kernfs_symlink },		/* symlink */
-	{ &vop_readdir_desc, kernfs_readdir },		/* readdir */
-	{ &vop_readlink_desc, kernfs_readlink },	/* readlink */
-	{ &vop_abortop_desc, kernfs_abortop },		/* abortop */
-	{ &vop_inactive_desc, kernfs_inactive },	/* inactive */
-	{ &vop_reclaim_desc, kernfs_reclaim },		/* reclaim */
-	{ &vop_lock_desc, kernfs_lock },		/* lock */
-	{ &vop_unlock_desc, kernfs_unlock },		/* unlock */
-	{ &vop_bmap_desc, kernfs_bmap },		/* bmap */
-	{ &vop_strategy_desc, kernfs_strategy },	/* strategy */
-	{ &vop_print_desc, kernfs_print },		/* print */
-	{ &vop_islocked_desc, kernfs_islocked },	/* islocked */
-	{ &vop_pathconf_desc, kernfs_pathconf },	/* pathconf */
-	{ &vop_advlock_desc, kernfs_advlock },		/* advlock */
-	{ &vop_blkatoff_desc, kernfs_blkatoff },	/* blkatoff */
-	{ &vop_valloc_desc, kernfs_valloc },		/* valloc */
-	{ &vop_vfree_desc, kernfs_vfree },		/* vfree */
-	{ &vop_truncate_desc, kernfs_truncate },	/* truncate */
-	{ &vop_update_desc, kernfs_update },		/* update */
-	{ &vop_bwrite_desc, kernfs_bwrite },		/* bwrite */
-	{ &vop_putpages_desc, kernfs_putpages },	/* putpages */
-	{ NULL, NULL }
-};
-const struct vnodeopv_desc kernfs_vnodeop_opv_desc =
-	{ &kernfs_vnodeop_p, kernfs_vnodeop_entries };
-
-static __inline int
-kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b)
-{
-	if (a->kf_type < b->kf_type)
-		return -1;
-	if (a->kf_type > b->kf_type)
-		return 1;
-	if (a->kf_fileop < b->kf_fileop)
-		return -1;
-	if (a->kf_fileop > b->kf_fileop)
-		return 1;
-	return (0);
-}
-
-SPLAY_HEAD(kfsfileoptree, kernfs_fileop) kfsfileoptree =
-	SPLAY_INITIALIZER(kfsfileoptree);
-SPLAY_PROTOTYPE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare);
-SPLAY_GENERATE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare);
-
-kfstype
-kernfs_alloctype(int nkf, const struct kernfs_fileop *kf)
-{
-	static u_char nextfreetype = KFSlasttype;
-	struct kernfs_fileop *dkf, *fkf, skf;
-	int i;
-
-	/* XXX need to keep track of dkf's memory if we support
-           deallocating types */
-	dkf = malloc(sizeof(kernfs_default_fileops), M_TEMP, M_WAITOK);
-	memcpy(dkf, kernfs_default_fileops, sizeof(kernfs_default_fileops));
-
-	for (i = 0; i < sizeof(kernfs_default_fileops) /
-		     sizeof(kernfs_default_fileops[0]); i++) {
-		dkf[i].kf_type = nextfreetype;
-		SPLAY_INSERT(kfsfileoptree, &kfsfileoptree, &dkf[i]);
-	}
-
-	for (i = 0; i < nkf; i++) {
-		skf.kf_type = nextfreetype;
-		skf.kf_fileop = kf[i].kf_fileop;
-		if ((fkf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
-			fkf->kf_genop = kf[i].kf_genop;
-	}
-
-	return nextfreetype++;
-}
-
-int
-kernfs_try_fileop(kfstype type, kfsfileop fileop, void *v, int error)
-{
-	struct kernfs_fileop *kf, skf;
-
-	skf.kf_type = type;
-	skf.kf_fileop = fileop;
-	if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
-		if (kf->kf_vop)
-			return kf->kf_vop(v);
-	return error;
-}
-
-int
-kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *buf,
-    size_t len, int error)
-{
-	struct kernfs_fileop *kf, skf;
-
-	skf.kf_type = type;
-	skf.kf_fileop = KERNFS_XWRITE;
-	if ((kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf)))
-		if (kf->kf_xwrite)
-			return kf->kf_xwrite(kfs, buf, len);
-	return error;
-}
-
-int
-kernfs_addentry(kernfs_parentdir_t *pkt, kernfs_entry_t *dkt)
-{
-	struct kernfs_subdir *ks, *parent;
-
-	if (pkt == NULL) {
-		SIMPLEQ_INSERT_TAIL(&dyn_kern_targets, dkt, dkt_queue);
-		nkern_targets++;
-		if (dkt->dkt_kt.kt_vtype == VDIR)
-			nkern_dirs++;
-	} else {
-		parent = (struct kernfs_subdir *)pkt->kt_data;
-		SIMPLEQ_INSERT_TAIL(&parent->ks_entries, dkt, dkt_queue);
-		parent->ks_nentries++;
-		if (dkt->dkt_kt.kt_vtype == VDIR)
-			parent->ks_dirs++;
-	}
-	if (dkt->dkt_kt.kt_vtype == VDIR && dkt->dkt_kt.kt_data == NULL) {
-		ks = malloc(sizeof(struct kernfs_subdir),
-		    M_TEMP, M_WAITOK);
-		SIMPLEQ_INIT(&ks->ks_entries);
-		ks->ks_nentries = 2; /* . and .. */
-		ks->ks_dirs = 2;
-		ks->ks_parent = pkt ? pkt : &kern_targets[0];
-		dkt->dkt_kt.kt_data = ks;
-	}
-	return 0;
-}
-
-static int
-kernfs_xread(kfs, off, bufp, len, wrlen)
-	struct kernfs_node *kfs;
-	int off;
-	char **bufp;
-	size_t len;
-	size_t *wrlen;
-{
-	const struct kern_target *kt;
-#ifdef IPSEC
-	struct mbuf *m;
-#endif
-
-	kt = kfs->kfs_kt;
-
-	switch (kfs->kfs_type) {
-	case KFStime: {
-		struct timeval tv;
-
-		microtime(&tv);
-		snprintf(*bufp, len, "%ld %ld\n", tv.tv_sec, tv.tv_usec);
-		break;
-	}
-
-	case KFSint: {
-		int *ip = kt->kt_data;
-
-		snprintf(*bufp, len, "%d\n", *ip);
-		break;
-	}
-
-	case KFSstring: {
-		char *cp = kt->kt_data;
-
-		*bufp = cp;
-		break;
-	}
-
-	case KFSmsgbuf: {
-		long n;
-
-		/*
-		 * deal with cases where the message buffer has
-		 * become corrupted.
-		 */
-		if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) {
-			msgbufenabled = 0;
-			return (ENXIO);
-		}
-
-		/*
-		 * Note that reads of /kern/msgbuf won't necessarily yield
-		 * consistent results, if the message buffer is modified
-		 * while the read is in progress.  The worst that can happen
-		 * is that incorrect data will be read.  There's no way
-		 * that this can crash the system unless the values in the
-		 * message buffer header are corrupted, but that'll cause
-		 * the system to die anyway.
-		 */
-		if (off >= msgbufp->msg_bufs) {
-			*wrlen = 0;
-			return (0);
-		}
-		n = msgbufp->msg_bufx + off;
-		if (n >= msgbufp->msg_bufs)
-			n -= msgbufp->msg_bufs;
-		len = min(msgbufp->msg_bufs - n, msgbufp->msg_bufs - off);
-		*bufp = msgbufp->msg_bufc + n;
-		*wrlen = len;
-		return (0);
-	}
-
-	case KFShostname: {
-		char *cp = hostname;
-		int xlen = hostnamelen;
-
-		if (xlen >= (len - 2))
-			return (EINVAL);
-
-		memcpy(*bufp, cp, xlen);
-		(*bufp)[xlen] = '\n';
-		(*bufp)[xlen+1] = '\0';
-		len = strlen(*bufp);
-		break;
-	}
-
-	case KFSavenrun:
-		averunnable.fscale = FSCALE;
-		snprintf(*bufp, len, "%d %d %d %ld\n",
-		    averunnable.ldavg[0], averunnable.ldavg[1],
-		    averunnable.ldavg[2], averunnable.fscale);
-		break;
-
-#ifdef IPSEC
-	case KFSipsecsa:
-		/*
-		 * Note that SA configuration could be changed during the
-		 * read operation, resulting in garbled output.
-		 */
-		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
-		if (!m)
-			return (ENOBUFS);
-		if (off >= m->m_pkthdr.len) {
-			*wrlen = 0;
-			m_freem(m);
-			return (0);
-		}
-		if (len > m->m_pkthdr.len - off)
-			len = m->m_pkthdr.len - off;
-		m_copydata(m, off, len, *bufp);
-		*wrlen = len;
-		m_freem(m);
-		return (0);
-
-	case KFSipsecsp:
-		/*
-		 * Note that SP configuration could be changed during the
-		 * read operation, resulting in garbled output.
-		 */
-		if (!kfs->kfs_v) {
-			struct secpolicy *sp;
-
-			sp = key_getspbyid(kfs->kfs_value);
-			if (sp)
-				kfs->kfs_v = sp;
-			else
-				return (ENOENT);
-		}
-		m = key_setdumpsp((struct secpolicy *)kfs->kfs_v,
-		    SADB_X_SPDGET, 0, 0);
-		if (!m)
-			return (ENOBUFS);
-		if (off >= m->m_pkthdr.len) {
-			*wrlen = 0;
-			m_freem(m);
-			return (0);
-		}
-		if (len > m->m_pkthdr.len - off)
-			len = m->m_pkthdr.len - off;
-		m_copydata(m, off, len, *bufp);
-		*wrlen = len;
-		m_freem(m);
-		return (0);
-#endif
-
-	default:
-		*wrlen = 0;
-		return (0);
-	}
-
-	len = strlen(*bufp);
-	if (len <= off)
-		*wrlen = 0;
-	else {
-		*bufp += off;
-		*wrlen = len - off;
-	}
-	return (0);
-}
-
-static int
-kernfs_xwrite(kfs, buf, len)
-	const struct kernfs_node *kfs;
-	char *buf;
-	size_t len;
-{
-
-	switch (kfs->kfs_type) {
-	case KFShostname:
-		if (buf[len-1] == '\n')
-			--len;
-		memcpy(hostname, buf, len);
-		hostname[len] = '\0';
-		hostnamelen = (size_t) len;
-		return (0);
-
-	default:
-		return kernfs_try_xwrite(kfs->kfs_type, kfs, buf, len, EIO);
-	}
-}
-
-
-/*
- * vp is the current namei directory
- * ndp is the name to locate in that directory...
- */
-int
-kernfs_lookup(v)
-	void *v;
-{
-	struct vop_lookup_args /* {
-		struct vnode * a_dvp;
-		struct vnode ** a_vpp;
-		struct componentname * a_cnp;
-	} */ *ap = v;
-	struct componentname *cnp = ap->a_cnp;
-	struct vnode **vpp = ap->a_vpp;
-	struct vnode *dvp = ap->a_dvp;
-	const char *pname = cnp->cn_nameptr;
-	const struct kernfs_node *kfs;
-	const struct kern_target *kt;
-	const struct dyn_kern_target *dkt;
-	const struct kernfs_subdir *ks;
-	int error, i, wantpunlock;
-#ifdef IPSEC
-	char *ep;
-	u_int32_t id;
-#endif
-
-	*vpp = NULLVP;
-	cnp->cn_flags &= ~PDIRUNLOCK;
-
-	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
-		return (EROFS);
-
-	if (cnp->cn_namelen == 1 && *pname == '.') {
-		*vpp = dvp;
-		VREF(dvp);
-		return (0);
-	}
-
-	wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));
-	kfs = VTOKERN(dvp);
-	switch (kfs->kfs_type) {
-	case KFSkern:
-		/*
-		 * Shouldn't get here with .. in the root node.
-		 */
-		if (cnp->cn_flags & ISDOTDOT)
-			return (EIO);
-
-		for (i = 0; i < static_nkern_targets; i++) {
-			kt = &kern_targets[i];
-			if (cnp->cn_namelen == kt->kt_namlen &&
-			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
-				goto found;
-		}
-		SIMPLEQ_FOREACH(dkt, &dyn_kern_targets, dkt_queue) {
-			if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen &&
-			    memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) {
-				kt = &dkt->dkt_kt;
-				goto found;
-			}
-		}
-		break;
-
-	found:
-		error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0);
-		if ((error == 0) && wantpunlock) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return (error);
-
-	case KFSsubdir:
-		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
-		if (cnp->cn_flags & ISDOTDOT) {
-			kt = ks->ks_parent;
-			goto found;
-		}
-
-		SIMPLEQ_FOREACH(dkt, &ks->ks_entries, dkt_queue) {
-			if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen &&
-			    memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) {
-				kt = &dkt->dkt_kt;
-				goto found;
-			}
-		}
-		break;
-
-#ifdef IPSEC
-	case KFSipsecsadir:
-		if (cnp->cn_flags & ISDOTDOT) {
-			kt = &kern_targets[0];
-			goto found;
-		}
-
-		for (i = 2; i < nipsecsa_targets; i++) {
-			kt = &ipsecsa_targets[i];
-			if (cnp->cn_namelen == kt->kt_namlen &&
-			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
-				goto found;
-		}
-
-		ep = NULL;
-		id = strtoul(pname, &ep, 10);
-		if (!ep || *ep || ep == pname)
-			break;
-
-		error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsa, &ipsecsa_kt, id);
-		if ((error == 0) && wantpunlock) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return (error);
-
-	case KFSipsecspdir:
-		if (cnp->cn_flags & ISDOTDOT) {
-			kt = &kern_targets[0];
-			goto found;
-		}
-
-		for (i = 2; i < nipsecsp_targets; i++) {
-			kt = &ipsecsp_targets[i];
-			if (cnp->cn_namelen == kt->kt_namlen &&
-			    memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
-				goto found;
-		}
-
-		ep = NULL;
-		id = strtoul(pname, &ep, 10);
-		if (!ep || *ep || ep == pname)
-			break;
-
-		error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsp, &ipsecsp_kt, id);
-		if ((error == 0) && wantpunlock) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return (error);
-#endif
-
-	default:
-		return (ENOTDIR);
-	}
-
-	return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
-}
-
-int
-kernfs_open(v)
-	void *v;
-{
-	struct vop_open_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-#ifdef IPSEC
-	struct mbuf *m;
-	struct secpolicy *sp;
-#endif
-
-	switch (kfs->kfs_type) {
-#ifdef IPSEC
-	case KFSipsecsa:
-		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
-		if (m) {
-			m_freem(m);
-			return (0);
-		} else
-			return (ENOENT);
-
-	case KFSipsecsp:
-		sp = key_getspbyid(kfs->kfs_value);
-		if (sp) {
-			kfs->kfs_v = sp;
-			return (0);
-		} else
-			return (ENOENT);
-#endif
-
-	default:
-		return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN,
-		    v, 0);
-	}
-}
-
-int
-kernfs_close(v)
-	void *v;
-{
-	struct vop_close_args /* {
-		struct vnode *a_vp;
-		int a_fflag;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-
-	switch (kfs->kfs_type) {
-#ifdef IPSEC
-	case KFSipsecsp:
-		key_freesp((struct secpolicy *)kfs->kfs_v);
-		break;
-#endif
-
-	default:
-		return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE,
-		    v, 0);
-	}
-
-	return (0);
-}
-
-int
-kernfs_access(v)
-	void *v;
-{
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct vattr va;
-	int error;
-
-	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0)
-		return (error);
-
-	return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid,
-	    ap->a_mode, ap->a_cred));
-}
-
-static int
-kernfs_default_fileop_getattr(v)
-	void *v;
-{
-	struct vop_getattr_args /* {
-		struct vnode *a_vp;
-		struct vattr *a_vap;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct vattr *vap = ap->a_vap;
-
-	vap->va_nlink = 1;
-	vap->va_bytes = vap->va_size = 0;
-
-	return 0;
-}
-
-int
-kernfs_getattr(v)
-	void *v;
-{
-	struct vop_getattr_args /* {
-		struct vnode *a_vp;
-		struct vattr *a_vap;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-	struct kernfs_subdir *ks;
-	struct vattr *vap = ap->a_vap;
-	int error = 0;
-	char strbuf[KSTRING], *buf;
-	size_t nread, total;
-
-	VATTR_NULL(vap);
-	vap->va_type = ap->a_vp->v_type;
-	vap->va_uid = 0;
-	vap->va_gid = 0;
-	vap->va_mode = kfs->kfs_mode;
-	vap->va_fileid = kfs->kfs_fileno;
-	vap->va_flags = 0;
-	vap->va_size = 0;
-	vap->va_blocksize = DEV_BSIZE;
-	/*
-	 * Make all times be current TOD, except for the "boottime" node.
-	 * Avoid microtime(9), it's slow.
-	 * We don't guard the read from time(9) with splclock(9) since we
-	 * don't actually need to be THAT sure the access is atomic.
-	 */
-	if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 &&
-	    !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) {
-		TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime);
-	} else {
-		TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime);
-	}
-	vap->va_atime = vap->va_mtime = vap->va_ctime;
-	vap->va_gen = 0;
-	vap->va_flags = 0;
-	vap->va_rdev = 0;
-	vap->va_bytes = 0;
-
-	switch (kfs->kfs_type) {
-	case KFSkern:
-		vap->va_nlink = nkern_dirs;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-
-	case KFSroot:
-		vap->va_nlink = 1;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-
-	case KFSsubdir:
-		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
-		vap->va_nlink = ks->ks_dirs;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-
-	case KFSnull:
-	case KFStime:
-	case KFSint:
-	case KFSstring:
-	case KFShostname:
-	case KFSavenrun:
-	case KFSdevice:
-	case KFSmsgbuf:
-#ifdef IPSEC
-	case KFSipsecsa:
-	case KFSipsecsp:
-#endif
-		vap->va_nlink = 1;
-		total = 0;
-		do {
-			buf = strbuf;
-			error = kernfs_xread(kfs, total, &buf,
-			    sizeof(strbuf), &nread);
-			total += nread;
-		} while (error == 0 && nread != 0);
-		vap->va_bytes = vap->va_size = total;
-		break;
-
-#ifdef IPSEC
-	case KFSipsecsadir:
-	case KFSipsecspdir:
-		vap->va_nlink = 2;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-#endif
-
-	default:
-		error = kernfs_try_fileop(kfs->kfs_type,
-		    KERNFS_FILEOP_GETATTR, v, EINVAL);
-		break;
-	}
-
-	return (error);
-}
-
-/*ARGSUSED*/
-int
-kernfs_setattr(v)
-	void *v;
-{
-
-	/*
-	 * Silently ignore attribute changes.
-	 * This allows for open with truncate to have no
-	 * effect until some data is written.  I want to
-	 * do it this way because all writes are atomic.
-	 */
-	return (0);
-}
-
-int
-kernfs_read(v)
-	void *v;
-{
-	struct vop_read_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		int  a_ioflag;
-		struct ucred *a_cred;
-	} */ *ap = v;
-	struct uio *uio = ap->a_uio;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-	char strbuf[KSTRING], *bf;
-	int off;
-	size_t len;
-	int error;
-
-	if (ap->a_vp->v_type == VDIR)
-		return (EOPNOTSUPP);
-
-	off = (int)uio->uio_offset;
-	/* Don't allow negative offsets */
-	if (off < 0)
-		return EINVAL;
-
-	bf = strbuf;
-	if ((error = kernfs_xread(kfs, off, &bf, sizeof(strbuf), &len)) == 0)
-		error = uiomove(bf, len, uio);
-	return (error);
-}
-
-static int
-kernfs_default_xwrite(v)
-	void *v;
-{
-	struct vop_write_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		int  a_ioflag;
-		struct ucred *a_cred;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-	struct uio *uio = ap->a_uio;
-	int error, xlen;
-	char strbuf[KSTRING];
-
-	if (uio->uio_offset != 0)
-		return (EINVAL);
-
-	xlen = min(uio->uio_resid, KSTRING-1);
-	if ((error = uiomove(strbuf, xlen, uio)) != 0)
-		return (error);
-
-	if (uio->uio_resid != 0)
-		return (EIO);
-
-	strbuf[xlen] = '\0';
-	xlen = strlen(strbuf);
-	return (kernfs_xwrite(kfs, strbuf, xlen));
-}
-
-int
-kernfs_write(v)
-	void *v;
-{
-	struct vop_write_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		int  a_ioflag;
-		struct ucred *a_cred;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-
-	return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, 0);
-}
-
-int
-kernfs_ioctl(v)
-	void *v;
-{
-	struct vop_ioctl_args /* {
-		const struct vnodeop_desc *a_desc;
-		struct vnode *a_vp;
-		u_long a_command;
-		void *a_data;
-		int a_fflag;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-
-	return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_IOCTL, v,
-	    EPASSTHROUGH);
-}
-
-static int
-kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt,
-    u_int32_t value, struct vop_readdir_args *ap)
-{
-	struct kernfs_node *kfs;
-	struct vnode *vp;
-	int error;
-
-	if ((error = kernfs_allocvp(ap->a_vp->v_mount, &vp, kt->kt_tag, kt,
-	    value)) != 0)
-		return error;
-	if (kt->kt_tag == KFSdevice) {
-		struct vattr va;
-		if ((error = VOP_GETATTR(vp, &va, ap->a_cred,
-		    ap->a_uio->uio_segflg == UIO_USERSPACE ?
-		    ap->a_uio->uio_procp : &proc0)) != 0)
-			return (error);
-		d->d_fileno = va.va_fileid;
-	} else {
-		kfs = VTOKERN(vp);
-		d->d_fileno = kfs->kfs_fileno;
-	}
-	vput(vp);
-	return 0;
-}
-
-static int
-kernfs_setdirentfileno(struct dirent *d, off_t entry,
-    struct kernfs_node *thisdir_kfs, const struct kern_target *parent_kt,
-    const struct kern_target *kt, struct vop_readdir_args *ap)
-{
-	const struct kern_target *ikt;
-	int error;
-
-	switch (entry) {
-	case 0:
-		d->d_fileno = thisdir_kfs->kfs_fileno;
-		return 0;
-	case 1:
-		ikt = parent_kt;
-		break;
-	default:
-		ikt = kt;
-		break;
-	}
-	if (ikt != thisdir_kfs->kfs_kt) {
-		if ((error = kernfs_setdirentfileno_kt(d, ikt, 0, ap)) != 0)
-			return error;
-	} else
-		d->d_fileno = thisdir_kfs->kfs_fileno;
-	return 0;
-}
-
-int
-kernfs_readdir(v)
-	void *v;
-{
-	struct vop_readdir_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		struct ucred *a_cred;
-		int *a_eofflag;
-		off_t **a_cookies;
-		int a_*ncookies;
-	} */ *ap = v;
-	struct uio *uio = ap->a_uio;
-	struct dirent d;
-	struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-	const struct kern_target *kt;
-	const struct dyn_kern_target *dkt = NULL;
-	const struct kernfs_subdir *ks;
-	off_t i, j;
-	int error;
-	off_t *cookies = NULL;
-	int ncookies = 0, n;
-#ifdef IPSEC
-	struct secasvar *sav, *sav2;
-	struct secpolicy *sp;
-#endif
-
-	if (uio->uio_resid < UIO_MX)
-		return (EINVAL);
-	if (uio->uio_offset < 0)
-		return (EINVAL);
-
-	error = 0;
-	i = uio->uio_offset;
-	memset(&d, 0, sizeof(d));
-	d.d_reclen = UIO_MX;
-	ncookies = uio->uio_resid / UIO_MX;
-
-	switch (kfs->kfs_type) {
-	case KFSkern:
-		if (i >= nkern_targets)
-			return (0);
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (nkern_targets - i));
-			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
-			    M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		n = 0;
-		for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) {
-			if (i < static_nkern_targets)
-				kt = &kern_targets[i];
-			else {
-				if (dkt == NULL) {
-					dkt = SIMPLEQ_FIRST(&dyn_kern_targets);
-					for (j = static_nkern_targets; j < i &&
-						     dkt != NULL; j++)
-						dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
-					if (j != i)
-						break;
-				} else {
-					dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
-					if (dkt == NULL)
-						break;
-				}
-				kt = &dkt->dkt_kt;
-			}
-			if (kt->kt_tag == KFSdevice) {
-				dev_t *dp = kt->kt_data;
-				struct vnode *fvp;
-
-				if (*dp == NODEV ||
-				    !vfinddev(*dp, kt->kt_vtype, &fvp))
-					continue;
-			}
-			d.d_namlen = kt->kt_namlen;
-			if ((error = kernfs_setdirentfileno(&d, i, kfs,
-			    &kern_targets[0], kt, ap)) != 0)
-				break;
-			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
-			d.d_type = kt->kt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-		}
-		ncookies = n;
-		break;
-
-	case KFSroot:
-		if (i >= 2)
-			return 0;
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (2 - i));
-			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
-			    M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		n = 0;
-		for (; i < 2 && uio->uio_resid >= UIO_MX; i++) {
-			kt = &kern_targets[i];
-			d.d_namlen = kt->kt_namlen;
-			d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0);
-			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
-			d.d_type = kt->kt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-		}
-		ncookies = n;
-		break;
-
-	case KFSsubdir:
-		ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data;
-		if (i >= ks->ks_nentries)
-			return (0);
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (ks->ks_nentries - i));
-			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
-			    M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		dkt = SIMPLEQ_FIRST(&ks->ks_entries);
-		for (j = 0; j < i && dkt != NULL; j++)
-			dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
-		n = 0;
-		for (; i < ks->ks_nentries && uio->uio_resid >= UIO_MX; i++) {
-			if (i < 2)
-				kt = &subdir_targets[i];
-			else {
-				/* check if ks_nentries lied to us */
-				if (dkt == NULL)
-					break;
-				kt = &dkt->dkt_kt;
-				dkt = SIMPLEQ_NEXT(dkt, dkt_queue);
-			}
-			if (kt->kt_tag == KFSdevice) {
-				dev_t *dp = kt->kt_data;
-				struct vnode *fvp;
-
-				if (*dp == NODEV ||
-				    !vfinddev(*dp, kt->kt_vtype, &fvp))
-					continue;
-			}
-			d.d_namlen = kt->kt_namlen;
-			if ((error = kernfs_setdirentfileno(&d, i, kfs,
-			    ks->ks_parent, kt, ap)) != 0)
-				break;
-			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
-			d.d_type = kt->kt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-		}
-		ncookies = n;
-		break;
-
-#ifdef IPSEC
-	case KFSipsecsadir:
-		/* count SA in the system */
-		n = 0;
-		TAILQ_FOREACH(sav, &satailq, tailq) {
-			for (sav2 = TAILQ_FIRST(&satailq);
-			    sav2 != sav;
-			    sav2 = TAILQ_NEXT(sav2, tailq)) {
-				if (sav->spi == sav2->spi) {
-					/* multiple SA with same SPI */
-					break;
-				}
-			}
-			if (sav == sav2 || sav->spi != sav2->spi)
-				n++;
-		}
-
-		if (i >= nipsecsa_targets + n)
-			return (0);
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (n - i));
-			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
-			    M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		n = 0;
-		for (; i < nipsecsa_targets && uio->uio_resid >= UIO_MX; i++) {
-			kt = &ipsecsa_targets[i];
-			d.d_namlen = kt->kt_namlen;
-			if ((error = kernfs_setdirentfileno(&d, i, kfs,
-			    &kern_targets[0], kt, ap)) != 0)
-				break;
-			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
-			d.d_type = kt->kt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-		}
-		if (error) {
-			ncookies = n;
-			break;
-		}
-
-		TAILQ_FOREACH(sav, &satailq, tailq) {
-			for (sav2 = TAILQ_FIRST(&satailq);
-			    sav2 != sav;
-			    sav2 = TAILQ_NEXT(sav2, tailq)) {
-				if (sav->spi == sav2->spi) {
-					/* multiple SA with same SPI */
-					break;
-				}
-			}
-			if (sav != sav2 && sav->spi == sav2->spi)
-				continue;
-			if (uio->uio_resid < UIO_MX)
-				break;
-			if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsa_kt,
-			    sav->spi, ap)) != 0)
-				break;
-			d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
-			    "%u", ntohl(sav->spi));
-			d.d_type = DT_REG;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-			i++;
-		}
-		ncookies = n;
-		break;
-
-	case KFSipsecspdir:
-		/* count SP in the system */
-		n = 0;
-		TAILQ_FOREACH(sp, &sptailq, tailq)
-			n++;
-
-		if (i >= nipsecsp_targets + n)
-			return (0);
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (n - i));
-			cookies = malloc(ncookies * sizeof(off_t), M_TEMP,
-			    M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		n = 0;
-		for (; i < nipsecsp_targets && uio->uio_resid >= UIO_MX; i++) {
-			kt = &ipsecsp_targets[i];
-			d.d_namlen = kt->kt_namlen;
-			if ((error = kernfs_setdirentfileno(&d, i, kfs,
-			    &kern_targets[0], kt, ap)) != 0)
-				break;
-			memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1);
-			d.d_type = kt->kt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-		}
-		if (error) {
-			ncookies = n;
-			break;
-		}
-
-		TAILQ_FOREACH(sp, &sptailq, tailq) {
-			if (uio->uio_resid < UIO_MX)
-				break;
-			if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsp_kt,
-			    sp->id, ap)) != 0)
-				break;
-			d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
-			    "%u", sp->id);
-			d.d_type = DT_REG;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			n++;
-			i++;
-		}
-		ncookies = n;
-		break;
-#endif
-
-	default:
-		error = ENOTDIR;
-		break;
-	}
-
-	if (ap->a_ncookies) {
-		if (error) {
-			if (cookies)
-				free(*ap->a_cookies, M_TEMP);
-			*ap->a_ncookies = 0;
-			*ap->a_cookies = NULL;
-		} else
-			*ap->a_ncookies = ncookies;
-	}
-
-	uio->uio_offset = i;
-	return (error);
-}
-
-int
-kernfs_inactive(v)
-	void *v;
-{
-	struct vop_inactive_args /* {
-		struct vnode *a_vp;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct vnode *vp = ap->a_vp;
-	const struct kernfs_node *kfs = VTOKERN(ap->a_vp);
-#ifdef IPSEC
-	struct mbuf *m;
-	struct secpolicy *sp;
-#endif
-
-	VOP_UNLOCK(vp, 0);
-	switch (kfs->kfs_type) {
-#ifdef IPSEC
-	case KFSipsecsa:
-		m = key_setdumpsa_spi(htonl(kfs->kfs_value));
-		if (m)
-			m_freem(m);
-		else
-			vgone(vp);
-		break;
-	case KFSipsecsp:
-		sp = key_getspbyid(kfs->kfs_value);
-		if (sp)
-			key_freesp(sp);
-		else {
-			/* should never happen as we hold a refcnt */
-			vgone(vp);
-		}
-		break;
-#endif
-	default:
-		break;
-	}
-	return (0);
-}
-
-int
-kernfs_reclaim(v)
-	void *v;
-{
-	struct vop_reclaim_args /* {
-		struct vnode *a_vp;
-	} */ *ap = v;
-
-	return (kernfs_freevp(ap->a_vp));
-}
-
-/*
- * Return POSIX pathconf information applicable to special devices.
- */
-int
-kernfs_pathconf(v)
-	void *v;
-{
-	struct vop_pathconf_args /* {
-		struct vnode *a_vp;
-		int a_name;
-		register_t *a_retval;
-	} */ *ap = v;
-
-	switch (ap->a_name) {
-	case _PC_LINK_MAX:
-		*ap->a_retval = LINK_MAX;
-		return (0);
-	case _PC_MAX_CANON:
-		*ap->a_retval = MAX_CANON;
-		return (0);
-	case _PC_MAX_INPUT:
-		*ap->a_retval = MAX_INPUT;
-		return (0);
-	case _PC_PIPE_BUF:
-		*ap->a_retval = PIPE_BUF;
-		return (0);
-	case _PC_CHOWN_RESTRICTED:
-		*ap->a_retval = 1;
-		return (0);
-	case _PC_VDISABLE:
-		*ap->a_retval = _POSIX_VDISABLE;
-		return (0);
-	case _PC_SYNC_IO:
-		*ap->a_retval = 1;
-		return (0);
-	default:
-		return (EINVAL);
-	}
-	/* NOTREACHED */
-}
-
-/*
- * Print out the contents of a /dev/fd vnode.
- */
-/* ARGSUSED */
-int
-kernfs_print(v)
-	void *v;
-{
-
-	printf("tag VT_KERNFS, kernfs vnode\n");
-	return (0);
-}
-
-int
-kernfs_link(v)
-	void *v;
-{
-	struct vop_link_args /* {
-		struct vnode *a_dvp;
-		struct vnode *a_vp;
-		struct componentname *a_cnp;
-	} */ *ap = v;
-
-	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
-	vput(ap->a_dvp);
-	return (EROFS);
-}
-
-int
-kernfs_symlink(v)
-	void *v;
-{
-	struct vop_symlink_args /* {
-		struct vnode *a_dvp;
-		struct vnode **a_vpp;
-		struct componentname *a_cnp;
-		struct vattr *a_vap;
-		char *a_target;
-	} */ *ap = v;
-
-	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
-	vput(ap->a_dvp);
-	return (EROFS);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/Makefile mult-netbsd-3.1/sys/miscfs/procfs/Makefile
--- NetBSD-3.1/sys/miscfs/procfs/Makefile	1998-06-13 00:23:04.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/Makefile	1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-#	$NetBSD: Makefile,v 1.1 1998/06/12 23:23:04 cgd Exp $
-
-INCSDIR= /usr/include/miscfs/procfs
-
-INCS=	procfs.h
-
-.include <bsd.kinc.mk>
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/files.procfs mult-netbsd-3.1/sys/miscfs/procfs/files.procfs
--- NetBSD-3.1/sys/miscfs/procfs/files.procfs	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/files.procfs	1970-01-01 01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-#	$NetBSD: files.procfs,v 1.4 2005/02/26 22:59:00 perry Exp $
-
-deffs	PROCFS
-
-file	miscfs/procfs/procfs_cmdline.c	procfs
-file	miscfs/procfs/procfs_ctl.c	procfs
-file	miscfs/procfs/procfs_fd.c	procfs
-file	miscfs/procfs/procfs_fpregs.c	procfs
-file	miscfs/procfs/procfs_linux.c	procfs
-file	miscfs/procfs/procfs_map.c	procfs
-file	miscfs/procfs/procfs_mem.c	procfs
-file	miscfs/procfs/procfs_note.c	procfs
-file	miscfs/procfs/procfs_regs.c	procfs
-file	miscfs/procfs/procfs_status.c	procfs
-file	miscfs/procfs/procfs_subr.c	procfs
-file	miscfs/procfs/procfs_vfsops.c	procfs
-file	miscfs/procfs/procfs_vnops.c	procfs
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs.h mult-netbsd-3.1/sys/miscfs/procfs/procfs.h
--- NetBSD-3.1/sys/miscfs/procfs/procfs.h	2004-09-20 18:53:08.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,244 +0,0 @@
-/*	$NetBSD: procfs.h,v 1.56 2004/09/20 17:53:08 jdolecek Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs.h	8.9 (Berkeley) 5/14/95
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs.h	8.9 (Berkeley) 5/14/95
- */
-
-/* This also pulls in __HAVE_PROCFS_MACHDEP */
-#include <sys/ptrace.h>
-
-#ifdef _KERNEL
-/*
- * The different types of node in a procfs filesystem
- */
-typedef enum {
-	PFSroot,	/* the filesystem root */
-	PFScurproc,	/* symbolic link for curproc */
-	PFSself,	/* like curproc, but this is the Linux name */
-	PFSproc,	/* a process-specific sub-directory */
-	PFSfile,	/* the executable file */
-	PFSmem,		/* the process's memory image */
-	PFSregs,	/* the process's register set */
-	PFSfpregs,	/* the process's FP register set */
-	PFSctl,		/* process control */
-	PFSstat,	/* process status (if -o linux) */
-	PFSstatus,	/* process status */
-	PFSnote,	/* process notifier */
-	PFSnotepg,	/* process group notifier */
-	PFSmap,		/* memory map */
-	PFScmdline,	/* process command line args */
-	PFSmeminfo,	/* system memory info (if -o linux) */
-	PFScpuinfo,	/* CPU info (if -o linux) */
-	PFSmaps,	/* memory map, Linux style (if -o linux) */
-	PFSfd,		/* a directory containing the processes open fd's */
-	PFSuptime,	/* elapsed time since (if -o linux) */
-	PFSmounts,	/* mounted filesystems (if -o linux) */
-#ifdef __HAVE_PROCFS_MACHDEP
-	PROCFS_MACHDEP_NODE_TYPES
-#endif
-} pfstype;
-
-/*
- * control data for the proc file system.
- */
-struct pfsnode {
-	LIST_ENTRY(pfsnode) pfs_hash;	/* hash chain */
-	struct vnode	*pfs_vnode;	/* vnode associated with this pfsnode */
-	pfstype		pfs_type;	/* type of procfs node */
-	pid_t		pfs_pid;	/* associated process */
-	int		pfs_fd;		/* associated fd if not -1 */
-	mode_t		pfs_mode;	/* mode bits for stat() */
-	u_long		pfs_flags;	/* open flags */
-	u_long		pfs_fileno;	/* unique file id */
-};
-
-#define PROCFS_NOTELEN	64	/* max length of a note (/proc/$pid/note) */
-#define PROCFS_CTLLEN 	8	/* max length of a ctl msg (/proc/$pid/ctl */
-
-#endif /* _KERNEL */
-
-struct procfs_args {
-	int version;
-	int flags;
-};
-
-#define PROCFS_ARGSVERSION	1
-
-#define PROCFSMNT_LINUXCOMPAT	0x01
-
-#define PROCFSMNT_BITS "\177\20" \
-    "b\00linuxcompat\0"
-
-/*
- * Kernel stuff follows
- */
-#ifdef _KERNEL
-#define CNEQ(cnp, s, len) \
-	 ((cnp)->cn_namelen == (len) && \
-	  (memcmp((s), (cnp)->cn_nameptr, (len)) == 0))
-
-#define UIO_MX 32
-
-#define PROCFS_FILENO(pid, type, fd) \
-    (((type) < PFSproc) ? ((type) + 2) : \
-	(((fd) == -1) ? ((((pid)+1) << 5) + ((int) (type))) : \
-	((((pid)+1) << 16) | ((fd) << 5) | ((int) (type)))))
-
-struct procfsmount {
-	void *pmnt_exechook;
-	int pmnt_flags;
-};
-
-#define VFSTOPROC(mp)	((struct procfsmount *)(mp)->mnt_data)
-
-/*
- * Convert between pfsnode vnode
- */
-#define VTOPFS(vp)	((struct pfsnode *)(vp)->v_data)
-#define PFSTOV(pfs)	((pfs)->pfs_vnode)
-
-typedef struct vfs_namemap vfs_namemap_t;
-struct vfs_namemap {
-	const char *nm_name;
-	int nm_val;
-};
-
-int vfs_getuserstr __P((struct uio *, char *, int *));
-const vfs_namemap_t *vfs_findname __P((const vfs_namemap_t *, const char *, int));
-
-#define PFIND(pid) ((pid) ? pfind(pid) : &proc0)
-int procfs_freevp __P((struct vnode *));
-int procfs_allocvp __P((struct mount *, struct vnode **, pid_t, pfstype, int));
-int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_doregs __P((struct proc *, struct lwp *, struct pfsnode *,
-    struct uio *));
-int procfs_dofpregs __P((struct proc *, struct lwp *, struct pfsnode *,
-    struct uio *));
-int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_doctl __P((struct proc *, struct lwp *, struct pfsnode *,
-    struct uio *));
-int procfs_do_pid_stat __P((struct proc *, struct lwp *, struct pfsnode *,
-    struct uio *));
-int procfs_dostatus __P((struct proc *, struct lwp *, struct pfsnode *,
-    struct uio *));
-int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *, int));
-int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_domeminfo __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_docpuinfo __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_dofd __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_douptime __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-int procfs_domounts __P((struct proc *, struct proc *, struct pfsnode *,
-    struct uio *));
-
-void procfs_revoke_vnodes __P((struct proc *, void *));
-void procfs_hashinit __P((void));
-void procfs_hashreinit __P((void));
-void procfs_hashdone __P((void));
-int procfs_getfp __P((struct pfsnode *, struct proc **, struct file **));
-
-/* functions to check whether or not files should be displayed */
-int procfs_validfile __P((struct proc *, struct mount *));
-int procfs_validfpregs __P((struct proc *, struct mount *));
-int procfs_validregs __P((struct proc *, struct mount *));
-int procfs_validmap __P((struct proc *, struct mount *));
-
-int procfs_rw __P((void *));
-
-int procfs_getcpuinfstr __P((char *, int *));
-
-#define PROCFS_LOCKED	0x01
-#define PROCFS_WANT	0x02
-
-extern int (**procfs_vnodeop_p) __P((void *));
-extern struct vfsops procfs_vfsops;
-
-int	procfs_root __P((struct mount *, struct vnode **));
-
-#ifdef __HAVE_PROCFS_MACHDEP
-struct vattr;
-
-void	procfs_machdep_allocvp(struct vnode *);
-int	procfs_machdep_rw(struct proc *, struct lwp *, struct pfsnode *,
-	    struct uio *);
-int	procfs_machdep_getattr(struct vnode *, struct vattr *, struct proc *);
-#endif
-
-#ifdef SYSCTL_SETUP_PROTO
-SYSCTL_SETUP_PROTO(sysctl_vfs_procfs_setup);
-#endif /* SYSCTL_SETUP_PROTO */
-#endif /* _KERNEL */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_cmdline.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_cmdline.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_cmdline.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_cmdline.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,190 +0,0 @@
-/*	$NetBSD: procfs_cmdline.c,v 1.19 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz>
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jaromir Dolecek.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the NetBSD
- *	Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_cmdline.c,v 1.19 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/syslimits.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/exec.h>
-#include <sys/malloc.h>
-#include <miscfs/procfs/procfs.h>
-
-#include <uvm/uvm_extern.h>
-
-/*
- * code for returning process's command line arguments
- */
-int
-procfs_docmdline(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-	struct ps_strings pss;
-	int count, error;
-	size_t i, len, xlen, upper_bound;
-	struct uio auio;
-	struct iovec aiov;
-	vaddr_t argv;
-	char *arg;
-
-	/* Don't allow writing. */
-	if (uio->uio_rw != UIO_READ)
-		return (EOPNOTSUPP);
-
-	/*
-	 * Allocate a temporary buffer to hold the arguments.
-	 */
-	arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
-
-	/*
-	 * Zombies don't have a stack, so we can't read their psstrings.
-	 * System processes also don't have a user stack.  This is what
-	 * ps(1) would display.
-	 */
-	if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
-		len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm);
-		error = uiomove_frombuf(arg, len, uio);
-
-		free(arg, M_TEMP);
-		return (error);
-	}
-
-	/*
-	 * NOTE: Don't bother doing a process_checkioperm() here
-	 * because the psstrings info is available by using ps(1),
-	 * so it's not like there's anything to protect here.
-	 */
-
-	/*
-	 * Lock the process down in memory.
-	 */
-	/* XXXCDC: how should locking work here? */
-	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
-		free(arg, M_TEMP);
-		return (EFAULT);
-	}
-	p->p_vmspace->vm_refcnt++;	/* XXX */
-
-	/*
-	 * Read in the ps_strings structure.
-	 */
-	aiov.iov_base = &pss;
-	aiov.iov_len = sizeof(pss);
-	auio.uio_iov = &aiov;
-	auio.uio_iovcnt = 1;
-	auio.uio_offset = (vaddr_t)p->p_psstr;
-	auio.uio_resid = sizeof(pss);
-	auio.uio_segflg = UIO_SYSSPACE;
-	auio.uio_rw = UIO_READ;
-	auio.uio_procp = NULL;
-	error = uvm_io(&p->p_vmspace->vm_map, &auio);
-	if (error)
-		goto bad;
-
-	/*
-	 * Now read the address of the argument vector.
-	 */
-	aiov.iov_base = &argv;
-	aiov.iov_len = sizeof(argv);
-	auio.uio_iov = &aiov;
-	auio.uio_iovcnt = 1;
-	auio.uio_offset = (vaddr_t)pss.ps_argvstr;
-	auio.uio_resid = sizeof(argv);
-	auio.uio_segflg = UIO_SYSSPACE;
-	auio.uio_rw = UIO_READ;
-	auio.uio_procp = NULL;
-	error = uvm_io(&p->p_vmspace->vm_map, &auio);
-	if (error)
-		goto bad;
-
-	/*
-	 * Now copy in the actual argument vector, one page at a time,
-	 * since we don't know how long the vector is (though, we do
-	 * know how many NUL-terminated strings are in the vector).
-	 */
-	len = 0;
-	count = pss.ps_nargvstr;
-	upper_bound = round_page(uio->uio_offset + uio->uio_resid);
-	for (; count && len < upper_bound; len += xlen) {
-		aiov.iov_base = arg;
-		aiov.iov_len = PAGE_SIZE;
-		auio.uio_iov = &aiov;
-		auio.uio_iovcnt = 1;
-		auio.uio_offset = argv + len;
-		xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
-		auio.uio_resid = xlen;
-		auio.uio_segflg = UIO_SYSSPACE;
-		auio.uio_rw = UIO_READ;
-		auio.uio_procp = NULL;
-		error = uvm_io(&p->p_vmspace->vm_map, &auio);
-		if (error)
-			goto bad;
-
-		for (i = 0; i < xlen && count != 0; i++) {
-			if (arg[i] == '\0')
-				count--;	/* one full string */
-		}
-
-		if (count == 0)
-			i--;		/* exclude the final NUL */
-
-		if (len + i > uio->uio_offset) {
-			/* Have data in this page, copy it out */
-			error = uiomove(arg + uio->uio_offset - len,
-			    i + len - uio->uio_offset, uio);
-			if (error || uio->uio_resid <= 0)
-				break;
-		}
-	}
-
- bad:
-	/*
-	 * Release the process.
-	 */
-	uvmspace_free(p->p_vmspace);
-
-	free(arg, M_TEMP);
-	return (error);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_ctl.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_ctl.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_ctl.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_ctl.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,376 +0,0 @@
-/*	$NetBSD: procfs_ctl.c,v 1.28 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_ctl.c	8.4 (Berkeley) 6/15/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_ctl.c	8.4 (Berkeley) 6/15/94
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_ctl.c,v 1.28 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/resource.h>
-#include <sys/resourcevar.h>
-#include <sys/signalvar.h>
-#include <miscfs/procfs/procfs.h>
-
-#define PROCFS_CTL_ATTACH	1
-#define PROCFS_CTL_DETACH	2
-#define PROCFS_CTL_STEP		3
-#define PROCFS_CTL_RUN		4
-#define PROCFS_CTL_WAIT		5
-
-static const vfs_namemap_t ctlnames[] = {
-	/* special /proc commands */
-	{ "attach",	PROCFS_CTL_ATTACH },
-	{ "detach",	PROCFS_CTL_DETACH },
-	{ "step",	PROCFS_CTL_STEP },
-	{ "run",	PROCFS_CTL_RUN },
-	{ "wait",	PROCFS_CTL_WAIT },
-	{ 0 },
-};
-
-static const vfs_namemap_t signames[] = {
-	/* regular signal names */
-	{ "hup",	SIGHUP },	{ "int",	SIGINT },
-	{ "quit",	SIGQUIT },	{ "ill",	SIGILL },
-	{ "trap",	SIGTRAP },	{ "abrt",	SIGABRT },
-	{ "iot",	SIGIOT },	{ "emt",	SIGEMT },
-	{ "fpe",	SIGFPE },	{ "kill",	SIGKILL },
-	{ "bus",	SIGBUS },	{ "segv",	SIGSEGV },
-	{ "sys",	SIGSYS },	{ "pipe",	SIGPIPE },
-	{ "alrm",	SIGALRM },	{ "term",	SIGTERM },
-	{ "urg",	SIGURG },	{ "stop",	SIGSTOP },
-	{ "tstp",	SIGTSTP },	{ "cont",	SIGCONT },
-	{ "chld",	SIGCHLD },	{ "ttin",	SIGTTIN },
-	{ "ttou",	SIGTTOU },	{ "io",		SIGIO },
-	{ "xcpu",	SIGXCPU },	{ "xfsz",	SIGXFSZ },
-	{ "vtalrm",	SIGVTALRM },	{ "prof",	SIGPROF },
-	{ "winch",	SIGWINCH },	{ "info",	SIGINFO },
-	{ "usr1",	SIGUSR1 },	{ "usr2",	SIGUSR2 },
-	{ 0 },
-};
-
-int procfs_control __P((struct proc *, struct lwp *, int, int));
-
-/* Macros to clear/set/test flags. */
-#define	SET(t, f)	(t) |= (f)
-#define	CLR(t, f)	(t) &= ~(f)
-#define	ISSET(t, f)	((t) & (f))
-
-int
-procfs_control(curp, l, op, sig)
-	struct proc *curp;
-	struct lwp *l;
-	int op, sig;
-{
-	int s, error;
-	struct proc *p = l->l_proc;
-
-	/*
-	 * You cannot do anything to the process if it is currently exec'ing
-	 */
-	if (ISSET(p->p_flag, P_INEXEC))
-		return (EAGAIN);
-
-	switch (op) {
-	/*
-	 * Attach - attaches the target process for debugging
-	 * by the calling process.
-	 */
-	case PROCFS_CTL_ATTACH:
-		/*
-		 * You can't attach to a process if:
-		 *      (1) it's the process that's doing the attaching,
-		 */
-		if (p->p_pid == curp->p_pid)
-			return (EINVAL);
-
-		/*
-		 *      (2) it's already being traced, or
-		 */
-		if (ISSET(p->p_flag, P_TRACED))
-			return (EBUSY);
-
-		/*
-		 *      (3) it's not owned by you, or is set-id on exec
-		 *          (unless you're root), or...
-		 */
-		if ((p->p_cred->p_ruid != curp->p_cred->p_ruid ||
-			ISSET(p->p_flag, P_SUGID)) &&
-		    (error = suser(curp->p_ucred, &curp->p_acflag)) != 0)
-			return (error);
-
-		/*
-		 *      (4) ...it's init, which controls the security level
-		 *          of the entire system, and the system was not
-		 *          compiled with permanently insecure mode turned
-		 *          on.
-		 */
-		if (p == initproc && securelevel > -1)
-			return (EPERM);
-		break;
-
-	/*
-	 * Target process must be stopped, owned by (curp) and
-	 * be set up for tracing (P_TRACED flag set).
-	 * Allow DETACH to take place at any time for sanity.
-	 * Allow WAIT any time, of course.
-	 *
-	 * Note that the semantics of DETACH are different here
-	 * from ptrace(2).
-	 */
-	case PROCFS_CTL_DETACH:
-	case PROCFS_CTL_WAIT:
-		/*
-		 * You can't do what you want to the process if:
-		 *      (1) It's not being traced at all,
-		 */
-		if (!ISSET(p->p_flag, P_TRACED))
-			return (EPERM);
-
-		/*
-		 *	(2) it's being traced by ptrace(2) (which has
-		 *	    different signal delivery semantics), or
-		 */
-		if (!ISSET(p->p_flag, P_FSTRACE))
-			return (EBUSY);
-
-		/*
-		 *      (3) it's not being traced by _you_.
-		 */
-		if (p->p_pptr != curp)
-			return (EBUSY);
-		break;
-
-	default:
-		/*
-		 * You can't do what you want to the process if:
-		 *      (1) It's not being traced at all,
-		 */
-		if (!ISSET(p->p_flag, P_TRACED))
-			return (EPERM);
-
-		/*
-		 *	(2) it's being traced by ptrace(2) (which has
-		 *	    different signal delivery semantics),
-		 */
-		if (!ISSET(p->p_flag, P_FSTRACE))
-			return (EBUSY);
-
-		/*
-		 *      (3) it's not being traced by _you_, or
-		 */
-		if (p->p_pptr != curp)
-			return (EBUSY);
-
-		/*
-		 *      (4) it's not currently stopped.
-		 */
-		if (p->p_stat != SSTOP || !ISSET(p->p_flag, P_WAITED))
-			return (EBUSY);
-		break;
-	}
-
-	/* Do single-step fixup if needed. */
-	FIX_SSTEP(p);
-
-	switch (op) {
-	case PROCFS_CTL_ATTACH:
-		/*
-		 * Go ahead and set the trace flag.
-		 * Save the old parent (it's reset in
-		 *   _DETACH, and also in kern_exit.c:wait4()
-		 * Reparent the process so that the tracing
-		 *   proc gets to see all the action.
-		 * Stop the target.
-		 */
-		SET(p->p_flag, P_TRACED|P_FSTRACE);
-		p->p_opptr = p->p_pptr;
-		if (p->p_pptr != curp) {
-			p->p_pptr->p_flag |= P_CHTRACED;
-			proc_reparent(p, curp);
-		}
-		sig = SIGSTOP;
-		goto sendsig;
-
-#ifdef PT_STEP
-	case PROCFS_CTL_STEP:
-		/*
-		 * Step.  Let the target process execute a single instruction.
-		 */
-#endif
-	case PROCFS_CTL_RUN:
-	case PROCFS_CTL_DETACH:
-#ifdef PT_STEP
-		PHOLD(l);
-		error = process_sstep(l, op == PROCFS_CTL_STEP);
-		PRELE(l);
-		if (error)
-			return (error);
-#endif
-
-		if (op == PROCFS_CTL_DETACH) {
-			/* give process back to original parent */
-			if (p->p_opptr != p->p_pptr) {
-				struct proc *pp = p->p_opptr;
-				proc_reparent(p, pp ? pp : initproc);
-			}
-
-			/* not being traced any more */
-			p->p_opptr = NULL;
-			CLR(p->p_flag, P_TRACED|P_FSTRACE|P_WAITED);
-		}
-
-	sendsig:
-		/* Finally, deliver the requested signal (or none). */
-		if (l->l_stat == LSSTOP) {
-			p->p_xstat = sig;
-			SCHED_LOCK(s);
-			setrunnable(l);
-			SCHED_UNLOCK(s);
-		} else {
-			if (sig != 0)
-				psignal(p, sig);
-		}
-		return (0);
-
-	case PROCFS_CTL_WAIT:
-		/*
-		 * Wait for the target process to stop.
-		 */
-		while (l->l_stat != LSSTOP && P_ZOMBIE(p)) {
-			error = tsleep(l, PWAIT|PCATCH, "procfsx", 0);
-			if (error)
-				return (error);
-		}
-		return (0);
-	}
-
-	panic("procfs_control");
-}
-
-int
-procfs_doctl(curp, l, pfs, uio)
-	struct proc *curp;
-	struct lwp *l;
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-	int xlen;
-	int error;
-	char msg[PROCFS_CTLLEN+1];
-	const vfs_namemap_t *nm;
-	struct proc *p = l->l_proc;
-
-	if (uio->uio_rw != UIO_WRITE)
-		return (EOPNOTSUPP);
-
-	xlen = PROCFS_CTLLEN;
-	error = vfs_getuserstr(uio, msg, &xlen);
-	if (error)
-		return (error);
-
-	/*
-	 * Map signal names into signal generation
-	 * or debug control.  Unknown commands and/or signals
-	 * return EOPNOTSUPP.
-	 *
-	 * Sending a signal while the process is being debugged
-	 * also has the side effect of letting the target continue
-	 * to run.  There is no way to single-step a signal delivery.
-	 */
-	error = EOPNOTSUPP;
-
-	nm = vfs_findname(ctlnames, msg, xlen);
-	if (nm) {
-		error = procfs_control(curp, l, nm->nm_val, 0);
-	} else {
-		nm = vfs_findname(signames, msg, xlen);
-		if (nm) {
-			if (ISSET(p->p_flag, P_TRACED) &&
-			    p->p_pptr == curp)
-				error = procfs_control(curp, l, PROCFS_CTL_RUN,
-				    nm->nm_val);
-			else {
-				psignal(p, nm->nm_val);
-				error = 0;
-			}
-		}
-	}
-
-	return (error);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_fd.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_fd.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_fd.c	2003-06-29 23:31:45.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_fd.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,84 +0,0 @@
-/*	$NetBSD: procfs_fd.c,v 1.5 2003/06/29 22:31:45 fvdl Exp $	*/
-
-/*-
- * Copyright (c) 2003 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_fd.c,v 1.5 2003/06/29 22:31:45 fvdl Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_dofd(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-	int error;
-	struct file *fp;
-	struct proc *pown;
-	off_t offs;
-
-	if ((error = procfs_getfp(pfs, &pown, &fp)) != 0)
-		return error;
-
-	FILE_USE(fp);
-
-	offs = fp->f_offset;
-
-	switch (uio->uio_rw) {
-	case UIO_READ:
-		error = (*fp->f_ops->fo_read)(fp, &offs, uio, curp->p_ucred, 0);
-		break;
-	case UIO_WRITE:
-		error = (*fp->f_ops->fo_write)(fp, &offs, uio, curp->p_ucred,0);
-		break;
-	default:
-		panic("bad uio op");
-	}
-
-	FILE_UNUSE(fp, pown);
-
-	return (error);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_fpregs.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_fpregs.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_fpregs.c	2003-08-07 17:32:41.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_fpregs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,105 +0,0 @@
-/*	$NetBSD: procfs_fpregs.c,v 1.14 2003/08/07 16:32:41 agc Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_fpregs.c	8.2 (Berkeley) 6/15/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_fpregs.c	8.2 (Berkeley) 6/15/94
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_fpregs.c,v 1.14 2003/08/07 16:32:41 agc Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ptrace.h>
-
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_dofpregs(curp, l, pfs, uio)
-	struct proc *curp;		/* tracer */
-	struct lwp *l;			/* traced */
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-
-	return (process_dofpregs(curp, l, uio));
-}
-
-int
-procfs_validfpregs(p, mp)
-	struct proc *p;
-	struct mount *mp;
-{
-
-	return (process_validfpregs(p));
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_linux.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_linux.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_linux.c	2006-10-24 18:04:12.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_linux.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,318 +0,0 @@
-/*      $NetBSD: procfs_linux.c,v 1.22.2.1 2006/10/24 17:04:12 ghen Exp $      */
-
-/*
- * Copyright (c) 2001 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Frank van der Linden for Wasabi Systems, Inc.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed for the NetBSD Project by
- *      Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- *    or promote products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
- * 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.22.2.1 2006/10/24 17:04:12 ghen Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/exec.h>
-#include <sys/resource.h>
-#include <sys/resourcevar.h>
-#include <sys/signal.h>
-#include <sys/signalvar.h>
-#include <sys/tty.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-
-#include <miscfs/procfs/procfs.h>
-#include <compat/linux/common/linux_exec.h>
-
-#include <uvm/uvm_extern.h>
-#include <uvm/uvm.h>
-
-#define PGTOB(p)	((unsigned long)(p) << PAGE_SHIFT)
-#define PGTOKB(p)	((unsigned long)(p) << (PAGE_SHIFT - 10))
-
-/*
- * Linux compatible /proc/meminfo. Only active when the -o linux
- * mountflag is used.
- */
-int
-procfs_domeminfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
-		 struct uio *uio)
-{
-	char buf[512];
-	int len;
-
-	len = snprintf(buf, sizeof buf,
-		"        total:    used:    free:  shared: buffers: cached:\n"
-		"Mem:  %8lu %8lu %8lu %8lu %8lu %8lu\n"
-		"Swap: %8lu %8lu %8lu\n"
-		"MemTotal:  %8lu kB\n"
-		"MemFree:   %8lu kB\n"
-		"MemShared: %8lu kB\n"
-		"Buffers:   %8lu kB\n"
-		"Cached:    %8lu kB\n"
-		"SwapTotal: %8lu kB\n"
-		"SwapFree:  %8lu kB\n",
-		PGTOB(uvmexp.npages),
-		PGTOB(uvmexp.npages - uvmexp.free),
-		PGTOB(uvmexp.free),
-		0L,
-		PGTOB(uvmexp.filepages),
-		PGTOB(uvmexp.anonpages + uvmexp.filepages + uvmexp.execpages),
-		PGTOB(uvmexp.swpages),
-		PGTOB(uvmexp.swpginuse),
-		PGTOB(uvmexp.swpages - uvmexp.swpginuse),
-		PGTOKB(uvmexp.npages),
-		PGTOKB(uvmexp.free),
-		0L,
-		PGTOKB(uvmexp.filepages),
-		PGTOKB(uvmexp.anonpages + uvmexp.filepages + uvmexp.execpages),
-		PGTOKB(uvmexp.swpages),
-		PGTOKB(uvmexp.swpages - uvmexp.swpginuse));
-
-	if (len == 0)
-		return 0;
-
-	return (uiomove_frombuf(buf, len, uio));
-}
-
-/*
- * Linux compatible /proc/<pid>/stat. Only active when the -o linux
- * mountflag is used.
- */
-int
-procfs_do_pid_stat(struct proc *curp, struct lwp *l, struct pfsnode *pfs,
-		 struct uio *uio)
-{
-	char buf[512];
-	int len;
-	struct proc *p = l->l_proc;
-	struct tty *tty = p->p_session->s_ttyp;
-	struct rusage *ru = &p->p_stats->p_ru;
-	struct rusage *cru = &p->p_stats->p_cru;
-	struct vm_map *map = &p->p_vmspace->vm_map;
-	struct vm_map_entry *entry;
-	unsigned long stext = 0, etext = 0, sstack = 0;
-
-	if (map != &curproc->p_vmspace->vm_map)
-		vm_map_lock_read(map);
-	for (entry = map->header.next; entry != &map->header;
-	    entry = entry->next) {
-		if (UVM_ET_ISSUBMAP(entry))
-			continue;
-		/* assume text is the first entry */
-		if (stext == etext) {
-			stext = entry->start;
-			etext = entry->end;
-			break;
-		}
-	}
-#ifdef LINUX_USRSTACK
-	if (strcmp(p->p_emul->e_name, "linux") == 0 &&
-	    LINUX_USRSTACK < USRSTACK)
-		sstack = (unsigned long) LINUX_USRSTACK;
-	else
-#endif
-		sstack = (unsigned long) USRSTACK;
-
-	if (map != &curproc->p_vmspace->vm_map)
-		vm_map_unlock_read(map);
-
-	len = snprintf(buf, sizeof(buf),
-	    "%d (%s) %c %d %d %d %d %d "
-	    "%u "
-	    "%lu %lu %lu %lu %lu %lu %lu %lu "
-	    "%d %d %d "
-	    "%lu %lu %lu %lu %" PRIu64 " "
-	    "%lu %lu %lu "
-	    "%u %u "
-	    "%u %u %u %u "
-	    "%lu %lu %lu %d %d\n",
-
-	    p->p_pid,
-	    p->p_comm,
-	    "0IR3SZD"[(p->p_stat > 6) ? 0 : (int)p->p_stat],
-	    (p->p_pptr != NULL) ? p->p_pptr->p_pid : 0,
-
-	    p->p_pgid,
-	    p->p_session->s_sid,
-	    tty ? tty->t_dev : 0,
-	    (tty && tty->t_pgrp) ? tty->t_pgrp->pg_id : 0,
-
-	    p->p_flag,
-
-	    ru->ru_minflt,
-	    cru->ru_minflt,
-	    ru->ru_majflt,
-	    cru->ru_majflt,
-	    ru->ru_utime.tv_sec,
-	    ru->ru_stime.tv_sec,
-	    cru->ru_utime.tv_sec,
-	    cru->ru_stime.tv_sec,
-
-	    p->p_nice,					/* XXX: priority */
-	    p->p_nice,
-	    0,
-
-	    p->p_rtime.tv_sec,
-	    p->p_stats->p_start.tv_sec,
-	    ru->ru_ixrss + ru->ru_idrss + ru->ru_isrss,
-	    ru->ru_maxrss,
-	    p->p_rlimit[RLIMIT_RSS].rlim_cur,
-
-	    stext,					/* start code */
-	    etext,					/* end code */
-	    sstack,					/* mm start stack */
-	    0,						/* XXX: pc */
-	    0,						/* XXX: sp */
-	    p->p_sigctx.ps_siglist.__bits[0],		/* pending */
-	    p->p_sigctx.ps_sigmask.__bits[0],		/* blocked */
-	    p->p_sigctx.ps_sigignore.__bits[0],		/* ignored */
-	    p->p_sigctx.ps_sigcatch.__bits[0],		/* caught */
-
-	    (unsigned long)(intptr_t)l->l_wchan,
-	    ru->ru_nvcsw,
-	    ru->ru_nivcsw,
-	    p->p_exitsig,
-	    0);						/* XXX: processor */
-
-	if (len == 0)
-		return 0;
-
-	return (uiomove_frombuf(buf, len, uio));
-}
-
-int
-procfs_docpuinfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
-		 struct uio *uio)
-{
-	int len = 4096;
-	char *buf = malloc(len, M_TEMP, M_WAITOK);
-	int error;
-
-	if (procfs_getcpuinfstr(buf, &len) < 0) {
-		error = ENOSPC;
-		goto done;
-	}
-
-	if (len == 0) {
-		error = 0;
-		goto done;
-	}
-
-	error = uiomove_frombuf(buf, len, uio);
-done:
-	free(buf, M_TEMP);
-	return error;
-}
-
-int
-procfs_douptime(struct proc *curp, struct proc *p, struct pfsnode *pfs,
-		 struct uio *uio)
-{
-	char buf[512];
-	int len;
-	struct timeval runtime;
-	u_int64_t idle;
-
-	timersub(&curcpu()->ci_schedstate.spc_runtime, &boottime, &runtime);
-	idle = curcpu()->ci_schedstate.spc_cp_time[CP_IDLE];
-	len = snprintf(buf, sizeof(buf),
-	    "%lu.%02lu %" PRIu64 ".%02" PRIu64 "\n",
-	    runtime.tv_sec, runtime.tv_usec / 10000,
-	    idle / hz, (((idle % hz) * 100) / hz) % 100);
-
-	if (len == 0)
-		return 0;
-
-	return (uiomove_frombuf(buf, len, uio));
-}
-
-int
-procfs_domounts(struct proc *curp, struct proc *p, struct pfsnode *pfs,
-		 struct uio *uio)
-{
-	char buf[512], *mtab = NULL;
-	const char *fsname;
-	size_t len, mtabsz = 0;
-	struct mount *mp, *nmp;
-	struct statvfs *sfs;
-	int error = 0;
-
-	simple_lock(&mountlist_slock);
-	for (mp = CIRCLEQ_FIRST(&mountlist); mp != (void *)&mountlist;
-	     mp = nmp) {
-		if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock)) {
-			nmp = CIRCLEQ_NEXT(mp, mnt_list);
-			continue;
-		}
-
-		sfs = &mp->mnt_stat;
-
-		/* Linux uses different names for some filesystems */
-		fsname = sfs->f_fstypename;
-		if (strcmp(fsname, "procfs") == 0)
-			fsname = "proc";
-		else if (strcmp(fsname, "ext2fs") == 0)
-			fsname = "ext2";
-
-		len = snprintf(buf, sizeof(buf), "%s %s %s %s%s%s%s%s%s 0 0\n",
-			sfs->f_mntfromname,
-			sfs->f_mntonname,
-			fsname,
-			(mp->mnt_flag & MNT_RDONLY) ? "ro" : "rw",
-			(mp->mnt_flag & MNT_NOSUID) ? ",nosuid" : "",
-			(mp->mnt_flag & MNT_NOEXEC) ? ",noexec" : "",
-			(mp->mnt_flag & MNT_NODEV) ? ",nodev" : "",
-			(mp->mnt_flag & MNT_SYNCHRONOUS) ? ",sync" : "",
-			(mp->mnt_flag & MNT_NOATIME) ? ",noatime" : ""
-			);
-
-		mtab = realloc(mtab, mtabsz + len, M_TEMP, M_WAITOK);
-		memcpy(mtab + mtabsz, buf, len);
-		mtabsz += len;
-
-		simple_lock(&mountlist_slock);
-		nmp = CIRCLEQ_NEXT(mp, mnt_list);
-		vfs_unbusy(mp);
-	}
-	simple_unlock(&mountlist_slock);
-
-	if (mtabsz > 0) {
-		error = uiomove_frombuf(mtab, mtabsz, uio);
-		free(mtab, M_TEMP);
-	}
-
-	return error;
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_map.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_map.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_map.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_map.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,261 +0,0 @@
-/*	$NetBSD: procfs_map.c,v 1.21 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_status.c	8.3 (Berkeley) 2/17/94
- *
- *	$FreeBSD: procfs_map.c,v 1.18 1998/12/04 22:54:51 archie Exp $
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_status.c	8.3 (Berkeley) 2/17/94
- *
- *	$FreeBSD: procfs_map.c,v 1.18 1998/12/04 22:54:51 archie Exp $
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_map.c,v 1.21 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/namei.h>
-#include <miscfs/procfs/procfs.h>
-
-#include <sys/lock.h>
-
-#include <uvm/uvm.h>
-
-#define MEBUFFERSIZE 256
-
-extern int getcwd_common __P((struct vnode *, struct vnode *,
-			      char **, char *, int, int, struct proc *));
-
-static int procfs_vnode_to_path(struct vnode *vp, char *path, int len,
-				struct proc *curp, struct proc *p);
-
-/*
- * The map entries can *almost* be read with programs like cat.  However,
- * large maps need special programs to read.  It is not easy to implement
- * a program that can sense the required size of the buffer, and then
- * subsequently do a read with the appropriate size.  This operation cannot
- * be atomic.  The best that we can do is to allow the program to do a read
- * with an arbitrarily large buffer, and return as much as we can.  We can
- * return an error code if the buffer is too small (EFBIG), then the program
- * can try a bigger buffer.
- */
-int
-procfs_domap(struct proc *curp, struct proc *p, struct pfsnode *pfs,
-	     struct uio *uio, int linuxmode)
-{
-	size_t len;
-	int error;
-	struct vm_map *map = &p->p_vmspace->vm_map;
-	struct vm_map_entry *entry;
-	char mebuffer[MEBUFFERSIZE];
-	char *path;
-	struct vnode *vp;
-	struct vattr va;
-	dev_t dev;
-	long fileid;
-
-	if (uio->uio_rw != UIO_READ)
-		return (EOPNOTSUPP);
-
-	if (uio->uio_offset != 0)
-		return (0);
-
-	error = 0;
-	if (map != &curproc->p_vmspace->vm_map)
-		vm_map_lock_read(map);
-	for (entry = map->header.next;
-		((uio->uio_resid > 0) && (entry != &map->header));
-		entry = entry->next) {
-
-		if (UVM_ET_ISSUBMAP(entry))
-			continue;
-
-		if (linuxmode != 0) {
-			path = (char *)malloc(MAXPATHLEN * 4, M_TEMP, M_WAITOK);
-			if (path == NULL) {
-				error = ENOMEM;
-				break;
-			}
-			*path = 0;
-
-			dev = (dev_t)0;
-			fileid = 0;
-			if (UVM_ET_ISOBJ(entry) &&
-			    UVM_OBJ_IS_VNODE(entry->object.uvm_obj)) {
-				vp = (struct vnode *)entry->object.uvm_obj;
-				error = VOP_GETATTR(vp, &va, curp->p_ucred,
-				    curp);
-				if (error == 0 && vp != pfs->pfs_vnode) {
-					fileid = va.va_fileid;
-					dev = va.va_fsid;
-					error = procfs_vnode_to_path(vp, path,
-					    MAXPATHLEN * 4, curp, p);
-				}
-			}
-			snprintf(mebuffer, sizeof(mebuffer),
-			    "%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %ld     %s\n",
-			    (int)sizeof(void *) * 2,(unsigned long)entry->start,
-			    (int)sizeof(void *) * 2,(unsigned long)entry->end,
-			    (entry->protection & VM_PROT_READ) ? 'r' : '-',
-			    (entry->protection & VM_PROT_WRITE) ? 'w' : '-',
-			    (entry->protection & VM_PROT_EXECUTE) ? 'x' : '-',
-			    (entry->etype & UVM_ET_COPYONWRITE) ? 'p' : 's',
-			    (int)sizeof(void *) * 2,
-			    (unsigned long)entry->offset,
-			    major(dev), minor(dev), fileid, path);
-			free(path, M_TEMP);
-		} else {
-			snprintf(mebuffer, sizeof(mebuffer),
-			    "0x%lx 0x%lx %c%c%c %c%c%c %s %s %d %d %d\n",
-			    entry->start, entry->end,
-			    (entry->protection & VM_PROT_READ) ? 'r' : '-',
-			    (entry->protection & VM_PROT_WRITE) ? 'w' : '-',
-			    (entry->protection & VM_PROT_EXECUTE) ? 'x' : '-',
-			    (entry->max_protection & VM_PROT_READ) ? 'r' : '-',
-			    (entry->max_protection & VM_PROT_WRITE) ? 'w' : '-',
-			    (entry->max_protection & VM_PROT_EXECUTE) ?
-				'x' : '-',
-			    (entry->etype & UVM_ET_COPYONWRITE) ?
-				"COW" : "NCOW",
-			    (entry->etype & UVM_ET_NEEDSCOPY) ? "NC" : "NNC",
-			    entry->inheritance, entry->wired_count,
-			    entry->advice);
-		}
-
-		len = strlen(mebuffer);
-		if (len > uio->uio_resid) {
-			error = EFBIG;
-			break;
-		}
-		error = uiomove(mebuffer, len, uio);
-		if (error)
-			break;
-	}
-	if (map != &curproc->p_vmspace->vm_map)
-		vm_map_unlock_read(map);
-	return error;
-}
-
-int
-procfs_validmap(struct proc *p, struct mount *mp)
-{
-	return ((p->p_flag & P_SYSTEM) == 0);
-}
-
-/*
- * Try to find a pathname for a vnode. Since there is no mapping
- * vnode -> parent directory, this needs the NAMECACHE_ENTER_REVERSE
- * option to work (to make cache_revlookup succeed).
- */
-static int procfs_vnode_to_path(struct vnode *vp, char *path, int len,
-				struct proc *curp, struct proc *p)
-{
-	int error, lenused, elen;
-	char *bp, *bend;
-	struct vnode *dvp;
-
-	bp = bend = &path[len];
-	*(--bp) = '\0';
-
-	error = vget(vp, LK_EXCLUSIVE | LK_RETRY);
-	if (error != 0)
-		return error;
-	error = cache_revlookup(vp, &dvp, &bp, path);
-	vput(vp);
-	if (error != 0)
-		return (error == -1 ? ENOENT : error);
-
-	error = vget(dvp, 0);
-	if (error != 0)
-		return error;
-	*(--bp) = '/';
-	/* XXX GETCWD_CHECK_ACCESS == 0x0001 */
-	error = getcwd_common(dvp, NULL, &bp, path, len / 2, 1, curp);
-
-	/*
-	 * Strip off emulation path for emulated processes looking at
-	 * the maps file of a process of the same emulation. (Won't
-	 * work if /emul/xxx is a symlink..)
-	 */
-	if (curp->p_emul == p->p_emul && curp->p_emul->e_path != NULL) {
-		elen = strlen(curp->p_emul->e_path);
-		if (!strncmp(bp, curp->p_emul->e_path, elen))
-			bp = &bp[elen];
-	}
-
-	lenused = bend - bp;
-
-	memcpy(path, bp, lenused);
-	path[lenused] = 0;
-
-	return 0;
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_mem.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_mem.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_mem.c	2003-08-07 17:32:41.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_mem.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,99 +0,0 @@
-/*	$NetBSD: procfs_mem.c,v 1.34 2003/08/07 16:32:41 agc Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry and Sean Eric Fagan.
- *
- * 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.
- *
- *	@(#)procfs_mem.c	8.5 (Berkeley) 6/15/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993 Sean Eric Fagan
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry and Sean Eric Fagan.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_mem.c	8.5 (Berkeley) 6/15/94
- */
-
-/*
- * This is a lightly hacked and merged version
- * of sef's pread/pwrite functions
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_mem.c,v 1.34 2003/08/07 16:32:41 agc Exp $");
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ptrace.h>
-
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_domem(curp, p, pfs, uio)
-	struct proc *curp;		/* tracer */
-	struct proc *p;			/* traced */
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-
-	return (process_domem(curp, p, uio));
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_note.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_note.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_note.c	2003-08-07 17:32:42.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_note.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,107 +0,0 @@
-/*	$NetBSD: procfs_note.c,v 1.12 2003/08/07 16:32:42 agc Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_note.c	8.2 (Berkeley) 1/21/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_note.c	8.2 (Berkeley) 1/21/94
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_note.c,v 1.12 2003/08/07 16:32:42 agc Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/signal.h>
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_donote(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-	int xlen;
-	int error;
-	char note[PROCFS_NOTELEN+1];
-
-	if (uio->uio_rw != UIO_WRITE)
-		return (EINVAL);
-
-	xlen = PROCFS_NOTELEN;
-	error = vfs_getuserstr(uio, note, &xlen);
-	if (error)
-		return (error);
-
-	/* send to process's notify function */
-	return (EOPNOTSUPP);
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_regs.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_regs.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_regs.c	2003-08-07 17:32:42.000000000 +0100
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_regs.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,102 +0,0 @@
-/*	$NetBSD: procfs_regs.c,v 1.20 2003/08/07 16:32:42 agc Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_regs.c	8.4 (Berkeley) 6/15/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_regs.c	8.4 (Berkeley) 6/15/94
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_regs.c,v 1.20 2003/08/07 16:32:42 agc Exp $");
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ptrace.h>
-
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_doregs(curp, l, pfs, uio)
-	struct proc *curp;		/* tracer */
-	struct lwp *l;			/* traced */
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-
-	return (process_doregs(curp, l, uio));
-}
-
-int
-procfs_validregs(p, mp)
-	struct proc *p;
-	struct mount *mp;
-{
-
-	return (process_validregs(p));
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_status.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_status.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_status.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_status.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,171 +0,0 @@
-/*	$NetBSD: procfs_status.c,v 1.24 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_status.c	8.4 (Berkeley) 6/15/94
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_status.c	8.4 (Berkeley) 6/15/94
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_status.c,v 1.24 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/resource.h>
-#include <sys/resourcevar.h>
-#include <miscfs/procfs/procfs.h>
-
-int
-procfs_dostatus(curp, l, pfs, uio)
-	struct proc *curp;
-	struct lwp *l;
-	struct pfsnode *pfs;
-	struct uio *uio;
-{
-	struct session *sess;
-	struct tty *tp;
-	struct ucred *cr;
-	struct proc *p = l->l_proc;
-	char *ps;
-	char *sep;
-	int pid, ppid, pgid, sid;
-	u_int i;
-	char psbuf[256+MAXHOSTNAMELEN];		/* XXX - conservative */
-
-	if (uio->uio_rw != UIO_READ)
-		return (EOPNOTSUPP);
-
-	pid = p->p_pid;
-	ppid = p->p_pptr ? p->p_pptr->p_pid : 0,
-	pgid = p->p_pgrp->pg_id;
-	sess = p->p_pgrp->pg_session;
-	sid = sess->s_sid;
-
-/* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid gid groups ... */
-
-	ps = psbuf;
-	memcpy(ps, p->p_comm, MAXCOMLEN);
-	ps[MAXCOMLEN] = '\0';
-	ps += strlen(ps);
-	ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " %d %d %d %d ",
-	    pid, ppid, pgid, sid);
-
-	if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp))
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "%d,%d ",
-		    major(tp->t_dev), minor(tp->t_dev));
-	else
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "%d,%d ",
-		    -1, -1);
-
-	sep = "";
-	if (sess->s_ttyvp) {
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "%sctty", sep);
-		sep = ",";
-	}
-	if (SESS_LEADER(p)) {
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "%ssldr", sep);
-		sep = ",";
-	}
-	if (*sep != ',')
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "noflags");
-
-	if (l->l_flag & L_INMEM)
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " %ld,%ld",
-		    p->p_stats->p_start.tv_sec, p->p_stats->p_start.tv_usec);
-	else
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " -1,-1");
-
-	{
-		struct timeval ut, st;
-
-		calcru(p, &ut, &st, (void *) 0);
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf),
-		    " %ld,%ld %ld,%ld", ut.tv_sec, ut.tv_usec, st.tv_sec,
-		    st.tv_usec);
-	}
-
-	ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " %s",
-	    (l->l_wchan && l->l_wmesg) ? l->l_wmesg : "nochan");
-
-	cr = p->p_ucred;
-
-	ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " %d", cr->cr_uid);
-	ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), " %d", cr->cr_gid);
-	for (i = 0; i < cr->cr_ngroups; i++)
-		ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), ",%d",
-		    cr->cr_groups[i]);
-	ps += snprintf(ps, sizeof(psbuf) - (ps - psbuf), "\n");
-
-	return (uiomove_frombuf(psbuf, ps - psbuf, uio));
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_subr.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_subr.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_subr.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_subr.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,588 +0,0 @@
-/*	$NetBSD: procfs_subr.c,v 1.63 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_subr.c	8.6 (Berkeley) 5/14/95
- */
-
-/*
- * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_subr.c	8.6 (Berkeley) 5/14/95
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.63 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-
-#include <miscfs/procfs/procfs.h>
-
-void procfs_hashins __P((struct pfsnode *));
-void procfs_hashrem __P((struct pfsnode *));
-struct vnode *procfs_hashget __P((pid_t, pfstype, int, struct mount *));
-
-LIST_HEAD(pfs_hashhead, pfsnode) *pfs_hashtbl;
-u_long	pfs_ihash;	/* size of hash table - 1 */
-#define PFSPIDHASH(pid)	((pid) & pfs_ihash)
-
-struct lock pfs_hashlock;
-struct simplelock pfs_hash_slock;
-
-#define	ISSET(t, f)	((t) & (f))
-
-/*
- * allocate a pfsnode/vnode pair.  the vnode is
- * referenced, and locked.
- *
- * the pid, pfs_type, and mount point uniquely
- * identify a pfsnode.  the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all pfsnodes are maintained on a singly-linked
- * list.  new nodes are only allocated when they cannot
- * be found on this list.  entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list.  this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one process trying to get the same
- * vnode.  this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference.  this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
- */
-int
-procfs_allocvp(mp, vpp, pid, pfs_type, fd)
-	struct mount *mp;
-	struct vnode **vpp;
-	pid_t pid;
-	pfstype pfs_type;
-	int fd;
-{
-	struct pfsnode *pfs;
-	struct vnode *vp;
-	int error;
-
-	do {
-		if ((*vpp = procfs_hashget(pid, pfs_type, fd, mp)) != NULL)
-			return (0);
-	} while (lockmgr(&pfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
-
-	if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, &vp)) != 0) {
-		*vpp = NULL;
-		lockmgr(&pfs_hashlock, LK_RELEASE, NULL);
-		return (error);
-	}
-
-	MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
-	vp->v_data = pfs;
-
-	pfs->pfs_pid = pid;
-	pfs->pfs_type = pfs_type;
-	pfs->pfs_vnode = vp;
-	pfs->pfs_flags = 0;
-	pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type, fd);
-	pfs->pfs_fd = fd;
-
-	switch (pfs_type) {
-	case PFSroot:	/* /proc = dr-xr-xr-x */
-		pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-		vp->v_type = VDIR;
-		vp->v_flag = VROOT;
-		break;
-
-	case PFScurproc:	/* /proc/curproc = lr-xr-xr-x */
-	case PFSself:	/* /proc/self    = lr-xr-xr-x */
-		pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
-		vp->v_type = VLNK;
-		break;
-
-	case PFSproc:	/* /proc/N = dr-xr-xr-x */
-	case PFSfd:
-		if (fd == -1) {	/* /proc/N/fd = dr-xr-xr-x */
-			pfs->pfs_mode = S_IRUSR|S_IXUSR;
-			vp->v_type = VDIR;
-		} else {	/* /proc/N/fd/M = [ps-]rw------- */
-			struct file *fp;
-			struct vnode *vxp;
-			struct proc *pown;
-
-			/* XXX can procfs_getfp() ever fail here? */
-			if ((error = procfs_getfp(pfs, &pown, &fp)) != 0)
-				goto bad;
-			FILE_USE(fp);
-
-			pfs->pfs_mode = S_IRUSR|S_IWUSR;
-			switch (fp->f_type) {
-			case DTYPE_VNODE:
-				vxp = (struct vnode *)fp->f_data;
-
-				/*
-				 * We make symlinks for directories
-				 * to avoid cycles.
-				 */
-				if (vxp->v_type == VDIR)
-					goto symlink;
-				vp->v_type = vxp->v_type;
-				break;
-			case DTYPE_PIPE:
-				vp->v_type = VFIFO;
-				break;
-			case DTYPE_SOCKET:
-				vp->v_type = VSOCK;
-				break;
-			case DTYPE_KQUEUE:
-			case DTYPE_MISC:
-			symlink:
-				pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|
-				    S_IXGRP|S_IROTH|S_IXOTH;
-				vp->v_type = VLNK;
-				break;
-			default:
-				error = EOPNOTSUPP;
-				FILE_UNUSE(fp, pown);
-				goto bad;
-			}
-			FILE_UNUSE(fp, pown);
-		}
-		break;
-
-	case PFSfile:	/* /proc/N/file = -rw------- */
-	case PFSmem:	/* /proc/N/mem = -rw------- */
-	case PFSregs:	/* /proc/N/regs = -rw------- */
-	case PFSfpregs:	/* /proc/N/fpregs = -rw------- */
-		pfs->pfs_mode = S_IRUSR|S_IWUSR;
-		vp->v_type = VREG;
-		break;
-
-	case PFSctl:	/* /proc/N/ctl = --w------ */
-	case PFSnote:	/* /proc/N/note = --w------ */
-	case PFSnotepg:	/* /proc/N/notepg = --w------ */
-		pfs->pfs_mode = S_IWUSR;
-		vp->v_type = VREG;
-		break;
-
-	case PFSmap:	/* /proc/N/map = -r--r--r-- */
-	case PFSmaps:	/* /proc/N/maps = -r--r--r-- */
-	case PFSstatus:	/* /proc/N/status = -r--r--r-- */
-	case PFSstat:	/* /proc/N/stat = -r--r--r-- */
-	case PFScmdline:	/* /proc/N/cmdline = -r--r--r-- */
-	case PFSmeminfo:	/* /proc/meminfo = -r--r--r-- */
-	case PFScpuinfo:	/* /proc/cpuinfo = -r--r--r-- */
-	case PFSuptime:	/* /proc/uptime = -r--r--r-- */
-	case PFSmounts:	/* /proc/mounts = -r--r--r-- */
-		pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
-		vp->v_type = VREG;
-		break;
-
-#ifdef __HAVE_PROCFS_MACHDEP
-	PROCFS_MACHDEP_NODETYPE_CASES
-		procfs_machdep_allocvp(vp);
-		break;
-#endif
-
-	default:
-		panic("procfs_allocvp");
-	}
-
-	procfs_hashins(pfs);
-	uvm_vnp_setsize(vp, 0);
-	lockmgr(&pfs_hashlock, LK_RELEASE, NULL);
-
-	*vpp = vp;
-	return (0);
-
- bad:
-	lockmgr(&pfs_hashlock, LK_RELEASE, NULL);
-	FREE(pfs, M_TEMP);
-	ungetnewvnode(vp);
-	return (error);
-}
-
-int
-procfs_freevp(vp)
-	struct vnode *vp;
-{
-	struct pfsnode *pfs = VTOPFS(vp);
-
-	procfs_hashrem(pfs);
-
-	FREE(vp->v_data, M_TEMP);
-	vp->v_data = 0;
-	return (0);
-}
-
-int
-procfs_rw(v)
-	void *v;
-{
-	struct vop_read_args *ap = v;
-	struct vnode *vp = ap->a_vp;
-	struct uio *uio = ap->a_uio;
-	struct proc *curp = uio->uio_procp;
-	struct pfsnode *pfs = VTOPFS(vp);
-	struct lwp *l;
-	struct proc *p;
-
-	if (uio->uio_offset < 0)
-		return EINVAL;
-	p = PFIND(pfs->pfs_pid);
-	if (p == 0)
-		return ESRCH;
-	/*
-	 * Do not allow init to be modified while in secure mode; it
-	 * could be duped into changing the security level.
-	 */
-	if (uio->uio_rw == UIO_WRITE && p == initproc && securelevel > -1)
-		return EPERM;
-
-	/* XXX NJWLWP
-	 * The entire procfs interface needs work to be useful to
-	 * a process with multiple LWPs. For the moment, we'll
-	 * just kluge this and fail on others.
-	 */
-	l = proc_representative_lwp(p);
-
-	switch (pfs->pfs_type) {
-	case PFSnote:
-	case PFSnotepg:
-		return (procfs_donote(curp, p, pfs, uio));
-
-	case PFSregs:
-		return (procfs_doregs(curp, l, pfs, uio));
-
-	case PFSfpregs:
-		return (procfs_dofpregs(curp, l, pfs, uio));
-
-	case PFSctl:
-		return (procfs_doctl(curp, l, pfs, uio));
-
-	case PFSstatus:
-		return (procfs_dostatus(curp, l, pfs, uio));
-
-	case PFSstat:
-		return (procfs_do_pid_stat(curp, l, pfs, uio));
-
-	case PFSmap:
-		return (procfs_domap(curp, p, pfs, uio, 0));
-
-	case PFSmaps:
-		return (procfs_domap(curp, p, pfs, uio, 1));
-
-	case PFSmem:
-		return (procfs_domem(curp, p, pfs, uio));
-
-	case PFScmdline:
-		return (procfs_docmdline(curp, p, pfs, uio));
-
-	case PFSmeminfo:
-		return (procfs_domeminfo(curp, p, pfs, uio));
-
-	case PFScpuinfo:
-		return (procfs_docpuinfo(curp, p, pfs, uio));
-
-	case PFSfd:
-		return (procfs_dofd(curp, p, pfs, uio));
-
-	case PFSuptime:
-		return (procfs_douptime(curp, p, pfs, uio));
-
-	case PFSmounts:
-		return (procfs_domounts(curp, p, pfs, uio));
-
-#ifdef __HAVE_PROCFS_MACHDEP
-	PROCFS_MACHDEP_NODETYPE_CASES
-		return (procfs_machdep_rw(curp, l, pfs, uio));
-#endif
-
-	default:
-		return (EOPNOTSUPP);
-	}
-}
-
-/*
- * Get a string from userland into (buf).  Strip a trailing
- * nl character (to allow easy access from the shell).
- * The buffer should be *buflenp + 1 chars long.  vfs_getuserstr
- * will automatically add a nul char at the end.
- *
- * Returns 0 on success or the following errors
- *
- * EINVAL:    file offset is non-zero.
- * EMSGSIZE:  message is longer than kernel buffer
- * EFAULT:    user i/o buffer is not addressable
- */
-int
-vfs_getuserstr(uio, buf, buflenp)
-	struct uio *uio;
-	char *buf;
-	int *buflenp;
-{
-	int xlen;
-	int error;
-
-	if (uio->uio_offset != 0)
-		return (EINVAL);
-
-	xlen = *buflenp;
-
-	/* must be able to read the whole string in one go */
-	if (xlen < uio->uio_resid)
-		return (EMSGSIZE);
-	xlen = uio->uio_resid;
-
-	if ((error = uiomove(buf, xlen, uio)) != 0)
-		return (error);
-
-	/* allow multiple writes without seeks */
-	uio->uio_offset = 0;
-
-	/* cleanup string and remove trailing newline */
-	buf[xlen] = '\0';
-	xlen = strlen(buf);
-	if (xlen > 0 && buf[xlen-1] == '\n')
-		buf[--xlen] = '\0';
-	*buflenp = xlen;
-
-	return (0);
-}
-
-const vfs_namemap_t *
-vfs_findname(nm, buf, buflen)
-	const vfs_namemap_t *nm;
-	const char *buf;
-	int buflen;
-{
-
-	for (; nm->nm_name; nm++)
-		if (memcmp(buf, nm->nm_name, buflen+1) == 0)
-			return (nm);
-
-	return (0);
-}
-
-/*
- * Initialize pfsnode hash table.
- */
-void
-procfs_hashinit()
-{
-	lockinit(&pfs_hashlock, PINOD, "pfs_hashlock", 0, 0);
-	pfs_hashtbl = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT,
-	    M_WAITOK, &pfs_ihash);
-	simple_lock_init(&pfs_hash_slock);
-}
-
-void
-procfs_hashreinit()
-{
-	struct pfsnode *pp;
-	struct pfs_hashhead *oldhash, *hash;
-	u_long i, oldmask, mask, val;
-
-	hash = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT, M_WAITOK,
-	    &mask);
-
-	simple_lock(&pfs_hash_slock);
-	oldhash = pfs_hashtbl;
-	oldmask = pfs_ihash;
-	pfs_hashtbl = hash;
-	pfs_ihash = mask;
-	for (i = 0; i <= oldmask; i++) {
-		while ((pp = LIST_FIRST(&oldhash[i])) != NULL) {
-			LIST_REMOVE(pp, pfs_hash);
-			val = PFSPIDHASH(pp->pfs_pid);
-			LIST_INSERT_HEAD(&hash[val], pp, pfs_hash);
-		}
-	}
-	simple_unlock(&pfs_hash_slock);
-	hashdone(oldhash, M_UFSMNT);
-}
-
-/*
- * Free pfsnode hash table.
- */
-void
-procfs_hashdone()
-{
-	hashdone(pfs_hashtbl, M_UFSMNT);
-}
-
-struct vnode *
-procfs_hashget(pid, type, fd, mp)
-	pid_t pid;
-	pfstype type;
-	int fd;
-	struct mount *mp;
-{
-	struct pfs_hashhead *ppp;
-	struct pfsnode *pp;
-	struct vnode *vp;
-
-loop:
-	simple_lock(&pfs_hash_slock);
-	ppp = &pfs_hashtbl[PFSPIDHASH(pid)];
-	LIST_FOREACH(pp, ppp, pfs_hash) {
-		vp = PFSTOV(pp);
-		if (pid == pp->pfs_pid && pp->pfs_type == type &&
-		    pp->pfs_fd == fd && vp->v_mount == mp) {
-			simple_lock(&vp->v_interlock);
-			simple_unlock(&pfs_hash_slock);
-			if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
-				goto loop;
-			return (vp);
-		}
-	}
-	simple_unlock(&pfs_hash_slock);
-	return (NULL);
-}
-
-/*
- * Insert the pfsnode into the hash table and lock it.
- */
-void
-procfs_hashins(pp)
-	struct pfsnode *pp;
-{
-	struct pfs_hashhead *ppp;
-
-	/* lock the pfsnode, then put it on the appropriate hash list */
-	lockmgr(&pp->pfs_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
-
-	simple_lock(&pfs_hash_slock);
-	ppp = &pfs_hashtbl[PFSPIDHASH(pp->pfs_pid)];
-	LIST_INSERT_HEAD(ppp, pp, pfs_hash);
-	simple_unlock(&pfs_hash_slock);
-}
-
-/*
- * Remove the pfsnode from the hash table.
- */
-void
-procfs_hashrem(pp)
-	struct pfsnode *pp;
-{
-	simple_lock(&pfs_hash_slock);
-	LIST_REMOVE(pp, pfs_hash);
-	simple_unlock(&pfs_hash_slock);
-}
-
-void
-procfs_revoke_vnodes(p, arg)
-	struct proc *p;
-	void *arg;
-{
-	struct pfsnode *pfs, *pnext;
-	struct vnode *vp;
-	struct mount *mp = (struct mount *)arg;
-	struct pfs_hashhead *ppp;
-
-	if (!(p->p_flag & P_SUGID))
-		return;
-
-	ppp = &pfs_hashtbl[PFSPIDHASH(p->p_pid)];
-	for (pfs = LIST_FIRST(ppp); pfs; pfs = pnext) {
-		vp = PFSTOV(pfs);
-		pnext = LIST_NEXT(pfs, pfs_hash);
-		if (vp->v_usecount > 0 && pfs->pfs_pid == p->p_pid &&
-		    vp->v_mount == mp)
-			VOP_REVOKE(vp, REVOKEALL);
-	}
-}
-
-int
-procfs_getfp(pfs, pown, fp)
-	struct pfsnode *pfs;
-	struct proc **pown;
-	struct file **fp;
-{
-	struct proc *p = PFIND(pfs->pfs_pid);
-
-	if (p == NULL)
-		return ESRCH;
-
-	if (pfs->pfs_fd == -1)
-		return EINVAL;
-
-	if ((*fp = fd_getfile(p->p_fd, pfs->pfs_fd)) == NULL)
-		return EBADF;
-
-	*pown = p;
-	return 0;
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_vfsops.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_vfsops.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_vfsops.c	2005-01-02 16:08:30.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_vfsops.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,387 +0,0 @@
-/*	$NetBSD: procfs_vfsops.c,v 1.59 2005/01/02 16:08:30 thorpej Exp $	*/
-
-/*
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_vfsops.c	8.7 (Berkeley) 5/10/95
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_vfsops.c	8.7 (Berkeley) 5/10/95
- */
-
-/*
- * procfs VFS interface
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.59 2005/01/02 16:08:30 thorpej Exp $");
-
-#if defined(_KERNEL_OPT)
-#include "opt_compat_netbsd.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/syslog.h>
-#include <sys/mount.h>
-#include <sys/dirent.h>
-#include <sys/signalvar.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-
-#include <miscfs/procfs/procfs.h>
-
-#include <uvm/uvm_extern.h>			/* for PAGE_SIZE */
-
-void	procfs_init __P((void));
-void	procfs_reinit __P((void));
-void	procfs_done __P((void));
-int	procfs_mount __P((struct mount *, const char *, void *,
-			  struct nameidata *, struct proc *));
-int	procfs_start __P((struct mount *, int, struct proc *));
-int	procfs_unmount __P((struct mount *, int, struct proc *));
-int	procfs_quotactl __P((struct mount *, int, uid_t, void *,
-			     struct proc *));
-int	procfs_statvfs __P((struct mount *, struct statvfs *, struct proc *));
-int	procfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
-int	procfs_vget __P((struct mount *, ino_t, struct vnode **));
-int	procfs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
-int	procfs_checkexp __P((struct mount *, struct mbuf *, int *,
-			   struct ucred **));
-int	procfs_vptofh __P((struct vnode *, struct fid *));
-
-/*
- * VFS Operations.
- *
- * mount system call
- */
-/* ARGSUSED */
-int
-procfs_mount(mp, path, data, ndp, p)
-	struct mount *mp;
-	const char *path;
-	void *data;
-	struct nameidata *ndp;
-	struct proc *p;
-{
-	struct procfsmount *pmnt;
-	struct procfs_args args;
-	int error;
-
-	if (UIO_MX & (UIO_MX-1)) {
-		log(LOG_ERR, "procfs: invalid directory entry size");
-		return (EINVAL);
-	}
-
-	if (mp->mnt_flag & MNT_GETARGS) {
-		pmnt = VFSTOPROC(mp);
-		if (pmnt == NULL)
-			return EIO;
-		args.version = PROCFS_ARGSVERSION;
-		args.flags = pmnt->pmnt_flags;
-		return copyout(&args, data, sizeof(args));
-	}
-
-	if (mp->mnt_flag & MNT_UPDATE)
-		return (EOPNOTSUPP);
-
-	if (data != NULL) {
-		error = copyin(data, &args, sizeof args);
-		if (error != 0)
-			return error;
-
-		if (args.version != PROCFS_ARGSVERSION)
-			return EINVAL;
-	} else
-		args.flags = 0;
-
-	pmnt = (struct procfsmount *) malloc(sizeof(struct procfsmount),
-	    M_UFSMNT, M_WAITOK);   /* XXX need new malloc type */
-
-	mp->mnt_stat.f_namemax = MAXNAMLEN;
-	mp->mnt_flag |= MNT_LOCAL;
-	mp->mnt_data = pmnt;
-	vfs_getnewfsid(mp);
-
-	error = set_statvfs_info(path, UIO_USERSPACE, "procfs", UIO_SYSSPACE,
-	    mp, p);
-	pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp);
-	pmnt->pmnt_flags = args.flags;
-
-	return error;
-}
-
-/*
- * unmount system call
- */
-int
-procfs_unmount(mp, mntflags, p)
-	struct mount *mp;
-	int mntflags;
-	struct proc *p;
-{
-	int error;
-	int flags = 0;
-
-	if (mntflags & MNT_FORCE)
-		flags |= FORCECLOSE;
-
-	if ((error = vflush(mp, 0, flags)) != 0)
-		return (error);
-
-	exechook_disestablish(VFSTOPROC(mp)->pmnt_exechook);
-
-	free(mp->mnt_data, M_UFSMNT);
-	mp->mnt_data = 0;
-
-	return (0);
-}
-
-int
-procfs_root(mp, vpp)
-	struct mount *mp;
-	struct vnode **vpp;
-{
-
-	return (procfs_allocvp(mp, vpp, 0, PFSroot, -1));
-}
-
-/* ARGSUSED */
-int
-procfs_start(mp, flags, p)
-	struct mount *mp;
-	int flags;
-	struct proc *p;
-{
-
-	return (0);
-}
-
-/*
- * Get file system statistics.
- */
-int
-procfs_statvfs(mp, sbp, p)
-	struct mount *mp;
-	struct statvfs *sbp;
-	struct proc *p;
-{
-
-	sbp->f_bsize = PAGE_SIZE;
-	sbp->f_frsize = PAGE_SIZE;
-	sbp->f_iosize = PAGE_SIZE;
-	sbp->f_blocks = 1;	/* avoid divide by zero in some df's */
-	sbp->f_bfree = 0;
-	sbp->f_bavail = 0;
-	sbp->f_bresvd = 0;
-	sbp->f_files = maxproc;			/* approx */
-	sbp->f_ffree = maxproc - nprocs;	/* approx */
-	sbp->f_favail = maxproc - nprocs;	/* approx */
-	sbp->f_fresvd = 0;
-	copy_statvfs_info(sbp, mp);
-	return (0);
-}
-
-/*ARGSUSED*/
-int
-procfs_quotactl(mp, cmds, uid, arg, p)
-	struct mount *mp;
-	int cmds;
-	uid_t uid;
-	void *arg;
-	struct proc *p;
-{
-
-	return (EOPNOTSUPP);
-}
-
-/*ARGSUSED*/
-int
-procfs_sync(mp, waitfor, uc, p)
-	struct mount *mp;
-	int waitfor;
-	struct ucred *uc;
-	struct proc *p;
-{
-
-	return (0);
-}
-
-/*ARGSUSED*/
-int
-procfs_vget(mp, ino, vpp)
-	struct mount *mp;
-	ino_t ino;
-	struct vnode **vpp;
-{
-	return (EOPNOTSUPP);
-}
-
-/*ARGSUSED*/
-int
-procfs_fhtovp(mp, fhp, vpp)
-	struct mount *mp;
-	struct fid *fhp;
-	struct vnode **vpp;
-{
-
-	return (EINVAL);
-}
-
-/*ARGSUSED*/
-int
-procfs_checkexp(mp, mb, what, anon)
-	struct mount *mp;
-	struct mbuf *mb;
-	int *what;
-	struct ucred **anon;
-{
-
-	return (EINVAL);
-}
-
-/*ARGSUSED*/
-int
-procfs_vptofh(vp, fhp)
-	struct vnode *vp;
-	struct fid *fhp;
-{
-
-	return (EINVAL);
-}
-
-void
-procfs_init()
-{
-	procfs_hashinit();
-}
-
-void
-procfs_reinit()
-{
-	procfs_hashreinit();
-}
-
-void
-procfs_done()
-{
-	procfs_hashdone();
-}
-
-SYSCTL_SETUP(sysctl_vfs_procfs_setup, "sysctl vfs.procfs subtree setup")
-{
-
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_NODE, "vfs", NULL,
-		       NULL, 0, NULL, 0,
-		       CTL_VFS, CTL_EOL);
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_NODE, "procfs",
-		       SYSCTL_DESCR("Process file system"),
-		       NULL, 0, NULL, 0,
-		       CTL_VFS, 12, CTL_EOL);
-	/*
-	 * XXX the "12" above could be dynamic, thereby eliminating
-	 * one more instance of the "number to vfs" mapping problem,
-	 * but "12" is the order as taken from sys/mount.h
-	 */
-}
-
-extern const struct vnodeopv_desc procfs_vnodeop_opv_desc;
-
-const struct vnodeopv_desc * const procfs_vnodeopv_descs[] = {
-	&procfs_vnodeop_opv_desc,
-	NULL,
-};
-
-struct vfsops procfs_vfsops = {
-	MOUNT_PROCFS,
-	procfs_mount,
-	procfs_start,
-	procfs_unmount,
-	procfs_root,
-	procfs_quotactl,
-	procfs_statvfs,
-	procfs_sync,
-	procfs_vget,
-	procfs_fhtovp,
-	procfs_vptofh,
-	procfs_init,
-	procfs_reinit,
-	procfs_done,
-	NULL,
-	NULL,				/* vfs_mountroot */
-	procfs_checkexp,
-	(int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
-	vfs_stdextattrctl,
-	procfs_vnodeopv_descs,
-};
diff -r -u -N --exclude CVS NetBSD-3.1/sys/miscfs/procfs/procfs_vnops.c mult-netbsd-3.1/sys/miscfs/procfs/procfs_vnops.c
--- NetBSD-3.1/sys/miscfs/procfs/procfs_vnops.c	2005-02-26 22:59:00.000000000 +0000
+++ mult-netbsd-3.1/sys/miscfs/procfs/procfs_vnops.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1410 +0,0 @@
-/*	$NetBSD: procfs_vnops.c,v 1.121 2005/02/26 22:59:00 perry Exp $	*/
-
-/*
- * Copyright (c) 1993, 1995
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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.
- *
- *	@(#)procfs_vnops.c	8.18 (Berkeley) 5/21/95
- */
-
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. 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.
- *
- *	@(#)procfs_vnops.c	8.18 (Berkeley) 5/21/95
- */
-
-/*
- * procfs vnode interface
- */
-
-#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.121 2005/02/26 22:59:00 perry Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/kernel.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/dirent.h>
-#include <sys/resourcevar.h>
-#include <sys/stat.h>
-#include <sys/ptrace.h>
-
-#include <uvm/uvm_extern.h>	/* for PAGE_SIZE */
-
-#include <machine/reg.h>
-
-#include <miscfs/genfs/genfs.h>
-#include <miscfs/procfs/procfs.h>
-
-/*
- * Vnode Operations.
- *
- */
-
-static int procfs_validfile_linux __P((struct proc *, struct mount *));
-static int procfs_root_readdir_callback(struct proc *, void *);
-
-/*
- * This is a list of the valid names in the
- * process-specific sub-directories.  It is
- * used in procfs_lookup and procfs_readdir
- */
-static const struct proc_target {
-	u_char	pt_type;
-	u_char	pt_namlen;
-	const char	*pt_name;
-	pfstype	pt_pfstype;
-	int	(*pt_valid) __P((struct proc *, struct mount *));
-} proc_targets[] = {
-#define N(s) sizeof(s)-1, s
-	/*	  name		type		validp */
-	{ DT_DIR, N("."),	PFSproc,		NULL },
-	{ DT_DIR, N(".."),	PFSroot,		NULL },
-	{ DT_DIR, N("fd"),	PFSfd,		NULL },
-	{ DT_REG, N("file"),	PFSfile,		procfs_validfile },
-	{ DT_REG, N("mem"),	PFSmem,		NULL },
-	{ DT_REG, N("regs"),	PFSregs,		procfs_validregs },
-	{ DT_REG, N("fpregs"),	PFSfpregs,	procfs_validfpregs },
-	{ DT_REG, N("ctl"),	PFSctl,		NULL },
-	{ DT_REG, N("stat"),	PFSstat,		procfs_validfile_linux },
-	{ DT_REG, N("status"),	PFSstatus,	NULL },
-	{ DT_REG, N("note"),	PFSnote,		NULL },
-	{ DT_REG, N("notepg"),	PFSnotepg,	NULL },
-	{ DT_REG, N("map"),	PFSmap,		procfs_validmap },
-	{ DT_REG, N("maps"),	PFSmaps,		procfs_validmap },
-	{ DT_REG, N("cmdline"), PFScmdline,	NULL },
-	{ DT_REG, N("exe"),	PFSfile,		procfs_validfile_linux },
-#ifdef __HAVE_PROCFS_MACHDEP
-	PROCFS_MACHDEP_NODETYPE_DEFNS
-#endif
-#undef N
-};
-static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
-
-/*
- * List of files in the root directory. Note: the validate function will
- * be called with p == NULL for these ones.
- */
-static const struct proc_target proc_root_targets[] = {
-#define N(s) sizeof(s)-1, s
-	/*	  name		    type	    validp */
-	{ DT_REG, N("meminfo"),     PFSmeminfo,        procfs_validfile_linux },
-	{ DT_REG, N("cpuinfo"),     PFScpuinfo,        procfs_validfile_linux },
-	{ DT_REG, N("uptime"),      PFSuptime,         procfs_validfile_linux },
-	{ DT_REG, N("mounts"),	    PFSmounts,	       procfs_validfile_linux },
-#undef N
-};
-static const int nproc_root_targets =
-    sizeof(proc_root_targets) / sizeof(proc_root_targets[0]);
-
-int	procfs_lookup	__P((void *));
-#define	procfs_create	genfs_eopnotsupp
-#define	procfs_mknod	genfs_eopnotsupp
-int	procfs_open	__P((void *));
-int	procfs_close	__P((void *));
-int	procfs_access	__P((void *));
-int	procfs_getattr	__P((void *));
-int	procfs_setattr	__P((void *));
-#define	procfs_read	procfs_rw
-#define	procfs_write	procfs_rw
-#define	procfs_fcntl	genfs_fcntl
-#define	procfs_ioctl	genfs_enoioctl
-#define	procfs_poll	genfs_poll
-#define procfs_revoke	genfs_revoke
-#define	procfs_fsync	genfs_nullop
-#define	procfs_seek	genfs_nullop
-#define	procfs_remove	genfs_eopnotsupp
-int	procfs_link	__P((void *));
-#define	procfs_rename	genfs_eopnotsupp
-#define	procfs_mkdir	genfs_eopnotsupp
-#define	procfs_rmdir	genfs_eopnotsupp
-int	procfs_symlink	__P((void *));
-int	procfs_readdir	__P((void *));
-int	procfs_readlink	__P((void *));
-#define	procfs_abortop	genfs_abortop
-int	procfs_inactive	__P((void *));
-int	procfs_reclaim	__P((void *));
-#define	procfs_lock	genfs_lock
-#define	procfs_unlock	genfs_unlock
-#define	procfs_bmap	genfs_badop
-#define	procfs_strategy	genfs_badop
-int	procfs_print	__P((void *));
-int	procfs_pathconf	__P((void *));
-#define	procfs_islocked	genfs_islocked
-#define	procfs_advlock	genfs_einval
-#define	procfs_blkatoff	genfs_eopnotsupp
-#define	procfs_valloc	genfs_eopnotsupp
-#define	procfs_vfree	genfs_nullop
-#define	procfs_truncate	genfs_eopnotsupp
-#define	procfs_update	genfs_nullop
-#define	procfs_bwrite	genfs_eopnotsupp
-#define procfs_putpages	genfs_null_putpages
-
-static int atoi __P((const char *, size_t));
-
-/*
- * procfs vnode operations.
- */
-int (**procfs_vnodeop_p) __P((void *));
-const struct vnodeopv_entry_desc procfs_vnodeop_entries[] = {
-	{ &vop_default_desc, vn_default_error },
-	{ &vop_lookup_desc, procfs_lookup },		/* lookup */
-	{ &vop_create_desc, procfs_create },		/* create */
-	{ &vop_mknod_desc, procfs_mknod },		/* mknod */
-	{ &vop_open_desc, procfs_open },		/* open */
-	{ &vop_close_desc, procfs_close },		/* close */
-	{ &vop_access_desc, procfs_access },		/* access */
-	{ &vop_getattr_desc, procfs_getattr },		/* getattr */
-	{ &vop_setattr_desc, procfs_setattr },		/* setattr */
-	{ &vop_read_desc, procfs_read },		/* read */
-	{ &vop_write_desc, procfs_write },		/* write */
-	{ &vop_fcntl_desc, procfs_fcntl },		/* fcntl */
-	{ &vop_ioctl_desc, procfs_ioctl },		/* ioctl */
-	{ &vop_poll_desc, procfs_poll },		/* poll */
-	{ &vop_revoke_desc, procfs_revoke },		/* revoke */
-	{ &vop_fsync_desc, procfs_fsync },		/* fsync */
-	{ &vop_seek_desc, procfs_seek },		/* seek */
-	{ &vop_remove_desc, procfs_remove },		/* remove */
-	{ &vop_link_desc, procfs_link },		/* link */
-	{ &vop_rename_desc, procfs_rename },		/* rename */
-	{ &vop_mkdir_desc, procfs_mkdir },		/* mkdir */
-	{ &vop_rmdir_desc, procfs_rmdir },		/* rmdir */
-	{ &vop_symlink_desc, procfs_symlink },		/* symlink */
-	{ &vop_readdir_desc, procfs_readdir },		/* readdir */
-	{ &vop_readlink_desc, procfs_readlink },	/* readlink */
-	{ &vop_abortop_desc, procfs_abortop },		/* abortop */
-	{ &vop_inactive_desc, procfs_inactive },	/* inactive */
-	{ &vop_reclaim_desc, procfs_reclaim },		/* reclaim */
-	{ &vop_lock_desc, procfs_lock },		/* lock */
-	{ &vop_unlock_desc, procfs_unlock },		/* unlock */
-	{ &vop_bmap_desc, procfs_bmap },		/* bmap */
-	{ &vop_strategy_desc, procfs_strategy },	/* strategy */
-	{ &vop_print_desc, procfs_print },		/* print */
-	{ &vop_islocked_desc, procfs_islocked },	/* islocked */
-	{ &vop_pathconf_desc, procfs_pathconf },	/* pathconf */
-	{ &vop_advlock_desc, procfs_advlock },		/* advlock */
-	{ &vop_blkatoff_desc, procfs_blkatoff },	/* blkatoff */
-	{ &vop_valloc_desc, procfs_valloc },		/* valloc */
-	{ &vop_vfree_desc, procfs_vfree },		/* vfree */
-	{ &vop_truncate_desc, procfs_truncate },	/* truncate */
-	{ &vop_update_desc, procfs_update },		/* update */
-	{ &vop_putpages_desc, procfs_putpages },	/* putpages */
-	{ NULL, NULL }
-};
-const struct vnodeopv_desc procfs_vnodeop_opv_desc =
-	{ &procfs_vnodeop_p, procfs_vnodeop_entries };
-/*
- * set things up for doing i/o on
- * the pfsnode (vp).  (vp) is locked
- * on entry, and should be left locked
- * on exit.
- *
- * for procfs we don't need to do anything
- * in particular for i/o.  all that is done
- * is to support exclusive open on process
- * memory images.
- */
-int
-procfs_open(v)
-	void *v;
-{
-	struct vop_open_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-	struct proc *p1, *p2;
-	int error;
-
-	p1 = ap->a_p;				/* tracer */
-	p2 = PFIND(pfs->pfs_pid);		/* traced */
-
-	if (p2 == NULL)
-		return (ENOENT);		/* was ESRCH, jsp */
-
-	switch (pfs->pfs_type) {
-	case PFSmem:
-		if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
-		    ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)))
-			return (EBUSY);
-
-		if ((error = process_checkioperm(p1, p2)) != 0)
-			return (error);
-
-		if (ap->a_mode & FWRITE)
-			pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
-
-		return (0);
-
-	default:
-		break;
-	}
-
-	return (0);
-}
-
-/*
- * close the pfsnode (vp) after doing i/o.
- * (vp) is not locked on entry or exit.
- *
- * nothing to do for procfs other than undo
- * any exclusive open flag (see _open above).
- */
-int
-procfs_close(v)
-	void *v;
-{
-	struct vop_close_args /* {
-		struct vnode *a_vp;
-		int  a_fflag;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
-	switch (pfs->pfs_type) {
-	case PFSmem:
-		if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL))
-			pfs->pfs_flags &= ~(FWRITE|O_EXCL);
-		break;
-
-	default:
-		break;
-	}
-
-	return (0);
-}
-
-/*
- * _inactive is called when the pfsnode
- * is vrele'd and the reference count goes
- * to zero.  (vp) will be on the vnode free
- * list, so to get it back vget() must be
- * used.
- *
- * for procfs, check if the process is still
- * alive and if it isn't then just throw away
- * the vnode by calling vgone().  this may
- * be overkill and a waste of time since the
- * chances are that the process will still be
- * there and PFIND is not free.
- *
- * (vp) is locked on entry, but must be unlocked on exit.
- */
-int
-procfs_inactive(v)
-	void *v;
-{
-	struct vop_inactive_args /* {
-		struct vnode *a_vp;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
-	VOP_UNLOCK(ap->a_vp, 0);
-	if (PFIND(pfs->pfs_pid) == NULL)
-		vgone(ap->a_vp);
-
-	return (0);
-}
-
-/*
- * _reclaim is called when getnewvnode()
- * wants to make use of an entry on the vnode
- * free list.  at this time the filesystem needs
- * to free any private data and remove the node
- * from any private lists.
- */
-int
-procfs_reclaim(v)
-	void *v;
-{
-	struct vop_reclaim_args /* {
-		struct vnode *a_vp;
-	} */ *ap = v;
-
-	return (procfs_freevp(ap->a_vp));
-}
-
-/*
- * Return POSIX pathconf information applicable to special devices.
- */
-int
-procfs_pathconf(v)
-	void *v;
-{
-	struct vop_pathconf_args /* {
-		struct vnode *a_vp;
-		int a_name;
-		register_t *a_retval;
-	} */ *ap = v;
-
-	switch (ap->a_name) {
-	case _PC_LINK_MAX:
-		*ap->a_retval = LINK_MAX;
-		return (0);
-	case _PC_MAX_CANON:
-		*ap->a_retval = MAX_CANON;
-		return (0);
-	case _PC_MAX_INPUT:
-		*ap->a_retval = MAX_INPUT;
-		return (0);
-	case _PC_PIPE_BUF:
-		*ap->a_retval = PIPE_BUF;
-		return (0);
-	case _PC_CHOWN_RESTRICTED:
-		*ap->a_retval = 1;
-		return (0);
-	case _PC_VDISABLE:
-		*ap->a_retval = _POSIX_VDISABLE;
-		return (0);
-	case _PC_SYNC_IO:
-		*ap->a_retval = 1;
-		return (0);
-	default:
-		return (EINVAL);
-	}
-	/* NOTREACHED */
-}
-
-/*
- * _print is used for debugging.
- * just print a readable description
- * of (vp).
- */
-int
-procfs_print(v)
-	void *v;
-{
-	struct vop_print_args /* {
-		struct vnode *a_vp;
-	} */ *ap = v;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
-	printf("tag VT_PROCFS, type %d, pid %d, mode %x, flags %lx\n",
-	    pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags);
-	return 0;
-}
-
-int
-procfs_link(v)
-	void *v;
-{
-	struct vop_link_args /* {
-		struct vnode *a_dvp;
-		struct vnode *a_vp;
-		struct componentname *a_cnp;
-	} */ *ap = v;
-
-	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
-	vput(ap->a_dvp);
-	return (EROFS);
-}
-
-int
-procfs_symlink(v)
-	void *v;
-{
-	struct vop_symlink_args /* {
-		struct vnode *a_dvp;
-		struct vnode **a_vpp;
-		struct componentname *a_cnp;
-		struct vattr *a_vap;
-		char *a_target;
-	} */ *ap = v;
-
-	VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
-	vput(ap->a_dvp);
-	return (EROFS);
-}
-
-/*
- * Invent attributes for pfsnode (vp) and store
- * them in (vap).
- * Directories lengths are returned as zero since
- * any real length would require the genuine size
- * to be computed, and nothing cares anyway.
- *
- * this is relatively minimal for procfs.
- */
-int
-procfs_getattr(v)
-	void *v;
-{
-	struct vop_getattr_args /* {
-		struct vnode *a_vp;
-		struct vattr *a_vap;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-	struct vattr *vap = ap->a_vap;
-	struct proc *procp;
-	int error;
-
-	/* first check the process still exists */
-	switch (pfs->pfs_type) {
-	case PFSroot:
-	case PFScurproc:
-	case PFSself:
-		procp = 0;
-		break;
-
-	default:
-		procp = PFIND(pfs->pfs_pid);
-		if (procp == NULL)
-			return (ENOENT);
-		break;
-	}
-
-	error = 0;
-
-	/* start by zeroing out the attributes */
-	VATTR_NULL(vap);
-
-	/* next do all the common fields */
-	vap->va_type = ap->a_vp->v_type;
-	vap->va_mode = pfs->pfs_mode;
-	vap->va_fileid = pfs->pfs_fileno;
-	vap->va_flags = 0;
-	vap->va_blocksize = PAGE_SIZE;
-
-	/*
-	 * Make all times be current TOD.  Avoid microtime(9), it's slow.
-	 * We don't guard the read from time(9) with splclock(9) since we
-	 * don't actually need to be THAT sure the access is atomic.
-	 *
-	 * It would be possible to get the process start
-	 * time from the p_stat structure, but there's
-	 * no "file creation" time stamp anyway, and the
-	 * p_stat structure is not addressible if u. gets
-	 * swapped out for that process.
-	 */
-	TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime);
-	vap->va_atime = vap->va_mtime = vap->va_ctime;
-
-	switch (pfs->pfs_type) {
-	case PFSmem:
-	case PFSregs:
-	case PFSfpregs:
-#if defined(__HAVE_PROCFS_MACHDEP) && defined(PROCFS_MACHDEP_PROTECT_CASES)
-	PROCFS_MACHDEP_PROTECT_CASES
-#endif
-		/*
-		 * If the process has exercised some setuid or setgid
-		 * privilege, then rip away read/write permission so
-		 * that only root can gain access.
-		 */
-		if (procp->p_flag & P_SUGID)
-			vap->va_mode &= ~(S_IRUSR|S_IWUSR);
-		/* FALLTHROUGH */
-	case PFSctl:
-	case PFSstatus:
-	case PFSstat:
-	case PFSnote:
-	case PFSnotepg:
-	case PFSmap:
-	case PFSmaps:
-	case PFScmdline:
-		vap->va_nlink = 1;
-		vap->va_uid = procp->p_ucred->cr_uid;
-		vap->va_gid = procp->p_ucred->cr_gid;
-		break;
-	case PFSmeminfo:
-	case PFScpuinfo:
-	case PFSuptime:
-	case PFSmounts:
-		vap->va_nlink = 1;
-		vap->va_uid = vap->va_gid = 0;
-		break;
-
-	default:
-		break;
-	}
-
-	/*
-	 * now do the object specific fields
-	 *
-	 * The size could be set from struct reg, but it's hardly
-	 * worth the trouble, and it puts some (potentially) machine
-	 * dependent data into this machine-independent code.  If it
-	 * becomes important then this function should break out into
-	 * a per-file stat function in the corresponding .c file.
-	 */
-
-	switch (pfs->pfs_type) {
-	case PFSroot:
-		/*
-		 * Set nlink to 1 to tell fts(3) we don't actually know.
-		 */
-		vap->va_nlink = 1;
-		vap->va_uid = 0;
-		vap->va_gid = 0;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-
-	case PFScurproc: {
-		char buf[16];		/* should be enough */
-		vap->va_nlink = 1;
-		vap->va_uid = 0;
-		vap->va_gid = 0;
-		vap->va_bytes = vap->va_size =
-		    snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid);
-		break;
-	}
-
-	case PFSself:
-		vap->va_nlink = 1;
-		vap->va_uid = 0;
-		vap->va_gid = 0;
-		vap->va_bytes = vap->va_size = sizeof("curproc") - 1;
-		break;
-
-	case PFSfd:
-		if (pfs->pfs_fd != -1) {
-			struct file *fp;
-			struct proc *pown;
-
-			if ((error = procfs_getfp(pfs, &pown, &fp)) != 0)
-				return error;
-			FILE_USE(fp);
-			vap->va_nlink = 1;
-			vap->va_uid = fp->f_cred->cr_uid;
-			vap->va_gid = fp->f_cred->cr_gid;
-			switch (fp->f_type) {
-			case DTYPE_VNODE:
-				vap->va_bytes = vap->va_size =
-				    ((struct vnode *)fp->f_data)->v_size;
-				break;
-			default:
-				vap->va_bytes = vap->va_size = 0;
-				break;
-			}
-			FILE_UNUSE(fp, pown);
-			break;
-		}
-		/*FALLTHROUGH*/
-	case PFSproc:
-		vap->va_nlink = 2;
-		vap->va_uid = procp->p_ucred->cr_uid;
-		vap->va_gid = procp->p_ucred->cr_gid;
-		vap->va_bytes = vap->va_size = DEV_BSIZE;
-		break;
-
-	case PFSfile:
-		error = EOPNOTSUPP;
-		break;
-
-	case PFSmem:
-		vap->va_bytes = vap->va_size =
-			ctob(procp->p_vmspace->vm_tsize +
-				    procp->p_vmspace->vm_dsize +
-				    procp->p_vmspace->vm_ssize);
-		break;
-
-#if defined(PT_GETREGS) || defined(PT_SETREGS)
-	case PFSregs:
-		vap->va_bytes = vap->va_size = sizeof(struct reg);
-		break;
-#endif
-
-#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
-	case PFSfpregs:
-		vap->va_bytes = vap->va_size = sizeof(struct fpreg);
-		break;
-#endif
-
-	case PFSctl:
-	case PFSstatus:
-	case PFSstat:
-	case PFSnote:
-	case PFSnotepg:
-	case PFScmdline:
-	case PFSmeminfo:
-	case PFScpuinfo:
-	case PFSuptime:
-	case PFSmounts:
-		vap->va_bytes = vap->va_size = 0;
-		break;
-	case PFSmap:
-	case PFSmaps:
-		/*
-		 * Advise a larger blocksize for the map files, so that
-		 * they may be read in one pass.
-		 */
-		vap->va_blocksize = 4 * PAGE_SIZE;
-		vap->va_bytes = vap->va_size = 0;
-		break;
-
-#ifdef __HAVE_PROCFS_MACHDEP
-	PROCFS_MACHDEP_NODETYPE_CASES
-		error = procfs_machdep_getattr(ap->a_vp, vap, procp);
-		break;
-#endif
-
-	default:
-		panic("procfs_getattr");
-	}
-
-	return (error);
-}
-
-/*ARGSUSED*/
-int
-procfs_setattr(v)
-	void *v;
-{
-	/*
-	 * just fake out attribute setting
-	 * it's not good to generate an error
-	 * return, otherwise things like creat()
-	 * will fail when they try to set the
-	 * file length to 0.  worse, this means
-	 * that echo $note > /proc/$pid/note will fail.
-	 */
-
-	return (0);
-}
-
-/*
- * implement access checking.
- *
- * actually, the check for super-user is slightly
- * broken since it will allow read access to write-only
- * objects.  this doesn't cause any particular trouble
- * but does mean that the i/o entry points need to check
- * that the operation really does make sense.
- */
-int
-procfs_access(v)
-	void *v;
-{
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		struct ucred *a_cred;
-		struct proc *a_p;
-	} */ *ap = v;
-	struct vattr va;
-	int error;
-
-	if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0)
-		return (error);
-
-	return (vaccess(va.va_type, va.va_mode,
-	    va.va_uid, va.va_gid, ap->a_mode, ap->a_cred));
-}
-
-/*
- * lookup.  this is incredibly complicated in the
- * general case, however for most pseudo-filesystems
- * very little needs to be done.
- *
- * Locking isn't hard here, just poorly documented.
- *
- * If we're looking up ".", just vref the parent & return it.
- *
- * If we're looking up "..", unlock the parent, and lock "..". If everything
- * went ok, and we're on the last component and the caller requested the
- * parent locked, try to re-lock the parent. We do this to prevent lock
- * races.
- *
- * For anything else, get the needed node. Then unlock the parent if not
- * the last component or not LOCKPARENT (i.e. if we wouldn't re-lock the
- * parent in the .. case).
- *
- * We try to exit with the parent locked in error cases.
- */
-int
-procfs_lookup(v)
-	void *v;
-{
-	struct vop_lookup_args /* {
-		struct vnode * a_dvp;
-		struct vnode ** a_vpp;
-		struct componentname * a_cnp;
-	} */ *ap = v;
-	struct componentname *cnp = ap->a_cnp;
-	struct vnode **vpp = ap->a_vpp;
-	struct vnode *dvp = ap->a_dvp;
-	const char *pname = cnp->cn_nameptr;
-	const struct proc_target *pt = NULL;
-	struct vnode *fvp;
-	pid_t pid;
-	struct pfsnode *pfs;
-	struct proc *p = NULL;
-	int i, error, wantpunlock, iscurproc = 0, isself = 0;
-
-	*vpp = NULL;
-	cnp->cn_flags &= ~PDIRUNLOCK;
-
-	if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
-		return (EROFS);
-
-	if (cnp->cn_namelen == 1 && *pname == '.') {
-		*vpp = dvp;
-		VREF(dvp);
-		return (0);
-	}
-
-	wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN));
-	pfs = VTOPFS(dvp);
-	switch (pfs->pfs_type) {
-	case PFSroot:
-		/*
-		 * Shouldn't get here with .. in the root node.
-		 */
-		if (cnp->cn_flags & ISDOTDOT)
-			return (EIO);
-
-		iscurproc = CNEQ(cnp, "curproc", 7);
-		isself = CNEQ(cnp, "self", 4);
-
-		if (iscurproc || isself) {
-			error = procfs_allocvp(dvp->v_mount, vpp, 0,
-			    iscurproc ? PFScurproc : PFSself, -1);
-			if ((error == 0) && (wantpunlock)) {
-				VOP_UNLOCK(dvp, 0);
-				cnp->cn_flags |= PDIRUNLOCK;
-			}
-			return (error);
-		}
-
-		for (i = 0; i < nproc_root_targets; i++) {
-			pt = &proc_root_targets[i];
-			if (cnp->cn_namelen == pt->pt_namlen &&
-			    memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
-			    (pt->pt_valid == NULL ||
-			     (*pt->pt_valid)(p, dvp->v_mount)))
-				break;
-		}
-
-		if (i != nproc_root_targets) {
-			error = procfs_allocvp(dvp->v_mount, vpp, 0,
-			    pt->pt_pfstype, -1);
-			if ((error == 0) && (wantpunlock)) {
-				VOP_UNLOCK(dvp, 0);
-				cnp->cn_flags |= PDIRUNLOCK;
-			}
-			return (error);
-		}
-
-		pid = (pid_t)atoi(pname, cnp->cn_namelen);
-
-		p = PFIND(pid);
-		if (p == NULL)
-			break;
-
-		error = procfs_allocvp(dvp->v_mount, vpp, pid, PFSproc, -1);
-		if ((error == 0) && (wantpunlock)) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return (error);
-
-	case PFSproc:
-		/*
-		 * do the .. dance. We unlock the directory, and then
-		 * get the root dir. That will automatically return ..
-		 * locked. Then if the caller wanted dvp locked, we
-		 * re-lock.
-		 */
-		if (cnp->cn_flags & ISDOTDOT) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-			error = procfs_root(dvp->v_mount, vpp);
-			if ((error == 0) && (wantpunlock == 0) &&
-				    ((error = vn_lock(dvp, LK_EXCLUSIVE)) == 0))
-				cnp->cn_flags &= ~PDIRUNLOCK;
-			return (error);
-		}
-
-		p = PFIND(pfs->pfs_pid);
-		if (p == NULL)
-			break;
-
-		for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
-			if (cnp->cn_namelen == pt->pt_namlen &&
-			    memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
-			    (pt->pt_valid == NULL ||
-			     (*pt->pt_valid)(p, dvp->v_mount)))
-				goto found;
-		}
-		break;
-
-	found:
-		if (pt->pt_pfstype == PFSfile) {
-			fvp = p->p_textvp;
-			/* We already checked that it exists. */
-			VREF(fvp);
-			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
-			if (wantpunlock) {
-				VOP_UNLOCK(dvp, 0);
-				cnp->cn_flags |= PDIRUNLOCK;
-			}
-			*vpp = fvp;
-			return (0);
-		}
-
-		error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
-		    pt->pt_pfstype, -1);
-		if ((error == 0) && (wantpunlock)) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return (error);
-
-	case PFSfd: {
-		int fd;
-		struct file *fp;
-		/*
-		 * do the .. dance. We unlock the directory, and then
-		 * get the proc dir. That will automatically return ..
-		 * locked. Then if the caller wanted dvp locked, we
-		 * re-lock.
-		 */
-		if (cnp->cn_flags & ISDOTDOT) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-			error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
-			    PFSproc, -1);
-			if ((error == 0) && (wantpunlock == 0) &&
-				    ((error = vn_lock(dvp, LK_EXCLUSIVE)) == 0))
-				cnp->cn_flags &= ~PDIRUNLOCK;
-			return (error);
-		}
-		fd = atoi(pname, cnp->cn_namelen);
-		p = PFIND(pfs->pfs_pid);
-		if (p == NULL || (fp = fd_getfile(p->p_fd, fd)) == NULL)
-			return ENOENT;
-		FILE_USE(fp);
-
-		switch (fp->f_type) {
-		case DTYPE_VNODE:
-			fvp = (struct vnode *)fp->f_data;
-
-			/* Don't show directories */
-			if (fvp->v_type == VDIR)
-				goto symlink;
-
-			VREF(fvp);
-			FILE_UNUSE(fp, p);
-			vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY |
-			    (p == curproc ? LK_CANRECURSE : 0));
-			*vpp = fvp;
-			error = 0;
-			break;
-		default:
-		symlink:
-			FILE_UNUSE(fp, p);
-			error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
-			    PFSfd, fd);
-			break;
-		}
-		if ((error == 0) && (wantpunlock)) {
-			VOP_UNLOCK(dvp, 0);
-			cnp->cn_flags |= PDIRUNLOCK;
-		}
-		return error;
-	}
-	default:
-		return (ENOTDIR);
-	}
-
-	return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
-}
-
-int
-procfs_validfile(p, mp)
-	struct proc *p;
-	struct mount *mp;
-{
-	return (p->p_textvp != NULL);
-}
-
-static int
-procfs_validfile_linux(p, mp)
-	struct proc *p;
-	struct mount *mp;
-{
-	int flags;
-
-	flags = VFSTOPROC(mp)->pmnt_flags;
-	return ((flags & PROCFSMNT_LINUXCOMPAT) &&
-	    (p == NULL || procfs_validfile(p, mp)));
-}
-
-struct procfs_root_readdir_ctx {
-	struct uio *uiop;
-	off_t *cookies;
-	int ncookies;
-	off_t off;
-	off_t startoff;
-	int error;
-};
-
-static int
-procfs_root_readdir_callback(struct proc *p, void *arg)
-{
-	struct procfs_root_readdir_ctx *ctxp = arg;
-	struct dirent d;
-	struct uio *uiop;
-	int error;
-
-	uiop = ctxp->uiop;
-	if (uiop->uio_resid < UIO_MX)
-		return -1; /* no space */
-
-	if (ctxp->off < ctxp->startoff) {
-		ctxp->off++;
-		return 0;
-	}
-
-	memset(&d, 0, UIO_MX);
-	d.d_reclen = UIO_MX;
-	d.d_fileno = PROCFS_FILENO(p->p_pid, PFSproc, -1);
-	d.d_namlen = snprintf(d.d_name,
-	    UIO_MX - offsetof(struct dirent, d_name), "%ld", (long)p->p_pid);
-	d.d_type = DT_DIR;
-
-	proclist_unlock_read();
-	error = uiomove(&d, UIO_MX, uiop);
-	proclist_lock_read();
-	if (error) {
-		ctxp->error = error;
-		return -1;
-	}
-
-	ctxp->ncookies++;
-	if (ctxp->cookies)
-		*(ctxp->cookies)++ = ctxp->off + 1;
-	ctxp->off++;
-
-	return 0;
-}
-
-/*
- * readdir returns directory entries from pfsnode (vp).
- *
- * the strategy here with procfs is to generate a single
- * directory entry at a time (struct dirent) and then
- * copy that out to userland using uiomove.  a more efficent
- * though more complex implementation, would try to minimize
- * the number of calls to uiomove().  for procfs, this is
- * hardly worth the added code complexity.
- *
- * this should just be done through read()
- */
-int
-procfs_readdir(v)
-	void *v;
-{
-	struct vop_readdir_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		struct ucred *a_cred;
-		int *a_eofflag;
-		off_t **a_cookies;
-		int *a_ncookies;
-	} */ *ap = v;
-	struct uio *uio = ap->a_uio;
-	struct dirent d;
-	struct pfsnode *pfs;
-	off_t i;
-	int error;
-	off_t *cookies = NULL;
-	int ncookies;
-	struct vnode *vp;
-	const struct proc_target *pt;
-	struct procfs_root_readdir_ctx ctx;
-
-	vp = ap->a_vp;
-	pfs = VTOPFS(vp);
-
-	if (uio->uio_resid < UIO_MX)
-		return (EINVAL);
-	if (uio->uio_offset < 0)
-		return (EINVAL);
-
-	error = 0;
-	i = uio->uio_offset;
-	memset(&d, 0, UIO_MX);
-	d.d_reclen = UIO_MX;
-	ncookies = uio->uio_resid / UIO_MX;
-
-	switch (pfs->pfs_type) {
-	/*
-	 * this is for the process-specific sub-directories.
-	 * all that is needed to is copy out all the entries
-	 * from the procent[] table (top of this file).
-	 */
-	case PFSproc: {
-		struct proc *p;
-
-		if (i >= nproc_targets)
-			return 0;
-
-		p = PFIND(pfs->pfs_pid);
-		if (p == NULL)
-			break;
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (nproc_targets - i));
-			cookies = malloc(ncookies * sizeof (off_t),
-			    M_TEMP, M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		for (pt = &proc_targets[i];
-		     uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
-			if (pt->pt_valid &&
-			    (*pt->pt_valid)(p, vp->v_mount) == 0)
-				continue;
-
-			d.d_fileno = PROCFS_FILENO(pfs->pfs_pid,
-			    pt->pt_pfstype, -1);
-			d.d_namlen = pt->pt_namlen;
-			memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1);
-			d.d_type = pt->pt_type;
-
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-		}
-
-	    	break;
-	}
-	case PFSfd: {
-		struct proc *p;
-		struct filedesc	*fdp;
-		struct file *fp;
-		int lim, nc = 0;
-
-		p = PFIND(pfs->pfs_pid);
-		if (p == NULL)
-			return ESRCH;
-
-		fdp = p->p_fd;
-
-		lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
-		if (i >= lim)
-			return 0;
-
-		if (ap->a_ncookies) {
-			ncookies = min(ncookies, (fdp->fd_nfiles + 2 - i));
-			cookies = malloc(ncookies * sizeof (off_t),
-			    M_TEMP, M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-
-		for (; i < 2 && uio->uio_resid >= UIO_MX; i++) {
-			pt = &proc_targets[i];
-			d.d_namlen = pt->pt_namlen;
-			d.d_fileno = PROCFS_FILENO(pfs->pfs_pid,
-			    pt->pt_pfstype, -1);
-			(void)memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1);
-			d.d_type = pt->pt_type;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			nc++;
-		}
-		if (error) {
-			ncookies = nc;
-			break;
-		}
-		for (; uio->uio_resid >= UIO_MX && i < fdp->fd_nfiles; i++) {
-			/* check the descriptor exists */
-			if ((fp = fd_getfile(fdp, i - 2)) == NULL)
-				continue;
-			simple_unlock(&fp->f_slock);
-
-			d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, PFSfd, i - 2);
-			d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
-			    "%lld", (long long)(i - 2));
-			d.d_type = VREG;
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			if (cookies)
-				*cookies++ = i + 1;
-			nc++;
-		}
-		ncookies = nc;
-		break;
-	}
-
-	/*
-	 * this is for the root of the procfs filesystem
-	 * what is needed are special entries for "curproc"
-	 * and "self" followed by an entry for each process
-	 * on allproc.
-	 */
-
-	case PFSroot: {
-		int nc = 0;
-
-		if (ap->a_ncookies) {
-			/*
-			 * XXX Potentially allocating too much space here,
-			 * but I'm lazy. This loop needs some work.
-			 */
-			cookies = malloc(ncookies * sizeof (off_t),
-			    M_TEMP, M_WAITOK);
-			*ap->a_cookies = cookies;
-		}
-		error = 0;
-		/* 0 ... 3 are static entries. */
-		for (; i <= 3 && uio->uio_resid >= UIO_MX; i++) {
-			switch (i) {
-			case 0:		/* `.' */
-			case 1:		/* `..' */
-				d.d_fileno = PROCFS_FILENO(0, PFSroot, -1);
-				d.d_namlen = i + 1;
-				memcpy(d.d_name, "..", d.d_namlen);
-				d.d_name[i + 1] = '\0';
-				d.d_type = DT_DIR;
-				break;
-
-			case 2:
-				d.d_fileno = PROCFS_FILENO(0, PFScurproc, -1);
-				d.d_namlen = sizeof("curproc") - 1;
-				memcpy(d.d_name, "curproc", sizeof("curproc"));
-				d.d_type = DT_LNK;
-				break;
-
-			case 3:
-				d.d_fileno = PROCFS_FILENO(0, PFSself, -1);
-				d.d_namlen = sizeof("self") - 1;
-				memcpy(d.d_name, "self", sizeof("self"));
-				d.d_type = DT_LNK;
-				break;
-			}
-
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			nc++;
-			if (cookies)
-				*cookies++ = i + 1;
-		}
-		/* 4 ... are process entries. */
-		ctx.uiop = uio;
-		ctx.error = 0;
-		ctx.off = 4;
-		ctx.startoff = i;
-		ctx.cookies = cookies;
-		ctx.ncookies = nc;
-		proclist_foreach_call(&allproc,
-		    procfs_root_readdir_callback, &ctx);
-		cookies = ctx.cookies;
-		nc = ctx.ncookies;
-		error = ctx.error;
-		if (error)
-			break;
-
-		/* misc entries. */
-		if (i < ctx.off)
-			i = ctx.off;
-		if (i >= ctx.off + nproc_root_targets)
-			break;
-		for (pt = &proc_root_targets[i - ctx.off];
-		    uio->uio_resid >= UIO_MX &&
-		    pt < &proc_root_targets[nproc_root_targets];
-		    pt++, i++) {
-			if (pt->pt_valid &&
-			    (*pt->pt_valid)(NULL, vp->v_mount) == 0)
-				continue;
-			d.d_fileno = PROCFS_FILENO(0, pt->pt_pfstype, -1);
-			d.d_namlen = pt->pt_namlen;
-			memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1);
-			d.d_type = pt->pt_type;
-
-			if ((error = uiomove(&d, UIO_MX, uio)) != 0)
-				break;
-			nc++;
-			if (cookies)
-				*cookies++ = i + 1;
-		}
-
-		ncookies = nc;
-		break;
-	}
-
-	default:
-		error = ENOTDIR;
-		break;
-	}
-
-	if (ap->a_ncookies) {
-		if (error) {
-			if (cookies)
-				free(*ap->a_cookies, M_TEMP);
-			*ap->a_ncookies = 0;
-			*ap->a_cookies = NULL;
-		} else
-			*ap->a_ncookies = ncookies;
-	}
-	uio->uio_offset = i;
-	return (error);
-}
-
-/*
- * readlink reads the link of `curproc'
- */
-int
-procfs_readlink(v)
-	void *v;
-{
-	struct vop_readlink_args *ap = v;
-	char buf[16];		/* should be enough */
-	char *bp = buf;
-	char *path = NULL;
-	int len;
-	int error = 0;
-	struct pfsnode *pfs = VTOPFS(ap->a_vp);
-
-	if (pfs->pfs_fileno == PROCFS_FILENO(0, PFScurproc, -1))
-		len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid);
-	else if (pfs->pfs_fileno == PROCFS_FILENO(0, PFSself, -1))
-		len = snprintf(buf, sizeof(buf), "%s", "curproc");
-	else {
-		struct file *fp;
-		struct proc *pown;
-		struct vnode *vxp, *vp;
-
-		if ((error = procfs_getfp(pfs, &pown, &fp)) != 0)
-			return error;
-		FILE_USE(fp);
-		switch (fp->f_type) {
-		case DTYPE_VNODE:
-			vxp = (struct vnode *)fp->f_data;
-			if (vxp->v_type != VDIR) {
-				FILE_UNUSE(fp, pown);
-				return EINVAL;
-			}
-			if ((path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK))
-			    == NULL) {
-				FILE_UNUSE(fp, pown);
-				return ENOMEM;
-			}
-			bp = path + MAXPATHLEN;
-			*--bp = '\0';
-			vp = curproc->p_cwdi->cwdi_rdir;
-			if (vp == NULL)
-				vp = rootvnode;
-			error = getcwd_common(vxp, vp, &bp, path,
-			    MAXPATHLEN / 2, 0, curproc);
-			FILE_UNUSE(fp, pown);
-			if (error) {
-				free(path, M_TEMP);
-				return error;
-			}
-			len = strlen(bp);
-			break;
-
-		case DTYPE_MISC:
-			len = snprintf(buf, sizeof(buf), "%s", "[misc]");
-			break;
-
-		case DTYPE_KQUEUE:
-			len = snprintf(buf, sizeof(buf), "%s", "[kqueue]");
-			break;
-
-		default:
-			return EINVAL;
-		}
-	}
-
-	error = uiomove(bp, len, ap->a_uio);
-	if (path)
-		free(path, M_TEMP);
-	return error;
-}
-
-/*
- * convert decimal ascii to int
- */
-static int
-atoi(b, len)
-	const char *b;
-	size_t len;
-{
-	int p = 0;
-
-	while (len--) {
-		char c = *b++;
-		if (c < '0' || c > '9')
-			return -1;
-		p = 10 * p + (c - '0');
-	}
-
-	return p;
-}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/net/bpf.c mult-netbsd-3.1/sys/net/bpf.c
--- NetBSD-3.1/sys/net/bpf.c	2005-02-26 22:45:09.000000000 +0000
+++ mult-netbsd-3.1/sys/net/bpf.c	2007-12-18 10:59:49.000000000 +0000
@@ -540,8 +540,11 @@
 	struct bpf_d *d;
 {
 	wakeup(d);
-	if (d->bd_async)
-		fownsignal(d->bd_pgid, SIGIO, 0, 0, NULL);
+	if (d->bd_async){
+		/* FIXME - instance */
+		printf("%s: defaulting to proc0 instance\n", __func__);
+		fownsignal(proc0.p_inst, d->bd_pgid, SIGIO, 0, 0, NULL);
+	}
 
 	selnotify(&d->bd_sel, 0);
 	/* XXX */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/net/if_tap.c mult-netbsd-3.1/sys/net/if_tap.c
--- NetBSD-3.1/sys/net/if_tap.c	2006-01-21 05:40:24.000000000 +0000
+++ mult-netbsd-3.1/sys/net/if_tap.c	2007-12-18 10:59:49.000000000 +0000
@@ -62,6 +62,7 @@
 #include <sys/select.h>
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
+#include <sys/inst.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
@@ -462,9 +463,12 @@
 		ifp->if_flags |= IFF_OACTIVE;
 		wakeup(sc);
 		selnotify(&sc->sc_rsel, 1);
-		if (sc->sc_flags & TAP_ASYNCIO)
-			fownsignal(sc->sc_pgid, SIGIO, POLL_IN,
+		if (sc->sc_flags & TAP_ASYNCIO) {
+			/* FIXME - instance */
+			printf("%s: defaulting to proc0 instance\n", __func__);
+			fownsignal(proc0.p_inst, sc->sc_pgid, SIGIO, POLL_IN,
 			    POLLIN|POLLRDNORM, NULL);
+		}
 	}
 }
 
@@ -554,8 +558,11 @@
 	ifp->if_flags &= ~IFF_RUNNING;
 	wakeup(sc);
 	selnotify(&sc->sc_rsel, 1);
-	if (sc->sc_flags & TAP_ASYNCIO)
-		fownsignal(sc->sc_pgid, SIGIO, POLL_HUP, 0, NULL);
+	if (sc->sc_flags & TAP_ASYNCIO) {
+		/* FIXME - instance */
+		printf("%s: defaulting to proc0 instance\n", __func__);
+		fownsignal(proc0.p_inst, sc->sc_pgid, SIGIO, POLL_HUP, 0, NULL);
+	}
 }
 
 /*
diff -r -u -N --exclude CVS NetBSD-3.1/sys/net/if_tun.c mult-netbsd-3.1/sys/net/if_tun.c
--- NetBSD-3.1/sys/net/if_tun.c	2005-01-24 21:25:09.000000000 +0000
+++ mult-netbsd-3.1/sys/net/if_tun.c	2007-12-18 10:59:49.000000000 +0000
@@ -64,6 +64,7 @@
 #endif
 
 #include <net/if_tun.h>
+#include <sys/inst.h>
 
 #define TUNDEBUG	if (tundebug) printf
 int	tundebug = 0;
@@ -254,8 +255,11 @@
 		tp->tun_flags &= ~TUN_RWAIT;
 		wakeup((caddr_t)tp);
 	}
-	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
-		fownsignal(tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL);
+	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) {
+		/* FIXME - instance */
+		printf("%s: defaulting to proc0 instance\n", __func__);
+		fownsignal(proc0.p_inst, tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL);
+	}
 
 	selwakeup(&tp->tun_rsel);
 
@@ -557,9 +561,12 @@
 		tp->tun_flags &= ~TUN_RWAIT;
 		wakeup((caddr_t)tp);
 	}
-	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
-		fownsignal(tp->tun_pgid, SIGIO, POLL_IN, POLLIN|POLLRDNORM,
+	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) {
+		/* FIXME - instance */
+		printf("%s: defaulting to proc0 instance\n", __func__);
+		fownsignal(proc0.p_inst, tp->tun_pgid, SIGIO, POLL_IN, POLLIN|POLLRDNORM,
 		    NULL);
+	}
 
 	selnotify(&tp->tun_rsel, 0);
 out:
diff -r -u -N --exclude CVS NetBSD-3.1/sys/net80211/ieee80211_ioctl.c mult-netbsd-3.1/sys/net80211/ieee80211_ioctl.c
--- NetBSD-3.1/sys/net80211/ieee80211_ioctl.c	2005-02-26 22:45:09.000000000 +0000
+++ mult-netbsd-3.1/sys/net80211/ieee80211_ioctl.c	2007-11-09 18:23:30.000000000 +0000
@@ -113,11 +113,15 @@
 		/* nothing appropriate */
 		break;
 	case WI_RID_NODENAME:
+#if 0		
+		/* FIXME: needs to be instance-switched. */
 		strlcpy((char *)&wreq.wi_val[1], hostname,
 		    sizeof(wreq.wi_val) - sizeof(wreq.wi_val[0]));
 		wreq.wi_val[0] = htole16(strlen(hostname));
 		wreq.wi_len = (1 + strlen(hostname) + 1) / 2;
 		break;
+#endif
+		return(EINVAL);
 	case WI_RID_CURRENT_SSID:
 		if (ic->ic_state != IEEE80211_S_RUN) {
 			wreq.wi_val[0] = 0;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/netinet6/icmp6.c mult-netbsd-3.1/sys/netinet6/icmp6.c
--- NetBSD-3.1/sys/netinet6/icmp6.c	2005-01-17 10:16:07.000000000 +0000
+++ mult-netbsd-3.1/sys/netinet6/icmp6.c	2007-11-09 18:23:30.000000000 +0000
@@ -150,13 +150,13 @@
 static int icmp6_ratelimit __P((const struct in6_addr *, const int, const int));
 static const char *icmp6_redirect_diag __P((struct in6_addr *,
 	struct in6_addr *, struct in6_addr *));
-static struct mbuf *ni6_input __P((struct mbuf *, int));
-static struct mbuf *ni6_nametodns __P((const char *, int, int));
-static int ni6_dnsmatch __P((const char *, int, const char *, int));
-static int ni6_addrs __P((struct icmp6_nodeinfo *, struct mbuf *,
-			  struct ifnet **, char *));
-static int ni6_store_addrs __P((struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
-				struct ifnet *, int));
+/*static struct mbuf *ni6_input __P((struct mbuf *, int));*/
+/*static struct mbuf *ni6_nametodns __P((const char *, int, int));*/
+/*static int ni6_dnsmatch __P((const char *, int, const char *, int));*/
+/*static int ni6_addrs __P((struct icmp6_nodeinfo *, struct mbuf *,
+			  struct ifnet **, char *));*/
+/*static int ni6_store_addrs __P((struct icmp6_nodeinfo *, struct icmp6_nodeinfo *,
+				struct ifnet *, int));*/
 static int icmp6_notify_error __P((struct mbuf *, int, int, int));
 static struct rtentry *icmp6_mtudisc_clone __P((struct sockaddr *));
 static void icmp6_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
@@ -675,6 +675,8 @@
 		break;		/* just pass it to applications */
 
 	case ICMP6_WRUREQUEST:	/* ICMP6_FQDN_QUERY */
+#if 0
+		/* FIXME: needs to be instance-switched. */
 	    {
 		enum { WRU, FQDN } mode;
 
@@ -750,6 +752,8 @@
 		}
 		break;
 	    }
+#endif
+	    return(-1);
 
 	case ICMP6_WRUREPLY:
 		if (code != 0)
@@ -1173,6 +1177,7 @@
 #ifndef offsetof		/* XXX */
 #define	offsetof(type, member)	((size_t)(&((type *)0)->member))
 #endif
+#if 0
 static struct mbuf *
 ni6_input(m, off)
 	struct mbuf *m;
@@ -1183,7 +1188,7 @@
 	u_int16_t qtype;
 	int subjlen;
 	int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
-	struct ni_reply_fqdn *fqdn;
+	/*struct ni_reply_fqdn *fqdn;*/
 	int addrs;		/* for NI_QTYPE_NODEADDR */
 	struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */
 	struct sockaddr_in6 sin6; /* double meaning; ip6_dst and subjectaddr */
@@ -1303,6 +1308,8 @@
 			 *   wildcard match, if gethostname(3) side has
 			 *   truncated hostname.
 			 */
+#if 0
+			/* FIXME - this needs to be instance-switched. */
 			n = ni6_nametodns(hostname, hostnamelen, 0);
 			if (!n || n->m_next || n->m_len == 0)
 				goto bad;
@@ -1317,6 +1324,8 @@
 			m_freem(n);
 			n = NULL;
 			break;
+#endif
+			return(NULL);
 
 		case ICMP6_NI_SUBJ_IPV4:	/* XXX: to be implemented? */
 		default:
@@ -1415,6 +1424,8 @@
 		break;
 	}
 	case NI_QTYPE_FQDN:
+#if 0
+		/* FIXME: needs to be instance-switched. */
 		nni6->ni_code = ICMP6_NI_SUCCESS;
 		fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
 						sizeof(struct ip6_hdr) +
@@ -1432,6 +1443,8 @@
 			goto bad;
 		n->m_pkthdr.len += n->m_next->m_len;
 		break;
+#endif
+		return(NULL);
 	case NI_QTYPE_NODEADDR:
 	{
 		int lenlim, copied;
@@ -1460,6 +1473,7 @@
 		m_freem(n);
 	return (NULL);
 }
+#endif
 #undef hostnamelen
 
 #define isupper(x) ('A' <= (x) && (x) <= 'Z')
@@ -1473,6 +1487,7 @@
  * XXX names with less than 2 dots (like "foo" or "foo.section") will be
  * treated as truncated name (two \0 at the end).  this is a wild guess.
  */
+#if 0
 static struct mbuf *
 ni6_nametodns(name, namelen, old)
 	const char *name;
@@ -1577,12 +1592,14 @@
 		m_freem(m);
 	return NULL;
 }
+#endif
 
 /*
  * check if two DNS-encoded string matches.  takes care of truncated
  * form (with \0\0 at the end).  no compression support.
  * XXX upper/lowercase match (see RFC2065)
  */
+#if 0
 static int
 ni6_dnsmatch(a, alen, b, blen)
 	const char *a;
@@ -1643,10 +1660,12 @@
 	else
 		return 0;
 }
+#endif
 
 /*
  * calculate the number of addresses to be returned in the node info reply.
  */
+#if 0
 static int
 ni6_addrs(ni6, m, ifpp, subj)
 	struct icmp6_nodeinfo *ni6;
@@ -1740,7 +1759,9 @@
 
 	return (addrs);
 }
+#endif
 
+#if 0
 static int
 ni6_store_addrs(ni6, nni6, ifp0, resid)
 	struct icmp6_nodeinfo *ni6, *nni6;
@@ -1883,6 +1904,7 @@
 
 	return (copied);
 }
+#endif
 
 /*
  * XXX almost dup'ed code with rip6_input.
diff -r -u -N --exclude CVS NetBSD-3.1/sys/netinet6/in6.c mult-netbsd-3.1/sys/netinet6/in6.c
--- NetBSD-3.1/sys/netinet6/in6.c	2005-02-01 15:29:23.000000000 +0000
+++ mult-netbsd-3.1/sys/netinet6/in6.c	2007-11-09 18:23:30.000000000 +0000
@@ -1153,6 +1153,8 @@
 		/*
 		 * join node information group address
 		 */
+#if 0
+		/* FIXME - needs to be instance-switched. */
 		if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr) == 0) {
 			imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error);
 			if (!imm) {
@@ -1166,6 +1168,7 @@
 				    imm, i6mm_chain);
 			}
 		}
+#endif
 
 		if (ifp->if_flags & IFF_LOOPBACK) {
 			/*
diff -r -u -N --exclude CVS NetBSD-3.1/sys/netinet6/in6_ifattach.c mult-netbsd-3.1/sys/netinet6/in6_ifattach.c
--- NetBSD-3.1/sys/netinet6/in6_ifattach.c	2004-04-20 18:12:03.000000000 +0100
+++ mult-netbsd-3.1/sys/netinet6/in6_ifattach.c	2007-11-09 18:23:30.000000000 +0000
@@ -91,14 +91,14 @@
 	struct ifnet *ifp;
 	struct in6_addr *in6;	/* upper 64bits are preserved */
 {
+#if 0
+	/* FIXME - this needs instance-separation */
 	MD5_CTX ctxt;
 	u_int8_t digest[16];
 
-#if 0
 	/* we need at least several letters as seed for ifid */
 	if (hostnamelen < 3)
 		return -1;
-#endif
 
 	/* generate 8 bytes of pseudo-random value. */
 	bzero(&ctxt, sizeof(ctxt));
@@ -108,6 +108,8 @@
 
 	/* assumes sizeof(digest) > sizeof(ifid) */
 	bcopy(digest, &in6->s6_addr[8], 8);
+#endif
+	bzero(&in6->s6_addr[8], 8);
 
 	/* make sure to set "u" bit to local, and "g" bit to individual. */
 	in6->s6_addr[8] &= ~EUI64_GBIT;	/* g bit to "individual" */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/nfs/nfs_bootdhcp.c mult-netbsd-3.1/sys/nfs/nfs_bootdhcp.c
--- NetBSD-3.1/sys/nfs/nfs_bootdhcp.c	2005-02-26 22:39:50.000000000 +0000
+++ mult-netbsd-3.1/sys/nfs/nfs_bootdhcp.c	2007-11-09 19:05:28.000000000 +0000
@@ -718,18 +718,18 @@
 			memcpy(&gateway, p, 4);
 			break;
 		    case TAG_HOST_NAME:
-			if (len >= sizeof(hostname)) {
+			if (len >= MAXHOSTNAMELEN) {
 				printf("nfs_boot: host name >= %lu bytes",
-				       (u_long)sizeof(hostname));
+				       (u_long)MAXHOSTNAMELEN);
 				break;
 			}
 			myname = p;
 			mynamelen = len;
 			break;
 		    case TAG_DOMAIN_NAME:
-			if (len >= sizeof(domainname)) {
+			if (len >= MAXHOSTNAMELEN) {
 				printf("nfs_boot: domain name >= %lu bytes",
-				       (u_long)sizeof(domainname));
+				       (u_long)MAXHOSTNAMELEN);
 				break;
 			}
 			mydomain = p;
@@ -769,6 +769,8 @@
 	/*
 	 * Store and print network config info.
 	 */
+#if 0
+	/* FIXME - needs instance-switching */
 	if (myname) {
 		myname[mynamelen] = '\0';
 		strncpy(hostname, myname, sizeof(hostname));
@@ -781,6 +783,7 @@
 		domainnamelen = mydomainlen;
 		printf("nfs_boot: my_domain=%s\n", domainname);
 	}
+#endif
 	nd->nd_myip = bootp->bp_yiaddr;
 	if (nd->nd_myip.s_addr)
 		printf("nfs_boot: my_addr=%s\n", inet_ntoa(nd->nd_myip));
diff -r -u -N --exclude CVS NetBSD-3.1/sys/nfs/nfs_bootparam.c mult-netbsd-3.1/sys/nfs/nfs_bootparam.c
--- NetBSD-3.1/sys/nfs/nfs_bootparam.c	2004-05-22 23:52:15.000000000 +0100
+++ mult-netbsd-3.1/sys/nfs/nfs_bootparam.c	2007-11-14 16:00:24.000000000 +0000
@@ -56,6 +56,8 @@
 #include <sys/reboot.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <sys/file.h>
+#include <sys/inst.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -115,15 +117,15 @@
 	struct proc *procp;
 {
 	struct ifnet *ifp = nd->nd_ifp;
-	struct in_addr my_ip, arps_ip, gw_ip;
+	struct in_addr 	my_ip, arps_ip, gw_ip;
 	struct sockaddr_in bp_sin;
 	struct sockaddr_in *sin;
 #ifndef NFS_BOOTPARAM_NOGATEWAY
 	struct nfs_dlmount *gw_ndm = 0;
-	char *p;
-	u_int32_t mask;
+	char 		*p;
+	u_int32_t 	mask;
 #endif
-	int error;
+	int 		error;
 
 	/*
 	 * Bring up the interface. (just set the "up" flag)
@@ -186,7 +188,7 @@
 		goto delout;
 	}
 	printf("nfs_boot: server_addr=%s\n", inet_ntoa(sin->sin_addr));
-	printf("nfs_boot: hostname=%s\n", hostname);
+	/*printf("nfs_boot: hostname=%s\n", hostbuf);*/
 
 	/*
 	 * Now fetch the server:pathname strings and server IP
@@ -310,10 +312,13 @@
 		/* encapsulated data here */
 	} *reply;
 
-	struct mbuf *m, *from;
+	struct mbuf 	*m, *from;
 	struct sockaddr_in *sin;
-	int error;
-	int16_t port;
+	int 		error;
+	int16_t 	port;
+	char		hostbuf[MAXHOSTNAMELEN],
+			dombuf[MAXHOSTNAMELEN];
+	size_t		hostbuflen, dombuflen;
 
 	/*
 	 * Build request message for PMAPPROC_CALLIT.
@@ -359,14 +364,20 @@
 	bpsin->sin_addr.s_addr = sin->sin_addr.s_addr;
 
 	/* client name */
-	hostnamelen = MAXHOSTNAMELEN-1;
-	m = xdr_string_decode(m, hostname, &hostnamelen);
+
+	hostbuflen = inst_get_phostnamelen(p);
+	inst_get_phostname(p, hostbuf, MAXHOSTNAMELEN);
+
+	m = xdr_string_decode(m, hostbuf, &hostbuflen);
 	if (m == NULL)
 		goto bad;
 
 	/* domain name */
-	domainnamelen = MAXHOSTNAMELEN-1;
-	m = xdr_string_decode(m, domainname, &domainnamelen);
+
+	dombuflen = inst_get_pdomainnamelen(p);
+	inst_get_pdomainname(p, dombuf, MAXHOSTNAMELEN);
+
+	m = xdr_string_decode(m, dombuf, &dombuflen);
 	if (m == NULL)
 		goto bad;
 
@@ -405,19 +416,24 @@
 	struct nfs_dlmount *ndm;
 	struct proc *p;
 {
-	char pathname[MNAMELEN];
-	struct in_addr inaddr;
+	char 		pathname[MNAMELEN];
+	struct in_addr	inaddr;
 	struct sockaddr_in *sin;
-	struct mbuf *m;
-	char *serv_name;
-	int error, sn_len, path_len;
+	struct mbuf 	*m;
+	char 		*serv_name;
+	int 		error, sn_len, path_len;
+	char		hostbuf[MAXHOSTNAMELEN];
+	size_t		hostbuflen;
 
 	/*
 	 * Build request message.
 	 */
 
 	/* client name (hostname) */
-	m  = xdr_string_encode(hostname, hostnamelen);
+	hostbuflen = inst_get_phostnamelen(p);
+	inst_get_phostname(p, hostbuf, MAXHOSTNAMELEN);
+
+	m  = xdr_string_encode(hostbuf, hostbuflen);
 	if (m == NULL)
 		return (ENOMEM);
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/nfs/nfs_node.c mult-netbsd-3.1/sys/nfs/nfs_node.c
--- NetBSD-3.1/sys/nfs/nfs_node.c	2005-08-24 19:43:37.000000000 +0100
+++ mult-netbsd-3.1/sys/nfs/nfs_node.c	2007-11-18 14:10:51.000000000 +0000
@@ -207,6 +207,7 @@
 	 * overwrite these.
 	 */
 	np->n_rcred = curproc->p_ucred;
+	/* FIXME - instances */
 	crhold(np->n_rcred);
 	np->n_wcred = curproc->p_ucred;
 	crhold(np->n_wcred);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/nfs/nfs_vfsops.c mult-netbsd-3.1/sys/nfs/nfs_vfsops.c
--- NetBSD-3.1/sys/nfs/nfs_vfsops.c	2005-09-27 11:31:29.000000000 +0100
+++ mult-netbsd-3.1/sys/nfs/nfs_vfsops.c	2007-11-09 18:23:31.000000000 +0000
@@ -155,8 +155,7 @@
 #endif
 	vp = nmp->nm_vnode;
 	np = VTONFS(vp);
-	cred = crget();
-	cred->cr_ngroups = 0;
+	cred = crdupinst(p->p_ucred);
 #ifndef NFS_V2_ONLY
 	if (v3 && (nmp->nm_iflag & NFSMNT_GOTFSINFO) == 0)
 		(void)nfs_fsinfo(nmp, vp, cred, p);
@@ -778,10 +777,9 @@
 	MALLOC(attrs, struct vattr *, sizeof(struct vattr), M_TEMP, M_WAITOK);
 	VOP_GETATTR(*vpp, attrs, p->p_ucred, p);
 	if ((nmp->nm_flag & NFSMNT_NFSV3) && ((*vpp)->v_type == VDIR)) {
-		cr = crget();
+		cr = crdupinst(p->p_ucred);
 		cr->cr_uid = attrs->va_uid;
 		cr->cr_gid = attrs->va_gid;
-		cr->cr_ngroups = 0;
 		nfs_cookieheuristic(*vpp, &nmp->nm_iflag, p, cr);
 		crfree(cr);
 	}
diff -r -u -N --exclude CVS NetBSD-3.1/sys/nfs/nfs_vnops.c mult-netbsd-3.1/sys/nfs/nfs_vnops.c
--- NetBSD-3.1/sys/nfs/nfs_vnops.c	2006-07-16 13:21:21.000000000 +0100
+++ mult-netbsd-3.1/sys/nfs/nfs_vnops.c	2007-11-18 14:10:51.000000000 +0000
@@ -475,12 +475,14 @@
 		if (np->n_rcred != NULL)
 			crfree(np->n_rcred);
 		np->n_rcred = ap->a_cred;
+		/* FIXME - instances */
 		crhold(np->n_rcred);
 	}
 	if (ap->a_mode & FWRITE) {
 		if (np->n_wcred != NULL)
 			crfree(np->n_wcred);
 		np->n_wcred = ap->a_cred;
+		/* FIXME - instances */
 		crhold(np->n_wcred);
 	}
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/Makefile mult-netbsd-3.1/sys/sys/Makefile
--- NetBSD-3.1/sys/sys/Makefile	2005-01-02 16:08:30.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/Makefile	2007-11-15 13:34:52.000000000 +0000
@@ -13,6 +13,7 @@
 	fcntl.h fdio.h featuretest.h file.h filedesc.h filio.h \
 	float_ieee754.h fstypes.h gmon.h hash.h \
 	ieee754.h inttypes.h ioccom.h ioctl.h ioctl_compat.h ipc.h \
+	inst.h \
 	joystick.h \
 	kcore.h kgdb.h ksem.h ksyms.h ktrace.h \
 	lkm.h localedef.h lock.h lockf.h lwp.h \
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/event.h mult-netbsd-3.1/sys/sys/event.h
--- NetBSD-3.1/sys/sys/event.h	2005-02-26 22:25:34.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/event.h	2007-11-26 15:08:35.000000000 +0000
@@ -199,14 +199,15 @@
 };
 
 struct proc;
+struct inst;
 
 void	knote(struct klist *, long);
 void	knote_remove(struct proc *, struct klist *);
 void	knote_fdclose(struct proc *, int);
 int 	kqueue_register(struct kqueue *, struct kevent *, struct proc *);
 
-int	kfilter_register(const char *, const struct filterops *, int *);
-int	kfilter_unregister(const char *);
+int	kfilter_register(struct inst *, const char *, const struct filterops *, int *);
+int	kfilter_unregister(struct inst *, const char *);
 
 int	filt_seltrue(struct knote *, long);
 int	seltrue_kqfilter(dev_t, struct knote *);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/file.h mult-netbsd-3.1/sys/sys/file.h
--- NetBSD-3.1/sys/sys/file.h	2005-02-12 23:14:03.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/file.h	2007-11-14 16:00:24.000000000 +0000
@@ -149,9 +149,7 @@
 #define	FOF_UPDATE_OFFSET	0x01	/* update the file offset */
 
 LIST_HEAD(filelist, file);
-extern struct filelist	filehead;	/* head of list of open files */
 extern int		maxfiles;	/* kernel limit on # of open files */
-extern int		nfiles;		/* actual number of open files */
 
 extern const struct fileops vnops;	/* vnode operations for files */
 
@@ -167,7 +165,15 @@
 
 int	fsetown(struct proc *, pid_t *, int, const void *);
 int	fgetown(struct proc *, pid_t, int, void *);
-void	fownsignal(pid_t, int, int, int, void *);
+
+/*
+ * Send signal to descriptor owner, either process or process group,
+ * within the instance context i.
+ */
+void
+fownsignal(struct inst *i, pid_t pgid, int signo, 
+		int code, int band, void *fdescdata);
+
 
 int	fdclone(struct proc *, struct file *, int, int, const struct fileops *,
     void *);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/filedesc.h mult-netbsd-3.1/sys/sys/filedesc.h
--- NetBSD-3.1/sys/sys/filedesc.h	2004-06-10 07:15:23.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/filedesc.h	2007-11-18 14:10:51.000000000 +0000
@@ -135,7 +135,7 @@
 int	falloc(struct proc *, struct file **, int *);
 void	ffree(struct file *);
 struct filedesc *fdcopy(struct proc *);
-struct filedesc *fdinit(struct proc *);
+struct filedesc *fdinit(void);
 void	fdshare(struct proc *, struct proc *);
 void	fdunshare(struct proc *);
 void	fdinit1(struct filedesc0 *);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/inst.h mult-netbsd-3.1/sys/sys/inst.h
--- NetBSD-3.1/sys/sys/inst.h	1970-01-01 01:00:00.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/inst.h	2007-12-19 13:35:20.000000000 +0000
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2007 Kristaps Dzonsons <kristaps.dzonsons@latnet.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
+
+/*
+ * The user-land component of this is very much under development.  The
+ * following few structures are used in the instctl() system call in
+ * order to control underlying instances.
+ */
+
+/*
+ * The following define instance states (i_state).
+ */
+
+#define INST_INIT	(0)	/* Doesn't have init(8). */
+#define INST_RUNNING	(1)	/* Running (has init(8)). */
+#define INST_EXITING	(2)	/* Exited & waiting on init(8). */
+#define INST_REAPED	(3)	/* Exited & waiting for reap. */
+
+
+struct instctl_create 
+{
+	const char	*root;	/* The chroot() (XXX - temporary). */
+};
+
+struct instctl_kill 
+{
+	unsigned int	uuid;	/* The target instance's uuid. */
+	int		sig;	/* Which signal to send. */
+#define IC_KILLSLOW	0x00	/* SIGTERM to instinit(8) */
+#define IC_KILLFAST	0x01	/* SIGKILL to instinit(8) */
+};
+
+struct instctl 
+{
+	int		ic_op;	/* Operation to perform. */
+#define IC_CREATE	0x00	/* Create an instance. */
+#define IC_DEBUG	0x01	/* Configure debugging. */
+#define IC_KILL		0x02	/* Kill an instance. */
+	union {
+		struct instctl_create ic_create;
+		int	ic_debug;
+#define IC_NONE		0x00	/* No debugging messages. */
+#define IC_ALLOC	0x01	/* Instance alloc/free. */
+#define IC_REFCNT	0x02	/* Change to refcount. */
+#define IC_SYSCALL	0x04	/* Report inst syscalls. */
+#define IC_DAEMON	0x05	/* instdaemon(9) reports. */
+#define IC_ALL		0xffff	/* All debugging messages. */
+		struct instctl_kill ic_kill;
+	} ic_data;
+};
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int	instctl(const struct instctl *);
+
+__END_DECLS
+
+#ifdef _KERNEL
+
+MALLOC_DECLARE(M_INST);
+
+typedef struct inst_acct	*inst_acct_t;
+typedef struct inst_res		*inst_res_t;
+typedef struct inst_proc	*inst_proc_t;
+typedef struct inst_pipe	*inst_pipe_t;
+typedef struct inst_kevt	*inst_kevt_t;
+typedef struct inst_fork	*inst_fork_t;
+typedef struct inst_ktrc	*inst_ktrc_t;
+
+#include <sys/proc.h>
+#include <sys/lwp.h>
+#include <sys/file.h>
+#include <sys/lock.h>
+
+LIST_HEAD(instlist, inst);
+
+/* Maximum number of instances (XXX - hack). */
+#define INST_MAX	(256)
+
+/* Kernel structure describing an instance context.  This must contain
+ * all values required for instance processing.  Locking is done on a
+ * per-structure level using the i_lock value.  All modifications must
+ * be appropriately locked. */
+struct inst 
+{
+	uint		i_uuid; 	/* Global, unique id. */
+	uint		i_refcnt;	/* Reference counter. */
+	struct inst	*i_parent;	/* Parent inst (or NULL). */
+	struct simplelock i_lock;	/* Lock for all subs. */
+	char		i_host[MAXHOSTNAMELEN]; /* Hostname. */
+	char		i_domain[MAXHOSTNAMELEN]; /* Domainname. */
+	LIST_ENTRY(inst) i_list;	/* List of all instances. */
+
+	char		i_root[MAXPATHLEN]; /* XXX - hack */
+
+	int		i_state;	/* State of the instance. */
+
+	inst_acct_t	i_acct;
+	inst_res_t	i_res;
+	inst_proc_t	i_proc;
+	inst_pipe_t	i_pipe;
+	inst_kevt_t	i_kevt;
+	inst_fork_t	i_fork;
+	inst_ktrc_t	i_ktrc;
+
+	/*
+	 * These are counters for all entities contained by this
+	 * instance.  The instance should be locked in order to modify
+	 * these values (i_nprocs needs the proclist lock, too).
+	 */
+
+	int		i_npipes;  	/* Number of allocated pipes. */
+	int		i_ncreds;	/* Number of allocated creds. */
+	int		i_nprocs;	/* Number of allocated procs. */
+	int		i_nsess;	/* Number of allocated sesss. */
+	int		i_nfiles;	/* Number of allocated files. */
+	int		i_nsocks;	/* Number of allocated sockets. */
+
+	/*
+	 * Processes contained within the instance.  When modifying ANY
+	 * of these, the process lock must be acquired.
+	 */
+
+	struct lock	i_proclist_lock;/* Lock for process lists. */
+	struct lwplist	i_alllwp;	/* List of all lwps. */
+	struct proclist	i_allproc;	/* List of all procs. */
+	struct proclist	i_zombproc;	/* List of zombie procs. */
+	struct proclist_desc i_proclists[3];
+	struct proc	*i_initproc;	/* Link to init(8) process. */
+
+	/*
+	 * Files contained within the instance.  When modifying ANY of
+	 * these, the file lock must be acquired.
+	 */
+
+	struct filelist	i_filehead;	/* List of allocated files. */
+	struct simplelock i_filelist_lock; /* Lock for file list. */
+};
+
+
+void		instdaemon(void *);
+__volatile int	instdaemon_sem;
+
+/*
+ * Access of the global instance context.
+ */
+struct instlist	allinst;
+
+/*
+ * NOTE that calling this function will put a hold on the instance so
+ * that it doesn't exit between executing this function and getting the
+ * result.  This obviously isn't the case if the instance couldn't be
+ * found and NULL is returned.
+ */
+struct inst	*inst_lookup(u_int uuid);
+
+/*
+ * Locking of the various parts and sub-parts.
+ */
+void		instlist_lock_read(void);
+void		instlist_unlock_read(void);
+void		proclist_lock_read(struct inst *i);
+void		proclist_unlock_read(struct inst *);
+int		proclist_lock_write(struct inst *);
+void		proclist_unlock_write(struct inst *, int);
+
+/*
+ * Allocation and release of the actual instance structure.
+ */
+void		inst_init(void);
+#define	INST_WAIT	(0)
+#define INST_NOWAIT	(1)
+struct inst	*inst_alloc(int flags);
+
+/*
+ * Allocation and release of sub-structures.  These follow the semantics
+ * for malloc() and free() (in terms of flags).
+ */
+int		inst_res_alloc(inst_res_t *, int);
+int		inst_acct_alloc(inst_acct_t *, int);
+int		inst_proc_alloc(inst_proc_t *, int);
+int		inst_pipe_alloc(inst_pipe_t *, int);
+int		inst_kevt_alloc(inst_kevt_t *, int);
+int		inst_fork_alloc(inst_fork_t *, int);
+int		inst_ktrc_alloc(inst_ktrc_t *, int);
+
+void		inst_proc_free(inst_proc_t);
+void		inst_res_free(inst_res_t);
+void		inst_acct_free(inst_acct_t);
+void		inst_pipe_free(inst_pipe_t);
+void		inst_kevt_free(inst_kevt_t);
+void		inst_fork_free(inst_fork_t);
+void		inst_ktrc_free(inst_ktrc_t);
+
+/*
+ * Reference acquisition and release.
+ */
+void		inst_hold(struct inst *i);
+void		inst_release(struct inst *i);
+
+/*
+ * Possibly-deprecate these helper functions...
+ */
+void		inst_get_hostname(struct lwp *l, 
+			char *buf, size_t len);
+void		inst_get_phostname(struct proc *p,
+			char *buf, size_t len);
+int		inst_set_hostname(struct lwp *l, const char *buf);
+size_t		inst_get_hostnamelen(struct lwp *l);
+size_t		inst_get_phostnamelen(struct proc *p);
+int		inst_copyoutstr_hostname(struct lwp *l, 
+			void *uaddr, size_t len, size_t *done);
+int		inst_copyout_hostname(struct lwp *l, void *uaddr, 
+			size_t len);
+void		inst_get_domainname(struct lwp *l, char *buf, 
+			size_t len);
+void		inst_get_pdomainname(struct proc *l, char *buf, 
+			size_t len);
+int		inst_set_domainname(struct lwp *l, const char *buf);
+size_t		inst_get_domainnamelen(struct lwp *l);
+size_t		inst_get_pdomainnamelen(struct proc *p);
+
+#endif	/* _KERNEL */
+#endif	/* !_SYS_INST_H */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/kernel.h mult-netbsd-3.1/sys/sys/kernel.h
--- NetBSD-3.1/sys/sys/kernel.h	2003-10-02 13:14:00.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/kernel.h	2007-11-09 19:05:28.000000000 +0000
@@ -43,10 +43,6 @@
 /* Global variables for the kernel. */
 
 extern long hostid;
-extern char hostname[MAXHOSTNAMELEN];
-extern int hostnamelen;
-extern char domainname[MAXHOSTNAMELEN];
-extern int domainnamelen;
 
 extern volatile struct timeval mono_time;
 extern struct timeval boottime;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/lwp.h mult-netbsd-3.1/sys/sys/lwp.h
--- NetBSD-3.1/sys/sys/lwp.h	2006-04-07 13:27:23.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/lwp.h	2007-11-18 14:10:51.000000000 +0000
@@ -47,6 +47,10 @@
 #include <sys/queue.h>
 #include <sys/callout.h>
 
+
+LIST_HEAD(lwplist, lwp);
+
+
 struct	lwp {
 	struct	lwp *l_forw;		/* Doubly-linked run/sleep queue. */
 	struct	lwp *l_back;
@@ -54,6 +58,8 @@
 
 	struct proc *l_proc;	/* Process with which we are associated. */
 
+#define l_inst		l_proc->p_inst
+
 	LIST_ENTRY(lwp) l_sibling;	/* Entry on process's list of LWPs. */
 
 	struct cpu_info * __volatile l_cpu; /* CPU we're running on if
@@ -92,12 +98,12 @@
 	struct	mdlwp l_md;	/* Any machine-dependent fields. */
 };
 
-LIST_HEAD(lwplist, lwp);		/* a list of LWPs */
-
-extern struct lwplist alllwp;		/* List of all LWPs. */
+/*
+ * See lwp_pool.
+ */
+extern struct pool
+lwp_uc_pool;
 
-extern struct pool lwp_pool;		/* memory pool for LWPs */
-extern struct pool lwp_uc_pool;		/* memory pool for LWP startup args */
 
 extern struct lwp lwp0;			/* LWP for proc0 */
 
@@ -165,6 +171,7 @@
 void	cpu_switchto (struct lwp *, struct lwp *);
 #endif
 
+
 int newlwp(struct lwp *, struct proc *, vaddr_t, int /* XXX boolean_t */, int,
     void *, size_t, void (*)(void *), void *, struct lwp **);
 
@@ -176,7 +183,15 @@
 void	startlwp(void *);
 void	upcallret(struct lwp *);
 void	lwp_exit (struct lwp *);
-void	lwp_exit2 (struct lwp *);
+
+/*
+ * Release the memory resources of an LWP and put it back into the LWP
+ * pool.
+ */
+void
+lwp_exit2(struct lwp *lwp);
+
+
 struct lwp *proc_representative_lwp(struct proc *);
 inline int lwp_suspend(struct lwp *, struct lwp *);
 #endif	/* _KERNEL */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/pipe.h mult-netbsd-3.1/sys/sys/pipe.h
--- NetBSD-3.1/sys/sys/pipe.h	2005-02-03 19:20:01.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/pipe.h	2007-11-14 17:12:02.000000000 +0000
@@ -100,6 +100,7 @@
  * Two of these are linked together to produce bi-directional pipes.
  */
 struct pipe {
+	struct	inst *pipe_inst;	/* pipe owning instance */
 	struct	simplelock pipe_slock;	/* pipe mutex */
 	struct	lock pipe_lock;		/* long-term pipe lock */
 	struct	pipebuf pipe_buffer;	/* data storage */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/proc.h mult-netbsd-3.1/sys/sys/proc.h
--- NetBSD-3.1/sys/sys/proc.h	2006-04-07 13:31:52.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/proc.h	2007-12-16 14:56:45.000000000 +0000
@@ -53,20 +53,24 @@
 #include <sys/siginfo.h>
 #include <sys/event.h>
 
+
 /*
- * One structure allocated per session.
+ * One structure allocated per session.  Each session is associated with
+ * an instance.
  */
 struct session {
 	int		s_count;	/* Ref cnt; pgrps in session */
 	u_int		s_flags;
 #define	S_LOGIN_SET	1		/* s_login set in this session */
 	struct proc	*s_leader;	/* Session leader */
+	struct inst	*s_inst;	/* Instance of session */
 	struct vnode	*s_ttyvp;	/* Vnode of controlling terminal */
 	struct tty	*s_ttyp;	/* Controlling terminal */
 	char		s_login[MAXLOGNAME]; /* Setlogin() name */
 	pid_t		s_sid;		/* Session ID (pid of leader) */
 };
 
+
 /*
  * One structure allocated per process group.
  */
@@ -155,6 +159,7 @@
 
 	/* Substructures: */
 	struct pcred	*p_cred;	/* Process owner's identity */
+
 	struct filedesc	*p_fd;		/* Ptr to open files structure */
 	struct cwdinfo	*p_cwdi;	/* cdir/rdir/cmask info */
 	struct pstats	*p_stats;	/* Accounting/statistics (PROC ONLY) */
@@ -165,6 +170,8 @@
 	void		*p_ksems;	/* p1003.1b semaphores */
 
 #define	p_ucred		p_cred->pc_ucred
+#define p_inst 		p_ucred->cr_inst
+
 #define	p_rlimit	p_limit->pl_rlimit
 
 	int		p_exitsig;	/* signal to sent to parent on exit */
@@ -211,7 +218,6 @@
 
 	int		p_traceflag;	/* Kernel trace points */
 	void		*p_tracep;	/* Trace private data */
-	void		*p_systrace;	/* Back pointer to systrace */
 
 	struct vnode 	*p_textvp;	/* Vnode of executable */
 
@@ -297,7 +303,6 @@
 #define	P_NOCLDWAIT	0x00020000 /* No zombies if child dies */
 #define	P_32		0x00040000 /* 32-bit process (used on 64-bit kernels) */
 #define	P_INEXEC	0x00100000 /* Process is exec'ing and can't be traced */
-#define	P_SYSTRACE	0x00200000 /* Process system call tracing active */
 #define	P_CHTRACED	0x00400000 /* Child has been traced & reparented */
 #define	P_STOPFORK	0x00800000 /* Child will be stopped on fork(2) */
 #define	P_STOPEXEC	0x01000000 /* Will be stopped on exec(2) */
@@ -332,6 +337,17 @@
 	int		p_refcnt;	/* Number of references */
 };
 
+
+/*
+ * Put a pcred back into the pool.
+ */
+void
+pcred_free(struct pcred *p);
+
+struct pcred *
+pcred_alloc(void);
+
+
 LIST_HEAD(proclist, proc);		/* A list of processes */
 
 /*
@@ -403,91 +419,143 @@
 }
 #define	curproc	__curproc()
 
-extern struct proc	proc0;		/* Process slot for swapper */
-extern int		nprocs, maxproc; /* Current and max number of procs */
-
-/* Process list lock; see kern_proc.c for locking protocol details */
-extern struct lock	proclist_lock;
-
-extern struct proclist	allproc;	/* List of all processes */
-extern struct proclist	zombproc;	/* List of zombie processes */
-
-extern SLIST_HEAD(deadprocs, proc) deadprocs;	/* List of dead processes */
-extern struct simplelock deadproc_slock;
+extern struct proc	proc0;	/* Process slot for swapper */
+extern int		maxproc;/* Max number of procs (FIXME - instance) */
 
-extern struct proc	*initproc;	/* Process slots for init, pager */
+/* Forward declaration. */
+struct inst;
 
-extern const struct proclist_desc proclists[];
+/* Return NULL if no process by that name found. */
+struct proc 	*p_find(struct inst *, pid_t, uint);
+/* Return NULL if none found. */
+struct pgrp 	*pg_find(struct inst *, pid_t, uint);
 
-extern struct pool	pcred_pool;	/* Memory pool for pcreds */
-extern struct pool	plimit_pool;	/* Memory pool for plimits */
-extern struct pool 	pstats_pool;	/* memory pool for pstats */
-extern struct pool	rusage_pool;	/* Memory pool for rusages */
-extern struct pool	ptimer_pool;	/* Memory pool for ptimers */
-
-struct proc *p_find(pid_t, uint);	/* Find process by id */
-struct pgrp *pg_find(pid_t, uint);	/* Find process group by id */
 /* Flags values for p_find() and pg_find(). */
 #define PFIND_ZOMBIE		1	/* look for zombies as well */
 #define PFIND_LOCKED		2	/* proclist locked on entry */
 #define PFIND_UNLOCK_FAIL	4	/* unlock proclist on failure */
 #define PFIND_UNLOCK_OK		8	/* unlock proclist on success */
 #define PFIND_UNLOCK		(PFIND_UNLOCK_OK | PFIND_UNLOCK_FAIL)
-/* For source compatibility. but UNLOCK_OK gives a stale answer... */
-#define pfind(pid) p_find((pid), PFIND_UNLOCK)
-#define pgfind(pgid) pg_find((pgid), PFIND_UNLOCK)
 
+#define pfind(inst, pid) \
+	p_find((inst), (pid), PFIND_UNLOCK)
+
+#define pgfind(inst, pgid) \
+	pg_find((inst), (pgid), PFIND_UNLOCK)
+
+/* Forward-declaration. */
 struct simplelock;
-int	enterpgrp(struct proc *, pid_t, int);
-void	fixjobc(struct proc *, struct pgrp *, int);
-int	inferior(struct proc *, struct proc *);
-int	leavepgrp(struct proc *);
-void	sessdelete(struct session *);
-void	yield(void);
-struct lwp *chooselwp(void);
-void	pgdelete(struct pgrp *);
-void	procinit(void);
-void	resetprocpriority(struct proc *);
-void	suspendsched(void);
-int	ltsleep(const void *, int, const char *, int,
-	    __volatile struct simplelock *);
-void	wakeup(const void *);
-void	wakeup_one(const void *);
-void	exit1(struct lwp *, int);
-int	find_stopped_child(struct proc *, pid_t, int, struct proc **);
-struct proc *proc_alloc(void);
-void	proc0_insert(struct proc *, struct lwp *, struct pgrp *, struct session *);
-void	proc_free(struct proc *);
-void	proc_free_mem(struct proc *);
+
+/* Move p to a new or existing process group (and session).  If we are
+ * creating a new pgrp, the pgid should equal the calling process' pid.
+ * It's only valid to enter a process group that is in the session of
+ * the process.  mksess should be set if we are creating a pgroup. */
+int		enterpgrp(struct proc *, pid_t, int);
+
+/* Adjust pgrp jobc counters when specified process changes process
+ * group.  We count the number of processes in each process gruop that
+ * "qualify" the group for terminal job control (those with a parent in
+ * a different process group of the same session).  If that count
+ * reaches 0, the process group becomes orphaned.  Check both the
+ * specified process' process group and that of its children.  If ent is
+ * 0, p is leaving pgrp; if it's 1, it's entering.  This must be called
+ * with the i_proclist_lock held. */
+void		fixjobc(struct proc *, struct pgrp *, int);
+
+/* Is p below q in the process hierarchy?  Returns 0 if not (or not in
+ * the same instance), 1 if they are (XXX - name misleading). */
+int		inferior(struct proc *, struct proc *);
+
+/* If the process group is empty, also deletes the process group. */
+int		leavepgrp(struct proc *);
+
+/* Delete a session (the session has no members). */
+void		sessdelete(struct session *s);
+
+void		yield(void);
+struct lwp 	*chooselwp(void);
+void		pgdelete(struct pgrp *);
+void		resetprocpriority(struct proc *);
+void		suspendsched(void);
+int		ltsleep(const void *, int, const char *, int,
+			__volatile struct simplelock *);
+void		wakeup(const void *);
+void		wakeup_one(const void *);
+void		exit1(struct lwp *, int);
+int		find_stopped_child(struct proc *, pid_t, 
+			int, struct proc **);
+
+
+/* Allocate a process from within an instance. */
+struct proc 	*proc_alloc(struct inst *);
+
+/*
+ * Set entry for process 0 (init).
+ */
+void
+proc0_insert(struct proc *p0, struct lwp *l0, 
+		struct pgrp *pg0, struct session *s0);
+
+
+/*
+ * Frees last resources of a process.  Puts process back into available
+ * process pool.
+ */
+void
+proc_free_mem(struct inst *i, struct proc *p);
+
+
+void	proc_free(struct proc *p);
 void	exit_lwps(struct lwp *l);
 int	fork1(struct lwp *, int, int, void *, size_t,
-	    void (*)(void *), void *, register_t *, struct proc **);
+		void (*)(void *), void *, register_t *, 
+		struct proc **);
+int	forkinst1(void (*)(void *), void *, const char *, 
+		register_t *, struct proc **);
 void	rqinit(void);
 int	groupmember(gid_t, const struct ucred *);
-int	pgid_in_session(struct proc *, pid_t);
+
+
+/*
+ * Check if process group pgid is in session of process p.  Treats
+ * negative ids as process ids.  Used to validate TIOCSPGRP requests.
+ * Returns EINVAL if pgid doesn't exist or EPERM if the sessions are
+ * invalid, or 0 on success.
+ */
+int
+pgid_in_session(struct proc *p, pid_t pgid);
+
+
 #ifndef cpu_idle
 void	cpu_idle(void);
 #endif
-void	cpu_exit(struct lwp *);
+
+/*
+ * Machdep routine to completely free up a lwp from an instance.
+ */
+void
+cpu_exit(struct lwp *);
+
+
 void	cpu_lwp_fork(struct lwp *, struct lwp *, void *, size_t,
 	    void (*)(void *), void *);
 #ifndef cpu_lwp_free
 void	cpu_lwp_free(struct lwp *, int);
 #endif
-
 void	child_return(void *);
-
 int	proc_isunder(struct proc *, struct proc *);
 void	proc_stop(struct proc *, int);
 
-void	proclist_lock_read(void);
-void	proclist_unlock_read(void);
-int	proclist_lock_write(void);
-void	proclist_unlock_write(int);
-void	p_sugid(struct proc *);
 
-int	proclist_foreach_call(struct proclist *,
-    int (*)(struct proc *, void *arg), void *);
+
+/*
+ * Mark a process as suid/sgid and reset some values (XXX) to their
+ * defaults.
+ */
+void
+p_sugid(struct proc *p);
+
+
 static __inline struct proc *_proclist_skipmarker(struct proc *);
 
 static __inline struct proc *
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/ras.h mult-netbsd-3.1/sys/sys/ras.h
--- NetBSD-3.1/sys/sys/ras.h	2004-07-19 04:12:31.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/ras.h	2007-11-11 13:27:03.000000000 +0000
@@ -55,7 +55,6 @@
 
 #ifdef _KERNEL
 
-struct pool;
 struct proc;
 
 caddr_t ras_lookup(struct proc *, caddr_t);
@@ -63,8 +62,6 @@
 int ras_fork(struct proc *, struct proc *);
 int ras_purgeall(struct proc *);
 
-extern struct pool ras_pool;
-
 #else
 
 #ifndef	RAS_DECL
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/resourcevar.h mult-netbsd-3.1/sys/sys/resourcevar.h
--- NetBSD-3.1/sys/sys/resourcevar.h	2005-02-03 19:20:02.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/resourcevar.h	2007-11-18 14:10:51.000000000 +0000
@@ -76,6 +76,7 @@
 	struct simplelock p_slock;	/* mutex for p_refcnt */
 };
 
+
 /* add user profiling from AST */
 #define	ADDUPROF(p)							\
 	do {								\
@@ -96,10 +97,12 @@
 	rlim_t	ui_sbsize;	/* socket buffer size */
 
 };
-#define	UIHASH(uid)	(&uihashtbl[(uid) & uihash])
-extern LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
-extern u_long uihash;		/* size of hash table - 1 */
-int       chgproccnt(uid_t, int);
+
+
+LIST_HEAD(uihashhead, uidinfo);
+
+
+int       chgproccnt(struct inst *i, uid_t, int);
 int       chgsbsize(uid_t, u_long *, u_long, rlim_t);
 
 extern char defcorename[];
@@ -107,11 +110,42 @@
 void	 addupc_task(struct proc *, u_long, u_int);
 void	 calcru(struct proc *, struct timeval *, struct timeval *,
 	    struct timeval *);
-struct plimit *limcopy(struct plimit *);
-void limfree(struct plimit *);
+
+
+/*
+ * Make a copy of the plimit structure.  We share these structures
+ * copy-on-write after fork and copy when a limit has changed. XXX -
+ * should be limdup.
+ */
+struct plimit *
+limcopy(struct plimit *lim);
+
+
+/*
+ * Dereference a limit (and possibly put it back in the pool).
+ */
+void
+limfree(struct plimit *lim);
+
+
+
 void	ruadd(struct rusage *, struct rusage *);
-struct	pstats *pstatscopy(struct pstats *);
-void 	pstatsfree(struct pstats *);
+
+
+/*
+ * Create a new pstats from an old.  XXX - should be pstatsdup.
+ */
+struct pstats *
+pstatscopy(struct pstats *ps);
+
+
+/*
+ * Put a pstats back into the pool.
+ */
+void
+pstatsfree(struct pstats *ps);
+
+
 extern rlim_t maxdmap;
 extern rlim_t maxsmap;
 #endif
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/savar.h mult-netbsd-3.1/sys/sys/savar.h
--- NetBSD-3.1/sys/sys/savar.h	2005-10-21 18:39:40.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/savar.h	2007-11-13 18:31:33.000000000 +0000
@@ -69,6 +69,14 @@
 	union sau_state	sau_interrupted;
 };
 
+
+/*
+ * Global pool of supdata_upcall memory.
+ */
+extern struct pool
+saupcall_pool;
+
+
 #define	SAU_FLAG_DEFERRED_EVENT		0x1
 #define	SAU_FLAG_DEFERRED_INTERRUPTED	0x2
 
@@ -115,11 +123,6 @@
 
 #define SA_FLAG_ALL	SA_FLAG_PREEMPT
 
-extern struct pool sadata_pool;		/* memory pool for sadata structures */
-extern struct pool saupcall_pool;	/* memory pool for pending upcalls */
-extern struct pool sastack_pool;	/* memory pool for sastack structs */
-extern struct pool savp_pool;		/* memory pool for sadata_vp structures */
-
 #ifdef _KERNEL
 #include <sys/mallocvar.h>
 
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/select.h mult-netbsd-3.1/sys/sys/select.h
--- NetBSD-3.1/sys/sys/select.h	2005-03-19 13:23:15.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/select.h	2007-11-19 14:26:40.000000000 +0000
@@ -48,6 +48,7 @@
 struct selinfo {
 	struct klist	sel_klist;	/* knotes attached to this selinfo */
 	pid_t		sel_pid;	/* process to be notified */
+	u_int		sel_iid;	/* process instance uuid */
 	uint8_t		sel_collision;	/* non-zero if a collision occurred */
 };
 #endif /* !_NETBSD_SOURCE_ */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/signalvar.h mult-netbsd-3.1/sys/sys/signalvar.h
--- NetBSD-3.1/sys/sys/signalvar.h	2005-10-21 18:39:40.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/signalvar.h	2007-11-10 19:27:12.000000000 +0000
@@ -142,15 +142,58 @@
 int	coredump(struct lwp *, const char *);
 int	coredump_netbsd(struct lwp *, struct vnode *, struct ucred *);
 void	execsigs(struct proc *);
-void	gsignal(int, int);
-void	kgsignal(int, struct ksiginfo *, void *);
+
+/*
+ * See kgsignal().
+ */
+void
+gsignal(struct inst *i, int pgid, int signum);
+
+/*
+ * Delivers a signal specification to a process group in instance i.
+ */
+void
+kgsignal(struct inst *i, int pgid, struct ksiginfo *ksi, void *data);
+
+
+/*
+ * Calls through to kpgsignal().  See kpgsignal() for caveats. 
+ */
+void
+pgsignal(struct pgrp *pgrp, int sig, int checktty);
+
+
+/*
+ * Deliver a signal to a process group.  This DOES NOT check for
+ * instance correctness (there's no "caller").  If checktty is 1, limit
+ * to members who have a controlling terminal.
+ */
+void
+kpgsignal(struct pgrp *pgrp, struct ksiginfo *ks, 
+		void *data, int checktty);
+
+
 int	issignal(struct lwp *);
-void	pgsignal(struct pgrp *, int, int);
-void	kpgsignal(struct pgrp *, struct ksiginfo *, void *, int);
 void	postsig(int);
 void	psignal1(struct proc *, int, int);
-void	kpsignal1(struct proc *, struct ksiginfo *, void *, int);
-#define	kpsignal(p, ksi, data)		kpsignal1((p), (ksi), (data), 1)
+
+
+/*
+ * This delivers a signal to a process.  Note that this DOES NOT check
+ * for instance correctness (there's no "caller"). 
+ */
+void
+kpsignal1(struct proc *p, struct ksiginfo *ks, void *data, int dolock);
+
+
+/*
+ * Calls through to kpsignal1() and requests locking.  See kpsignal1()
+ * for caveats.
+ */
+#define	kpsignal(p, ksi, data) \
+	kpsignal1((p), (ksi), (data), 1)
+
+
 #define	psignal(p, sig)			psignal1((p), (sig), 1)
 #define	sched_psignal(p, sig)		psignal1((p), (sig), 0)
 void	siginit(struct proc *);
@@ -158,7 +201,16 @@
 void	sigexit(struct lwp *, int);
 void	killproc(struct proc *, const char *);
 void	setsigvec(struct proc *, int, struct sigaction *);
-int	killpg1(struct proc *, struct ksiginfo *, int, int);
+
+
+/*
+ * Common code for process, group, or broadcast kill.  cp is the calling
+ * process.
+ */
+int
+killpg1(struct proc *cp, struct ksiginfo *ks, int pgid, int all);
+
+
 struct lwp *proc_unstop(struct proc *p);
 
 int	sigaction1(struct proc *, int, const struct sigaction *,
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/socketvar.h mult-netbsd-3.1/sys/sys/socketvar.h
--- NetBSD-3.1/sys/sys/socketvar.h	2004-09-03 19:14:09.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/socketvar.h	2007-11-15 14:48:25.000000000 +0000
@@ -131,6 +131,7 @@
 					struct mbuf **, int *);
 	struct mowner	*so_mowner;	/* who owns mbufs for this socket */
 	uid_t		so_uid;		/* who opened the socket */
+	struct inst	*so_inst;	/* ...and from which instance */
 };
 
 #define	SB_EMPTY_FIXUP(sb)						\
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/syscall.h mult-netbsd-3.1/sys/sys/syscall.h
--- NetBSD-3.1/sys/sys/syscall.h	2005-02-27 00:03:25.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/syscall.h	2007-11-15 13:34:52.000000000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.h,v 1.156 2005/02/27 00:03:25 perry Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call numbers.
@@ -1025,5 +1025,8 @@
 /* syscall: "pollts" ret: "int" args: "struct pollfd *" "u_int" "const struct timespec *" "const sigset_t *" */
 #define	SYS_pollts	374
 
-#define	SYS_MAXSYSCALL	375
+/* syscall: "instctl" ret: "int" args: "struct instctl *" */
+#define	SYS_instctl	375
+
+#define	SYS_MAXSYSCALL	376
 #define	SYS_NSYSENT	512
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/syscallargs.h mult-netbsd-3.1/sys/sys/syscallargs.h
--- NetBSD-3.1/sys/sys/syscallargs.h	2005-02-27 00:03:25.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/syscallargs.h	2007-11-15 13:34:52.000000000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscallargs.h,v 1.138 2005/02/27 00:03:25 perry Exp $ */
+/* $NetBSD$ */
 
 /*
  * System call argument lists.
@@ -1588,6 +1588,10 @@
 	syscallarg(const sigset_t *) mask;
 };
 
+struct sys_instctl_args {
+	syscallarg(struct instctl *) ctl;
+};
+
 /*
  * System call prototypes.
  */
@@ -2251,4 +2255,6 @@
 
 int	sys_pollts(struct lwp *, void *, register_t *);
 
+int	sys_instctl(struct lwp *, void *, register_t *);
+
 #endif /* _SYS__SYSCALLARGS_H_ */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/sysctl.h mult-netbsd-3.1/sys/sys/sysctl.h
--- NetBSD-3.1/sys/sys/sysctl.h	2005-06-10 16:10:51.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/sysctl.h	2007-12-17 11:11:39.000000000 +0000
@@ -269,7 +269,11 @@
 #define	KERN_BUF		76	/* struct: buffers */
 #define	KERN_FILE2		77	/* struct: file entries */
 #define	KERN_VERIEXEC		78	/* node: verified exec */
-#define	KERN_MAXID		79	/* number of valid kern ids */
+#define	KERN_INST		79	/* struct: instance entries */
+#define	KERN_PROC2_INST		80	/* struct: instance process entries */
+#define	KERN_LWP_INST		81	/* struct: instance lwp entries */
+#define	KERN_PROC_ARGS_INST	82	/* struct: instance process argv/env */
+#define	KERN_MAXID		83	/* number of valid kern ids */
 
 
 #define	CTL_KERN_NAMES { \
@@ -368,6 +372,12 @@
 #define	KERN_PROC_RGID		 8	/* by real gid */
 
 /*
+ * KERN_INST subtypes.
+ */
+#define KERN_INST_ALL		0	/* Everything. */
+#define KERN_INST_CUR		1	/* The current instance. */
+
+/*
  * KERN_PROC_TTY sub-subtypes
  */
 #define	KERN_PROC_TTY_NODEV	NODEV		/* no controlling tty */
@@ -429,6 +439,21 @@
 	u_int32_t	__bits[4];
 } ki_sigset_t;
 
+
+struct kinfo_inst {
+	u_int32_t	i_uuid;
+	u_int32_t	i_refcnt;
+	u_int32_t	i_state;
+	char		i_host[MAXHOSTNAMELEN];
+	char		i_domain[MAXHOSTNAMELEN];
+	u_int32_t	i_nprocs;
+	u_int32_t	i_nfiles;
+	u_int32_t	i_nsocks;
+	u_int32_t	i_npipes;
+	u_int32_t	i_ncreds;
+	u_int32_t	i_nsess;
+};
+
 struct kinfo_proc2 {
 	u_int64_t p_forw;		/* PTR: linked run/sleep queue. */
 	u_int64_t p_back;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/systrace.h mult-netbsd-3.1/sys/sys/systrace.h
--- NetBSD-3.1/sys/sys/systrace.h	2006-10-16 21:36:50.000000000 +0100
+++ mult-netbsd-3.1/sys/sys/systrace.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,222 +0,0 @@
-/*	$NetBSD: systrace.h,v 1.12.14.3 2006/10/16 20:36:50 ghen Exp $	*/
-
-/*
- * Copyright 2002 Niels Provos <provos@citi.umich.edu>
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by Niels Provos.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SYSTRACE_H_
-#define _SYSTRACE_H_
-
-#include <sys/select.h>
-#include <sys/ioccom.h>
-#include <sys/lock.h>
-
-#define SYSTR_EMULEN	8	/* sync with sys proc */
-
-struct str_msg_emul {
-	char emul[SYSTR_EMULEN];
-};
-
-struct str_msg_ugid {
-	uid_t uid;
-	gid_t gid;
-};
-
-#define SYSTR_MAX_POLICIES	64
-#define SYSTR_MAXARGS		64
-#define SYSTR_MAXFNAME		8
-#define SYSTR_MAXREPLEN		2048
-
-struct str_msg_ask {
-	int32_t code;
-	int32_t argsize;
-	register_t args[SYSTR_MAXARGS];
-	register_t rval[2];
-	int32_t result;
-};
-
-/* Queued on fork or exit of a process */
-
-struct str_msg_child {
-	pid_t new_pid;
-};
-
-#define SYSTR_MSG_ASK		1
-#define SYSTR_MSG_RES		2
-#define SYSTR_MSG_EMUL		3
-#define SYSTR_MSG_CHILD		4
-#define SYSTR_MSG_UGID		5
-#define SYSTR_MSG_POLICYFREE	6
-
-#define SYSTR_MSG_NOPROCESS(x) \
-	((x)->msg.msg_type == SYSTR_MSG_CHILD || \
-	 (x)->msg.msg_type == SYSTR_MSG_POLICYFREE)
-
-struct str_message {
-	int32_t msg_type;
-	pid_t msg_pid;
-	u_int16_t msg_seqnr;	/* answer has to match seqnr */
-	int16_t msg_policy;
-	union {
-		struct str_msg_emul msg_emul;
-		struct str_msg_ugid msg_ugid;
-		struct str_msg_ask msg_ask;
-		struct str_msg_child msg_child;
-	} msg_data;
-};
-
-struct str_process;
-struct str_msgcontainer {
-	TAILQ_ENTRY(str_msgcontainer) next;
-	struct str_process *strp;
-
-	struct str_message msg;
-};
-
-
-struct systrace_answer {
-	pid_t stra_pid;
-	u_int16_t stra_seqnr;
-	int16_t reserved;
- 	uid_t stra_seteuid;	/* elevated privileges for system call */
- 	uid_t stra_setegid;
-	int32_t stra_policy;
-	int32_t stra_error;
-	int32_t stra_flags;
-};
-
-#define SYSTR_READ		1
-#define SYSTR_WRITE		2
-
-struct systrace_io {
-	pid_t strio_pid;
-	int32_t strio_op;
-	void *strio_offs;
-	void *strio_addr;
-	size_t strio_len;
-};
-
-#define SYSTR_POLICY_NEW	1
-#define SYSTR_POLICY_ASSIGN	2
-#define SYSTR_POLICY_MODIFY	3
-
-struct systrace_policy {
-	int32_t strp_op;
-	int32_t strp_num;
-	union {
-		struct {
-			int16_t code;
-			int16_t policy;
-		} assign;
-		pid_t pid;
-		int32_t maxents;
-	} strp_data;
-};
-
-#define strp_pid	strp_data.pid
-#define strp_maxents	strp_data.maxents
-#define strp_code	strp_data.assign.code
-#define strp_policy	strp_data.assign.policy
-
-#define SYSTR_NOLINKS	1
-
-struct systrace_replace {
-	pid_t strr_pid;
-	u_int16_t strr_seqnr;
-	int16_t reserved;
-	int32_t strr_nrepl;
-	caddr_t	strr_base;	/* Base memory */
-	size_t strr_len;	/* Length of memory */
-	int32_t strr_argind[SYSTR_MAXARGS];
-	size_t strr_off[SYSTR_MAXARGS];
-	size_t strr_offlen[SYSTR_MAXARGS];
-	int32_t strr_flags[SYSTR_MAXARGS];
-};
-
-#define STRIOCATTACH	_IOW('s', 101, pid_t)
-#define STRIOCDETACH	_IOW('s', 102, pid_t)
-#define STRIOCANSWER	_IOW('s', 103, struct systrace_answer)
-#define STRIOCIO	_IOWR('s', 104, struct systrace_io)
-#define STRIOCPOLICY	_IOWR('s', 105, struct systrace_policy)
-#define STRIOCGETCWD	_IOW('s', 106, pid_t)
-#define STRIOCRESCWD	_IO('s', 107)
-#define STRIOCREPORT	_IOW('s', 108, pid_t)
-#define STRIOCREPLACE	_IOW('s', 109, struct systrace_replace)
-
-#define SYSTR_POLICY_ASK	0
-#define SYSTR_POLICY_PERMIT	1
-#define SYSTR_POLICY_NEVER	2
-
-#define SYSTR_FLAGS_RESULT	0x001
-#define SYSTR_FLAGS_SETEUID	0x002
-#define SYSTR_FLAGS_SETEGID	0x004
-
-#ifdef _KERNEL
-#include <sys/namei.h>
-
-/* XXX: these shouldn't be here. */
-#define SET(t, f)	((t) |= (f))
-#define	ISSET(t, f)	((t) & (f))
-#define	CLR(t, f)	((t) &= ~(f))
-
-struct fsystrace {
-	struct lock lock;
-	struct selinfo si;
-
-	TAILQ_HEAD(strprocessq, str_process) processes;
-	size_t nprocesses;
-
-	TAILQ_HEAD(strpolicyq, str_policy) policies;
-
-	TAILQ_HEAD(strmessageq, str_msgcontainer) messages;
-
-	size_t npolicynr;
-	size_t npolicies;
-
-	int issuser;
-	uid_t p_ruid;
-	gid_t p_rgid;
-
-	/* cwd magic */
-	pid_t fd_pid;
-	struct vnode *fd_cdir;
-	struct vnode *fd_rdir;
-};
-
-/* Internal prototypes */
-
-int systrace_enter(struct proc *, register_t, void *);
-void systrace_namei(struct nameidata *);
-void systrace_exit(struct proc *, register_t, void *, register_t [], int);
-void systrace_sys_exit(struct proc *);
-void systrace_sys_fork(struct proc *, struct proc *);
-void systrace_init(void);
-
-#endif /* _KERNEL */
-#endif /* !_SYSTRACE_H_ */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/time.h mult-netbsd-3.1/sys/sys/time.h
--- NetBSD-3.1/sys/sys/time.h	2005-02-26 22:25:34.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/time.h	2007-11-13 18:31:33.000000000 +0000
@@ -192,6 +192,11 @@
 	struct proc *pt_proc;
 };
 
+
+extern struct pool
+ptimer_pool;
+
+
 #define pt_ch	pt_data.pt_ch
 #define pt_list	pt_data.pt_nonreal.pt_list
 #define pt_active	pt_data.pt_nonreal.pt_active
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/tprintf.h mult-netbsd-3.1/sys/sys/tprintf.h
--- NetBSD-3.1/sys/sys/tprintf.h	2005-02-03 19:20:02.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/tprintf.h	2007-11-12 16:59:26.000000000 +0000
@@ -34,14 +34,38 @@
 #ifndef _SYS_TPRINF_H_
 #define _SYS_TPRINF_H_
 
+/*
+ * Note that all of these are documented in the kernel manual pages;
+ * what follows are minimal explanations.
+ */
+
 #ifdef _KERNEL
+
 typedef struct session *tpr_t;
 
-tpr_t	tprintf_open(struct proc *);
-void	tprintf_close(tpr_t);
+/*
+ * Open a channel to the process's (session's) terminal.  This holds a
+ * reference to both the session and the instance.  Returns NULL if the
+ * process cannot be printed to.
+ */
+tpr_t
+tprintf_open(struct proc *);
+
+
+/*
+ * Close a channel opened with tprintf_open().
+ */
+void
+tprintf_close(tpr_t);
+
+
+/*
+ * Write to a channel opened with tprintf_open().
+ */
+void
+tprintf(tpr_t, const char *fmt, ...)
+	__attribute__((__format__(__printf__,2,3)));
 
-void	tprintf(tpr_t, const char *fmt, ...)
-    __attribute__((__format__(__printf__,2,3)));
 #endif /* _KERNEL */
 
 #endif /* _SYS_TPRINF_H_ */
diff -r -u -N --exclude CVS NetBSD-3.1/sys/sys/ucred.h mult-netbsd-3.1/sys/sys/ucred.h
--- NetBSD-3.1/sys/sys/ucred.h	2005-02-26 22:25:34.000000000 +0000
+++ mult-netbsd-3.1/sys/sys/ucred.h	2007-11-23 10:17:20.000000000 +0000
@@ -49,6 +49,9 @@
 	gid_t		cr_groups[NGROUPS];	/* groups */
 };
 
+/* Forward declaration. */
+struct inst;
+
 struct ucred {
 	struct simplelock cr_lock;		/* mutex for ref count */
 	u_int32_t	cr_ref;			/* reference count */
@@ -57,6 +60,7 @@
 	gid_t		cr_gid;			/* effective group id */
 	u_int32_t	cr_ngroups;		/* number of groups */
 	gid_t		cr_groups[NGROUPS];	/* groups */
+	struct inst	*cr_inst;
 };
 
 #define NOCRED ((struct ucred *)-1)	/* no credential available */
@@ -86,8 +90,9 @@
 
 struct ucred	*crcopy(struct ucred *);
 struct ucred	*crdup(const struct ucred *);
+struct ucred	*crdupinst(const struct ucred *);
 void		crfree(struct ucred *);
-struct ucred	*crget(void);
+struct ucred	*crget(struct inst *);
 int		suser(const struct ucred *, u_short *);
 void		crcvt(struct ucred *, const struct uucred *);
 int		crcmp(const struct ucred *, const struct uucred *);
diff -r -u -N --exclude CVS NetBSD-3.1/sys/ufs/ufs/ufs_quota.c mult-netbsd-3.1/sys/ufs/ufs/ufs_quota.c
--- NetBSD-3.1/sys/ufs/ufs/ufs_quota.c	2005-02-26 22:32:20.000000000 +0000
+++ mult-netbsd-3.1/sys/ufs/ufs/ufs_quota.c	2007-11-18 14:10:51.000000000 +0000
@@ -388,6 +388,7 @@
 	 * Save the credential of the process that turned on quotas.
 	 * Set up the time limits for this quota.
 	 */
+	/* FIXME - instances */
 	crhold(p->p_ucred);
 	ump->um_cred[type] = p->p_ucred;
 	ump->um_btime[type] = MAX_DQ_TIME;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/uvm/uvm_glue.c mult-netbsd-3.1/sys/uvm/uvm_glue.c
--- NetBSD-3.1/sys/uvm/uvm_glue.c	2005-12-06 20:00:12.000000000 +0000
+++ mult-netbsd-3.1/sys/uvm/uvm_glue.c	2007-11-23 10:17:20.000000000 +0000
@@ -83,6 +83,7 @@
 #include <sys/resourcevar.h>
 #include <sys/buf.h>
 #include <sys/user.h>
+#include <sys/inst.h>
 
 #include <uvm/uvm.h>
 
@@ -375,8 +376,7 @@
  */
 
 void
-uvm_proc_exit(p)
-	struct proc *p;
+uvm_proc_exit(struct proc *p)
 {
 	struct lwp *l = curlwp; /* XXX */
 	struct vmspace *ovm;
@@ -479,11 +479,11 @@
  */
 
 void
-uvm_scheduler()
+uvm_scheduler(void)
 {
-	struct lwp *l, *ll;
-	int pri;
-	int ppri;
+	struct lwp	*l, *ll;
+	struct inst	*i;
+	int 		pri, ppri;
 
 loop:
 #ifdef DEBUG
@@ -491,30 +491,39 @@
 		tsleep(&proc0, PVM, "noswap", 0);
 #endif
 	ll = NULL;		/* process to choose */
-	ppri = INT_MIN;	/* its priority */
-	proclist_lock_read();
+	ppri = INT_MIN;		/* its priority */
+
+	instlist_lock_read();
 
-	LIST_FOREACH(l, &alllwp, l_list) {
-		/* is it a runnable swapped out process? */
-		if (l->l_stat == LSRUN && (l->l_flag & L_INMEM) == 0) {
-			pri = l->l_swtime + l->l_slptime -
-			    (l->l_proc->p_nice - NZERO) * 8;
-			if (pri > ppri) {   /* higher priority?  remember it. */
-				ll = l;
-				ppri = pri;
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			/* is it a runnable swapped out process? */
+			if (l->l_stat == LSRUN && 
+					(l->l_flag & L_INMEM) == 0) {
+				pri = l->l_swtime + l->l_slptime -
+					(l->l_proc->p_nice - NZERO) * 8;
+				if (pri > ppri) {   
+					ll = l;
+					ppri = pri;
+				}
 			}
 		}
+		proclist_unlock_read(i);
 	}
+	instlist_unlock_read();
+
 	/*
 	 * XXXSMP: possible unlock/sleep race between here and the
 	 * "scheduler" tsleep below..
 	 */
-	proclist_unlock_read();
+
 
 #ifdef DEBUG
 	if (swapdebug & SDB_FOLLOW)
 		printf("scheduler: running, procp %p pri %d\n", ll, ppri);
 #endif
+
 	/*
 	 * Nothing to do, back to sleep
 	 */
@@ -524,29 +533,35 @@
 	}
 
 	/*
-	 * we have found swapped out process which we would like to bring
-	 * back in.
+	 * we have found swapped out process which we would like to
+	 * bring back in.
 	 *
-	 * XXX: this part is really bogus cuz we could deadlock on memory
-	 * despite our feeble check
+	 * XXX: this part is really bogus cuz we could deadlock on
+	 * memory despite our feeble check
 	 */
 	if (uvmexp.free > atop(USPACE)) {
 #ifdef DEBUG
 		if (swapdebug & SDB_SWAPIN)
-			printf("swapin: pid %d(%s)@%p, pri %d free %d\n",
-	     l->l_proc->p_pid, l->l_proc->p_comm, l->l_addr, ppri, uvmexp.free);
+			printf("swapin: pid %d(%s)@%p, iid %d pri %d "
+					"free %d\n", l->l_proc->p_pid, 
+					l->l_proc->p_comm, l->l_addr, 
+					l->l_inst->i_uuid, ppri, 
+					uvmexp.free);
 #endif
 		uvm_swapin(l);
 		goto loop;
 	}
+
 	/*
-	 * not enough memory, jab the pageout daemon and wait til the coast
-	 * is clear
+	 * not enough memory, jab the pageout daemon and wait til the coast is
+	 * clear
 	 */
 #ifdef DEBUG
 	if (swapdebug & SDB_FOLLOW)
-		printf("scheduler: no room for pid %d(%s), free %d\n",
-	   l->l_proc->p_pid, l->l_proc->p_comm, uvmexp.free);
+		printf("scheduler: no room for pid %d(%s), iid %d, "
+				"free %d\n", l->l_proc->p_pid, 
+				l->l_proc->p_comm, l->l_inst->i_uuid,
+				uvmexp.free);
 #endif
 	uvm_wait("schedpwait");
 #ifdef DEBUG
@@ -556,10 +571,10 @@
 	goto loop;
 }
 
+
 /*
  * swappable: is LWP "l" swappable?
  */
-
 #define	swappable(l)							\
 	(((l)->l_flag & (L_INMEM)) &&					\
 	 ((((l)->l_proc->p_flag) & (P_SYSTEM | P_WEXIT)) == 0) &&	\
@@ -575,17 +590,18 @@
  *   are swapped... otherwise the longest-sleeping or stopped process
  *   is swapped, otherwise the longest resident process...
  */
-
 void
 uvm_swapout_threads()
 {
-	struct lwp *l;
-	struct lwp *outl, *outl2;
-	int outpri, outpri2;
-	int didswap = 0;
-	extern int maxslp;
+	struct lwp 	*l, *outl, *outl2;
+	int 		outpri, outpri2, didswap;
+	struct inst	*i;
+
+	extern int 	maxslp;
 	/* XXXCDC: should move off to uvmexp. or uvm., also in uvm_meter */
 
+	didswap = 0;
+
 #ifdef DEBUG
 	if (!enableswap)
 		return;
@@ -597,54 +613,61 @@
 	 */
 	outl = outl2 = NULL;
 	outpri = outpri2 = 0;
-	proclist_lock_read();
-	LIST_FOREACH(l, &alllwp, l_list) {
-		KASSERT(l->l_proc != NULL);
-		if (!swappable(l))
-			continue;
-		switch (l->l_stat) {
-		case LSONPROC:
-			continue;
-
-		case LSRUN:
-			if (l->l_swtime > outpri2) {
-				outl2 = l;
-				outpri2 = l->l_swtime;
-			}
-			continue;
 
-		case LSSLEEP:
-		case LSSTOP:
-			if (l->l_slptime >= maxslp) {
-				uvm_swapout(l);
-				didswap++;
-			} else if (l->l_slptime > outpri) {
-				outl = l;
-				outpri = l->l_slptime;
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			KASSERT(l->l_proc != NULL);
+			if (!swappable(l))
+				continue;
+			switch (l->l_stat) {
+			case LSONPROC:
+				continue;
+	
+			case LSRUN:
+				if (l->l_swtime > outpri2) {
+					outl2 = l;
+					outpri2 = l->l_swtime;
+				}
+				continue;
+	
+			case LSSLEEP:
+			case LSSTOP:
+				if (l->l_slptime >= maxslp) {
+					uvm_swapout(l);
+					didswap++;
+				} else if (l->l_slptime > outpri) {
+					outl = l;
+					outpri = l->l_slptime;
+				}
+				continue;
 			}
-			continue;
 		}
+		proclist_unlock_read(i);
 	}
-	proclist_unlock_read();
+	instlist_unlock_read();
 
 	/*
 	 * If we didn't get rid of any real duds, toss out the next most
-	 * likely sleeping/stopped or running candidate.  We only do this
-	 * if we are real low on memory since we don't gain much by doing
-	 * it (USPACE bytes).
+	 * likely sleeping/stopped or running candidate.  We only do
+	 * this if we are real low on memory since we don't gain much by
+	 * doing it (USPACE bytes).
 	 */
 	if (didswap == 0 && uvmexp.free <= atop(round_page(USPACE))) {
 		if ((l = outl) == NULL)
 			l = outl2;
 #ifdef DEBUG
 		if (swapdebug & SDB_SWAPOUT)
-			printf("swapout_threads: no duds, try procp %p\n", l);
+			printf("swapout_threads: no duds, "
+					"try procp %p\n", l);
 #endif
 		if (l)
 			uvm_swapout(l);
 	}
 }
 
+
 /*
  * uvm_swapout: swap out lwp "l"
  *
@@ -652,10 +675,8 @@
  *   the pmap.
  * - XXXCDC: should deactivate all process' private anonymous memory
  */
-
 static void
-uvm_swapout(l)
-	struct lwp *l;
+uvm_swapout(struct lwp *l)
 {
 	vaddr_t addr;
 	int s;
@@ -699,11 +720,11 @@
 	pmap_collect(vm_map_pmap(&p->p_vmspace->vm_map));
 }
 
+
 /*
  * uvm_coredump_walkmap: walk a process's map for the purpose of dumping
  * a core file.
  */
-
 int
 uvm_coredump_walkmap(p, vp, cred, func, cookie)
 	struct proc *p;
diff -r -u -N --exclude CVS NetBSD-3.1/sys/uvm/uvm_meter.c mult-netbsd-3.1/sys/uvm/uvm_meter.c
--- NetBSD-3.1/sys/uvm/uvm_meter.c	2004-10-10 10:57:31.000000000 +0100
+++ mult-netbsd-3.1/sys/uvm/uvm_meter.c	2007-11-23 10:17:20.000000000 +0000
@@ -49,6 +49,7 @@
 #include <sys/kernel.h>
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
+#include <sys/inst.h>
 
 /*
  * maxslp: ???? XXXCDC
@@ -92,27 +93,32 @@
  * 1, 5, and 15 minute internvals.
  */
 static void
-uvm_loadav(avg)
-	struct loadavg *avg;
+uvm_loadav(struct loadavg *avg)
 {
-	int i, nrun;
-	struct lwp *l;
+	int 		i, nrun;
+	struct lwp 	*l;
+	struct inst	*inst;
 
-	proclist_lock_read();
 	nrun = 0;
-	LIST_FOREACH(l, &alllwp, l_list) {
-		switch (l->l_stat) {
-		case LSSLEEP:
-			if (l->l_priority > PZERO || l->l_slptime > 1)
-				continue;
-		/* fall through */
-		case LSRUN:
-		case LSONPROC:
-		case LSIDL:
-			nrun++;
+	instlist_lock_read();
+	LIST_FOREACH(inst, &allinst, i_list) {
+		proclist_lock_read(inst);
+		LIST_FOREACH(l, &inst->i_alllwp, l_list) {
+			switch (l->l_stat) {
+			case LSSLEEP:
+				if (l->l_priority > PZERO || l->l_slptime > 1)
+					continue;
+			/* fall through */
+			case LSRUN:
+			case LSONPROC:
+			case LSIDL:
+				nrun++;
+			}
 		}
+		proclist_unlock_read(inst);
 	}
-	proclist_unlock_read();
+	instlist_unlock_read();
+
 	for (i = 0; i < 3; i++)
 		avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
 		    nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
@@ -417,10 +423,10 @@
  * uvm_total: calculate the current state of the system.
  */
 static void
-uvm_total(totalp)
-	struct vmtotal *totalp;
+uvm_total(struct vmtotal *totalp)
 {
-	struct lwp *l;
+	struct lwp	*l;
+	struct inst	*i;
 #if 0
 	struct vm_map_entry *	entry;
 	struct vm_map *map;
@@ -432,62 +438,43 @@
 	/*
 	 * calculate process statistics
 	 */
-
-	proclist_lock_read();
-	    LIST_FOREACH(l, &alllwp, l_list) {
-		if (l->l_proc->p_flag & P_SYSTEM)
-			continue;
-		switch (l->l_stat) {
-		case 0:
-			continue;
-
-		case LSSLEEP:
-		case LSSTOP:
-			if (l->l_flag & L_INMEM) {
-				if (l->l_priority <= PZERO)
-					totalp->t_dw++;
-				else if (l->l_slptime < maxslp)
-					totalp->t_sl++;
-			} else if (l->l_slptime < maxslp)
-				totalp->t_sw++;
-			if (l->l_slptime >= maxslp)
+	instlist_lock_read();
+	LIST_FOREACH(i, &allinst, i_list) {
+		proclist_lock_read(i);
+		LIST_FOREACH(l, &i->i_alllwp, l_list) {
+			if (l->l_proc->p_flag & P_SYSTEM)
 				continue;
-			break;
-
-		case LSRUN:
-		case LSONPROC:
-		case LSIDL:
-			if (l->l_flag & L_INMEM)
-				totalp->t_rq++;
-			else
-				totalp->t_sw++;
-			if (l->l_stat == LSIDL)
+			switch (l->l_stat) {
+			case 0:
 				continue;
-			break;
+			case LSSLEEP:
+			case LSSTOP:
+				if (l->l_flag & L_INMEM) {
+					if (l->l_priority <= PZERO)
+						totalp->t_dw++;
+					else if (l->l_slptime < maxslp)
+						totalp->t_sl++;
+				} else if (l->l_slptime < maxslp)
+					totalp->t_sw++;
+				if (l->l_slptime >= maxslp)
+					continue;
+				break;
+			case LSRUN:
+			case LSONPROC:
+			case LSIDL:
+				if (l->l_flag & L_INMEM)
+					totalp->t_rq++;
+				else
+					totalp->t_sw++;
+				if (l->l_stat == LSIDL)
+					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
+		proclist_unlock_read(i);
 	}
-	proclist_unlock_read();
+	instlist_unlock_read();
+
 	/*
 	 * Calculate object memory usage statistics.
 	 */
