When a process is exiting accounting code always allocates new rlimit,
copies old limits over and sets RLIMIT_FSIZE to RLIM_INFINITY.

Since I don't see any good for keeping old limits with exception of
RLIMIT_FSIZE, allocation each time looks unnecessary. Thus I propose the
following:
=========================

acct: create a special plimit object and set it for exiting processes
instead of allocating new one each time

We set all limits to RLIM_INFINITY which sould be ok (even though we
care only about RLIMT_FSIZE).

diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index 3362112..af167d9 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -133,6 +133,7 @@ static int           acct_configured;
 static int              acct_suspended;
 static struct vnode    *acct_vp;
 static struct ucred    *acct_cred;
+static struct plimit   *acct_limit;
 static int              acct_flags;
 static struct sx        acct_sx;
 
@@ -196,7 +197,7 @@ int
 sys_acct(struct thread *td, struct acct_args *uap)
 {
        struct nameidata nd;
-       int error, flags, replacing;
+       int error, flags, i, replacing;
 
        error = priv_check(td, PRIV_ACCT);
        if (error)
@@ -267,6 +268,15 @@ sys_acct(struct thread *td, struct acct_args *uap)
        }
 
        /*
+        * Create our own rlimit object without limits. This is used with
+        * exiting processes to eliminate any file size limits.
+        */
+       acct_limit = lim_alloc();
+       for (i = 0; i < RLIM_NLIMITS; i++)
+               acct_limit->pl_rlimit[i].rlim_cur =
+                   acct_limit->pl_rlimit[i].rlim_max = RLIM_INFINITY;
+
+       /*
         * Save the new accounting file vnode, and schedule the new
         * free space watcher.
         */
@@ -314,6 +324,7 @@ acct_disable(struct thread *td, int logging)
        sx_assert(&acct_sx, SX_XLOCKED);
        error = vn_close(acct_vp, acct_flags, acct_cred, td);
        crfree(acct_cred);
+       lim_free(acct_limit);
        acct_configured = 0;
        acct_vp = NULL;
        acct_cred = NULL;
@@ -334,7 +345,6 @@ acct_process(struct thread *td)
 {
        struct acctv2 acct;
        struct timeval ut, st, tmp;
-       struct plimit *newlim, *oldlim;
        struct proc *p;
        struct rusage ru;
        int t, ret;
@@ -410,7 +420,6 @@ acct_process(struct thread *td)
 
        /* (8) The boolean flags that tell how the process terminated, etc. */
        acct.ac_flagx = p->p_acflag;
-       PROC_UNLOCK(p);
 
        /* Setup ancillary structure fields. */
        acct.ac_flagx |= ANVER;
@@ -419,16 +428,11 @@ acct_process(struct thread *td)
        acct.ac_len = acct.ac_len2 = sizeof(acct);
 
        /*
-        * Eliminate any file size rlimit.
+        * Use our own rlimit to eliminate any file size limits.
         */
-       newlim = lim_alloc();
-       PROC_LOCK(p);
-       oldlim = p->p_limit;
-       lim_copy(newlim, oldlim);
-       newlim->pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
-       p->p_limit = newlim;
+       lim_free(p->p_limit);
+       p->p_limit = lim_hold(acct_limit);
        PROC_UNLOCK(p);
-       lim_free(oldlim);
 
        /*
         * Write the accounting information to the file.
-- 
Mateusz Guzik <mjguzik gmail.com>
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to