8b911815fd121b88703e0f901a8f2be9209a8974
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
* %sccs.include.proprietary.c%
* @(#)kern_acct.c 8.6 (Berkeley) %G%
#include <sys/resourcevar.h>
* Values associated with enabling and disabling accounting
int acctsuspend
= 2; /* stop accounting when < 2% free space left */
int acctresume
= 4; /* resume when free space risen to > 4% */
int acctchkfreq
= 15; /* frequency (in seconds) to check space */
* SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
* Enable or disable process accounting.
* If a non-null filename is given, that file is used to store accounting
* records on process exit. If a null filename is given process accounting
* is suspended. If accounting is enabled, the system checks the amount
* of freespace on the filesystem at timeval intervals. If the amount of
* freespace is below acctsuspend percent, accounting is suspended. If
* accounting has been suspended, and freespace rises above acctresume,
register struct vnode
*vp
;
extern void acctwatch
__P((void *));
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
if (uap
->fname
== NULL
) {
error
= vn_close(vp
, FWRITE
, p
->p_ucred
, p
);
untimeout(acctwatch
, NULL
);
NDINIT(&nd
, LOOKUP
, FOLLOW
, UIO_USERSPACE
, uap
->fname
, p
);
if (error
= vn_open(&nd
, FWRITE
, 0644))
if (vp
->v_type
!= VREG
) {
(void) vn_close(vp
, FWRITE
, p
->p_ucred
, p
);
error
= vn_close(oacctp
, FWRITE
, p
->p_ucred
, p
);
* Periodically check the file system to see if accounting
* should be turned on or off. Beware the case where the vnode
* has been vgone()'d out from underneath us, e.g. when the file
* system containing the accounting file has been forcibly unmounted.
if (savacctp
->v_type
== VBAD
) {
(void) vn_close(savacctp
, FWRITE
, NOCRED
, NULL
);
(void)VFS_STATFS(savacctp
->v_mount
, &sb
, (struct proc
*)0);
if (sb
.f_bavail
> acctresume
* sb
.f_blocks
/ 100) {
log(LOG_NOTICE
, "Accounting resumed\n");
if (acctp
->v_type
== VBAD
) {
(void) vn_close(acctp
, FWRITE
, NOCRED
, NULL
);
(void)VFS_STATFS(acctp
->v_mount
, &sb
, (struct proc
*)0);
if (sb
.f_bavail
<= acctsuspend
* sb
.f_blocks
/ 100) {
log(LOG_NOTICE
, "Accounting suspended\n");
timeout(acctwatch
, NULL
, acctchkfreq
* hz
);
* This routine calculates an accounting record for a process and,
* if accounting is enabled, writes it to the accounting file.
register struct rusage
*ru
;
struct timeval t
, ut
, st
;
register struct acct
*ap
= &acctbuf
;
if ((vp
= acctp
) == NULL
)
if (vp
->v_type
== VBAD
) {
(void) vn_close(vp
, FWRITE
, NOCRED
, NULL
);
bcopy(p
->p_comm
, ap
->ac_comm
, sizeof(ap
->ac_comm
));
calcru(p
, &ut
, &st
, NULL
);
ap
->ac_utime
= compress(ut
.tv_sec
, ut
.tv_usec
);
ap
->ac_stime
= compress(st
.tv_sec
, st
.tv_usec
);
timevalsub(&t
, &p
->p_stats
->p_start
);
ap
->ac_etime
= compress(t
.tv_sec
, t
.tv_usec
);
ap
->ac_btime
= p
->p_stats
->p_start
.tv_sec
;
ap
->ac_uid
= p
->p_cred
->p_ruid
;
ap
->ac_gid
= p
->p_cred
->p_rgid
;
if (i
= t
.tv_sec
* hz
+ t
.tv_usec
/ tick
)
ap
->ac_mem
= (ru
->ru_ixrss
+ ru
->ru_idrss
+ ru
->ru_isrss
) / i
;
ap
->ac_io
= compress(ru
->ru_inblock
+ ru
->ru_oublock
, (long)0);
if (p
->p_flag
& P_CONTROLT
&& p
->p_session
->s_ttyp
)
ap
->ac_tty
= p
->p_session
->s_ttyp
->t_dev
;
ap
->ac_flag
= p
->p_acflag
;
VOP_LEASE(vp
, p
, p
->p_ucred
, LEASE_WRITE
);
return (vn_rdwr(UIO_WRITE
, vp
, (caddr_t
)ap
, sizeof (acctbuf
), (off_t
)0,
UIO_SYSSPACE
, IO_UNIT
|IO_APPEND
, p
->p_ucred
, (int *)0,
* Produce a pseudo-floating point representation
* with 3 bits base-8 exponent, 13 bits fraction.
register exp
= 0, round
= 0;
t
= t
* AHZ
; /* compiler will convert only this format to a shift */
t
+= ut
/ (1000000 / AHZ
);