xref: /csrg-svn/sys/kern/kern_resource.c (revision 8031)
1*8031Sroot /*	kern_resource.c	4.12	82/09/04	*/
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"
127817Sroot #include "../h/uio.h"
13*8031Sroot #include "../h/vm.h"
147Sbill 
15*8031Sroot getpriority()
16*8031Sroot {
17*8031Sroot 	register struct a {
18*8031Sroot 		int	which;
19*8031Sroot 		int	who;
20*8031Sroot 	} *uap = (struct a *)u.u_ap;
21*8031Sroot 	register struct proc *p;
22*8031Sroot 
23*8031Sroot 	u.u_r.r_val1 = NZERO+20;
24*8031Sroot 	u.u_error = ESRCH;
25*8031Sroot 	switch (uap->which) {
26*8031Sroot 
27*8031Sroot 	case PRIO_PROCESS:
28*8031Sroot 		if (uap->who == 0)
29*8031Sroot 			p = u.u_procp;
30*8031Sroot 		else
31*8031Sroot 			p = pfind(uap->who);
32*8031Sroot 		if (p == 0)
33*8031Sroot 			return;
34*8031Sroot 		u.u_r.r_val1 = u.u_procp->p_nice;
35*8031Sroot 		break;
36*8031Sroot 
37*8031Sroot 	case PRIO_PGRP:
38*8031Sroot 		if (uap->who == 0)
39*8031Sroot 			uap->who = u.u_procp->p_pgrp;
40*8031Sroot 		for (p = proc; p < procNPROC; p++)
41*8031Sroot 			if (p->p_pgrp == uap->who &&
42*8031Sroot 			    p->p_nice < u.u_r.r_val1) {
43*8031Sroot 				u.u_r.r_val1 = p->p_nice;
44*8031Sroot 				u.u_error = 0;
45*8031Sroot 			}
46*8031Sroot 		break;
47*8031Sroot 
48*8031Sroot 	default:
49*8031Sroot 		u.u_error = EINVAL;
50*8031Sroot 		break;
51*8031Sroot 	}
52*8031Sroot 	u.u_r.r_val1 -= NZERO;
53*8031Sroot }
54*8031Sroot 
55*8031Sroot setpriority()
56*8031Sroot {
57*8031Sroot 	register struct a {
58*8031Sroot 		int	which;
59*8031Sroot 		int	who;
60*8031Sroot 		int	prio;
61*8031Sroot 	} *uap = (struct a *)u.u_ap;
62*8031Sroot 	register struct proc *p;
63*8031Sroot 
64*8031Sroot 	u.u_error = ESRCH;
65*8031Sroot 	switch (uap->which) {
66*8031Sroot 
67*8031Sroot 	case PRIO_PROCESS:
68*8031Sroot 		p = pfind(uap->who);
69*8031Sroot 		if (p == 0)
70*8031Sroot 			return;
71*8031Sroot 		donice(p, uap->prio);
72*8031Sroot 		break;
73*8031Sroot 
74*8031Sroot 	case PRIO_PGRP:
75*8031Sroot 		for (p = proc; p < procNPROC; p++)
76*8031Sroot 			if (p->p_pgrp == uap->who)
77*8031Sroot 				donice(p, uap->prio);
78*8031Sroot 		break;
79*8031Sroot 
80*8031Sroot 	default:
81*8031Sroot 		u.u_error = EINVAL;
82*8031Sroot 		break;
83*8031Sroot 	}
84*8031Sroot }
85*8031Sroot 
86*8031Sroot donice(p, n)
87*8031Sroot 	register struct proc *p;
88*8031Sroot 	register int n;
89*8031Sroot {
90*8031Sroot 
91*8031Sroot 	if (u.u_uid && u.u_ruid &&
92*8031Sroot 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
93*8031Sroot 		u.u_error = EPERM;
94*8031Sroot 		return;
95*8031Sroot 	}
96*8031Sroot 	n += p->p_nice;
97*8031Sroot 	if (n >= 2*NZERO)
98*8031Sroot 		n = 2*NZERO - 1;
99*8031Sroot 	if (n < 0)
100*8031Sroot 		n = 0;
101*8031Sroot 	if (n < p->p_nice && !suser())
102*8031Sroot 		return;
103*8031Sroot 	p->p_nice = n;
104*8031Sroot 	(void) setpri(p);
105*8031Sroot 	if (u.u_error == ESRCH)
106*8031Sroot 		u.u_error = 0;
107*8031Sroot }
108*8031Sroot 
109*8031Sroot setlimit()
110*8031Sroot {
111*8031Sroot 	register struct a {
112*8031Sroot 		u_int	which;
113*8031Sroot 		struct	rlimit *lim;
114*8031Sroot 	} *uap = (struct a *)u.u_ap;
115*8031Sroot 	struct rlimit alim;
116*8031Sroot 	register struct rlimit *alimp;
117*8031Sroot 
118*8031Sroot 	if (uap->which >= RLIM_NLIMITS) {
119*8031Sroot 		u.u_error = EINVAL;
120*8031Sroot 		return;
121*8031Sroot 	}
122*8031Sroot 	alimp = &u.u_rlimit[uap->which];
123*8031Sroot 	if (copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) {
124*8031Sroot 		u.u_error = EFAULT;
125*8031Sroot 		return;
126*8031Sroot 	}
127*8031Sroot 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
128*8031Sroot 		if (!suser())
129*8031Sroot 			return;
130*8031Sroot 	switch (uap->which) {
131*8031Sroot 
132*8031Sroot 	case RLIMIT_DATA:
133*8031Sroot 		if (alim.rlim_cur > ctob(MAXDSIZ))
134*8031Sroot 			alim.rlim_cur = ctob(MAXDSIZ);
135*8031Sroot 		break;
136*8031Sroot 
137*8031Sroot 	case RLIMIT_STACK:
138*8031Sroot 		if (alim.rlim_cur > ctob(MAXSSIZ))
139*8031Sroot 			alim.rlim_cur = ctob(MAXSSIZ);
140*8031Sroot 		break;
141*8031Sroot 	}
142*8031Sroot 	*alimp = alim;
143*8031Sroot 	if (uap->which == RLIMIT_RSS)
144*8031Sroot 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
145*8031Sroot }
146*8031Sroot 
147*8031Sroot getlimit()
148*8031Sroot {
149*8031Sroot 	register struct a {
150*8031Sroot 		u_int	which;
151*8031Sroot 		struct	rlimit *rlp;
152*8031Sroot 	} *uap = (struct a *)u.u_ap;
153*8031Sroot 
154*8031Sroot 	if (uap->which >= RLIM_NLIMITS) {
155*8031Sroot 		u.u_error = EINVAL;
156*8031Sroot 		return;
157*8031Sroot 	}
158*8031Sroot 	if (copyout((caddr_t)&u.u_rlimit[uap->which], uap->rlp,
159*8031Sroot 	    sizeof (struct rlimit))) {
160*8031Sroot 		u.u_error = EFAULT;
161*8031Sroot 		return;
162*8031Sroot 	}
163*8031Sroot }
164*8031Sroot 
165*8031Sroot getrusage()
166*8031Sroot {
167*8031Sroot 	register struct a {
168*8031Sroot 		int	who;
169*8031Sroot 		struct	rusage *rusage;
170*8031Sroot 	} *uap = (struct a *)u.u_ap;
171*8031Sroot 	register struct rusage *rup;
172*8031Sroot 
173*8031Sroot 	switch (uap->who) {
174*8031Sroot 
175*8031Sroot 	case RUSAGE_SELF:
176*8031Sroot 		rup = &u.u_ru;
177*8031Sroot 		break;
178*8031Sroot 
179*8031Sroot 	case RUSAGE_CHILDREN:
180*8031Sroot 		rup = &u.u_cru;
181*8031Sroot 		break;
182*8031Sroot 
183*8031Sroot 	default:
184*8031Sroot 		u.u_error = EINVAL;
185*8031Sroot 		return;
186*8031Sroot 	}
187*8031Sroot 	if (copyout((caddr_t)rup, uap->rusage, sizeof (struct rusage))) {
188*8031Sroot 		u.u_error = EFAULT;
189*8031Sroot 		return;
190*8031Sroot 	}
191*8031Sroot }
192*8031Sroot 
193*8031Sroot ruadd(ru, ru2)
194*8031Sroot 	register struct rusage *ru, *ru2;
195*8031Sroot {
196*8031Sroot 	register int *ip, *ip2;
197*8031Sroot 	register int i;
198*8031Sroot 
199*8031Sroot 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
200*8031Sroot 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
201*8031Sroot 	if (ru->ru_maxrss < ru2->ru_maxrss)
202*8031Sroot 		ru->ru_maxrss = ru2->ru_maxrss;
203*8031Sroot 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
204*8031Sroot 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
205*8031Sroot 		*ip++ += *ip2++;
206*8031Sroot }
207*8031Sroot 
2083098Swnj struct	inode *acctp;
2097499Sroot struct	inode *savacctp;
2103098Swnj 
2117499Sroot long	acctlow	= 2;		/* stop accounting when < 2% data space left */
2127499Sroot long	accthigh = 4;		/* resume when space risen to > 4% */
2137499Sroot 
2147Sbill /*
2157Sbill  * Perform process accounting functions.
2167Sbill  */
2177Sbill sysacct()
2187Sbill {
2197Sbill 	register struct inode *ip;
2207Sbill 	register struct a {
2217Sbill 		char	*fname;
2227Sbill 	} *uap;
2237Sbill 
2247Sbill 	uap = (struct a *)u.u_ap;
2257Sbill 	if (suser()) {
2267499Sroot 		if (savacctp) {
2277499Sroot 			acctp = savacctp;
2287499Sroot 			savacctp = NULL;
2297499Sroot 		}
2307Sbill 		if (uap->fname==NULL) {
2313109Swnj 			if (ip = acctp) {
2327141Smckusick 				irele(ip);
2337Sbill 				acctp = NULL;
2347Sbill 			}
2357Sbill 			return;
2367Sbill 		}
2375990Swnj 		ip = namei(uchar, 0, 1);
2387Sbill 		if(ip == NULL)
2397Sbill 			return;
2407Sbill 		if((ip->i_mode & IFMT) != IFREG) {
2417Sbill 			u.u_error = EACCES;
2427Sbill 			iput(ip);
2437Sbill 			return;
2447Sbill 		}
2457376Skre 		if (acctp && (acctp->i_number != ip->i_number ||
2467376Skre 		    acctp->i_dev != ip->i_dev))
2477376Skre 			irele(acctp);
2487Sbill 		acctp = ip;
2497121Smckusick 		iunlock(ip);
2507Sbill 	}
2517Sbill }
2527Sbill 
2533098Swnj struct	acct acctbuf;
2547Sbill /*
2557Sbill  * On exit, write a record on the accounting file.
2567Sbill  */
2577Sbill acct()
2587Sbill {
2597Sbill 	register i;
2607Sbill 	register struct inode *ip;
2617Sbill 	off_t siz;
2623098Swnj 	register struct acct *ap = &acctbuf;
2637Sbill 
2647499Sroot 	if (savacctp && savacctp->i_fs->fs_cstotal.cs_nbfree >
2657499Sroot 	    accthigh * savacctp->i_fs->fs_dsize / 100) {
2667499Sroot 		acctp = savacctp;
2677499Sroot 		savacctp = NULL;
2687499Sroot 		printf("Accounting resumed\n");
2697499Sroot 	}
2707Sbill 	if ((ip=acctp)==NULL)
2717Sbill 		return;
2727499Sroot 	if (acctp->i_fs->fs_cstotal.cs_nbfree <
2737499Sroot 	    acctlow * acctp->i_fs->fs_dsize / 100) {
2747499Sroot 		savacctp = acctp;
2757499Sroot 		acctp = NULL;
2767499Sroot 		printf("Accounting suspended\n");
2777499Sroot 		return;
2787499Sroot 	}
2794816Swnj 	ilock(ip);
2803098Swnj 	for (i=0; i<sizeof(ap->ac_comm); i++)
2813098Swnj 		ap->ac_comm[i] = u.u_comm[i];
282*8031Sroot 	ap->ac_utime = compress((long)u.u_ru.ru_utime.tv_sec);
283*8031Sroot 	ap->ac_stime = compress((long)u.u_ru.ru_stime.tv_sec);
2843098Swnj 	ap->ac_etime = compress((long)(time - u.u_start));
2853098Swnj 	ap->ac_btime = u.u_start;
2863098Swnj 	ap->ac_uid = u.u_ruid;
2873098Swnj 	ap->ac_gid = u.u_rgid;
2883098Swnj 	ap->ac_mem = 0;
289*8031Sroot 	if (i = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec)
290*8031Sroot 		ap->ac_mem =
291*8031Sroot 		    (u.u_ru.ru_ixrss + u.u_ru.ru_idrss + u.u_ru.ru_isrss) / i;
292*8031Sroot 	ap->ac_io = compress((long)(u.u_ru.ru_inblock + u.u_ru.ru_oublock));
2937376Skre 	if (u.u_ttyp)
2947376Skre 		ap->ac_tty = u.u_ttyd;
2957376Skre 	else
2967376Skre 		ap->ac_tty = NODEV;
2973098Swnj 	ap->ac_flag = u.u_acflag;
2987Sbill 	siz = ip->i_size;
2997817Sroot 	u.u_error =
3007817Sroot 	    rdwri(UIO_WRITE, ip, (caddr_t)ap, sizeof (acctbuf), siz,
3017817Sroot 		1, (int *)0);
3027817Sroot 	if (u.u_error)
3037Sbill 		ip->i_size = siz;
3047121Smckusick 	iunlock(ip);
3057Sbill }
3067Sbill 
3077Sbill /*
3087Sbill  * Produce a pseudo-floating point representation
3097Sbill  * with 3 bits base-8 exponent, 13 bits fraction.
3107Sbill  */
3117Sbill compress(t)
3121784Sbill register long t;
3137Sbill {
3147Sbill 	register exp = 0, round = 0;
3157Sbill 
3167Sbill 	while (t >= 8192) {
3177Sbill 		exp++;
3187Sbill 		round = t&04;
3197Sbill 		t >>= 3;
3207Sbill 	}
3217Sbill 	if (round) {
3227Sbill 		t++;
3237Sbill 		if (t >= 8192) {
3247Sbill 			t >>= 3;
3257Sbill 			exp++;
3267Sbill 		}
3277Sbill 	}
3287Sbill 	return((exp<<13) + t);
3297Sbill }
3307499Sroot 
331*8031Sroot #ifndef NOCOMPAT
332*8031Sroot onice()
3337499Sroot {
3347499Sroot 	register struct a {
335*8031Sroot 		int	niceness;
336*8031Sroot 	} *uap;
3377499Sroot 
338*8031Sroot 	uap = (struct a *)u.u_ap;
339*8031Sroot 	donice(u.u_procp, uap->niceness);
3407499Sroot }
341*8031Sroot #endif
342