acct: shared rlimit object for exiting processes

From: Mateusz Guzik <mjguzik_at_gmail.com>
Date: Thu, 23 May 2013 03:06:23 +0200
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
_at__at_ -133,6 +133,7 _at__at_ 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;
 
_at__at_ -196,7 +197,7 _at__at_ 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)
_at__at_ -267,6 +268,15 _at__at_ 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.
 	 */
_at__at_ -314,6 +324,7 _at__at_ 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;
_at__at_ -334,7 +345,6 _at__at_ 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;
_at__at_ -410,7 +420,6 _at__at_ 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;
_at__at_ -419,16 +428,11 _at__at_ 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>
Received on Wed May 22 2013 - 23:06:28 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:37 UTC