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