1 /* kern_resource.c 4.10 82/07/24 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/acct.h" 6 #include "../h/dir.h" 7 #include "../h/user.h" 8 #include "../h/inode.h" 9 #include "../h/proc.h" 10 #include "../h/seg.h" 11 #include "../h/fs.h" 12 13 struct inode *acctp; 14 struct inode *savacctp; 15 16 long acctlow = 2; /* stop accounting when < 2% data space left */ 17 long accthigh = 4; /* resume when space risen to > 4% */ 18 19 /* 20 * Perform process accounting functions. 21 */ 22 sysacct() 23 { 24 register struct inode *ip; 25 register struct a { 26 char *fname; 27 } *uap; 28 29 uap = (struct a *)u.u_ap; 30 if (suser()) { 31 if (savacctp) { 32 acctp = savacctp; 33 savacctp = NULL; 34 } 35 if (uap->fname==NULL) { 36 if (ip = acctp) { 37 irele(ip); 38 acctp = NULL; 39 } 40 return; 41 } 42 ip = namei(uchar, 0, 1); 43 if(ip == NULL) 44 return; 45 if((ip->i_mode & IFMT) != IFREG) { 46 u.u_error = EACCES; 47 iput(ip); 48 return; 49 } 50 if (acctp && (acctp->i_number != ip->i_number || 51 acctp->i_dev != ip->i_dev)) 52 irele(acctp); 53 acctp = ip; 54 iunlock(ip); 55 } 56 } 57 58 struct acct acctbuf; 59 /* 60 * On exit, write a record on the accounting file. 61 */ 62 acct() 63 { 64 register i; 65 register struct inode *ip; 66 off_t siz; 67 register struct acct *ap = &acctbuf; 68 69 if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree > 70 accthigh * savacctp->i_fs->fs_dsize / 100) { 71 acctp = savacctp; 72 savacctp = NULL; 73 printf("Accounting resumed\n"); 74 } 75 if ((ip=acctp)==NULL) 76 return; 77 if (acctp->i_fs->fs_cstotal.cs_nbfree < 78 acctlow * acctp->i_fs->fs_dsize / 100) { 79 savacctp = acctp; 80 acctp = NULL; 81 printf("Accounting suspended\n"); 82 return; 83 } 84 ilock(ip); 85 for (i=0; i<sizeof(ap->ac_comm); i++) 86 ap->ac_comm[i] = u.u_comm[i]; 87 ap->ac_utime = compress((long)u.u_vm.vm_utime); 88 ap->ac_stime = compress((long)u.u_vm.vm_stime); 89 ap->ac_etime = compress((long)(time - u.u_start)); 90 ap->ac_btime = u.u_start; 91 ap->ac_uid = u.u_ruid; 92 ap->ac_gid = u.u_rgid; 93 ap->ac_mem = 0; 94 if (i = u.u_vm.vm_utime + u.u_vm.vm_stime) 95 ap->ac_mem = (u.u_vm.vm_ixrss + u.u_vm.vm_idsrss) / i; 96 ap->ac_io = compress((long)(u.u_vm.vm_inblk + u.u_vm.vm_oublk)); 97 if (u.u_ttyp) 98 ap->ac_tty = u.u_ttyd; 99 else 100 ap->ac_tty = NODEV; 101 ap->ac_flag = u.u_acflag; 102 siz = ip->i_size; 103 u.u_offset = siz; 104 u.u_base = (caddr_t)ap; 105 u.u_count = sizeof(acctbuf); 106 u.u_segflg = 1; 107 u.u_error = 0; 108 writei(ip); 109 if(u.u_error) 110 ip->i_size = siz; 111 iunlock(ip); 112 } 113 114 /* 115 * Produce a pseudo-floating point representation 116 * with 3 bits base-8 exponent, 13 bits fraction. 117 */ 118 compress(t) 119 register long t; 120 { 121 register exp = 0, round = 0; 122 123 while (t >= 8192) { 124 exp++; 125 round = t&04; 126 t >>= 3; 127 } 128 if (round) { 129 t++; 130 if (t >= 8192) { 131 t >>= 3; 132 exp++; 133 } 134 } 135 return((exp<<13) + t); 136 } 137 138 vtimes() 139 { 140 register struct a { 141 struct vtimes *par_vm; 142 struct vtimes *ch_vm; 143 } *uap = (struct a *)u.u_ap; 144 145 if (uap->par_vm == 0) 146 goto onlych; 147 if (copyout((caddr_t)&u.u_vm, (caddr_t)uap->par_vm, 148 sizeof(struct vtimes)) < 0) 149 u.u_error = EFAULT; 150 onlych: 151 if (uap->ch_vm == 0) 152 return; 153 if (copyout((caddr_t)&u.u_cvm, (caddr_t)uap->ch_vm, 154 sizeof(struct vtimes)) < 0) 155 u.u_error = EFAULT; 156 } 157 158 vmsadd(vp, wp) 159 register struct vtimes *vp, *wp; 160 { 161 162 vp->vm_utime += wp->vm_utime; 163 vp->vm_stime += wp->vm_stime; 164 vp->vm_nswap += wp->vm_nswap; 165 vp->vm_idsrss += wp->vm_idsrss; 166 vp->vm_ixrss += wp->vm_ixrss; 167 if (vp->vm_maxrss < wp->vm_maxrss) 168 vp->vm_maxrss = wp->vm_maxrss; 169 vp->vm_majflt += wp->vm_majflt; 170 vp->vm_minflt += wp->vm_minflt; 171 vp->vm_inblk += wp->vm_inblk; 172 vp->vm_oublk += wp->vm_oublk; 173 } 174