1*7499Sroot /* kern_resource.c 4.10 82/07/24 */ 27Sbill 37Sbill #include "../h/param.h" 47Sbill #include "../h/systm.h" 57Sbill #include "../h/acct.h" 67Sbill #include "../h/dir.h" 77Sbill #include "../h/user.h" 87Sbill #include "../h/inode.h" 97Sbill #include "../h/proc.h" 107Sbill #include "../h/seg.h" 11*7499Sroot #include "../h/fs.h" 127Sbill 133098Swnj struct inode *acctp; 14*7499Sroot struct inode *savacctp; 153098Swnj 16*7499Sroot long acctlow = 2; /* stop accounting when < 2% data space left */ 17*7499Sroot long accthigh = 4; /* resume when space risen to > 4% */ 18*7499Sroot 197Sbill /* 207Sbill * Perform process accounting functions. 217Sbill */ 227Sbill sysacct() 237Sbill { 247Sbill register struct inode *ip; 257Sbill register struct a { 267Sbill char *fname; 277Sbill } *uap; 287Sbill 297Sbill uap = (struct a *)u.u_ap; 307Sbill if (suser()) { 31*7499Sroot if (savacctp) { 32*7499Sroot acctp = savacctp; 33*7499Sroot savacctp = NULL; 34*7499Sroot } 357Sbill if (uap->fname==NULL) { 363109Swnj if (ip = acctp) { 377141Smckusick irele(ip); 387Sbill acctp = NULL; 397Sbill } 407Sbill return; 417Sbill } 425990Swnj ip = namei(uchar, 0, 1); 437Sbill if(ip == NULL) 447Sbill return; 457Sbill if((ip->i_mode & IFMT) != IFREG) { 467Sbill u.u_error = EACCES; 477Sbill iput(ip); 487Sbill return; 497Sbill } 507376Skre if (acctp && (acctp->i_number != ip->i_number || 517376Skre acctp->i_dev != ip->i_dev)) 527376Skre irele(acctp); 537Sbill acctp = ip; 547121Smckusick iunlock(ip); 557Sbill } 567Sbill } 577Sbill 583098Swnj struct acct acctbuf; 597Sbill /* 607Sbill * On exit, write a record on the accounting file. 617Sbill */ 627Sbill acct() 637Sbill { 647Sbill register i; 657Sbill register struct inode *ip; 667Sbill off_t siz; 673098Swnj register struct acct *ap = &acctbuf; 687Sbill 69*7499Sroot if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree > 70*7499Sroot accthigh * savacctp->i_fs->fs_dsize / 100) { 71*7499Sroot acctp = savacctp; 72*7499Sroot savacctp = NULL; 73*7499Sroot printf("Accounting resumed\n"); 74*7499Sroot } 757Sbill if ((ip=acctp)==NULL) 767Sbill return; 77*7499Sroot if (acctp->i_fs->fs_cstotal.cs_nbfree < 78*7499Sroot acctlow * acctp->i_fs->fs_dsize / 100) { 79*7499Sroot savacctp = acctp; 80*7499Sroot acctp = NULL; 81*7499Sroot printf("Accounting suspended\n"); 82*7499Sroot return; 83*7499Sroot } 844816Swnj ilock(ip); 853098Swnj for (i=0; i<sizeof(ap->ac_comm); i++) 863098Swnj ap->ac_comm[i] = u.u_comm[i]; 873098Swnj ap->ac_utime = compress((long)u.u_vm.vm_utime); 883098Swnj ap->ac_stime = compress((long)u.u_vm.vm_stime); 893098Swnj ap->ac_etime = compress((long)(time - u.u_start)); 903098Swnj ap->ac_btime = u.u_start; 913098Swnj ap->ac_uid = u.u_ruid; 923098Swnj ap->ac_gid = u.u_rgid; 933098Swnj ap->ac_mem = 0; 9489Sbill if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) 953098Swnj ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; 963098Swnj ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); 977376Skre if (u.u_ttyp) 987376Skre ap->ac_tty = u.u_ttyd; 997376Skre else 1007376Skre ap->ac_tty = NODEV; 1013098Swnj ap->ac_flag = u.u_acflag; 1027Sbill siz = ip->i_size; 1037Sbill u.u_offset = siz; 1043098Swnj u.u_base = (caddr_t)ap; 1057Sbill u.u_count = sizeof(acctbuf); 1067Sbill u.u_segflg = 1; 1077Sbill u.u_error = 0; 1087Sbill writei(ip); 1097Sbill if(u.u_error) 1107Sbill ip->i_size = siz; 1117121Smckusick iunlock(ip); 1127Sbill } 1137Sbill 1147Sbill /* 1157Sbill * Produce a pseudo-floating point representation 1167Sbill * with 3 bits base-8 exponent, 13 bits fraction. 1177Sbill */ 1187Sbill compress(t) 1191784Sbill register long t; 1207Sbill { 1217Sbill register exp = 0, round = 0; 1227Sbill 1237Sbill while (t >= 8192) { 1247Sbill exp++; 1257Sbill round = t&04; 1267Sbill t >>= 3; 1277Sbill } 1287Sbill if (round) { 1297Sbill t++; 1307Sbill if (t >= 8192) { 1317Sbill t >>= 3; 1327Sbill exp++; 1337Sbill } 1347Sbill } 1357Sbill return((exp<<13) + t); 1367Sbill } 137*7499Sroot 138*7499Sroot vtimes() 139*7499Sroot { 140*7499Sroot register struct a { 141*7499Sroot struct vtimes *par_vm; 142*7499Sroot struct vtimes *ch_vm; 143*7499Sroot } *uap = (struct a *)u.u_ap; 144*7499Sroot 145*7499Sroot if (uap->par_vm == 0) 146*7499Sroot goto onlych; 147*7499Sroot if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm, 148*7499Sroot sizeof(struct vtimes)) < 0) 149*7499Sroot u.u_error = EFAULT; 150*7499Sroot onlych: 151*7499Sroot if (uap->ch_vm == 0) 152*7499Sroot return; 153*7499Sroot if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm, 154*7499Sroot sizeof(struct vtimes)) < 0) 155*7499Sroot u.u_error = EFAULT; 156*7499Sroot } 157*7499Sroot 158*7499Sroot vmsadd(vp, wp) 159*7499Sroot register struct vtimes *vp, *wp; 160*7499Sroot { 161*7499Sroot 162*7499Sroot vp->vm_utime += wp->vm_utime; 163*7499Sroot vp->vm_stime += wp->vm_stime; 164*7499Sroot vp->vm_nswap += wp->vm_nswap; 165*7499Sroot vp->vm_idsrss += wp->vm_idsrss; 166*7499Sroot vp->vm_ixrss += wp->vm_ixrss; 167*7499Sroot if (vp->vm_maxrss < wp->vm_maxrss) 168*7499Sroot vp->vm_maxrss = wp->vm_maxrss; 169*7499Sroot vp->vm_majflt += wp->vm_majflt; 170*7499Sroot vp->vm_minflt += wp->vm_minflt; 171*7499Sroot vp->vm_inblk += wp->vm_inblk; 172*7499Sroot vp->vm_oublk += wp->vm_oublk; 173*7499Sroot } 174