1*7817Sroot /* kern_resource.c 4.11 82/08/22 */ 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" 117499Sroot #include "../h/fs.h" 12*7817Sroot #include "../h/uio.h" 137Sbill 143098Swnj struct inode *acctp; 157499Sroot struct inode *savacctp; 163098Swnj 177499Sroot long acctlow = 2; /* stop accounting when < 2% data space left */ 187499Sroot long accthigh = 4; /* resume when space risen to > 4% */ 197499Sroot 207Sbill /* 217Sbill * Perform process accounting functions. 227Sbill */ 237Sbill sysacct() 247Sbill { 257Sbill register struct inode *ip; 267Sbill register struct a { 277Sbill char *fname; 287Sbill } *uap; 297Sbill 307Sbill uap = (struct a *)u.u_ap; 317Sbill if (suser()) { 327499Sroot if (savacctp) { 337499Sroot acctp = savacctp; 347499Sroot savacctp = NULL; 357499Sroot } 367Sbill if (uap->fname==NULL) { 373109Swnj if (ip = acctp) { 387141Smckusick irele(ip); 397Sbill acctp = NULL; 407Sbill } 417Sbill return; 427Sbill } 435990Swnj ip = namei(uchar, 0, 1); 447Sbill if(ip == NULL) 457Sbill return; 467Sbill if((ip->i_mode & IFMT) != IFREG) { 477Sbill u.u_error = EACCES; 487Sbill iput(ip); 497Sbill return; 507Sbill } 517376Skre if (acctp && (acctp->i_number != ip->i_number || 527376Skre acctp->i_dev != ip->i_dev)) 537376Skre irele(acctp); 547Sbill acctp = ip; 557121Smckusick iunlock(ip); 567Sbill } 577Sbill } 587Sbill 593098Swnj struct acct acctbuf; 607Sbill /* 617Sbill * On exit, write a record on the accounting file. 627Sbill */ 637Sbill acct() 647Sbill { 657Sbill register i; 667Sbill register struct inode *ip; 677Sbill off_t siz; 683098Swnj register struct acct *ap = &acctbuf; 697Sbill 707499Sroot if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree > 717499Sroot accthigh * savacctp->i_fs->fs_dsize / 100) { 727499Sroot acctp = savacctp; 737499Sroot savacctp = NULL; 747499Sroot printf("Accounting resumed\n"); 757499Sroot } 767Sbill if ((ip=acctp)==NULL) 777Sbill return; 787499Sroot if (acctp->i_fs->fs_cstotal.cs_nbfree < 797499Sroot acctlow * acctp->i_fs->fs_dsize / 100) { 807499Sroot savacctp = acctp; 817499Sroot acctp = NULL; 827499Sroot printf("Accounting suspended\n"); 837499Sroot return; 847499Sroot } 854816Swnj ilock(ip); 863098Swnj for (i=0; i<sizeof(ap->ac_comm); i++) 873098Swnj ap->ac_comm[i] = u.u_comm[i]; 883098Swnj ap->ac_utime = compress((long)u.u_vm.vm_utime); 893098Swnj ap->ac_stime = compress((long)u.u_vm.vm_stime); 903098Swnj ap->ac_etime = compress((long)(time - u.u_start)); 913098Swnj ap->ac_btime = u.u_start; 923098Swnj ap->ac_uid = u.u_ruid; 933098Swnj ap->ac_gid = u.u_rgid; 943098Swnj ap->ac_mem = 0; 9589Sbill if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) 963098Swnj ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; 973098Swnj ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); 987376Skre if (u.u_ttyp) 997376Skre ap->ac_tty = u.u_ttyd; 1007376Skre else 1017376Skre ap->ac_tty = NODEV; 1023098Swnj ap->ac_flag = u.u_acflag; 1037Sbill siz = ip->i_size; 104*7817Sroot u.u_error = 105*7817Sroot rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz, 106*7817Sroot 1, (int *)0); 107*7817Sroot if (u.u_error) 1087Sbill ip->i_size = siz; 1097121Smckusick iunlock(ip); 1107Sbill } 1117Sbill 1127Sbill /* 1137Sbill * Produce a pseudo-floating point representation 1147Sbill * with 3 bits base-8 exponent, 13 bits fraction. 1157Sbill */ 1167Sbill compress(t) 1171784Sbill register long t; 1187Sbill { 1197Sbill register exp = 0, round = 0; 1207Sbill 1217Sbill while (t >= 8192) { 1227Sbill exp++; 1237Sbill round = t&04; 1247Sbill t >>= 3; 1257Sbill } 1267Sbill if (round) { 1277Sbill t++; 1287Sbill if (t >= 8192) { 1297Sbill t >>= 3; 1307Sbill exp++; 1317Sbill } 1327Sbill } 1337Sbill return((exp<<13) + t); 1347Sbill } 1357499Sroot 1367499Sroot vtimes() 1377499Sroot { 1387499Sroot register struct a { 1397499Sroot struct vtimes *par_vm; 1407499Sroot struct vtimes *ch_vm; 1417499Sroot } *uap = (struct a *)u.u_ap; 1427499Sroot 1437499Sroot if (uap->par_vm == 0) 1447499Sroot goto onlych; 1457499Sroot if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm, 1467499Sroot sizeof(struct vtimes)) < 0) 1477499Sroot u.u_error = EFAULT; 1487499Sroot onlych: 1497499Sroot if (uap->ch_vm == 0) 1507499Sroot return; 1517499Sroot if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm, 1527499Sroot sizeof(struct vtimes)) < 0) 1537499Sroot u.u_error = EFAULT; 1547499Sroot } 1557499Sroot 1567499Sroot vmsadd(vp, wp) 1577499Sroot register struct vtimes *vp, *wp; 1587499Sroot { 1597499Sroot 1607499Sroot vp->vm_utime += wp->vm_utime; 1617499Sroot vp->vm_stime += wp->vm_stime; 1627499Sroot vp->vm_nswap += wp->vm_nswap; 1637499Sroot vp->vm_idsrss += wp->vm_idsrss; 1647499Sroot vp->vm_ixrss += wp->vm_ixrss; 1657499Sroot if (vp->vm_maxrss < wp->vm_maxrss) 1667499Sroot vp->vm_maxrss = wp->vm_maxrss; 1677499Sroot vp->vm_majflt += wp->vm_majflt; 1687499Sroot vp->vm_minflt += wp->vm_minflt; 1697499Sroot vp->vm_inblk += wp->vm_inblk; 1707499Sroot vp->vm_oublk += wp->vm_oublk; 1717499Sroot } 172