1*8176Sroot /* kern_resource.c 4.14 82/09/12 */ 27Sbill 37Sbill #include "../h/param.h" 47Sbill #include "../h/systm.h" 57Sbill #include "../h/dir.h" 67Sbill #include "../h/user.h" 77Sbill #include "../h/inode.h" 87Sbill #include "../h/proc.h" 97Sbill #include "../h/seg.h" 107499Sroot #include "../h/fs.h" 117817Sroot #include "../h/uio.h" 128031Sroot #include "../h/vm.h" 137Sbill 14*8176Sroot /* 15*8176Sroot * Resource controls and accounting. 16*8176Sroot */ 17*8176Sroot 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; 258031Sroot 268031Sroot u.u_r.r_val1 = NZERO+20; 278031Sroot u.u_error = ESRCH; 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; 378031Sroot u.u_r.r_val1 = u.u_procp->p_nice; 38*8176Sroot u.u_error = 0; 398031Sroot break; 408031Sroot 418031Sroot case PRIO_PGRP: 428031Sroot if (uap->who == 0) 438031Sroot uap->who = u.u_procp->p_pgrp; 44*8176Sroot for (p = proc; p < procNPROC; p++) { 45*8176Sroot if (p->p_stat == NULL) 46*8176Sroot continue; 478031Sroot if (p->p_pgrp == uap->who && 488031Sroot p->p_nice < u.u_r.r_val1) { 498031Sroot u.u_r.r_val1 = p->p_nice; 508031Sroot u.u_error = 0; 518031Sroot } 52*8176Sroot } 538031Sroot break; 548031Sroot 55*8176Sroot case PRIO_USER: 56*8176Sroot if (uap->who == 0) 57*8176Sroot uap->who = u.u_uid; 58*8176Sroot for (p = proc; p < procNPROC; p++) { 59*8176Sroot if (p->p_stat == NULL) 60*8176Sroot continue; 61*8176Sroot if (p->p_uid == uap->who && 62*8176Sroot p->p_nice < u.u_r.r_val1) { 63*8176Sroot u.u_r.r_val1 = p->p_nice; 64*8176Sroot u.u_error = 0; 65*8176Sroot } 66*8176Sroot } 67*8176Sroot break; 68*8176Sroot 698031Sroot default: 708031Sroot u.u_error = EINVAL; 718031Sroot break; 728031Sroot } 738031Sroot u.u_r.r_val1 -= NZERO; 748031Sroot } 758031Sroot 768031Sroot setpriority() 778031Sroot { 788031Sroot register struct a { 798031Sroot int which; 808031Sroot int who; 818031Sroot int prio; 828031Sroot } *uap = (struct a *)u.u_ap; 838031Sroot register struct proc *p; 848031Sroot 858031Sroot u.u_error = ESRCH; 868031Sroot switch (uap->which) { 878031Sroot 888031Sroot case PRIO_PROCESS: 89*8176Sroot if (uap->who == 0) 90*8176Sroot p = u.u_procp; 91*8176Sroot else 92*8176Sroot p = pfind(uap->who); 938031Sroot if (p == 0) 948031Sroot return; 958031Sroot donice(p, uap->prio); 968031Sroot break; 978031Sroot 988031Sroot case PRIO_PGRP: 99*8176Sroot if (uap->who == 0) 100*8176Sroot uap->who = u.u_procp->p_pgrp; 1018031Sroot for (p = proc; p < procNPROC; p++) 1028031Sroot if (p->p_pgrp == uap->who) 1038031Sroot donice(p, uap->prio); 1048031Sroot break; 1058031Sroot 106*8176Sroot case PRIO_USER: 107*8176Sroot if (uap->who == 0) 108*8176Sroot uap->who = u.u_uid; 109*8176Sroot for (p = proc; p < procNPROC; p++) 110*8176Sroot if (p->p_uid == uap->who) 111*8176Sroot donice(p, uap->prio); 112*8176Sroot break; 113*8176Sroot 1148031Sroot default: 1158031Sroot u.u_error = EINVAL; 1168031Sroot break; 1178031Sroot } 1188031Sroot } 1198031Sroot 1208031Sroot donice(p, n) 1218031Sroot register struct proc *p; 1228031Sroot register int n; 1238031Sroot { 1248031Sroot 1258031Sroot if (u.u_uid && u.u_ruid && 1268031Sroot u.u_uid != p->p_uid && u.u_ruid != p->p_uid) { 127*8176Sroot u.u_error = EACCES; 1288031Sroot return; 1298031Sroot } 130*8176Sroot n += NZERO; 1318031Sroot if (n >= 2*NZERO) 1328031Sroot n = 2*NZERO - 1; 1338031Sroot if (n < 0) 1348031Sroot n = 0; 135*8176Sroot if (n < p->p_nice && !suser()) { 136*8176Sroot u.u_error = EACCES; 1378031Sroot return; 138*8176Sroot } 1398031Sroot p->p_nice = n; 1408031Sroot (void) setpri(p); 1418031Sroot if (u.u_error == ESRCH) 1428031Sroot u.u_error = 0; 1438031Sroot } 1448031Sroot 1458100Sroot setrlimit() 1468031Sroot { 1478031Sroot register struct a { 1488031Sroot u_int which; 1498031Sroot struct rlimit *lim; 1508031Sroot } *uap = (struct a *)u.u_ap; 1518031Sroot struct rlimit alim; 1528031Sroot register struct rlimit *alimp; 1538031Sroot 1548031Sroot if (uap->which >= RLIM_NLIMITS) { 1558031Sroot u.u_error = EINVAL; 1568031Sroot return; 1578031Sroot } 1588031Sroot alimp = &u.u_rlimit[uap->which]; 1598031Sroot if (copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit))) { 1608031Sroot u.u_error = EFAULT; 1618031Sroot return; 1628031Sroot } 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: 1698031Sroot if (alim.rlim_cur > ctob(MAXDSIZ)) 1708031Sroot alim.rlim_cur = ctob(MAXDSIZ); 1718031Sroot break; 1728031Sroot 1738031Sroot case RLIMIT_STACK: 1748031Sroot if (alim.rlim_cur > ctob(MAXSSIZ)) 1758031Sroot alim.rlim_cur = ctob(MAXSSIZ); 1768031Sroot break; 1778031Sroot } 1788031Sroot *alimp = alim; 1798031Sroot if (uap->which == RLIMIT_RSS) 1808031Sroot u.u_procp->p_maxrss = alim.rlim_cur/NBPG; 1818031Sroot } 1828031Sroot 1838100Sroot getrlimit() 1848031Sroot { 1858031Sroot register struct a { 1868031Sroot u_int which; 1878031Sroot struct rlimit *rlp; 1888031Sroot } *uap = (struct a *)u.u_ap; 1898031Sroot 1908031Sroot if (uap->which >= RLIM_NLIMITS) { 1918031Sroot u.u_error = EINVAL; 1928031Sroot return; 1938031Sroot } 1948031Sroot if (copyout((caddr_t)&u.u_rlimit[uap->which], uap->rlp, 1958031Sroot sizeof (struct rlimit))) { 1968031Sroot u.u_error = EFAULT; 1978031Sroot return; 1988031Sroot } 1998031Sroot } 2008031Sroot 2018031Sroot getrusage() 2028031Sroot { 2038031Sroot register struct a { 2048031Sroot int who; 2058031Sroot struct rusage *rusage; 2068031Sroot } *uap = (struct a *)u.u_ap; 2078031Sroot register struct rusage *rup; 2088031Sroot 2098031Sroot switch (uap->who) { 2108031Sroot 2118031Sroot case RUSAGE_SELF: 2128031Sroot rup = &u.u_ru; 2138031Sroot break; 2148031Sroot 2158031Sroot case RUSAGE_CHILDREN: 2168031Sroot rup = &u.u_cru; 2178031Sroot break; 2188031Sroot 2198031Sroot default: 2208031Sroot u.u_error = EINVAL; 2218031Sroot return; 2228031Sroot } 2238031Sroot if (copyout((caddr_t)rup, uap->rusage, sizeof (struct rusage))) { 2248031Sroot u.u_error = EFAULT; 2258031Sroot return; 2268031Sroot } 2278031Sroot } 2288031Sroot 2298031Sroot ruadd(ru, ru2) 2308031Sroot register struct rusage *ru, *ru2; 2318031Sroot { 2328031Sroot register int *ip, *ip2; 2338031Sroot register int i; 2348031Sroot 2358031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2368031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2378031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2388031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2398031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2408031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2418031Sroot *ip++ += *ip2++; 2428031Sroot } 2438031Sroot 2448100Sroot #ifndef NOCOMPAT 2458100Sroot onice() 2467Sbill { 2477Sbill register struct a { 2488100Sroot int niceness; 249*8176Sroot } *uap = (struct a *)u.u_ap; 250*8176Sroot register struct proc *p = u.u_procp; 2517Sbill 252*8176Sroot donice(p, (p->p_nice-NZERO)+uap->niceness); 2537Sbill } 2547Sbill 255*8176Sroot #include "../h/times.h" 256*8176Sroot 2578100Sroot otimes() 2587Sbill { 259*8176Sroot register struct a { 260*8176Sroot struct tms *tmsb; 261*8176Sroot } *uap = (struct a *)u.u_ap; 262*8176Sroot struct tms atms; 2637Sbill 264*8176Sroot atms.tms_utime = scale60(&u.u_ru.ru_utime); 265*8176Sroot atms.tms_stime = scale60(&u.u_ru.ru_stime); 266*8176Sroot atms.tms_cutime = scale60(&u.u_cru.ru_utime); 267*8176Sroot atms.tms_cstime = scale60(&u.u_cru.ru_stime); 268*8176Sroot if (copyout((caddr_t)&atms, uap->tmsb, sizeof (atms))) { 269*8176Sroot u.u_error = EFAULT; 270*8176Sroot return; 271*8176Sroot } 2727Sbill } 2737Sbill 274*8176Sroot scale60(tvp) 275*8176Sroot register struct timeval *tvp; 276*8176Sroot { 277*8176Sroot 278*8176Sroot return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); 279*8176Sroot } 280*8176Sroot 281*8176Sroot #include <vtimes.h> 282*8176Sroot 2838100Sroot ovtimes() 2847Sbill { 285*8176Sroot register struct a { 286*8176Sroot struct vtimes *par; 287*8176Sroot struct vtimes *chi; 288*8176Sroot } *uap = (struct a *)u.u_ap; 289*8176Sroot struct vtimes avt; 2907Sbill 291*8176Sroot if (uap->par) { 292*8176Sroot getvtimes(&u.u_ru, &avt); 293*8176Sroot if (copyout((caddr_t)&avt, (caddr_t)uap->par, sizeof (avt))) { 294*8176Sroot u.u_error = EFAULT; 295*8176Sroot return; 296*8176Sroot } 297*8176Sroot } 298*8176Sroot if (uap->chi) { 299*8176Sroot getvtimes(&u.u_cru, &avt); 300*8176Sroot if (copyout((caddr_t)&avt, (caddr_t)uap->chi, sizeof (avt))) { 301*8176Sroot u.u_error = EFAULT; 302*8176Sroot return; 303*8176Sroot } 304*8176Sroot } 3057Sbill } 3067499Sroot 307*8176Sroot getvtimes(aru, avt) 308*8176Sroot register struct rusage *aru; 309*8176Sroot register struct vtimes *avt; 310*8176Sroot { 311*8176Sroot 312*8176Sroot avt->vm_utime = scale60(&aru->ru_utime); 313*8176Sroot avt->vm_stime = scale60(&aru->ru_stime); 314*8176Sroot avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60; 315*8176Sroot avt->vm_ixrss = aru->ru_ixrss / hz * 60; 316*8176Sroot avt->vm_maxrss = aru->ru_maxrss; 317*8176Sroot avt->vm_majflt = aru->ru_majflt; 318*8176Sroot avt->vm_minflt = aru->ru_minflt; 319*8176Sroot avt->vm_nswap = aru->ru_nswap; 320*8176Sroot avt->vm_inblk = aru->ru_inblock; 321*8176Sroot avt->vm_oublk = aru->ru_oublock; 322*8176Sroot } 323*8176Sroot 3248100Sroot ovlimit() 3257499Sroot { 3267499Sroot 327*8176Sroot u.u_error = EACCES; 3287499Sroot } 329