PERFORCE change 186525 for review
Edward Tomasz Napierala
trasz at FreeBSD.org
Wed Dec 1 23:22:11 UTC 2010
http://p4web.freebsd.org/@@186525?ac=10
Change 186525 by trasz at trasz_victim on 2010/12/01 23:21:50
Implement accounting and limits for SysV IPC.
Affected files ...
.. //depot/projects/soc2009/trasz_limits/TODO#30 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#37 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_msg.c#6 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_sem.c#7 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_shm.c#9 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/msg.h#3 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/sem.h#3 edit
.. //depot/projects/soc2009/trasz_limits/sys/sys/shm.h#3 edit
Differences ...
==== //depot/projects/soc2009/trasz_limits/TODO#30 (text+ko) ====
@@ -15,18 +15,13 @@
- number of kernel-visible threads (RUSAGE_NTHR)
- wallclock time (RUSAGE_WALLCLOCK)
- %cpu time (RUSAGE_PCTCPU)
-
-Limits to do:
-
-Milestone 2:
-
+ - number of SysV shared memory segments (RUSAGE_NSHM)
+ - SysV shared memory size, in megabytes (RUSAGE_SHMSIZE)
+ - number of SysV semaphores modified in a single semop(2) call (RUSAGE_NSEMOP)
+ - number of SysV semaphores (RUSAGE_NSEM)
+ - number of SysV queues (RUSAGE_NMSGQ)
- number of queued SysV messages (RUSAGE_MSGQQUEUED)
- SysV message queue size, in megabytes (RUSAGE_MSGQSIZE)
- - number of SysV queues (RUSAGE_NMSGQ)
- - number of SysV semaphores (RUSAGE_NSEM)
- - number of SysV semaphores modified in a single semop(2) call (RUSAGE_NSEMOP)
- - number of SysV shared memory segments (RUSAGE_NSHM)
- - SysV shared memory size, in megabytes (RUSAGE_SHMSIZE)
Milestone 3:
==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#37 (text+ko) ====
@@ -106,6 +106,12 @@
case RUSAGE_NTHR:
case RUSAGE_WALLCLOCK:
case RUSAGE_PCTCPU:
+ case RUSAGE_NMSGQ:
+ case RUSAGE_MSGQQUEUED:
+ case RUSAGE_MSGQSIZE:
+ case RUSAGE_NSEM:
+ case RUSAGE_NSHM:
+ case RUSAGE_SHMSIZE:
return (0);
default:
return (1);
@@ -133,6 +139,12 @@
switch (resource) {
case RUSAGE_SBSIZE:
case RUSAGE_SWAP:
+ case RUSAGE_NMSGQ:
+ case RUSAGE_MSGQQUEUED:
+ case RUSAGE_MSGQSIZE:
+ case RUSAGE_NSEM:
+ case RUSAGE_NSHM:
+ case RUSAGE_SHMSIZE:
return (1);
default:
return (0);
==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_msg.c#6 (text+ko) ====
@@ -56,6 +56,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/container.h>
#include <sys/kernel.h>
#include <sys/priv.h>
#include <sys/proc.h>
@@ -481,6 +482,14 @@
}
#endif
+#ifdef CONTAINERS
+ rusage_sub_cred(msqkptr->cred, RUSAGE_NMSGQ, 1);
+ rusage_sub_cred(msqkptr->cred, RUSAGE_MSGQQUEUED, msqkptr->u.msg_qnum);
+ rusage_sub_cred(msqkptr->cred, RUSAGE_MSGQSIZE, msqkptr->u.msg_cbytes);
+#endif
+ crfree(msqkptr->cred);
+ msqkptr->cred = NULL;
+
/* Free the message headers */
msghdr = msqkptr->u.msg_first;
while (msghdr != NULL) {
@@ -628,6 +637,12 @@
error = ENOSPC;
goto done2;
}
+#ifdef CONTAINERS
+ if (rusage_add(td->td_proc, RUSAGE_NMSGQ, 1)) {
+ error = ENOSPC;
+ goto done2;
+ }
+#endif
DPRINTF(("msqid %d is available\n", msqid));
msqkptr->u.msg_perm.key = key;
msqkptr->u.msg_perm.cuid = cred->cr_uid;
@@ -635,6 +650,8 @@
msqkptr->u.msg_perm.cgid = cred->cr_gid;
msqkptr->u.msg_perm.gid = cred->cr_gid;
msqkptr->u.msg_perm.mode = (msgflg & 0777);
+ crhold(cred);
+ msqkptr->cred = cred;
/* Make sure that the returned msqid is unique */
msqkptr->u.msg_perm.seq = (msqkptr->u.msg_perm.seq + 1) & 0x7fff;
msqkptr->u.msg_first = NULL;
@@ -685,6 +702,9 @@
register struct msqid_kernel *msqkptr;
register struct msg *msghdr;
short next;
+#ifdef CONTAINERS
+ size_t saved_msgsz;
+#endif
if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC))
return (ENOSYS);
@@ -722,6 +742,20 @@
goto done2;
#endif
+#ifdef CONTAINERS
+ if (rusage_add(td->td_proc, RUSAGE_MSGQQUEUED, 1)) {
+ error = EAGAIN;
+ goto done2;
+ }
+
+ saved_msgsz = msgsz;
+ if (rusage_add(td->td_proc, RUSAGE_MSGQSIZE, msgsz)) {
+ rusage_sub(td->td_proc, RUSAGE_MSGQQUEUED, 1);
+ error = EAGAIN;
+ goto done2;
+ }
+#endif
+
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
msginfo.msgssz, segs_needed));
@@ -736,7 +770,7 @@
if (msgsz > msqkptr->u.msg_qbytes) {
DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n"));
error = EINVAL;
- goto done2;
+ goto done3;
}
if (msqkptr->u.msg_perm.mode & MSG_LOCKED) {
@@ -763,7 +797,7 @@
DPRINTF(("need more resources but caller "
"doesn't want to wait\n"));
error = EAGAIN;
- goto done2;
+ goto done3;
}
if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) {
@@ -789,7 +823,7 @@
if (error != 0) {
DPRINTF(("msgsnd: interrupted system call\n"));
error = EINTR;
- goto done2;
+ goto done3;
}
/*
@@ -799,7 +833,7 @@
if (msqkptr->u.msg_qbytes == 0) {
DPRINTF(("msqid deleted\n"));
error = EIDRM;
- goto done2;
+ goto done3;
}
} else {
@@ -881,7 +915,7 @@
wakeup(msqkptr);
DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type));
error = EINVAL;
- goto done2;
+ goto done3;
}
/*
@@ -908,7 +942,7 @@
msg_freehdr(msghdr);
msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
wakeup(msqkptr);
- goto done2;
+ goto done3;
}
mtx_lock(&msq_mtx);
msgsz -= tlen;
@@ -932,7 +966,7 @@
msg_freehdr(msghdr);
wakeup(msqkptr);
error = EIDRM;
- goto done2;
+ goto done3;
}
#ifdef MAC
@@ -951,7 +985,7 @@
if (error != 0) {
msg_freehdr(msghdr);
wakeup(msqkptr);
- goto done2;
+ goto done3;
}
#endif
@@ -974,6 +1008,13 @@
wakeup(msqkptr);
td->td_retval[0] = 0;
+done3:
+#ifdef CONTAINERS
+ if (error) {
+ rusage_sub(td->td_proc, RUSAGE_MSGQQUEUED, 1);
+ rusage_sub(td->td_proc, RUSAGE_MSGQSIZE, saved_msgsz);
+ }
+#endif
done2:
mtx_unlock(&msq_mtx);
return (error);
@@ -1207,6 +1248,11 @@
msqkptr->u.msg_lrpid = td->td_proc->p_pid;
msqkptr->u.msg_rtime = time_second;
+#ifdef CONTAINERS
+ rusage_sub_cred(msqkptr->cred, RUSAGE_MSGQQUEUED, 1);
+ rusage_sub_cred(msqkptr->cred, RUSAGE_MSGQSIZE, msghdr->msg_ts);
+#endif
+
/*
* Make msgsz the actual amount that we'll be returning.
* Note that this effectively truncates the message if it is too long
==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_sem.c#7 (text+ko) ====
@@ -45,6 +45,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
+#include <sys/container.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/proc.h>
@@ -654,6 +655,11 @@
semakptr->u.sem_perm.cuid = cred->cr_uid;
semakptr->u.sem_perm.uid = cred->cr_uid;
semakptr->u.sem_perm.mode = 0;
+#ifdef CONTAINERS
+ rusage_sub_cred(semakptr->cred, RUSAGE_NSEM, semakptr->u.sem_nsems);
+#endif
+ crfree(semakptr->cred);
+ semakptr->cred = NULL;
SEMUNDO_LOCK();
semundo_clear(semidx, -1);
SEMUNDO_UNLOCK();
@@ -925,6 +931,12 @@
error = ENOSPC;
goto done2;
}
+#ifdef CONTAINERS
+ if (rusage_add(td->td_proc, RUSAGE_NSEM, nsems)) {
+ error = ENOSPC;
+ goto done2;
+ }
+#endif
DPRINTF(("semid %d is available\n", semid));
mtx_lock(&sema_mtx[semid]);
KASSERT((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0,
@@ -935,6 +947,8 @@
sema[semid].u.sem_perm.cgid = cred->cr_gid;
sema[semid].u.sem_perm.gid = cred->cr_gid;
sema[semid].u.sem_perm.mode = (semflg & 0777) | SEM_ALLOC;
+ crhold(cred);
+ sema[semid].cred = cred;
sema[semid].u.sem_perm.seq =
(sema[semid].u.sem_perm.seq + 1) & 0x7fff;
sema[semid].u.sem_nsems = nsems;
@@ -1004,13 +1018,16 @@
/* Allocate memory for sem_ops */
if (nsops <= SMALL_SOPS)
sops = small_sops;
- else if (nsops <= seminfo.semopm)
- sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
- else {
+ else if (nsops > seminfo.semopm) {
DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm,
nsops));
return (E2BIG);
- }
+#ifdef CONTAINERS
+ } else if (nsops > rusage_get_limit(td->td_proc, RUSAGE_NSEMOP)) {
+ return (E2BIG);
+#endif
+ } else
+ sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
DPRINTF(("error = %d from copyin(%p, %p, %d)\n", error,
uap->sops, sops, nsops * sizeof(sops[0])));
==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_shm.c#9 (text+ko) ====
@@ -67,6 +67,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/container.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
@@ -244,6 +245,12 @@
#ifdef MAC
mac_sysvshm_cleanup(shmseg);
#endif
+#ifdef CONTAINERS
+ rusage_sub_cred(shmseg->cred, RUSAGE_NSHM, 1);
+ rusage_sub_cred(shmseg->cred, RUSAGE_SHMSIZE, size);
+#endif
+ crfree(shmseg->cred);
+ shmseg->cred = NULL;
}
static int
@@ -665,6 +672,14 @@
shm_last_free = -1;
}
shmseg = &shmsegs[segnum];
+#ifdef CONTAINERS
+ if (rusage_add(td->td_proc, RUSAGE_NSHM, 1))
+ return (ENOSPC);
+ if (rusage_add(td->td_proc, RUSAGE_SHMSIZE, size)) {
+ rusage_sub(td->td_proc, RUSAGE_NSHM, 1);
+ return (ENOMEM);
+ }
+#endif
/*
* In case we sleep in malloc(), mark the segment present but deleted
* so that noone else tries to create the same key.
@@ -680,8 +695,13 @@
*/
shm_object = vm_pager_allocate(shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
0, size, VM_PROT_DEFAULT, 0, cred);
- if (shm_object == NULL)
+ if (shm_object == NULL) {
+#ifdef CONTAINERS
+ rusage_sub(td->td_proc, RUSAGE_NSHM, 1);
+ rusage_sub(td->td_proc, RUSAGE_SHMSIZE, size);
+#endif
return (ENOMEM);
+ }
VM_OBJECT_LOCK(shm_object);
vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shm_object, OBJ_NOSPLIT);
@@ -692,6 +712,8 @@
shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
(mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
+ crhold(cred);
+ shmseg->cred = cred;
shmseg->u.shm_segsz = uap->size;
shmseg->u.shm_cpid = td->td_proc->p_pid;
shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
==== //depot/projects/soc2009/trasz_limits/sys/sys/msg.h#3 (text+ko) ====
@@ -160,6 +160,7 @@
* Kernel-private components of the message queue.
*/
struct label *label; /* MAC label */
+ struct ucred *cred; /* creator's credentials */
};
#else /* !_KERNEL */
==== //depot/projects/soc2009/trasz_limits/sys/sys/sem.h#3 (text+ko) ====
@@ -126,6 +126,7 @@
struct semid_kernel {
struct semid_ds u;
struct label *label; /* MAC framework label */
+ struct ucred *cred; /* creator's credentials */
};
/* internal "mode" bits */
==== //depot/projects/soc2009/trasz_limits/sys/sys/shm.h#3 (text+ko) ====
@@ -124,6 +124,7 @@
struct shmid_ds u;
vm_object_t object;
struct label *label; /* MAC label */
+ struct ucred *cred; /* creator's credendials */
};
extern struct shminfo shminfo;
More information about the p4-projects
mailing list