|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * from: @(#)kern_acct.c 7.18 (Berkeley) 5/11/91
1.1.1.2 ! root 34: * kern_acct.c,v 1.9.2.1 1993/07/21 13:11:57 cgd Exp
1.1 root 35: */
36:
37: #include "param.h"
38: #include "systm.h"
39: #include "namei.h"
40: #include "resourcevar.h"
41: #include "proc.h"
42: #include "ioctl.h"
43: #include "termios.h"
44: #include "tty.h"
45: #include "vnode.h"
46: #include "mount.h"
47: #include "kernel.h"
48: #include "file.h"
49: #include "acct.h"
50: #include "syslog.h"
1.1.1.2 ! root 51: #include "acctbuf.h"
1.1 root 52:
1.1.1.2 ! root 53: #ifdef ACCOUNTING
! 54: int acct_on;
! 55: #endif
1.1 root 56:
57: /*
58: * Enable or disable process accounting.
59: *
1.1.1.2 ! root 60: * if "on" is nonzero, turn on accounting.
! 61: * recording of the actual accounting records is done by a user process
! 62: * reading /dev/acct.
1.1 root 63: */
1.1.1.2 ! root 64:
! 65: struct sysacct_args {
! 66: int acct_on;
! 67: };
! 68:
1.1 root 69: /* ARGSUSED */
1.1.1.2 ! root 70: int
1.1 root 71: sysacct(p, uap, retval)
72: struct proc *p;
1.1.1.2 ! root 73: struct sysacct_args *uap;
1.1 root 74: int *retval;
75: {
1.1.1.2 ! root 76: #ifdef ACCOUNTING
! 77: int error;
1.1 root 78:
1.1.1.2 ! root 79: if (error = suser(p->p_cred->pc_ucred, &p->p_acflag))
! 80: return (error);
! 81:
! 82: acct_on = (*uap).acct_on;
! 83: return 0;
! 84: #else
! 85: /* accounting not compiled in */
1.1 root 86: return (ENOSYS);
1.1.1.2 ! root 87: #endif
1.1 root 88: }
89:
1.1.1.2 ! root 90: #ifdef ACCOUNTING
1.1 root 91: /*
1.1.1.2 ! root 92: * This routine turns a number into a comp_t, which is a compressed
! 93: * floating point number. top 3 bits are an exponent (base 8), last 13 are
! 94: * the "fraction".
! 95: *
! 96: * this takes "units" and "microunits", because this is used for
! 97: * times and other things, too. comp_t's are in 1/AHZ units (why use
! 98: * a time unit for a general purpose thing?), so it's easiest to do
! 99: * conversion to those in here...
1.1 root 100: */
1.1.1.2 ! root 101:
! 102: #define COMP_T_FRACT_BITS 13 /* 13 bits of base */
! 103: #define MAX_COMP_T_FRACT (2<<COMP_T_FRACT_BITS - 1)
! 104: #define COMP_T_EXP_BASE_BITS 3 /* base-8 exponent */
! 105:
! 106: #define SHIFT_COMP_T(exponent, mant) \
! 107: { exponent++; mant >>= COMP_T_EXP_BASE_BITS; }
! 108: #define COMBINE_COMP_T(exponent, mant) \
! 109: (((exponent) << COMP_T_FRACT_BITS) + (mant))
! 110:
! 111: comp_t
! 112: make_comp_t(long s, long us)
1.1 root 113: {
1.1.1.2 ! root 114: long m, e = 0, round = 0;
1.1 root 115:
1.1.1.2 ! root 116: /* get mantissa to maximum precision -- hence "strange"
! 117: * division order
! 118: */
! 119: m = s*AHZ + us/(1000000/AHZ);
! 120:
! 121: /*
! 122: * convert as into a comp_t.
! 123: * as approx = comp_t_fract * 8^comp_t_exp
! 124: */
! 125: while (m > MAX_COMP_T_FRACT) {
! 126: round = m & 0x04; /* shifting 3, is 2nd bit set? */
! 127: SHIFT_COMP_T(e, m);
1.1 root 128: }
1.1.1.2 ! root 129:
! 130: /* if we round up, and overflow, shift it again */
! 131: if (round && (++m > MAX_COMP_T_FRACT))
! 132: SHIFT_COMP_T(e, m);
! 133:
! 134: return COMBINE_COMP_T(e, m);
! 135: }
! 136:
! 137: /*
! 138: * Write an accounting structure to the accounting log buffer
! 139: * mostly cloned from the system log routines...
! 140: */
! 141: void
! 142: acct_write(struct acct *a)
! 143: {
! 144: struct acctbuf *abp;
! 145: #ifdef ACCT_DEBUG
! 146: char commbuf[sizeof(a->ac_comm)];
! 147: #endif
! 148:
! 149: if (acctbufp == NULL)
! 150: acctbuf_init();
! 151:
! 152: abp = acctbufp;
! 153:
! 154: #ifdef ACCT_DEBUG
! 155: bcopy(a->ac_comm, commbuf, sizeof(a->ac_comm));
! 156: commbuf[sizeof(a->ac_comm)] = '\0';
! 157: printf("acct_write: command %s\n", a->ac_comm);
! 158: acctbuf_checkbuf("acct_write");
! 159: #endif
! 160: bcopy(a, &abp->recs[abp->ab_wind++], sizeof(struct acct));
! 161: if (abp->ab_wind < 0 || abp->ab_wind >= ACCT_NBRECS)
! 162: abp->ab_wind = 0;
! 163: if (abp->ab_wind == abp->ab_rind) {
! 164: #ifdef ACCT_DEBUG
! 165: printf("acct_write: accounting buffer overrun\n");
! 166: #endif
! 167: abp->ab_rind++;
! 168: if (abp->ab_rind < 0 || abp->ab_rind >= ACCT_NBRECS)
! 169: abp->ab_rind = 0;
1.1 root 170: }
1.1.1.2 ! root 171: acctwakeup();
1.1 root 172: }
173:
174: /*
175: * This routine calculates an accounting record for a process and,
1.1.1.2 ! root 176: * if accounting is enabled, writes it to the accounting buffer.
1.1 root 177: */
1.1.1.2 ! root 178: void
1.1 root 179: acct(p)
180: register struct proc *p;
181: {
1.1.1.2 ! root 182: struct acct a;
! 183: int s;
! 184: struct timeval t;
1.1 root 185:
1.1.1.2 ! root 186: if (!acct_on)
! 187: return;
! 188:
! 189: /* fill in accounting structure field by field.
! 190: * it really escapes me why some of these are declared
! 191: * as comp_t and some not... -- cgd
1.1 root 192: */
1.1.1.2 ! root 193: bcopy(p->p_comm, a.ac_comm, sizeof a.ac_comm); /* command name */
! 194: a.ac_utime = make_comp_t(p->p_utime.tv_sec, p->p_utime.tv_usec);
! 195: /* user time */
! 196: a.ac_stime = make_comp_t(p->p_stime.tv_sec, p->p_stime.tv_usec);
! 197: /* system time */
! 198: s = splclock();
! 199: t = time; /* get the current time, so we can subtract */
! 200: splx(s);
! 201: timevalsub(&t, &p->p_stats->p_start);
! 202: a.ac_etime = make_comp_t(t.tv_sec, t.tv_usec); /* elapsed time */
! 203: a.ac_btime = p->p_stats->p_start.tv_sec; /* starting time */
! 204: a.ac_uid = p->p_cred->p_ruid; /* user id */
! 205: a.ac_gid = p->p_cred->p_rgid; /* group id */
! 206: a.ac_mem = 0; /* XXX */ /* average memory usage */
! 207: a.ac_io = 0; /* XXX */ /* count of IO blocks */
! 208:
! 209: /* if we've got a tty, and it's controlling, note it */
! 210: if (p->p_session->s_ttyp && p->p_flag & SCTTY)
! 211: a.ac_tty = p->p_session->s_ttyp->t_dev;
! 212: else
! 213: a.ac_tty = NODEV;
! 214:
! 215: a.ac_flag = p->p_acflag; /* accounting flags */
! 216:
! 217: acct_write(&a);
! 218:
1.1 root 219: return;
220: }
1.1.1.2 ! root 221: #endif /* ACCOUNTING */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.