1*17400Skarels /* kern_resource.c 6.4 84/11/20 */ 27Sbill 317092Sbloom #include "param.h" 417092Sbloom #include "systm.h" 517092Sbloom #include "dir.h" 617092Sbloom #include "user.h" 717092Sbloom #include "inode.h" 817092Sbloom #include "proc.h" 917092Sbloom #include "seg.h" 1017092Sbloom #include "fs.h" 1117092Sbloom #include "uio.h" 1217092Sbloom #include "vm.h" 1317092Sbloom #include "kernel.h" 147Sbill 158176Sroot /* 168176Sroot * Resource controls and accounting. 178176Sroot */ 188176Sroot 198031Sroot getpriority() 208031Sroot { 218031Sroot register struct a { 228031Sroot int which; 238031Sroot int who; 248031Sroot } *uap = (struct a *)u.u_ap; 258031Sroot register struct proc *p; 26*17400Skarels int low = PRIO_MAX + 1; 278031Sroot 288031Sroot switch (uap->which) { 298031Sroot 308031Sroot case PRIO_PROCESS: 318031Sroot if (uap->who == 0) 328031Sroot p = u.u_procp; 338031Sroot else 348031Sroot p = pfind(uap->who); 358031Sroot if (p == 0) 368031Sroot return; 37*17400Skarels low = p->p_nice; 388031Sroot break; 398031Sroot 408031Sroot case PRIO_PGRP: 418031Sroot if (uap->who == 0) 428031Sroot uap->who = u.u_procp->p_pgrp; 4316530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 448031Sroot if (p->p_pgrp == uap->who && 45*17400Skarels p->p_nice < low) 46*17400Skarels low = p->p_nice; 478176Sroot } 488031Sroot break; 498031Sroot 508176Sroot case PRIO_USER: 518176Sroot if (uap->who == 0) 528176Sroot uap->who = u.u_uid; 5316530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 548176Sroot if (p->p_uid == uap->who && 55*17400Skarels p->p_nice < low) 56*17400Skarels low = p->p_nice; 578176Sroot } 588176Sroot break; 598176Sroot 608031Sroot default: 618031Sroot u.u_error = EINVAL; 62*17400Skarels return; 638031Sroot } 64*17400Skarels if (low == PRIO_MAX + 1) { 65*17400Skarels u.u_error = ESRCH; 66*17400Skarels return; 67*17400Skarels } 68*17400Skarels u.u_r.r_val1 = low; 698031Sroot } 708031Sroot 718031Sroot setpriority() 728031Sroot { 738031Sroot register struct a { 748031Sroot int which; 758031Sroot int who; 768031Sroot int prio; 778031Sroot } *uap = (struct a *)u.u_ap; 788031Sroot register struct proc *p; 79*17400Skarels int found = 0; 808031Sroot 818031Sroot switch (uap->which) { 828031Sroot 838031Sroot case PRIO_PROCESS: 848176Sroot if (uap->who == 0) 858176Sroot p = u.u_procp; 868176Sroot else 878176Sroot p = pfind(uap->who); 888031Sroot if (p == 0) 898031Sroot return; 908031Sroot donice(p, uap->prio); 91*17400Skarels found++; 928031Sroot break; 938031Sroot 948031Sroot case PRIO_PGRP: 958176Sroot if (uap->who == 0) 968176Sroot uap->who = u.u_procp->p_pgrp; 9716530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 98*17400Skarels if (p->p_pgrp == uap->who) { 998031Sroot donice(p, uap->prio); 100*17400Skarels found++; 101*17400Skarels } 1028031Sroot break; 1038031Sroot 1048176Sroot case PRIO_USER: 1058176Sroot if (uap->who == 0) 1068176Sroot uap->who = u.u_uid; 10716530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 108*17400Skarels if (p->p_uid == uap->who) { 1098176Sroot donice(p, uap->prio); 110*17400Skarels found++; 111*17400Skarels } 1128176Sroot break; 1138176Sroot 1148031Sroot default: 1158031Sroot u.u_error = EINVAL; 116*17400Skarels return; 1178031Sroot } 118*17400Skarels if (found == 0) 119*17400Skarels u.u_error = ESRCH; 1208031Sroot } 1218031Sroot 1228031Sroot donice(p, n) 1238031Sroot register struct proc *p; 1248031Sroot register int n; 1258031Sroot { 1268031Sroot 1278031Sroot if (u.u_uid && u.u_ruid && 1288031Sroot u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 1298176Sroot u.u_error = EACCES; 1308031Sroot return; 1318031Sroot } 132*17400Skarels if (n > PRIO_MAX) 133*17400Skarels n = PRIO_MAX; 134*17400Skarels if (n < PRIO_MIN) 135*17400Skarels n = PRIO_MIN; 1368176Sroot if (n < p->p_nice && !suser()) { 1378176Sroot u.u_error = EACCES; 1388031Sroot return; 1398176Sroot } 1408031Sroot p->p_nice = n; 1418031Sroot (void) setpri(p); 1428031Sroot } 1438031Sroot 1448100Sroot setrlimit() 1458031Sroot { 1468031Sroot register struct a { 1478031Sroot u_int which; 1488031Sroot struct rlimit *lim; 1498031Sroot } *uap = (struct a *)u.u_ap; 1508031Sroot struct rlimit alim; 1518031Sroot register struct rlimit *alimp; 1528031Sroot 1538031Sroot if (uap->which >= RLIM_NLIMITS) { 1548031Sroot u.u_error = EINVAL; 1558031Sroot return; 1568031Sroot } 1578031Sroot alimp = &u.u_rlimit[uap->which]; 1589997Ssam u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 1599997Ssam sizeof (struct rlimit)); 1609997Ssam if (u.u_error) 1618031Sroot return; 1628031Sroot if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 1638031Sroot if (!suser()) 1648031Sroot return; 1658031Sroot switch (uap->which) { 1668031Sroot 1678031Sroot case RLIMIT_DATA: 1688031Sroot if (alim.rlim_cur > ctob(MAXDSIZ)) 1698031Sroot alim.rlim_cur = ctob(MAXDSIZ); 1708031Sroot break; 1718031Sroot 1728031Sroot case RLIMIT_STACK: 1738031Sroot if (alim.rlim_cur > ctob(MAXSSIZ)) 1748031Sroot alim.rlim_cur = ctob(MAXSSIZ); 1758031Sroot break; 1768031Sroot } 1778031Sroot *alimp = alim; 1788031Sroot if (uap->which == RLIMIT_RSS) 1798031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1808031Sroot } 1818031Sroot 1828100Sroot getrlimit() 1838031Sroot { 1848031Sroot register struct a { 1858031Sroot u_int which; 1868031Sroot struct rlimit *rlp; 1878031Sroot } *uap = (struct a *)u.u_ap; 1888031Sroot 1898031Sroot if (uap->which >= RLIM_NLIMITS) { 1908031Sroot u.u_error = EINVAL; 1918031Sroot return; 1928031Sroot } 1939997Ssam u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 1949997Ssam sizeof (struct rlimit)); 1958031Sroot } 1968031Sroot 1978031Sroot getrusage() 1988031Sroot { 1998031Sroot register struct a { 2008031Sroot int who; 2018031Sroot struct rusage *rusage; 2028031Sroot } *uap = (struct a *)u.u_ap; 2038031Sroot register struct rusage *rup; 2048031Sroot 2058031Sroot switch (uap->who) { 2068031Sroot 2078031Sroot case RUSAGE_SELF: 2088031Sroot rup = &u.u_ru; 2098031Sroot break; 2108031Sroot 2118031Sroot case RUSAGE_CHILDREN: 2128031Sroot rup = &u.u_cru; 2138031Sroot break; 2148031Sroot 2158031Sroot default: 2168031Sroot u.u_error = EINVAL; 2178031Sroot return; 2188031Sroot } 2199997Ssam u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 2209997Ssam sizeof (struct rusage)); 2218031Sroot } 2228031Sroot 2238031Sroot ruadd(ru, ru2) 2248031Sroot register struct rusage *ru, *ru2; 2258031Sroot { 2268666Sroot register long *ip, *ip2; 2278031Sroot register int i; 2288031Sroot 2298031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2308031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2318031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2328031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2338031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2348031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2358031Sroot *ip++ += *ip2++; 2368031Sroot } 237