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