Author: trasz
Date: Wed Apr  6 18:11:24 2011
New Revision: 220398
URL: http://svn.freebsd.org/changeset/base/220398

Log:
  Add accounting for SysV-related resources.
  
  Sponsored by: The FreeBSD Foundation
  Reviewed by:  kib (earlier version)

Modified:
  head/sys/kern/sysv_msg.c
  head/sys/kern/sysv_sem.c
  head/sys/kern/sysv_shm.c

Modified: head/sys/kern/sysv_msg.c
==============================================================================
--- head/sys/kern/sysv_msg.c    Wed Apr  6 18:03:49 2011        (r220397)
+++ head/sys/kern/sysv_msg.c    Wed Apr  6 18:11:24 2011        (r220398)
@@ -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, msgf
        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, msgf
                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, msgf
                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, msgf
                                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, msgf
                        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, msgf
                        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, msgf
                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, msgf
                        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, msgf
                msg_freehdr(msghdr);
                wakeup(msqkptr);
                error = EIDRM;
-               goto done2;
+               goto done3;
        }
 
 #ifdef MAC
@@ -941,7 +968,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
        if (error != 0) {
                msg_freehdr(msghdr);
                wakeup(msqkptr);
-               goto done2;
+               goto done3;
        }
 #endif
 
@@ -964,6 +991,13 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgf
 
        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, msgt
        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

Modified: head/sys/kern/sysv_sem.c
==============================================================================
--- head/sys/kern/sysv_sem.c    Wed Apr  6 18:03:49 2011        (r220397)
+++ head/sys/kern/sysv_sem.c    Wed Apr  6 18:11:24 2011        (r220398)
@@ -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
                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_
                        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_ar
        /* 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,

Modified: head/sys/kern/sysv_shm.c
==============================================================================
--- head/sys/kern/sysv_shm.c    Wed Apr  6 18:03:49 2011        (r220397)
+++ head/sys/kern/sysv_shm.c    Wed Apr  6 18:11:24 2011        (r220398)
@@ -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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to