xref: /csrg-svn/sys/kern/kern_resource.c (revision 16530)
1 /*	kern_resource.c	6.2	84/05/22	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/dir.h"
6 #include "../h/user.h"
7 #include "../h/inode.h"
8 #include "../h/proc.h"
9 #include "../h/seg.h"
10 #include "../h/fs.h"
11 #include "../h/uio.h"
12 #include "../h/vm.h"
13 #include "../h/kernel.h"
14 
15 /*
16  * Resource controls and accounting.
17  */
18 
19 getpriority()
20 {
21 	register struct a {
22 		int	which;
23 		int	who;
24 	} *uap = (struct a *)u.u_ap;
25 	register struct proc *p;
26 
27 	u.u_r.r_val1 = NZERO+20;
28 	u.u_error = ESRCH;
29 	switch (uap->which) {
30 
31 	case PRIO_PROCESS:
32 		if (uap->who == 0)
33 			p = u.u_procp;
34 		else
35 			p = pfind(uap->who);
36 		if (p == 0)
37 			return;
38 		u.u_r.r_val1 = p->p_nice;
39 		u.u_error = 0;
40 		break;
41 
42 	case PRIO_PGRP:
43 		if (uap->who == 0)
44 			uap->who = u.u_procp->p_pgrp;
45 		for (p = allproc; p != NULL; p = p->p_nxt) {
46 			if (p->p_pgrp == uap->who &&
47 			    p->p_nice < u.u_r.r_val1) {
48 				u.u_r.r_val1 = p->p_nice;
49 				u.u_error = 0;
50 			}
51 		}
52 		break;
53 
54 	case PRIO_USER:
55 		if (uap->who == 0)
56 			uap->who = u.u_uid;
57 		for (p = allproc; p != NULL; p = p->p_nxt) {
58 			if (p->p_uid == uap->who &&
59 			    p->p_nice < u.u_r.r_val1) {
60 				u.u_r.r_val1 = p->p_nice;
61 				u.u_error = 0;
62 			}
63 		}
64 		break;
65 
66 	default:
67 		u.u_error = EINVAL;
68 		break;
69 	}
70 	u.u_r.r_val1 -= NZERO;
71 }
72 
73 setpriority()
74 {
75 	register struct a {
76 		int	which;
77 		int	who;
78 		int	prio;
79 	} *uap = (struct a *)u.u_ap;
80 	register struct proc *p;
81 
82 	u.u_error = ESRCH;
83 	switch (uap->which) {
84 
85 	case PRIO_PROCESS:
86 		if (uap->who == 0)
87 			p = u.u_procp;
88 		else
89 			p = pfind(uap->who);
90 		if (p == 0)
91 			return;
92 		donice(p, uap->prio);
93 		break;
94 
95 	case PRIO_PGRP:
96 		if (uap->who == 0)
97 			uap->who = u.u_procp->p_pgrp;
98 		for (p = allproc; p != NULL; p = p->p_nxt)
99 			if (p->p_pgrp == uap->who)
100 				donice(p, uap->prio);
101 		break;
102 
103 	case PRIO_USER:
104 		if (uap->who == 0)
105 			uap->who = u.u_uid;
106 		for (p = allproc; p != NULL; p = p->p_nxt)
107 			if (p->p_uid == uap->who)
108 				donice(p, uap->prio);
109 		break;
110 
111 	default:
112 		u.u_error = EINVAL;
113 		break;
114 	}
115 }
116 
117 donice(p, n)
118 	register struct proc *p;
119 	register int n;
120 {
121 
122 	if (u.u_uid && u.u_ruid &&
123 	    u.u_uid != p->p_uid && u.u_ruid != p->p_uid) {
124 		u.u_error = EACCES;
125 		return;
126 	}
127 	n += NZERO;
128 	if (n >= 2*NZERO)
129 		n = 2*NZERO - 1;
130 	if (n < 0)
131 		n = 0;
132 	if (n < p->p_nice && !suser()) {
133 		u.u_error = EACCES;
134 		return;
135 	}
136 	p->p_nice = n;
137 	(void) setpri(p);
138 	if (u.u_error == ESRCH)
139 		u.u_error = 0;
140 }
141 
142 setrlimit()
143 {
144 	register struct a {
145 		u_int	which;
146 		struct	rlimit *lim;
147 	} *uap = (struct a *)u.u_ap;
148 	struct rlimit alim;
149 	register struct rlimit *alimp;
150 
151 	if (uap->which >= RLIM_NLIMITS) {
152 		u.u_error = EINVAL;
153 		return;
154 	}
155 	alimp = &u.u_rlimit[uap->which];
156 	u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim,
157 		sizeof (struct rlimit));
158 	if (u.u_error)
159 		return;
160 	if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
161 		if (!suser())
162 			return;
163 	switch (uap->which) {
164 
165 	case RLIMIT_DATA:
166 		if (alim.rlim_cur > ctob(MAXDSIZ))
167 			alim.rlim_cur = ctob(MAXDSIZ);
168 		break;
169 
170 	case RLIMIT_STACK:
171 		if (alim.rlim_cur > ctob(MAXSSIZ))
172 			alim.rlim_cur = ctob(MAXSSIZ);
173 		break;
174 	}
175 	*alimp = alim;
176 	if (uap->which == RLIMIT_RSS)
177 		u.u_procp->p_maxrss = alim.rlim_cur/NBPG;
178 }
179 
180 getrlimit()
181 {
182 	register struct a {
183 		u_int	which;
184 		struct	rlimit *rlp;
185 	} *uap = (struct a *)u.u_ap;
186 
187 	if (uap->which >= RLIM_NLIMITS) {
188 		u.u_error = EINVAL;
189 		return;
190 	}
191 	u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp,
192 	    sizeof (struct rlimit));
193 }
194 
195 getrusage()
196 {
197 	register struct a {
198 		int	who;
199 		struct	rusage *rusage;
200 	} *uap = (struct a *)u.u_ap;
201 	register struct rusage *rup;
202 
203 	switch (uap->who) {
204 
205 	case RUSAGE_SELF:
206 		rup = &u.u_ru;
207 		break;
208 
209 	case RUSAGE_CHILDREN:
210 		rup = &u.u_cru;
211 		break;
212 
213 	default:
214 		u.u_error = EINVAL;
215 		return;
216 	}
217 	u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage,
218 	    sizeof (struct rusage));
219 }
220 
221 ruadd(ru, ru2)
222 	register struct rusage *ru, *ru2;
223 {
224 	register long *ip, *ip2;
225 	register int i;
226 
227 	timevaladd(&ru->ru_utime, &ru2->ru_utime);
228 	timevaladd(&ru->ru_stime, &ru2->ru_stime);
229 	if (ru->ru_maxrss < ru2->ru_maxrss)
230 		ru->ru_maxrss = ru2->ru_maxrss;
231 	ip = &ru->ru_first; ip2 = &ru2->ru_first;
232 	for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
233 		*ip++ += *ip2++;
234 }
235