Date: Wed, 1 Dec 2010 23:22:10 GMT From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 186525 for review Message-ID: <201012012322.oB1NMACC049885@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@186525?ac=10 Change 186525 by trasz@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201012012322.oB1NMACC049885>
