Add accounting for SysV-related resources.

Sponsored by:	The FreeBSD Foundation
Reviewed by:	kib (earlier version)
This commit is contained in:
Edward Tomasz Napierala 2011-04-06 18:11:24 +00:00
parent a2e53e9621
commit 3bcf74459f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=220398
3 changed files with 84 additions and 12 deletions

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/module.h>
#include <sys/msg.h>
#include <sys/racct.h>
#include <sys/syscall.h>
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
@ -466,6 +467,9 @@ kern_msgctl(td, msqid, cmd, msqbuf)
}
#endif
racct_sub_cred(msqkptr->cred, RACCT_NMSGQ, 1);
racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, msqkptr->u.msg_qnum);
racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msqkptr->u.msg_cbytes);
crfree(msqkptr->cred);
msqkptr->cred = NULL;
@ -616,6 +620,13 @@ msgget(td, uap)
error = ENOSPC;
goto done2;
}
PROC_LOCK(td->td_proc);
error = racct_add(td->td_proc, RACCT_NMSGQ, 1);
PROC_UNLOCK(td->td_proc);
if (error != 0) {
error = ENOSPC;
goto done2;
}
DPRINTF(("msqid %d is available\n", msqid));
msqkptr->u.msg_perm.key = key;
msqkptr->u.msg_perm.cuid = cred->cr_uid;
@ -675,6 +686,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
register struct msqid_kernel *msqkptr;
register struct msg *msghdr;
short next;
size_t saved_msgsz;
if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC))
return (ENOSYS);
@ -712,6 +724,21 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
goto done2;
#endif
PROC_LOCK(td->td_proc);
if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) {
PROC_UNLOCK(td->td_proc);
error = EAGAIN;
goto done2;
}
saved_msgsz = msgsz;
if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) {
racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
PROC_UNLOCK(td->td_proc);
error = EAGAIN;
goto done2;
}
PROC_UNLOCK(td->td_proc);
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
msginfo.msgssz, segs_needed));
@ -726,7 +753,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
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) {
@ -753,7 +780,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
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) {
@ -779,7 +806,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
if (error != 0) {
DPRINTF(("msgsnd: interrupted system call\n"));
error = EINTR;
goto done2;
goto done3;
}
/*
@ -789,7 +816,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
if (msqkptr->u.msg_qbytes == 0) {
DPRINTF(("msqid deleted\n"));
error = EIDRM;
goto done2;
goto done3;
}
} else {
@ -871,7 +898,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
wakeup(msqkptr);
DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type));
error = EINVAL;
goto done2;
goto done3;
}
/*
@ -898,7 +925,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
msg_freehdr(msghdr);
msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
wakeup(msqkptr);
goto done2;
goto done3;
}
mtx_lock(&msq_mtx);
msgsz -= tlen;
@ -922,7 +949,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
msg_freehdr(msghdr);
wakeup(msqkptr);
error = EIDRM;
goto done2;
goto done3;
}
#ifdef MAC
@ -941,7 +968,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
if (error != 0) {
msg_freehdr(msghdr);
wakeup(msqkptr);
goto done2;
goto done3;
}
#endif
@ -964,6 +991,13 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
wakeup(msqkptr);
td->td_retval[0] = 0;
done3:
if (error != 0) {
PROC_LOCK(td->td_proc);
racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
racct_sub(td->td_proc, RACCT_MSGQSIZE, saved_msgsz);
PROC_UNLOCK(td->td_proc);
}
done2:
mtx_unlock(&msq_mtx);
return (error);
@ -1197,6 +1231,9 @@ kern_msgrcv(td, msqid, msgp, msgsz, msgtyp, msgflg, mtype)
msqkptr->u.msg_lrpid = td->td_proc->p_pid;
msqkptr->u.msg_rtime = time_second;
racct_sub_cred(msqkptr->cred, RACCT_MSGQQUEUED, 1);
racct_sub_cred(msqkptr->cred, RACCT_MSGQSIZE, msghdr->msg_ts);
/*
* Make msgsz the actual amount that we'll be returning.
* Note that this effectively truncates the message if it is too long

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/racct.h>
#include <sys/sem.h>
#include <sys/syscall.h>
#include <sys/syscallsubr.h>
@ -656,6 +657,7 @@ kern_semctl(struct thread *td, int semid, int semnum, int cmd,
semakptr->u.sem_perm.cuid = cred->cr_uid;
semakptr->u.sem_perm.uid = cred->cr_uid;
semakptr->u.sem_perm.mode = 0;
racct_sub_cred(semakptr->cred, RACCT_NSEM, semakptr->u.sem_nsems);
crfree(semakptr->cred);
semakptr->cred = NULL;
SEMUNDO_LOCK();
@ -929,6 +931,13 @@ semget(struct thread *td, struct semget_args *uap)
error = ENOSPC;
goto done2;
}
PROC_LOCK(td->td_proc);
error = racct_add(td->td_proc, RACCT_NSEM, nsems);
PROC_UNLOCK(td->td_proc);
if (error != 0) {
error = ENOSPC;
goto done2;
}
DPRINTF(("semid %d is available\n", semid));
mtx_lock(&sema_mtx[semid]);
KASSERT((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0,
@ -1010,12 +1019,19 @@ semop(struct thread *td, struct semop_args *uap)
/* 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);
} else {
PROC_LOCK(td->td_proc);
if (nsops > racct_get_available(td->td_proc, RACCT_NSEMOP)) {
PROC_UNLOCK(td->td_proc);
return (E2BIG);
}
PROC_UNLOCK(td->td_proc);
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,

View File

@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mman.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/syscall.h>
@ -246,6 +247,8 @@ shm_deallocate_segment(shmseg)
#ifdef MAC
mac_sysvshm_cleanup(shmseg);
#endif
racct_sub_cred(shmseg->cred, RACCT_NSHM, 1);
racct_sub_cred(shmseg->cred, RACCT_SHMSIZE, size);
crfree(shmseg->cred);
shmseg->cred = NULL;
}
@ -669,6 +672,17 @@ shmget_allocate_segment(td, uap, mode)
shm_last_free = -1;
}
shmseg = &shmsegs[segnum];
PROC_LOCK(td->td_proc);
if (racct_add(td->td_proc, RACCT_NSHM, 1)) {
PROC_UNLOCK(td->td_proc);
return (ENOSPC);
}
if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) {
racct_sub(td->td_proc, RACCT_NSHM, 1);
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
PROC_UNLOCK(td->td_proc);
/*
* In case we sleep in malloc(), mark the segment present but deleted
* so that noone else tries to create the same key.
@ -684,8 +698,13 @@ shmget_allocate_segment(td, uap, mode)
*/
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) {
PROC_LOCK(td->td_proc);
racct_sub(td->td_proc, RACCT_NSHM, 1);
racct_sub(td->td_proc, RACCT_SHMSIZE, size);
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
VM_OBJECT_LOCK(shm_object);
vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shm_object, OBJ_NOSPLIT);