* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)kern_acct.c 7.16 (Berkeley) %G%
* 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% */
struct timeval chk
= { 15, 0 };/* frequency to check space for accounting */
* SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
* Perform process accounting functions.
register struct vnode
*vp
;
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
if (uap
->fname
== NULL
) {
untimeout(acctwatch
, (caddr_t
)&chk
);
nd
.ni_segflg
= UIO_USERSPACE
;
if (error
= vn_open(&nd
, p
, FWRITE
, 0644))
if (vp
->v_type
!= VREG
) {
* Periodically check the file system to see if accounting
* should be turned on or off.
struct timeval
*resettime
;
(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");
(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
, (caddr_t
)resettime
, hzto(resettime
));
* On exit, write a record on the accounting file.
register struct rusage
*ru
;
struct timeval t
, ut
, st
;
register struct acct
*ap
= &acctbuf
;
if ((vp
= acctp
) == NULL
)
bcopy(p
->p_comm
, ap
->ac_comm
, sizeof(ap
->ac_comm
));
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
&SCTTY
&& p
->p_session
->s_ttyp
)
ap
->ac_tty
= p
->p_session
->s_ttyp
->t_dev
;
ap
->ac_flag
= p
->p_acflag
;
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
);