123373Smckusick /* 229093Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323373Smckusick * All rights reserved. The Berkeley software License Agreement 423373Smckusick * specifies the terms and conditions for redistribution. 523373Smckusick * 6*37553Smckusick * @(#)kern_resource.c 7.4 (Berkeley) 04/26/89 723373Smckusick */ 87Sbill 917092Sbloom #include "param.h" 1017092Sbloom #include "dir.h" 1117092Sbloom #include "user.h" 1217092Sbloom #include "proc.h" 137Sbill 148176Sroot /* 158176Sroot * Resource controls and accounting. 168176Sroot */ 178176Sroot 188031Sroot getpriority() 198031Sroot { 208031Sroot register struct a { 218031Sroot int which; 228031Sroot int who; 238031Sroot } *uap = (struct a *)u.u_ap; 248031Sroot register struct proc *p; 2535810Smarc register int low = PRIO_MAX + 1; 268031Sroot 278031Sroot switch (uap->which) { 288031Sroot 298031Sroot case PRIO_PROCESS: 308031Sroot if (uap->who == 0) 318031Sroot p = u.u_procp; 328031Sroot else 338031Sroot p = pfind(uap->who); 348031Sroot if (p == 0) 3528149Skarels break; 3617400Skarels low = p->p_nice; 378031Sroot break; 388031Sroot 3935810Smarc case PRIO_PGRP: { 4035810Smarc register struct pgrp *pg; 4135810Smarc 428031Sroot if (uap->who == 0) 4335810Smarc pg = u.u_procp->p_pgrp; 4435810Smarc else if ((pg = pgfind(uap->who)) == NULL) 4535810Smarc break; 4635810Smarc for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 4735810Smarc if (p->p_nice < low) 4817400Skarels low = p->p_nice; 498176Sroot } 508031Sroot break; 5135810Smarc } 528031Sroot 538176Sroot case PRIO_USER: 548176Sroot if (uap->who == 0) 558176Sroot uap->who = u.u_uid; 5616530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 578176Sroot if (p->p_uid == uap->who && 5817400Skarels p->p_nice < low) 5917400Skarels low = p->p_nice; 608176Sroot } 618176Sroot break; 628176Sroot 638031Sroot default: 648031Sroot u.u_error = EINVAL; 6517400Skarels return; 668031Sroot } 6717400Skarels if (low == PRIO_MAX + 1) { 6817400Skarels u.u_error = ESRCH; 6917400Skarels return; 7017400Skarels } 7117400Skarels u.u_r.r_val1 = low; 728031Sroot } 738031Sroot 748031Sroot setpriority() 758031Sroot { 768031Sroot register struct a { 778031Sroot int which; 788031Sroot int who; 798031Sroot int prio; 808031Sroot } *uap = (struct a *)u.u_ap; 818031Sroot register struct proc *p; 8217400Skarels int found = 0; 838031Sroot 848031Sroot switch (uap->which) { 858031Sroot 868031Sroot case PRIO_PROCESS: 878176Sroot if (uap->who == 0) 888176Sroot p = u.u_procp; 898176Sroot else 908176Sroot p = pfind(uap->who); 918031Sroot if (p == 0) 9228149Skarels break; 938031Sroot donice(p, uap->prio); 9417400Skarels found++; 958031Sroot break; 968031Sroot 9735810Smarc case PRIO_PGRP: { 9835810Smarc register struct pgrp *pg; 9935810Smarc 1008176Sroot if (uap->who == 0) 10135810Smarc pg = u.u_procp->p_pgrp; 10235810Smarc else if ((pg = pgfind(uap->who)) == NULL) 10335810Smarc break; 10435810Smarc for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) { 10535810Smarc donice(p, uap->prio); 10635810Smarc found++; 10735810Smarc } 1088031Sroot break; 10935810Smarc } 1108031Sroot 1118176Sroot case PRIO_USER: 1128176Sroot if (uap->who == 0) 1138176Sroot uap->who = u.u_uid; 11416530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 11517400Skarels if (p->p_uid == uap->who) { 1168176Sroot donice(p, uap->prio); 11717400Skarels found++; 11817400Skarels } 1198176Sroot break; 1208176Sroot 1218031Sroot default: 1228031Sroot u.u_error = EINVAL; 12317400Skarels return; 1248031Sroot } 12517400Skarels if (found == 0) 12617400Skarels u.u_error = ESRCH; 1278031Sroot } 1288031Sroot 1298031Sroot donice(p, n) 1308031Sroot register struct proc *p; 1318031Sroot register int n; 1328031Sroot { 1338031Sroot 1348031Sroot if (u.u_uid && u.u_ruid && 1358031Sroot u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 13621001Smckusick u.u_error = EPERM; 1378031Sroot return; 1388031Sroot } 13917400Skarels if (n > PRIO_MAX) 14017400Skarels n = PRIO_MAX; 14117400Skarels if (n < PRIO_MIN) 14217400Skarels n = PRIO_MIN; 143*37553Smckusick if (n < p->p_nice && suser(u.u_cred, &u.u_acflag)) { 1448176Sroot u.u_error = EACCES; 1458031Sroot return; 1468176Sroot } 1478031Sroot p->p_nice = n; 1488031Sroot (void) setpri(p); 1498031Sroot } 1508031Sroot 1518100Sroot setrlimit() 1528031Sroot { 1538031Sroot register struct a { 1548031Sroot u_int which; 1558031Sroot struct rlimit *lim; 1568031Sroot } *uap = (struct a *)u.u_ap; 1578031Sroot struct rlimit alim; 1588031Sroot register struct rlimit *alimp; 15925257Skarels extern unsigned maxdmap; 1608031Sroot 1618031Sroot if (uap->which >= RLIM_NLIMITS) { 1628031Sroot u.u_error = EINVAL; 1638031Sroot return; 1648031Sroot } 1658031Sroot alimp = &u.u_rlimit[uap->which]; 1669997Ssam u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 1679997Ssam sizeof (struct rlimit)); 1689997Ssam if (u.u_error) 1698031Sroot return; 1708031Sroot if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 171*37553Smckusick if (u.u_error = suser(u.u_cred, &u.u_acflag)) 1728031Sroot return; 1738031Sroot switch (uap->which) { 1748031Sroot 1758031Sroot case RLIMIT_DATA: 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 case RLIMIT_STACK: 18318279Smckusick if (alim.rlim_cur > maxdmap) 18418279Smckusick alim.rlim_cur = maxdmap; 18518279Smckusick if (alim.rlim_max > maxdmap) 18618279Smckusick alim.rlim_max = maxdmap; 1878031Sroot break; 1888031Sroot } 1898031Sroot *alimp = alim; 1908031Sroot if (uap->which == RLIMIT_RSS) 1918031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1928031Sroot } 1938031Sroot 1948100Sroot getrlimit() 1958031Sroot { 1968031Sroot register struct a { 1978031Sroot u_int which; 1988031Sroot struct rlimit *rlp; 1998031Sroot } *uap = (struct a *)u.u_ap; 2008031Sroot 2018031Sroot if (uap->which >= RLIM_NLIMITS) { 2028031Sroot u.u_error = EINVAL; 2038031Sroot return; 2048031Sroot } 2059997Ssam u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 2069997Ssam sizeof (struct rlimit)); 2078031Sroot } 2088031Sroot 2098031Sroot getrusage() 2108031Sroot { 2118031Sroot register struct a { 2128031Sroot int who; 2138031Sroot struct rusage *rusage; 2148031Sroot } *uap = (struct a *)u.u_ap; 2158031Sroot register struct rusage *rup; 2168031Sroot 2178031Sroot switch (uap->who) { 2188031Sroot 2198031Sroot case RUSAGE_SELF: 2208031Sroot rup = &u.u_ru; 2218031Sroot break; 2228031Sroot 2238031Sroot case RUSAGE_CHILDREN: 2248031Sroot rup = &u.u_cru; 2258031Sroot break; 2268031Sroot 2278031Sroot default: 2288031Sroot u.u_error = EINVAL; 2298031Sroot return; 2308031Sroot } 2319997Ssam u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 2329997Ssam sizeof (struct rusage)); 2338031Sroot } 2348031Sroot 2358031Sroot ruadd(ru, ru2) 2368031Sroot register struct rusage *ru, *ru2; 2378031Sroot { 2388666Sroot register long *ip, *ip2; 2398031Sroot register int i; 2408031Sroot 2418031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2428031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2438031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2448031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2458031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2468031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2478031Sroot *ip++ += *ip2++; 2488031Sroot } 249