1*23373Smckusick /* 2*23373Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23373Smckusick * All rights reserved. The Berkeley software License Agreement 4*23373Smckusick * specifies the terms and conditions for redistribution. 5*23373Smckusick * 6*23373Smckusick * @(#)kern_resource.c 6.7 (Berkeley) 06/08/85 7*23373Smckusick */ 87Sbill 917092Sbloom #include "param.h" 1017092Sbloom #include "systm.h" 1117092Sbloom #include "dir.h" 1217092Sbloom #include "user.h" 1317092Sbloom #include "inode.h" 1417092Sbloom #include "proc.h" 1517092Sbloom #include "seg.h" 1617092Sbloom #include "fs.h" 1717092Sbloom #include "uio.h" 1817092Sbloom #include "vm.h" 1917092Sbloom #include "kernel.h" 207Sbill 218176Sroot /* 228176Sroot * Resource controls and accounting. 238176Sroot */ 248176Sroot 258031Sroot getpriority() 268031Sroot { 278031Sroot register struct a { 288031Sroot int which; 298031Sroot int who; 308031Sroot } *uap = (struct a *)u.u_ap; 318031Sroot register struct proc *p; 3217400Skarels int low = PRIO_MAX + 1; 338031Sroot 348031Sroot switch (uap->which) { 358031Sroot 368031Sroot case PRIO_PROCESS: 378031Sroot if (uap->who == 0) 388031Sroot p = u.u_procp; 398031Sroot else 408031Sroot p = pfind(uap->who); 418031Sroot if (p == 0) 428031Sroot return; 4317400Skarels low = p->p_nice; 448031Sroot break; 458031Sroot 468031Sroot case PRIO_PGRP: 478031Sroot if (uap->who == 0) 488031Sroot uap->who = u.u_procp->p_pgrp; 4916530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 508031Sroot if (p->p_pgrp == uap->who && 5117400Skarels p->p_nice < low) 5217400Skarels low = p->p_nice; 538176Sroot } 548031Sroot break; 558031Sroot 568176Sroot case PRIO_USER: 578176Sroot if (uap->who == 0) 588176Sroot uap->who = u.u_uid; 5916530Skarels for (p = allproc; p != NULL; p = p->p_nxt) { 608176Sroot if (p->p_uid == uap->who && 6117400Skarels p->p_nice < low) 6217400Skarels low = p->p_nice; 638176Sroot } 648176Sroot break; 658176Sroot 668031Sroot default: 678031Sroot u.u_error = EINVAL; 6817400Skarels return; 698031Sroot } 7017400Skarels if (low == PRIO_MAX + 1) { 7117400Skarels u.u_error = ESRCH; 7217400Skarels return; 7317400Skarels } 7417400Skarels u.u_r.r_val1 = low; 758031Sroot } 768031Sroot 778031Sroot setpriority() 788031Sroot { 798031Sroot register struct a { 808031Sroot int which; 818031Sroot int who; 828031Sroot int prio; 838031Sroot } *uap = (struct a *)u.u_ap; 848031Sroot register struct proc *p; 8517400Skarels int found = 0; 868031Sroot 878031Sroot switch (uap->which) { 888031Sroot 898031Sroot case PRIO_PROCESS: 908176Sroot if (uap->who == 0) 918176Sroot p = u.u_procp; 928176Sroot else 938176Sroot p = pfind(uap->who); 948031Sroot if (p == 0) 958031Sroot return; 968031Sroot donice(p, uap->prio); 9717400Skarels found++; 988031Sroot break; 998031Sroot 1008031Sroot case PRIO_PGRP: 1018176Sroot if (uap->who == 0) 1028176Sroot uap->who = u.u_procp->p_pgrp; 10316530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 10417400Skarels if (p->p_pgrp == uap->who) { 1058031Sroot donice(p, uap->prio); 10617400Skarels found++; 10717400Skarels } 1088031Sroot break; 1098031Sroot 1108176Sroot case PRIO_USER: 1118176Sroot if (uap->who == 0) 1128176Sroot uap->who = u.u_uid; 11316530Skarels for (p = allproc; p != NULL; p = p->p_nxt) 11417400Skarels if (p->p_uid == uap->who) { 1158176Sroot donice(p, uap->prio); 11617400Skarels found++; 11717400Skarels } 1188176Sroot break; 1198176Sroot 1208031Sroot default: 1218031Sroot u.u_error = EINVAL; 12217400Skarels return; 1238031Sroot } 12417400Skarels if (found == 0) 12517400Skarels u.u_error = ESRCH; 1268031Sroot } 1278031Sroot 1288031Sroot donice(p, n) 1298031Sroot register struct proc *p; 1308031Sroot register int n; 1318031Sroot { 1328031Sroot 1338031Sroot if (u.u_uid && u.u_ruid && 1348031Sroot u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 13521001Smckusick u.u_error = EPERM; 1368031Sroot return; 1378031Sroot } 13817400Skarels if (n > PRIO_MAX) 13917400Skarels n = PRIO_MAX; 14017400Skarels if (n < PRIO_MIN) 14117400Skarels n = PRIO_MIN; 1428176Sroot if (n < p->p_nice && !suser()) { 1438176Sroot u.u_error = EACCES; 1448031Sroot return; 1458176Sroot } 1468031Sroot p->p_nice = n; 1478031Sroot (void) setpri(p); 1488031Sroot } 1498031Sroot 1508100Sroot setrlimit() 1518031Sroot { 1528031Sroot register struct a { 1538031Sroot u_int which; 1548031Sroot struct rlimit *lim; 1558031Sroot } *uap = (struct a *)u.u_ap; 1568031Sroot struct rlimit alim; 1578031Sroot register struct rlimit *alimp; 15818279Smckusick extern int maxdmap; 1598031Sroot 1608031Sroot if (uap->which >= RLIM_NLIMITS) { 1618031Sroot u.u_error = EINVAL; 1628031Sroot return; 1638031Sroot } 1648031Sroot alimp = &u.u_rlimit[uap->which]; 1659997Ssam u.u_error = copyin((caddr_t)uap->lim, (caddr_t)&alim, 1669997Ssam sizeof (struct rlimit)); 1679997Ssam if (u.u_error) 1688031Sroot return; 1698031Sroot if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max) 1708031Sroot if (!suser()) 1718031Sroot return; 1728031Sroot switch (uap->which) { 1738031Sroot 1748031Sroot case RLIMIT_DATA: 17518279Smckusick if (alim.rlim_cur > maxdmap) 17618279Smckusick alim.rlim_cur = maxdmap; 17718279Smckusick if (alim.rlim_max > maxdmap) 17818279Smckusick alim.rlim_max = maxdmap; 1798031Sroot break; 1808031Sroot 1818031Sroot case RLIMIT_STACK: 18218279Smckusick if (alim.rlim_cur > maxdmap) 18318279Smckusick alim.rlim_cur = maxdmap; 18418279Smckusick if (alim.rlim_max > maxdmap) 18518279Smckusick alim.rlim_max = maxdmap; 1868031Sroot break; 1878031Sroot } 1888031Sroot *alimp = alim; 1898031Sroot if (uap->which == RLIMIT_RSS) 1908031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1918031Sroot } 1928031Sroot 1938100Sroot getrlimit() 1948031Sroot { 1958031Sroot register struct a { 1968031Sroot u_int which; 1978031Sroot struct rlimit *rlp; 1988031Sroot } *uap = (struct a *)u.u_ap; 1998031Sroot 2008031Sroot if (uap->which >= RLIM_NLIMITS) { 2018031Sroot u.u_error = EINVAL; 2028031Sroot return; 2038031Sroot } 2049997Ssam u.u_error = copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)uap->rlp, 2059997Ssam sizeof (struct rlimit)); 2068031Sroot } 2078031Sroot 2088031Sroot getrusage() 2098031Sroot { 2108031Sroot register struct a { 2118031Sroot int who; 2128031Sroot struct rusage *rusage; 2138031Sroot } *uap = (struct a *)u.u_ap; 2148031Sroot register struct rusage *rup; 2158031Sroot 2168031Sroot switch (uap->who) { 2178031Sroot 2188031Sroot case RUSAGE_SELF: 2198031Sroot rup = &u.u_ru; 2208031Sroot break; 2218031Sroot 2228031Sroot case RUSAGE_CHILDREN: 2238031Sroot rup = &u.u_cru; 2248031Sroot break; 2258031Sroot 2268031Sroot default: 2278031Sroot u.u_error = EINVAL; 2288031Sroot return; 2298031Sroot } 2309997Ssam u.u_error = copyout((caddr_t)rup, (caddr_t)uap->rusage, 2319997Ssam sizeof (struct rusage)); 2328031Sroot } 2338031Sroot 2348031Sroot ruadd(ru, ru2) 2358031Sroot register struct rusage *ru, *ru2; 2368031Sroot { 2378666Sroot register long *ip, *ip2; 2388031Sroot register int i; 2398031Sroot 2408031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2418031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2428031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2438031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2448031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2458031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2468031Sroot *ip++ += *ip2++; 2478031Sroot } 248