1 /*-
2 * Copyright (c) 1982, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_resource.c 8.5 (Berkeley) 1/21/94
39 * $FreeBSD: releng/5.1/sys/kern/kern_resource.c 113921 2003-04-23 18:48:55Z jhb $
40 */
41
42 #include "opt_compat.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/sysproto.h>
47 #include <sys/file.h>
48 #include <sys/kernel.h>
49 #include <sys/lock.h>
50 #include <sys/malloc.h>
51 #include <sys/mutex.h>
52 #include <sys/proc.h>
53 #include <sys/resourcevar.h>
54 #include <sys/sched.h>
55 #include <sys/sx.h>
56 #include <sys/sysent.h>
57 #include <sys/time.h>
58
59 #include <vm/vm.h>
60 #include <vm/vm_param.h>
61 #include <vm/pmap.h>
62 #include <vm/vm_map.h>
63
64 static int donice(struct thread *td, struct proc *chgp, int n);
65
66 static MALLOC_DEFINE(M_UIDINFO, "uidinfo", "uidinfo structures");
67 #define UIHASH(uid) (&uihashtbl[(uid) & uihash])
68 static struct mtx uihashtbl_mtx;
69 static LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
70 static u_long uihash; /* size of hash table - 1 */
71
72 static struct uidinfo *uilookup(uid_t uid);
73
74 /*
75 * Resource controls and accounting.
76 */
77
78 #ifndef _SYS_SYSPROTO_H_
79 struct getpriority_args {
80 int which;
81 int who;
82 };
83 #endif
84 /*
85 * MPSAFE
86 */
87 int
88 getpriority(td, uap)
89 struct thread *td;
90 register struct getpriority_args *uap;
91 {
92 struct proc *p;
93 int low = PRIO_MAX + 1;
94 int error = 0;
95 struct ksegrp *kg;
96
97 switch (uap->which) {
98 case PRIO_PROCESS:
99 if (uap->who == 0)
100 low = td->td_ksegrp->kg_nice;
101 else {
102 p = pfind(uap->who);
103 if (p == NULL)
104 break;
105 if (p_cansee(td, p) == 0) {
106 FOREACH_KSEGRP_IN_PROC(p, kg) {
107 if (kg->kg_nice < low)
108 low = kg->kg_nice;
109 }
110 }
111 PROC_UNLOCK(p);
112 }
113 break;
114
115 case PRIO_PGRP: {
116 register struct pgrp *pg;
117
118 sx_slock(&proctree_lock);
119 if (uap->who == 0) {
120 pg = td->td_proc->p_pgrp;
121 PGRP_LOCK(pg);
122 } else {
123 pg = pgfind(uap->who);
124 if (pg == NULL) {
125 sx_sunlock(&proctree_lock);
126 break;
127 }
128 }
129 sx_sunlock(&proctree_lock);
130 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
131 PROC_LOCK(p);
132 if (!p_cansee(td, p)) {
133 FOREACH_KSEGRP_IN_PROC(p, kg) {
134 if (kg->kg_nice < low)
135 low = kg->kg_nice;
136 }
137 }
138 PROC_UNLOCK(p);
139 }
140 PGRP_UNLOCK(pg);
141 break;
142 }
143
144 case PRIO_USER:
145 if (uap->who == 0)
146 uap->who = td->td_ucred->cr_uid;
147 sx_slock(&allproc_lock);
148 LIST_FOREACH(p, &allproc, p_list) {
149 PROC_LOCK(p);
150 if (!p_cansee(td, p) &&
151 p->p_ucred->cr_uid == uap->who) {
152 FOREACH_KSEGRP_IN_PROC(p, kg) {
153 if (kg->kg_nice < low)
154 low = kg->kg_nice;
155 }
156 }
157 PROC_UNLOCK(p);
158 }
159 sx_sunlock(&allproc_lock);
160 break;
161
162 default:
163 error = EINVAL;
164 break;
165 }
166 if (low == PRIO_MAX + 1 && error == 0)
167 error = ESRCH;
168 td->td_retval[0] = low;
169 return (error);
170 }
171
172 #ifndef _SYS_SYSPROTO_H_
173 struct setpriority_args {
174 int which;
175 int who;
176 int prio;
177 };
178 #endif
179 /*
180 * MPSAFE
181 */
182 /* ARGSUSED */
183 int
184 setpriority(td, uap)
185 struct thread *td;
186 register struct setpriority_args *uap;
187 {
188 struct proc *curp = td->td_proc;
189 register struct proc *p;
190 int found = 0, error = 0;
191
192 switch (uap->which) {
193 case PRIO_PROCESS:
194 if (uap->who == 0) {
195 PROC_LOCK(curp);
196 error = donice(td, curp, uap->prio);
197 PROC_UNLOCK(curp);
198 } else {
199 p = pfind(uap->who);
200 if (p == 0)
201 break;
202 if (p_cansee(td, p) == 0)
203 error = donice(td, p, uap->prio);
204 PROC_UNLOCK(p);
205 }
206 found++;
207 break;
208
209 case PRIO_PGRP: {
210 register struct pgrp *pg;
211
212 sx_slock(&proctree_lock);
213 if (uap->who == 0) {
214 pg = curp->p_pgrp;
215 PGRP_LOCK(pg);
216 } else {
217 pg = pgfind(uap->who);
218 if (pg == NULL) {
219 sx_sunlock(&proctree_lock);
220 break;
221 }
222 }
223 sx_sunlock(&proctree_lock);
224 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
225 PROC_LOCK(p);
226 if (!p_cansee(td, p)) {
227 error = donice(td, p, uap->prio);
228 found++;
229 }
230 PROC_UNLOCK(p);
231 }
232 PGRP_UNLOCK(pg);
233 break;
234 }
235
236 case PRIO_USER:
237 if (uap->who == 0)
238 uap->who = td->td_ucred->cr_uid;
239 sx_slock(&allproc_lock);
240 FOREACH_PROC_IN_SYSTEM(p) {
241 PROC_LOCK(p);
242 if (p->p_ucred->cr_uid == uap->who &&
243 !p_cansee(td, p)) {
244 error = donice(td, p, uap->prio);
245 found++;
246 }
247 PROC_UNLOCK(p);
248 }
249 sx_sunlock(&allproc_lock);
250 break;
251
252 default:
253 error = EINVAL;
254 break;
255 }
256 if (found == 0 && error == 0)
257 error = ESRCH;
258 return (error);
259 }
260
261 /*
262 * Set "nice" for a process. Doesn't really understand threaded processes well
263 * but does try. Has the unfortunate side effect of making all the NICE
264 * values for a process's ksegrps the same.. This suggests that
265 * NICE valuse should be stored as a process nice and deltas for the ksegrps.
266 * (but not yet).
267 */
268 static int
269 donice(struct thread *td, struct proc *p, int n)
270 {
271 int error;
272 int low = PRIO_MAX + 1;
273 struct ksegrp *kg;
274
275 PROC_LOCK_ASSERT(p, MA_OWNED);
276 if ((error = p_cansched(td, p)))
277 return (error);
278 if (n > PRIO_MAX)
279 n = PRIO_MAX;
280 if (n < PRIO_MIN)
281 n = PRIO_MIN;
282 /*
283 * Only allow nicing if to more than the lowest nice.
284 * e.g. nices of 4,3,2 allow nice to 3 but not 1
285 */
286 FOREACH_KSEGRP_IN_PROC(p, kg) {
287 if (kg->kg_nice < low)
288 low = kg->kg_nice;
289 }
290 if (n < low && suser(td))
291 return (EACCES);
292 mtx_lock_spin(&sched_lock);
293 FOREACH_KSEGRP_IN_PROC(p, kg) {
294 sched_nice(kg, n);
295 }
296 mtx_unlock_spin(&sched_lock);
297 return (0);
298 }
299
300 /* rtprio system call */
301 #ifndef _SYS_SYSPROTO_H_
302 struct rtprio_args {
303 int function;
304 pid_t pid;
305 struct rtprio *rtp;
306 };
307 #endif
308
309 /*
310 * Set realtime priority
311 */
312
313 /*
314 * MPSAFE
315 */
316 /* ARGSUSED */
317 int
318 rtprio(td, uap)
319 struct thread *td;
320 register struct rtprio_args *uap;
321 {
322 struct proc *curp = td->td_proc;
323 register struct proc *p;
324 struct rtprio rtp;
325 int error, cierror = 0;
326
327 /* Perform copyin before acquiring locks if needed. */
328 if (uap->function == RTP_SET)
329 cierror = copyin(uap->rtp, &rtp, sizeof(struct rtprio));
330
331 if (uap->pid == 0) {
332 p = curp;
333 PROC_LOCK(p);
334 } else {
335 p = pfind(uap->pid);
336 if (p == NULL)
337 return (ESRCH);
338 }
339
340 switch (uap->function) {
341 case RTP_LOOKUP:
342 if ((error = p_cansee(td, p)))
343 break;
344 mtx_lock_spin(&sched_lock);
345 pri_to_rtp(FIRST_KSEGRP_IN_PROC(p), &rtp);
346 mtx_unlock_spin(&sched_lock);
347 PROC_UNLOCK(p);
348 return (copyout(&rtp, uap->rtp, sizeof(struct rtprio)));
349 case RTP_SET:
350 if ((error = p_cansched(td, p)) || (error = cierror))
351 break;
352 /* disallow setting rtprio in most cases if not superuser */
353 if (suser(td) != 0) {
354 /* can't set someone else's */
355 if (uap->pid) {
356 error = EPERM;
357 break;
358 }
359 /* can't set realtime priority */
360 /*
361 * Realtime priority has to be restricted for reasons which should be
362 * obvious. However, for idle priority, there is a potential for
363 * system deadlock if an idleprio process gains a lock on a resource
364 * that other processes need (and the idleprio process can't run
365 * due to a CPU-bound normal process). Fix me! XXX
366 */
367 #if 0
368 if (RTP_PRIO_IS_REALTIME(rtp.type))
369 #endif
370 if (rtp.type != RTP_PRIO_NORMAL) {
371 error = EPERM;
372 break;
373 }
374 }
375 mtx_lock_spin(&sched_lock);
376 error = rtp_to_pri(&rtp, FIRST_KSEGRP_IN_PROC(p));
377 mtx_unlock_spin(&sched_lock);
378 break;
379 default:
380 error = EINVAL;
381 break;
382 }
383 PROC_UNLOCK(p);
384 return (error);
385 }
386
387 int
388 rtp_to_pri(struct rtprio *rtp, struct ksegrp *kg)
389 {
390
391 mtx_assert(&sched_lock, MA_OWNED);
392 if (rtp->prio > RTP_PRIO_MAX)
393 return (EINVAL);
394 switch (RTP_PRIO_BASE(rtp->type)) {
395 case RTP_PRIO_REALTIME:
396 kg->kg_user_pri = PRI_MIN_REALTIME + rtp->prio;
397 break;
398 case RTP_PRIO_NORMAL:
399 kg->kg_user_pri = PRI_MIN_TIMESHARE + rtp->prio;
400 break;
401 case RTP_PRIO_IDLE:
402 kg->kg_user_pri = PRI_MIN_IDLE + rtp->prio;
403 break;
404 default:
405 return (EINVAL);
406 }
407 sched_class(kg, rtp->type);
408 if (curthread->td_ksegrp == kg) {
409 curthread->td_base_pri = kg->kg_user_pri;
410 curthread->td_priority = kg->kg_user_pri; /* XXX dubious */
411 }
412 return (0);
413 }
414
415 void
416 pri_to_rtp(struct ksegrp *kg, struct rtprio *rtp)
417 {
418
419 mtx_assert(&sched_lock, MA_OWNED);
420 switch (PRI_BASE(kg->kg_pri_class)) {
421 case PRI_REALTIME:
422 rtp->prio = kg->kg_user_pri - PRI_MIN_REALTIME;
423 break;
424 case PRI_TIMESHARE:
425 rtp->prio = kg->kg_user_pri - PRI_MIN_TIMESHARE;
426 break;
427 case PRI_IDLE:
428 rtp->prio = kg->kg_user_pri - PRI_MIN_IDLE;
429 break;
430 default:
431 break;
432 }
433 rtp->type = kg->kg_pri_class;
434 }
435
436 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
437 #ifndef _SYS_SYSPROTO_H_
438 struct osetrlimit_args {
439 u_int which;
440 struct orlimit *rlp;
441 };
442 #endif
443 /*
444 * MPSAFE
445 */
446 /* ARGSUSED */
447 int
448 osetrlimit(td, uap)
449 struct thread *td;
450 register struct osetrlimit_args *uap;
451 {
452 struct orlimit olim;
453 struct rlimit lim;
454 int error;
455
456 if ((error = copyin(uap->rlp, &olim, sizeof(struct orlimit))))
457 return (error);
458 lim.rlim_cur = olim.rlim_cur;
459 lim.rlim_max = olim.rlim_max;
460 mtx_lock(&Giant);
461 error = dosetrlimit(td, uap->which, &lim);
462 mtx_unlock(&Giant);
463 return (error);
464 }
465
466 #ifndef _SYS_SYSPROTO_H_
467 struct ogetrlimit_args {
468 u_int which;
469 struct orlimit *rlp;
470 };
471 #endif
472 /*
473 * MPSAFE
474 */
475 /* ARGSUSED */
476 int
477 ogetrlimit(td, uap)
478 struct thread *td;
479 register struct ogetrlimit_args *uap;
480 {
481 struct proc *p = td->td_proc;
482 struct orlimit olim;
483 int error;
484
485 if (uap->which >= RLIM_NLIMITS)
486 return (EINVAL);
487 mtx_lock(&Giant);
488 olim.rlim_cur = p->p_rlimit[uap->which].rlim_cur;
489 if (olim.rlim_cur == -1)
490 olim.rlim_cur = 0x7fffffff;
491 olim.rlim_max = p->p_rlimit[uap->which].rlim_max;
492 if (olim.rlim_max == -1)
493 olim.rlim_max = 0x7fffffff;
494 error = copyout(&olim, uap->rlp, sizeof(olim));
495 mtx_unlock(&Giant);
496 return (error);
497 }
498 #endif /* COMPAT_43 || COMPAT_SUNOS */
499
500 #ifndef _SYS_SYSPROTO_H_
501 struct __setrlimit_args {
502 u_int which;
503 struct rlimit *rlp;
504 };
505 #endif
506 /*
507 * MPSAFE
508 */
509 /* ARGSUSED */
510 int
511 setrlimit(td, uap)
512 struct thread *td;
513 register struct __setrlimit_args *uap;
514 {
515 struct rlimit alim;
516 int error;
517
518 if ((error = copyin(uap->rlp, &alim, sizeof (struct rlimit))))
519 return (error);
520 mtx_lock(&Giant);
521 error = dosetrlimit(td, uap->which, &alim);
522 mtx_unlock(&Giant);
523 return (error);
524 }
525
526 int
527 dosetrlimit(td, which, limp)
528 struct thread *td;
529 u_int which;
530 struct rlimit *limp;
531 {
532 struct proc *p = td->td_proc;
533 register struct rlimit *alimp;
534 int error;
535
536 GIANT_REQUIRED;
537
538 if (which >= RLIM_NLIMITS)
539 return (EINVAL);
540 alimp = &p->p_rlimit[which];
541
542 /*
543 * Preserve historical bugs by treating negative limits as unsigned.
544 */
545 if (limp->rlim_cur < 0)
546 limp->rlim_cur = RLIM_INFINITY;
547 if (limp->rlim_max < 0)
548 limp->rlim_max = RLIM_INFINITY;
549
550 if (limp->rlim_cur > alimp->rlim_max ||
551 limp->rlim_max > alimp->rlim_max)
552 if ((error = suser_cred(td->td_ucred, PRISON_ROOT)))
553 return (error);
554 if (limp->rlim_cur > limp->rlim_max)
555 limp->rlim_cur = limp->rlim_max;
556 if (p->p_limit->p_refcnt > 1) {
557 p->p_limit->p_refcnt--;
558 p->p_limit = limcopy(p->p_limit);
559 alimp = &p->p_rlimit[which];
560 }
561
562 switch (which) {
563
564 case RLIMIT_CPU:
565 mtx_lock_spin(&sched_lock);
566 p->p_cpulimit = limp->rlim_cur;
567 mtx_unlock_spin(&sched_lock);
568 break;
569 case RLIMIT_DATA:
570 if (limp->rlim_cur > maxdsiz)
571 limp->rlim_cur = maxdsiz;
572 if (limp->rlim_max > maxdsiz)
573 limp->rlim_max = maxdsiz;
574 break;
575
576 case RLIMIT_STACK:
577 if (limp->rlim_cur > maxssiz)
578 limp->rlim_cur = maxssiz;
579 if (limp->rlim_max > maxssiz)
580 limp->rlim_max = maxssiz;
581 /*
582 * Stack is allocated to the max at exec time with only
583 * "rlim_cur" bytes accessible. If stack limit is going
584 * up make more accessible, if going down make inaccessible.
585 */
586 if (limp->rlim_cur != alimp->rlim_cur) {
587 vm_offset_t addr;
588 vm_size_t size;
589 vm_prot_t prot;
590
591 if (limp->rlim_cur > alimp->rlim_cur) {
592 prot = p->p_sysent->sv_stackprot;
593 size = limp->rlim_cur - alimp->rlim_cur;
594 addr = p->p_sysent->sv_usrstack -
595 limp->rlim_cur;
596 } else {
597 prot = VM_PROT_NONE;
598 size = alimp->rlim_cur - limp->rlim_cur;
599 addr = p->p_sysent->sv_usrstack -
600 alimp->rlim_cur;
601 }
602 addr = trunc_page(addr);
603 size = round_page(size);
604 (void) vm_map_protect(&p->p_vmspace->vm_map,
605 addr, addr+size, prot, FALSE);
606 }
607 break;
608
609 case RLIMIT_NOFILE:
610 if (limp->rlim_cur > maxfilesperproc)
611 limp->rlim_cur = maxfilesperproc;
612 if (limp->rlim_max > maxfilesperproc)
613 limp->rlim_max = maxfilesperproc;
614 break;
615
616 case RLIMIT_NPROC:
617 if (limp->rlim_cur > maxprocperuid)
618 limp->rlim_cur = maxprocperuid;
619 if (limp->rlim_max > maxprocperuid)
620 limp->rlim_max = maxprocperuid;
621 if (limp->rlim_cur < 1)
622 limp->rlim_cur = 1;
623 if (limp->rlim_max < 1)
624 limp->rlim_max = 1;
625 break;
626 }
627 *alimp = *limp;
628 return (0);
629 }
630
631 #ifndef _SYS_SYSPROTO_H_
632 struct __getrlimit_args {
633 u_int which;
634 struct rlimit *rlp;
635 };
636 #endif
637 /*
638 * MPSAFE
639 */
640 /* ARGSUSED */
641 int
642 getrlimit(td, uap)
643 struct thread *td;
644 register struct __getrlimit_args *uap;
645 {
646 int error;
647 struct proc *p = td->td_proc;
648
649 if (uap->which >= RLIM_NLIMITS)
650 return (EINVAL);
651 mtx_lock(&Giant);
652 error = copyout(&p->p_rlimit[uap->which], uap->rlp,
653 sizeof (struct rlimit));
654 mtx_unlock(&Giant);
655 return(error);
656 }
657
658 /*
659 * Transform the running time and tick information in proc p into user,
660 * system, and interrupt time usage.
661 */
662 void
663 calcru(p, up, sp, ip)
664 struct proc *p;
665 struct timeval *up;
666 struct timeval *sp;
667 struct timeval *ip;
668 {
669 /* {user, system, interrupt, total} {ticks, usec}; previous tu: */
670 u_int64_t ut, uu, st, su, it, iu, tt, tu, ptu;
671 struct timeval tv;
672 struct bintime bt;
673
674 mtx_assert(&sched_lock, MA_OWNED);
675 /* XXX: why spl-protect ? worst case is an off-by-one report */
676
677 ut = p->p_uticks;
678 st = p->p_sticks;
679 it = p->p_iticks;
680
681 tt = ut + st + it;
682 if (tt == 0) {
683 st = 1;
684 tt = 1;
685 }
686
687 if (curthread->td_proc == p) {
688 /*
689 * Adjust for the current time slice. This is actually fairly
690 * important since the error here is on the order of a time
691 * quantum, which is much greater than the sampling error.
692 * XXXKSE use a different test due to threads on other
693 * processors also being 'current'.
694 */
695
696 binuptime(&bt);
697 bintime_sub(&bt, PCPU_PTR(switchtime));
698 bintime_add(&bt, &p->p_runtime);
699 } else {
700 bt = p->p_runtime;
701 }
702 bintime2timeval(&bt, &tv);
703 tu = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
704 ptu = p->p_uu + p->p_su + p->p_iu;
705 if (tu < ptu || (int64_t)tu < 0) {
706 /* XXX no %qd in kernel. Truncate. */
707 printf("calcru: negative time of %ld usec for pid %d (%s)\n",
708 (long)tu, p->p_pid, p->p_comm);
709 tu = ptu;
710 }
711
712 /* Subdivide tu. */
713 uu = (tu * ut) / tt;
714 su = (tu * st) / tt;
715 iu = tu - uu - su;
716
717 /* Enforce monotonicity. */
718 if (uu < p->p_uu || su < p->p_su || iu < p->p_iu) {
719 if (uu < p->p_uu)
720 uu = p->p_uu;
721 else if (uu + p->p_su + p->p_iu > tu)
722 uu = tu - p->p_su - p->p_iu;
723 if (st == 0)
724 su = p->p_su;
725 else {
726 su = ((tu - uu) * st) / (st + it);
727 if (su < p->p_su)
728 su = p->p_su;
729 else if (uu + su + p->p_iu > tu)
730 su = tu - uu - p->p_iu;
731 }
732 KASSERT(uu + su + p->p_iu <= tu,
733 ("calcru: monotonisation botch 1"));
734 iu = tu - uu - su;
735 KASSERT(iu >= p->p_iu,
736 ("calcru: monotonisation botch 2"));
737 }
738 p->p_uu = uu;
739 p->p_su = su;
740 p->p_iu = iu;
741
742 up->tv_sec = uu / 1000000;
743 up->tv_usec = uu % 1000000;
744 sp->tv_sec = su / 1000000;
745 sp->tv_usec = su % 1000000;
746 if (ip != NULL) {
747 ip->tv_sec = iu / 1000000;
748 ip->tv_usec = iu % 1000000;
749 }
750 }
751
752 #ifndef _SYS_SYSPROTO_H_
753 struct getrusage_args {
754 int who;
755 struct rusage *rusage;
756 };
757 #endif
758 /*
759 * MPSAFE
760 */
761 /* ARGSUSED */
762 int
763 getrusage(td, uap)
764 register struct thread *td;
765 register struct getrusage_args *uap;
766 {
767 struct proc *p = td->td_proc;
768 register struct rusage *rup;
769 int error = 0;
770
771 mtx_lock(&Giant);
772
773 switch (uap->who) {
774 case RUSAGE_SELF:
775 rup = &p->p_stats->p_ru;
776 mtx_lock_spin(&sched_lock);
777 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
778 mtx_unlock_spin(&sched_lock);
779 break;
780
781 case RUSAGE_CHILDREN:
782 rup = &p->p_stats->p_cru;
783 break;
784
785 default:
786 rup = NULL;
787 error = EINVAL;
788 break;
789 }
790 mtx_unlock(&Giant);
791 if (error == 0) {
792 /* XXX Unlocked access to p_stats->p_ru or p_cru. */
793 error = copyout(rup, uap->rusage, sizeof (struct rusage));
794 }
795 return(error);
796 }
797
798 void
799 ruadd(ru, ru2)
800 register struct rusage *ru, *ru2;
801 {
802 register long *ip, *ip2;
803 register int i;
804
805 timevaladd(&ru->ru_utime, &ru2->ru_utime);
806 timevaladd(&ru->ru_stime, &ru2->ru_stime);
807 if (ru->ru_maxrss < ru2->ru_maxrss)
808 ru->ru_maxrss = ru2->ru_maxrss;
809 ip = &ru->ru_first; ip2 = &ru2->ru_first;
810 for (i = &ru->ru_last - &ru->ru_first; i >= 0; i--)
811 *ip++ += *ip2++;
812 }
813
814 /*
815 * Make a copy of the plimit structure.
816 * We share these structures copy-on-write after fork,
817 * and copy when a limit is changed.
818 */
819 struct plimit *
820 limcopy(lim)
821 struct plimit *lim;
822 {
823 register struct plimit *copy;
824
825 MALLOC(copy, struct plimit *, sizeof(struct plimit),
826 M_SUBPROC, M_WAITOK);
827 bcopy(lim->pl_rlimit, copy->pl_rlimit, sizeof(struct plimit));
828 copy->p_refcnt = 1;
829 return (copy);
830 }
831
832 /*
833 * Find the uidinfo structure for a uid. This structure is used to
834 * track the total resource consumption (process count, socket buffer
835 * size, etc.) for the uid and impose limits.
836 */
837 void
838 uihashinit()
839 {
840
841 uihashtbl = hashinit(maxproc / 16, M_UIDINFO, &uihash);
842 mtx_init(&uihashtbl_mtx, "uidinfo hash", NULL, MTX_DEF);
843 }
844
845 /*
846 * lookup a uidinfo struct for the parameter uid.
847 * uihashtbl_mtx must be locked.
848 */
849 static struct uidinfo *
850 uilookup(uid)
851 uid_t uid;
852 {
853 struct uihashhead *uipp;
854 struct uidinfo *uip;
855
856 mtx_assert(&uihashtbl_mtx, MA_OWNED);
857 uipp = UIHASH(uid);
858 LIST_FOREACH(uip, uipp, ui_hash)
859 if (uip->ui_uid == uid)
860 break;
861
862 return (uip);
863 }
864
865 /*
866 * Find or allocate a struct uidinfo for a particular uid.
867 * Increase refcount on uidinfo struct returned.
868 * uifree() should be called on a struct uidinfo when released.
869 */
870 struct uidinfo *
871 uifind(uid)
872 uid_t uid;
873 {
874 struct uidinfo *uip;
875
876 mtx_lock(&uihashtbl_mtx);
877 uip = uilookup(uid);
878 if (uip == NULL) {
879 struct uidinfo *old_uip;
880
881 mtx_unlock(&uihashtbl_mtx);
882 uip = malloc(sizeof(*uip), M_UIDINFO, M_WAITOK | M_ZERO);
883 mtx_lock(&uihashtbl_mtx);
884 /*
885 * There's a chance someone created our uidinfo while we
886 * were in malloc and not holding the lock, so we have to
887 * make sure we don't insert a duplicate uidinfo
888 */
889 if ((old_uip = uilookup(uid)) != NULL) {
890 /* someone else beat us to it */
891 free(uip, M_UIDINFO);
892 uip = old_uip;
893 } else {
894 uip->ui_mtxp = mtx_pool_alloc();
895 uip->ui_uid = uid;
896 LIST_INSERT_HEAD(UIHASH(uid), uip, ui_hash);
897 }
898 }
899 uihold(uip);
900 mtx_unlock(&uihashtbl_mtx);
901 return (uip);
902 }
903
904 /*
905 * Place another refcount on a uidinfo struct.
906 */
907 void
908 uihold(uip)
909 struct uidinfo *uip;
910 {
911
912 UIDINFO_LOCK(uip);
913 uip->ui_ref++;
914 UIDINFO_UNLOCK(uip);
915 }
916
917 /*-
918 * Since uidinfo structs have a long lifetime, we use an
919 * opportunistic refcounting scheme to avoid locking the lookup hash
920 * for each release.
921 *
922 * If the refcount hits 0, we need to free the structure,
923 * which means we need to lock the hash.
924 * Optimal case:
925 * After locking the struct and lowering the refcount, if we find
926 * that we don't need to free, simply unlock and return.
927 * Suboptimal case:
928 * If refcount lowering results in need to free, bump the count
929 * back up, loose the lock and aquire the locks in the proper
930 * order to try again.
931 */
932 void
933 uifree(uip)
934 struct uidinfo *uip;
935 {
936
937 /* Prepare for optimal case. */
938 UIDINFO_LOCK(uip);
939
940 if (--uip->ui_ref != 0) {
941 UIDINFO_UNLOCK(uip);
942 return;
943 }
944
945 /* Prepare for suboptimal case. */
946 uip->ui_ref++;
947 UIDINFO_UNLOCK(uip);
948 mtx_lock(&uihashtbl_mtx);
949 UIDINFO_LOCK(uip);
950
951 /*
952 * We must subtract one from the count again because we backed out
953 * our initial subtraction before dropping the lock.
954 * Since another thread may have added a reference after we dropped the
955 * initial lock we have to test for zero again.
956 */
957 if (--uip->ui_ref == 0) {
958 LIST_REMOVE(uip, ui_hash);
959 mtx_unlock(&uihashtbl_mtx);
960 if (uip->ui_sbsize != 0)
961 /* XXX no %qd in kernel. Truncate. */
962 printf("freeing uidinfo: uid = %d, sbsize = %ld\n",
963 uip->ui_uid, (long)uip->ui_sbsize);
964 if (uip->ui_proccnt != 0)
965 printf("freeing uidinfo: uid = %d, proccnt = %ld\n",
966 uip->ui_uid, uip->ui_proccnt);
967 UIDINFO_UNLOCK(uip);
968 FREE(uip, M_UIDINFO);
969 return;
970 }
971
972 mtx_unlock(&uihashtbl_mtx);
973 UIDINFO_UNLOCK(uip);
974 }
975
976 /*
977 * Change the count associated with number of processes
978 * a given user is using. When 'max' is 0, don't enforce a limit
979 */
980 int
981 chgproccnt(uip, diff, max)
982 struct uidinfo *uip;
983 int diff;
984 int max;
985 {
986
987 UIDINFO_LOCK(uip);
988 /* don't allow them to exceed max, but allow subtraction */
989 if (diff > 0 && uip->ui_proccnt + diff > max && max != 0) {
990 UIDINFO_UNLOCK(uip);
991 return (0);
992 }
993 uip->ui_proccnt += diff;
994 if (uip->ui_proccnt < 0)
995 printf("negative proccnt for uid = %d\n", uip->ui_uid);
996 UIDINFO_UNLOCK(uip);
997 return (1);
998 }
999
1000 /*
1001 * Change the total socket buffer size a user has used.
1002 */
1003 int
1004 chgsbsize(uip, hiwat, to, max)
1005 struct uidinfo *uip;
1006 u_int *hiwat;
1007 u_int to;
1008 rlim_t max;
1009 {
1010 rlim_t new;
1011 int s;
1012
1013 s = splnet();
1014 UIDINFO_LOCK(uip);
1015 new = uip->ui_sbsize + to - *hiwat;
1016 /* don't allow them to exceed max, but allow subtraction */
1017 if (to > *hiwat && new > max) {
1018 splx(s);
1019 UIDINFO_UNLOCK(uip);
1020 return (0);
1021 }
1022 uip->ui_sbsize = new;
1023 *hiwat = to;
1024 if (uip->ui_sbsize < 0)
1025 printf("negative sbsize for uid = %d\n", uip->ui_uid);
1026 splx(s);
1027 UIDINFO_UNLOCK(uip);
1028 return (1);
1029 }
Cache object: b094c6d5a43c1aa7438c24bc8573bd54
|