accounting: explicitly mark the exiting thread as doing accounting

and use the mark to stop applying file size limits on the write of
the accounting record.  This allows to remove hack to clear process
limits in acct_process(), and avoids the bug with the clearing being
ineffective because limits are also cached in the thread structure.

Reported and reviewed by:	markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D30257
This commit is contained in:
Konstantin Belousov 2021-05-14 02:48:58 +03:00
parent 70c05850e2
commit 9bb84c23e7
3 changed files with 8 additions and 22 deletions

View File

@ -141,7 +141,6 @@ 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;
@ -206,7 +205,7 @@ int
sys_acct(struct thread *td, struct acct_args *uap)
{
struct nameidata nd;
int error, flags, i, replacing;
int error, flags, replacing;
error = priv_check(td, PRIV_ACCT);
if (error)
@ -276,15 +275,6 @@ sys_acct(struct thread *td, struct acct_args *uap)
return (error);
}
/*
* Create our own plimit object without limits. It will be assigned
* to exiting processes.
*/
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.
@ -328,7 +318,6 @@ 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;
@ -349,7 +338,6 @@ acct_process(struct thread *td)
{
struct acctv3 acct;
struct timeval ut, st, tmp;
struct plimit *oldlim;
struct proc *p;
struct rusage ru;
int t, ret;
@ -374,6 +362,7 @@ acct_process(struct thread *td)
}
p = td->td_proc;
td->td_pflags2 |= TDP2_ACCT;
/*
* Get process accounting information.
@ -426,20 +415,14 @@ 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;
acct.ac_zero = 0;
acct.ac_version = 3;
acct.ac_len = acct.ac_len2 = sizeof(acct);
/*
* Eliminate rlimits (file size limit in particular).
*/
oldlim = p->p_limit;
p->p_limit = lim_hold(acct_limit);
PROC_UNLOCK(p);
lim_free(oldlim);
/*
* Write the accounting information to the file.
*/
@ -447,6 +430,7 @@ acct_process(struct thread *td)
(off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED,
NULL, td);
sx_sunlock(&acct_sx);
td->td_pflags2 &= ~TDP2_ACCT;
return (ret);
}

View File

@ -2360,7 +2360,8 @@ vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
struct thread *td)
{
if (vp->v_type != VREG || td == NULL)
if (vp->v_type != VREG || td == NULL ||
(td->td_pflags2 & TDP2_ACCT) != 0)
return (0);
if ((uoff_t)uio->uio_offset + uio->uio_resid >
lim_cur(td, RLIMIT_FSIZE)) {

View File

@ -528,6 +528,7 @@ do { \
#define TDP2_SBPAGES 0x00000001 /* Owns sbusy on some pages */
#define TDP2_COMPAT32RB 0x00000002 /* compat32 ABI for robust lists */
#define TDP2_ACCT 0x00000004 /* Doing accounting */
/*
* Reasons that the current thread can not be run yet.