1*12788Ssam /* kern_acct.c 4.1 83/05/27 */ 2*12788Ssam 3*12788Ssam #include "../h/param.h" 4*12788Ssam #include "../h/systm.h" 5*12788Ssam #include "../h/dir.h" 6*12788Ssam #include "../h/user.h" 7*12788Ssam #include "../h/inode.h" 8*12788Ssam #include "../h/fs.h" 9*12788Ssam #include "../h/kernel.h" 10*12788Ssam #include "../h/acct.h" 11*12788Ssam #include "../h/nami.h" 12*12788Ssam #include "../h/uio.h" 13*12788Ssam 14*12788Ssam /* 15*12788Ssam * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY. 16*12788Ssam */ 17*12788Ssam struct inode *acctp; 18*12788Ssam struct inode *savacctp; 19*12788Ssam 20*12788Ssam /* 21*12788Ssam * Perform process accounting functions. 22*12788Ssam */ 23*12788Ssam sysacct() 24*12788Ssam { 25*12788Ssam register struct inode *ip; 26*12788Ssam register struct a { 27*12788Ssam char *fname; 28*12788Ssam } *uap = (struct a *)u.u_ap; 29*12788Ssam 30*12788Ssam if (suser()) { 31*12788Ssam if (savacctp) { 32*12788Ssam acctp = savacctp; 33*12788Ssam savacctp = NULL; 34*12788Ssam } 35*12788Ssam if (uap->fname==NULL) { 36*12788Ssam if (ip = acctp) { 37*12788Ssam irele(ip); 38*12788Ssam acctp = NULL; 39*12788Ssam } 40*12788Ssam return; 41*12788Ssam } 42*12788Ssam ip = namei(uchar, LOOKUP, 1); 43*12788Ssam if(ip == NULL) 44*12788Ssam return; 45*12788Ssam if((ip->i_mode & IFMT) != IFREG) { 46*12788Ssam u.u_error = EACCES; 47*12788Ssam iput(ip); 48*12788Ssam return; 49*12788Ssam } 50*12788Ssam if (acctp && (acctp->i_number != ip->i_number || 51*12788Ssam acctp->i_dev != ip->i_dev)) 52*12788Ssam irele(acctp); 53*12788Ssam acctp = ip; 54*12788Ssam iunlock(ip); 55*12788Ssam } 56*12788Ssam } 57*12788Ssam 58*12788Ssam int acctsuspend = 2; /* stop accounting when < 2% free space left */ 59*12788Ssam int acctresume = 4; /* resume when free space risen to > 4% */ 60*12788Ssam 61*12788Ssam struct acct acctbuf; 62*12788Ssam /* 63*12788Ssam * On exit, write a record on the accounting file. 64*12788Ssam */ 65*12788Ssam acct() 66*12788Ssam { 67*12788Ssam register int i; 68*12788Ssam register struct inode *ip; 69*12788Ssam register struct fs *fs; 70*12788Ssam off_t siz; 71*12788Ssam register struct acct *ap = &acctbuf; 72*12788Ssam 73*12788Ssam if (savacctp) { 74*12788Ssam fs = savacctp->i_fs; 75*12788Ssam if (freespace(fs, fs->fs_minfree + acctresume) > 0) { 76*12788Ssam acctp = savacctp; 77*12788Ssam savacctp = NULL; 78*12788Ssam printf("Accounting resumed\n"); 79*12788Ssam } 80*12788Ssam } 81*12788Ssam if ((ip = acctp) == NULL) 82*12788Ssam return; 83*12788Ssam fs = acctp->i_fs; 84*12788Ssam if (freespace(fs, fs->fs_minfree + acctsuspend) <= 0) { 85*12788Ssam savacctp = acctp; 86*12788Ssam acctp = NULL; 87*12788Ssam printf("Accounting suspended\n"); 88*12788Ssam return; 89*12788Ssam } 90*12788Ssam ilock(ip); 91*12788Ssam for (i = 0; i < sizeof (ap->ac_comm); i++) 92*12788Ssam ap->ac_comm[i] = u.u_comm[i]; 93*12788Ssam ap->ac_utime = compress((long)u.u_ru.ru_utime.tv_sec); 94*12788Ssam ap->ac_stime = compress((long)u.u_ru.ru_stime.tv_sec); 95*12788Ssam ap->ac_etime = compress((long)time.tv_sec - u.u_start); 96*12788Ssam ap->ac_btime = u.u_start; 97*12788Ssam ap->ac_uid = u.u_ruid; 98*12788Ssam ap->ac_gid = u.u_rgid; 99*12788Ssam ap->ac_mem = 0; 100*12788Ssam if (i = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec) 101*12788Ssam ap->ac_mem = 102*12788Ssam (u.u_ru.ru_ixrss + u.u_ru.ru_idrss + u.u_ru.ru_isrss) / i; 103*12788Ssam ap->ac_io = compress((long)(u.u_ru.ru_inblock + u.u_ru.ru_oublock)); 104*12788Ssam if (u.u_ttyp) 105*12788Ssam ap->ac_tty = u.u_ttyd; 106*12788Ssam else 107*12788Ssam ap->ac_tty = NODEV; 108*12788Ssam ap->ac_flag = u.u_acflag; 109*12788Ssam siz = ip->i_size; 110*12788Ssam u.u_error = 0; /* XXX */ 111*12788Ssam u.u_error = 112*12788Ssam rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz, 113*12788Ssam 1, (int *)0); 114*12788Ssam if (u.u_error) 115*12788Ssam itrunc(ip, (u_long)siz); 116*12788Ssam iunlock(ip); 117*12788Ssam } 118*12788Ssam 119*12788Ssam /* 120*12788Ssam * Produce a pseudo-floating point representation 121*12788Ssam * with 3 bits base-8 exponent, 13 bits fraction. 122*12788Ssam */ 123*12788Ssam compress(t) 124*12788Ssam register long t; 125*12788Ssam { 126*12788Ssam register exp = 0, round = 0; 127*12788Ssam 128*12788Ssam while (t >= 8192) { 129*12788Ssam exp++; 130*12788Ssam round = t&04; 131*12788Ssam t >>= 3; 132*12788Ssam } 133*12788Ssam if (round) { 134*12788Ssam t++; 135*12788Ssam if (t >= 8192) { 136*12788Ssam t >>= 3; 137*12788Ssam exp++; 138*12788Ssam } 139*12788Ssam } 140*12788Ssam return ((exp<<13) + t); 141*12788Ssam } 142