1*8666Sroot /* kern_resource.c 4.17 82/10/19 */ 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 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; 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; 388176Sroot u.u_error = 0; 398031Sroot break; 408031Sroot 418031Sroot case PRIO_PGRP: 428031Sroot if (uap->who == 0) 438031Sroot uap->who = u.u_procp->p_pgrp; 448176Sroot for (p = proc; p < procNPROC; p++) { 458176Sroot if (p->p_stat == NULL) 468176Sroot 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 } 528176Sroot } 538031Sroot break; 548031Sroot 558176Sroot case PRIO_USER: 568176Sroot if (uap->who == 0) 578176Sroot uap->who = u.u_uid; 588176Sroot for (p = proc; p < procNPROC; p++) { 598176Sroot if (p->p_stat == NULL) 608176Sroot continue; 618176Sroot if (p->p_uid == uap->who && 628176Sroot p->p_nice < u.u_r.r_val1) { 638176Sroot u.u_r.r_val1 = p->p_nice; 648176Sroot u.u_error = 0; 658176Sroot } 668176Sroot } 678176Sroot break; 688176Sroot 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: 898176Sroot if (uap->who == 0) 908176Sroot p = u.u_procp; 918176Sroot else 928176Sroot p = pfind(uap->who); 938031Sroot if (p == 0) 948031Sroot return; 958031Sroot donice(p, uap->prio); 968031Sroot break; 978031Sroot 988031Sroot case PRIO_PGRP: 998176Sroot if (uap->who == 0) 1008176Sroot 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 1068176Sroot case PRIO_USER: 1078176Sroot if (uap->who == 0) 1088176Sroot uap->who = u.u_uid; 1098176Sroot for (p = proc; p < procNPROC; p++) 1108176Sroot if (p->p_uid == uap->who) 1118176Sroot donice(p, uap->prio); 1128176Sroot break; 1138176Sroot 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) { 1278176Sroot u.u_error = EACCES; 1288031Sroot return; 1298031Sroot } 1308176Sroot n += NZERO; 1318031Sroot if (n >= 2*NZERO) 1328031Sroot n = 2*NZERO - 1; 1338031Sroot if (n < 0) 1348031Sroot n = 0; 1358176Sroot if (n < p->p_nice && !suser()) { 1368176Sroot u.u_error = EACCES; 1378031Sroot return; 1388176Sroot } 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 } 1948624Sroot if (copyout((caddr_t)&u.u_rlimit[uap->which], (caddr_t)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 } 2238624Sroot if (copyout((caddr_t)rup, (caddr_t)uap->rusage, 2248624Sroot sizeof (struct rusage))) { 2258031Sroot u.u_error = EFAULT; 2268031Sroot return; 2278031Sroot } 2288031Sroot } 2298031Sroot 2308031Sroot ruadd(ru, ru2) 2318031Sroot register struct rusage *ru, *ru2; 2328031Sroot { 233*8666Sroot register long *ip, *ip2; 2348031Sroot register int i; 2358031Sroot 2368031Sroot timevaladd(&ru->ru_utime, &ru2->ru_utime); 2378031Sroot timevaladd(&ru->ru_stime, &ru2->ru_stime); 2388031Sroot if (ru->ru_maxrss < ru2->ru_maxrss) 2398031Sroot ru->ru_maxrss = ru2->ru_maxrss; 2408031Sroot ip = &ru->ru_first; ip2 = &ru2->ru_first; 2418031Sroot for (i = &ru->ru_last - &ru->ru_first; i > 0; i--) 2428031Sroot *ip++ += *ip2++; 2438031Sroot } 2448031Sroot 2458100Sroot #ifndef NOCOMPAT 2468100Sroot onice() 2477Sbill { 2487Sbill register struct a { 2498100Sroot int niceness; 2508176Sroot } *uap = (struct a *)u.u_ap; 2518176Sroot register struct proc *p = u.u_procp; 2527Sbill 2538176Sroot donice(p, (p->p_nice-NZERO)+uap->niceness); 2547Sbill } 2557Sbill 2568176Sroot #include "../h/times.h" 2578176Sroot 2588100Sroot otimes() 2597Sbill { 2608176Sroot register struct a { 2618176Sroot struct tms *tmsb; 2628176Sroot } *uap = (struct a *)u.u_ap; 2638176Sroot struct tms atms; 2647Sbill 2658176Sroot atms.tms_utime = scale60(&u.u_ru.ru_utime); 2668176Sroot atms.tms_stime = scale60(&u.u_ru.ru_stime); 2678176Sroot atms.tms_cutime = scale60(&u.u_cru.ru_utime); 2688176Sroot atms.tms_cstime = scale60(&u.u_cru.ru_stime); 2698624Sroot if (copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms))) { 2708176Sroot u.u_error = EFAULT; 2718176Sroot return; 2728176Sroot } 2737Sbill } 2747Sbill 2758176Sroot scale60(tvp) 2768176Sroot register struct timeval *tvp; 2778176Sroot { 2788176Sroot 2798176Sroot return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); 2808176Sroot } 2818176Sroot 2828176Sroot #include <vtimes.h> 2838176Sroot 2848100Sroot ovtimes() 2857Sbill { 2868176Sroot register struct a { 2878176Sroot struct vtimes *par; 2888176Sroot struct vtimes *chi; 2898176Sroot } *uap = (struct a *)u.u_ap; 2908176Sroot struct vtimes avt; 2917Sbill 2928176Sroot if (uap->par) { 2938176Sroot getvtimes(&u.u_ru, &avt); 2948176Sroot if (copyout((caddr_t)&avt, (caddr_t)uap->par, sizeof (avt))) { 2958176Sroot u.u_error = EFAULT; 2968176Sroot return; 2978176Sroot } 2988176Sroot } 2998176Sroot if (uap->chi) { 3008176Sroot getvtimes(&u.u_cru, &avt); 3018176Sroot if (copyout((caddr_t)&avt, (caddr_t)uap->chi, sizeof (avt))) { 3028176Sroot u.u_error = EFAULT; 3038176Sroot return; 3048176Sroot } 3058176Sroot } 3067Sbill } 3077499Sroot 3088176Sroot getvtimes(aru, avt) 3098176Sroot register struct rusage *aru; 3108176Sroot register struct vtimes *avt; 3118176Sroot { 3128176Sroot 3138176Sroot avt->vm_utime = scale60(&aru->ru_utime); 3148176Sroot avt->vm_stime = scale60(&aru->ru_stime); 3158176Sroot avt->vm_idsrss = ((aru->ru_idrss+aru->ru_isrss) / hz) * 60; 3168176Sroot avt->vm_ixrss = aru->ru_ixrss / hz * 60; 3178176Sroot avt->vm_maxrss = aru->ru_maxrss; 3188176Sroot avt->vm_majflt = aru->ru_majflt; 3198176Sroot avt->vm_minflt = aru->ru_minflt; 3208176Sroot avt->vm_nswap = aru->ru_nswap; 3218176Sroot avt->vm_inblk = aru->ru_inblock; 3228176Sroot avt->vm_oublk = aru->ru_oublock; 3238176Sroot } 3248176Sroot 3258100Sroot ovlimit() 3267499Sroot { 3277499Sroot 3288176Sroot u.u_error = EACCES; 3297499Sroot } 330