Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_acct.c
Show First 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | |||||
* Accounting vnode pointer, saved vnode pointer, and flags for each. | * Accounting vnode pointer, saved vnode pointer, and flags for each. | ||||
* acct_sx protects against changes to the active vnode and credentials | * acct_sx protects against changes to the active vnode and credentials | ||||
* while accounting records are being committed to disk. | * while accounting records are being committed to disk. | ||||
*/ | */ | ||||
static int acct_configured; | static int acct_configured; | ||||
static int acct_suspended; | static int acct_suspended; | ||||
static struct vnode *acct_vp; | static struct vnode *acct_vp; | ||||
static struct ucred *acct_cred; | static struct ucred *acct_cred; | ||||
static struct plimit *acct_limit; | |||||
static int acct_flags; | static int acct_flags; | ||||
static struct sx acct_sx; | static struct sx acct_sx; | ||||
SX_SYSINIT(acct, &acct_sx, "acct_sx"); | SX_SYSINIT(acct, &acct_sx, "acct_sx"); | ||||
/* | /* | ||||
* State of the accounting kthread. | * State of the accounting kthread. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Accounting system call. Written based on the specification and previous | * Accounting system call. Written based on the specification and previous | ||||
* implementation done by Mark Tinguely. | * implementation done by Mark Tinguely. | ||||
*/ | */ | ||||
int | int | ||||
sys_acct(struct thread *td, struct acct_args *uap) | sys_acct(struct thread *td, struct acct_args *uap) | ||||
{ | { | ||||
struct nameidata nd; | struct nameidata nd; | ||||
int error, flags, i, replacing; | int error, flags, replacing; | ||||
error = priv_check(td, PRIV_ACCT); | error = priv_check(td, PRIV_ACCT); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* If accounting is to be started to a file, open that file for | * If accounting is to be started to a file, open that file for | ||||
* appending and make sure it's a 'normal'. | * appending and make sure it's a 'normal'. | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (acct_state & ACCT_RUNNING) { | ||||
acct_state |= ACCT_EXITREQ; | acct_state |= ACCT_EXITREQ; | ||||
wakeup(&acct_state); | wakeup(&acct_state); | ||||
} | } | ||||
sx_xunlock(&acct_sx); | sx_xunlock(&acct_sx); | ||||
return (error); | 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 | * Save the new accounting file vnode, and schedule the new | ||||
* free space watcher. | * free space watcher. | ||||
*/ | */ | ||||
acct_vp = nd.ni_vp; | acct_vp = nd.ni_vp; | ||||
acct_cred = crhold(td->td_ucred); | acct_cred = crhold(td->td_ucred); | ||||
acct_flags = flags; | acct_flags = flags; | ||||
if (acct_state & ACCT_RUNNING) | if (acct_state & ACCT_RUNNING) | ||||
acct_state &= ~ACCT_EXITREQ; | acct_state &= ~ACCT_EXITREQ; | ||||
Show All 26 Lines | |||||
static int | static int | ||||
acct_disable(struct thread *td, int logging) | acct_disable(struct thread *td, int logging) | ||||
{ | { | ||||
int error; | int error; | ||||
sx_assert(&acct_sx, SX_XLOCKED); | sx_assert(&acct_sx, SX_XLOCKED); | ||||
error = vn_close(acct_vp, acct_flags, acct_cred, td); | error = vn_close(acct_vp, acct_flags, acct_cred, td); | ||||
crfree(acct_cred); | crfree(acct_cred); | ||||
lim_free(acct_limit); | |||||
acct_configured = 0; | acct_configured = 0; | ||||
acct_vp = NULL; | acct_vp = NULL; | ||||
acct_cred = NULL; | acct_cred = NULL; | ||||
acct_flags = 0; | acct_flags = 0; | ||||
if (logging) | if (logging) | ||||
log(LOG_NOTICE, "Accounting disabled\n"); | log(LOG_NOTICE, "Accounting disabled\n"); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Write out process accounting information, on process exit. | * Write out process accounting information, on process exit. | ||||
* Data to be written out is specified in Leffler, et al. | * Data to be written out is specified in Leffler, et al. | ||||
* and are enumerated below. (They're also noted in the system | * and are enumerated below. (They're also noted in the system | ||||
* "acct.h" header file.) | * "acct.h" header file.) | ||||
*/ | */ | ||||
int | int | ||||
acct_process(struct thread *td) | acct_process(struct thread *td) | ||||
{ | { | ||||
struct acctv3 acct; | struct acctv3 acct; | ||||
struct timeval ut, st, tmp; | struct timeval ut, st, tmp; | ||||
struct plimit *oldlim; | |||||
struct proc *p; | struct proc *p; | ||||
struct rusage ru; | struct rusage ru; | ||||
int t, ret; | int t, ret; | ||||
/* | /* | ||||
* Lockless check of accounting condition before doing the hard | * Lockless check of accounting condition before doing the hard | ||||
* work. | * work. | ||||
*/ | */ | ||||
if (acct_vp == NULL || acct_suspended) | if (acct_vp == NULL || acct_suspended) | ||||
return (0); | return (0); | ||||
sx_slock(&acct_sx); | sx_slock(&acct_sx); | ||||
/* | /* | ||||
* If accounting isn't enabled, don't bother. Have to check again | * If accounting isn't enabled, don't bother. Have to check again | ||||
* once we own the lock in case we raced with disabling of accounting | * once we own the lock in case we raced with disabling of accounting | ||||
* by another thread. | * by another thread. | ||||
*/ | */ | ||||
if (acct_vp == NULL || acct_suspended) { | if (acct_vp == NULL || acct_suspended) { | ||||
sx_sunlock(&acct_sx); | sx_sunlock(&acct_sx); | ||||
return (0); | return (0); | ||||
} | } | ||||
p = td->td_proc; | p = td->td_proc; | ||||
td->td_pflags2 |= TDP2_ACCT; | |||||
/* | /* | ||||
* Get process accounting information. | * Get process accounting information. | ||||
*/ | */ | ||||
sx_slock(&proctree_lock); | sx_slock(&proctree_lock); | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
Show All 36 Lines | acct_process(struct thread *td) | ||||
/* (7) The UID and GID of the process */ | /* (7) The UID and GID of the process */ | ||||
acct.ac_uid = p->p_ucred->cr_ruid; | acct.ac_uid = p->p_ucred->cr_ruid; | ||||
acct.ac_gid = p->p_ucred->cr_rgid; | acct.ac_gid = p->p_ucred->cr_rgid; | ||||
/* (8) The boolean flags that tell how the process terminated, etc. */ | /* (8) The boolean flags that tell how the process terminated, etc. */ | ||||
acct.ac_flagx = p->p_acflag; | acct.ac_flagx = p->p_acflag; | ||||
PROC_UNLOCK(p); | |||||
/* Setup ancillary structure fields. */ | /* Setup ancillary structure fields. */ | ||||
acct.ac_flagx |= ANVER; | acct.ac_flagx |= ANVER; | ||||
acct.ac_zero = 0; | acct.ac_zero = 0; | ||||
acct.ac_version = 3; | acct.ac_version = 3; | ||||
acct.ac_len = acct.ac_len2 = sizeof(acct); | 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. | * Write the accounting information to the file. | ||||
*/ | */ | ||||
ret = vn_rdwr(UIO_WRITE, acct_vp, (caddr_t)&acct, sizeof (acct), | ret = vn_rdwr(UIO_WRITE, acct_vp, (caddr_t)&acct, sizeof (acct), | ||||
(off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED, | (off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acct_cred, NOCRED, | ||||
NULL, td); | NULL, td); | ||||
sx_sunlock(&acct_sx); | sx_sunlock(&acct_sx); | ||||
td->td_pflags2 &= ~TDP2_ACCT; | |||||
return (ret); | return (ret); | ||||
} | } | ||||
/* FLOAT_CONVERSION_START (Regression testing; don't remove this line.) */ | /* FLOAT_CONVERSION_START (Regression testing; don't remove this line.) */ | ||||
/* Convert timevals and longs into IEEE-754 bit patterns. */ | /* Convert timevals and longs into IEEE-754 bit patterns. */ | ||||
/* Mantissa mask (MSB is implied, so subtract 1). */ | /* Mantissa mask (MSB is implied, so subtract 1). */ | ||||
▲ Show 20 Lines • Show All 202 Lines • Show Last 20 Lines |