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:
parent
70c05850e2
commit
9bb84c23e7
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user