1*21001Smckusick /* kern_resource.c 6.6 85/05/22 */ 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; 2617400Skarels 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; 3717400Skarels 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 && 4517400Skarels p->p_nice < low) 4617400Skarels 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 && 5517400Skarels p->p_nice < low) 5617400Skarels low = p->p_nice; 578176Sroot } 588176Sroot break; 598176Sroot 608031Sroot default: 618031Sroot u.u_error = EINVAL; 6217400Skarels return; 638031Sroot } 6417400Skarels if (low == PRIO_MAX + 1) { 6517400Skarels u.u_error = ESRCH; 6617400Skarels return; 6717400Skarels } 6817400Skarels 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; 7917400Skarels 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); 9117400Skarels 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) 9817400Skarels if (p->p_pgrp == uap->who) { 998031Sroot donice(p, uap->prio); 10017400Skarels found++; 10117400Skarels } 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) 10817400Skarels if (p->p_uid == uap->who) { 1098176Sroot donice(p, uap->prio); 11017400Skarels found++; 11117400Skarels } 1128176Sroot break; 1138176Sroot 1148031Sroot default: 1158031Sroot u.u_error = EINVAL; 11617400Skarels return; 1178031Sroot } 11817400Skarels if (found == 0) 11917400Skarels 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) { 129*21001Smckusick u.u_error = EPERM; 1308031Sroot return; 1318031Sroot } 13217400Skarels if (n > PRIO_MAX) 13317400Skarels n = PRIO_MAX; 13417400Skarels if (n < PRIO_MIN) 13517400Skarels 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; 15218279Smckusick extern int maxdmap; 1538031Sroot 1548031Sroot if (uap->which >= RLIM_NLIMITS) { 1558031Sroot u.u_error = EINVAL; 1568031Sroot return; 1578031Sroot } 1588031Sroot alimp = &u.u_rlimit[uap->which]; 1599997Ssam u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 1609997Ssam sizeof (struct rlimit)); 1619997Ssam if (u.u_error) 1628031Sroot return; 1638031Sroot if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 1648031Sroot if (!suser()) 1658031Sroot return; 1668031Sroot switch (uap->which) { 1678031Sroot 1688031Sroot case RLIMIT_DATA: 16918279Smckusick if (alim.rlim_cur > maxdmap) 17018279Smckusick alim.rlim_cur = maxdmap; 17118279Smckusick if (alim.rlim_max > maxdmap) 17218279Smckusick alim.rlim_max = maxdmap; 1738031Sroot break; 1748031Sroot 1758031Sroot case RLIMIT_STACK: 17618279Smckusick if (alim.rlim_cur > maxdmap) 17718279Smckusick alim.rlim_cur = maxdmap; 17818279Smckusick if (alim.rlim_max > maxdmap) 17918279Smckusick alim.rlim_max = maxdmap; 1808031Sroot break; 1818031Sroot } 1828031Sroot *alimp = alim; 1838031Sroot if (uap->which == RLIMIT_RSS) 1848031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1858031Sroot } 1868031Sroot 1878100Sroot getrlimit() 1888031Sroot { 1898031Sroot register struct a { 1908031Sroot u_int which; 1918031Sroot struct rlimit *rlp; 1928031Sroot } *uap = (struct a *)u.u_ap; 1938031Sroot 1948031Sroot if (uap->which >= RLIM_NLIMITS) { 1958031Sroot u.u_error = EINVAL; 1968031Sroot return; 1978031Sroot } 1989997Ssam u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 1999997Ssam sizeof (struct rlimit)); 2008031Sroot } 2018031Sroot 2028031Sroot getrusage() 2038031Sroot { 2048031Sroot register struct a { 2058031Sroot int who; 2068031Sroot struct rusage *rusage; 2078031Sroot } *uap = (struct a *)u.u_ap; 2088031Sroot register struct rusage *rup; 2098031Sroot 2108031Sroot switch (uap->who) { 2118031Sroot 2128031Sroot case RUSAGE_SELF: 2138031Sroot rup = &u.u_ru; 2148031Sroot break; 2158031Sroot 2168031Sroot case RUSAGE_CHILDREN: 2178031Sroot rup = &u.u_cru; 2188031Sroot break; 2198031Sroot 2208031Sroot default: 2218031Sroot u.u_error = EINVAL; 2228031Sroot return; 2238031Sroot } 2249997Ssam u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 2259997Ssam sizeof (struct rusage)); 2268031Sroot } 2278031Sroot 2288031Sroot ruadd(ru, ru2) 2298031Sroot register struct rusage *ru, *ru2; 2308031Sroot { 2318666Sroot register long *ip, *ip2; 2328031Sroot register int i; 2338031Sroot 2348031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2358031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2368031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2378031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2388031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2398031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2408031Sroot *ip++ += *ip2++; 2418031Sroot } 242