Add accounting for SysV-related resources.
Sponsored by: The FreeBSD Foundation Reviewed by: kib (earlier version)
This commit is contained in:
parent
54a18d388a
commit
d3c78eed8e
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user