summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMarko Zec <zec@FreeBSD.org>2009-05-08 14:11:06 +0000
committerMarko Zec <zec@FreeBSD.org>2009-05-08 14:11:06 +0000
commit29b02909eb4d38a8803d0e125285c19c92e34da5 (patch)
tree070fe9c96176ed914dfefc12a45fea29b98c4122 /sys/kern
parentfcec7b25b83cce28458a932d1302235b13cf459e (diff)
Notes
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_exit.c5
-rw-r--r--sys/kern/kern_fork.c3
-rw-r--r--sys/kern/kern_jail.c4
-rw-r--r--sys/kern/kern_linker.c12
-rw-r--r--sys/kern/kern_mib.c7
-rw-r--r--sys/kern/kern_prot.c10
-rw-r--r--sys/kern/kern_vimage.c23
8 files changed, 66 insertions, 3 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 96ebf36cc0d7..97b7f0fcf578 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -454,7 +454,10 @@ proc0_init(void *dummy __unused)
p->p_ucred->cr_ruidinfo = uifind(0);
p->p_ucred->cr_prison = NULL; /* Don't jail it. */
#ifdef VIMAGE
- p->p_ucred->cr_vnet = LIST_FIRST(&vnet_head);
+ KASSERT(LIST_FIRST(&vimage_head) != NULL, ("vimage_head empty"));
+ P_TO_VIMAGE(p) = LIST_FIRST(&vimage_head); /* set ucred->cr_vimage */
+ refcount_acquire(&P_TO_VIMAGE(p)->vi_ucredrefc);
+ LIST_FIRST(&vprocg_head)->nprocs++;
#endif
#ifdef AUDIT
audit_cred_kproc0(p->p_ucred);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index a10e915e0a11..89b92c61a1a1 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sdt.h>
#include <sys/shm.h>
#include <sys/sem.h>
+#include <sys/vimage.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -737,6 +738,7 @@ loop:
nfound++;
PROC_SLOCK(p);
if (p->p_state == PRS_ZOMBIE) {
+ INIT_VPROCG(P_TO_VPROCG(p));
if (rusage) {
*rusage = p->p_ru;
calcru(p, &rusage->ru_utime, &rusage->ru_stime);
@@ -837,6 +839,9 @@ loop:
uma_zfree(proc_zone, p);
sx_xlock(&allproc_lock);
nprocs--;
+#ifdef VIMAGE
+ vprocg->nprocs--;
+#endif
sx_xunlock(&allproc_lock);
return (0);
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 76695e711713..4e8dbb19ee2f 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -350,6 +350,9 @@ norfproc_fail:
* are hard-limits as to the number of processes that can run.
*/
nprocs++;
+#ifdef VIMAGE
+ P_TO_VPROCG(p1)->nprocs++;
+#endif
/*
* Find an unused process ID. We remember a range of unused IDs
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 069f1f0f1b9c..3bc5c10c6765 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -2218,6 +2218,10 @@ prison_check(struct ucred *cred1, struct ucred *cred2)
if (cred2->cr_prison != cred1->cr_prison)
return (ESRCH);
}
+#ifdef VIMAGE
+ if (cred2->cr_vimage->v_procg != cred1->cr_vimage->v_procg)
+ return (ESRCH);
+#endif
return (0);
}
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index 2237107e3704..4e0c5a30d3bc 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -992,6 +992,12 @@ kern_kldload(struct thread *td, const char *file, int *fileid)
if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0)
return (error);
+#ifdef VIMAGE
+ /* Only the default vimage is permitted to kldload modules. */
+ if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td)))
+ return (EPERM);
+#endif
+
/*
* It's possible that kldloaded module will attach a new ifnet,
* so vnet context must be set when this ocurs.
@@ -1063,6 +1069,12 @@ kern_kldunload(struct thread *td, int fileid, int flags)
if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0)
return (error);
+#ifdef VIMAGE
+ /* Only the default vimage is permitted to kldunload modules. */
+ if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td)))
+ return (EPERM);
+#endif
+
CURVNET_SET(TD_TO_VNET(td));
KLD_LOCK();
lf = linker_find_file_by_id(fileid);
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 05f90310ea09..43fcfa4ae0e3 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -208,8 +208,9 @@ static char machine_arch[] = MACHINE_ARCH;
SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD,
machine_arch, 0, "System architecture");
-/* should become #ifndef VIMAGE */
+#ifdef VIMAGE_GLOBALS
char hostname[MAXHOSTNAMELEN];
+#endif
/*
* This mutex is used to protect the hostname and domainname variables, and
@@ -348,12 +349,14 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW,
0, 0, sysctl_kern_config, "", "Kernel configuration file");
#endif
-/* should become #ifndef VIMAGE */
+#ifdef VIMAGE_GLOBALS
char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */
+#endif
static int
sysctl_domainname(SYSCTL_HANDLER_ARGS)
{
+ INIT_VPROCG(TD_TO_VPROCG(req->td));
char tmpdomainname[MAXHOSTNAMELEN];
int error;
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 9f13644f1528..b35f81f5316e 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socketvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
+#include <sys/vimage.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
@@ -1824,6 +1825,11 @@ crfree(struct ucred *cr)
*/
if (jailed(cr))
prison_free(cr->cr_prison);
+#ifdef VIMAGE
+ /* XXX TODO: find out why and when cr_vimage can be NULL here! */
+ if (cr->cr_vimage != NULL)
+ refcount_release(&cr->cr_vimage->vi_ucredrefc);
+#endif
#ifdef AUDIT
audit_cred_destroy(cr);
#endif
@@ -1859,6 +1865,10 @@ crcopy(struct ucred *dest, struct ucred *src)
uihold(dest->cr_ruidinfo);
if (jailed(dest))
prison_hold(dest->cr_prison);
+#ifdef VIMAGE
+ KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL"));
+ refcount_acquire(&dest->cr_vimage->vi_ucredrefc);
+#endif
#ifdef AUDIT
audit_cred_copy(src, dest);
#endif
diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c
index 21d502e4c3fe..e20b382029f5 100644
--- a/sys/kern/kern_vimage.c
+++ b/sys/kern/kern_vimage.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container");
MALLOC_DEFINE(M_VNET, "vnet", "network stack control block");
+MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block");
static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head;
static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head;
@@ -56,7 +57,13 @@ static int vnet_mod_constructor(struct vnet_modlink *);
static int vnet_mod_destructor(struct vnet_modlink *);
#ifdef VIMAGE
+struct vimage_list_head vimage_head;
struct vnet_list_head vnet_head;
+struct vprocg_list_head vprocg_head;
+#else
+#ifndef VIMAGE_GLOBALS
+struct vprocg vprocg_0;
+#endif
#endif
void
@@ -294,6 +301,8 @@ static void
vi_init(void *unused)
{
#ifdef VIMAGE
+ struct vimage *vip;
+ struct vprocg *vprocg;
struct vnet *vnet;
#endif
@@ -301,13 +310,27 @@ vi_init(void *unused)
TAILQ_INIT(&vnet_modpending_head);
#ifdef VIMAGE
+ LIST_INIT(&vimage_head);
+ LIST_INIT(&vprocg_head);
LIST_INIT(&vnet_head);
+ vip = malloc(sizeof(struct vimage), M_VIMAGE, M_NOWAIT | M_ZERO);
+ if (vip == NULL)
+ panic("malloc failed for struct vimage");
+ LIST_INSERT_HEAD(&vimage_head, vip, vi_le);
+
+ vprocg = malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO);
+ if (vprocg == NULL)
+ panic("malloc failed for struct vprocg");
+ vip->v_procg = vprocg;
+ LIST_INSERT_HEAD(&vprocg_head, vprocg, vprocg_le);
+
vnet = malloc(sizeof(struct vnet), M_VNET, M_NOWAIT | M_ZERO);
if (vnet == NULL)
panic("vi_alloc: malloc failed");
LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
vnet->vnet_magic_n = VNET_MAGIC_N;
+ vip->v_net = vnet;
/* We MUST clear curvnet in vi_init_done before going SMP. */
curvnet = LIST_FIRST(&vnet_head);