Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I operate a Linux system which has a lot of users but sometimes an abuse occurs; where a user might run a single process that uses up more than 80% of the CPU/Memory.

So is there a way to prevent this from happening by limiting the amount of CPU usage a process can use (to 10% for example)? I'm aware of cpulimit, but it unfortunately applies the limit to the processes I instruct it to limit (e.g single processes). So my question is, how can I apply the limit to all of the running processes and processes that will be run in the future without the need of providing their id/path for example?

share|improve this question
    
Are you experiencing performance problems? or is it just the numbers that bother you? –  richard Aug 24 at 12:08
    
@richard Performance problems, so that's why I was trying to kill/limit/put an end to processes which seem to be using a lot of CPU, but I already did so by writing a bash script. This is also a virtual machine if that helps –  Giovanni Mounir Aug 24 at 12:16
1  
Be careful of killing processes that may be 100% for very short time, also system processes. Consider cpulimit in conjunction with your search script. Have a policy and recommend the use of cpulimit, then search for over 10% and then limit to 5% (so users are encouraged to use cpulimit). Also make sure you can detect multiple processes adding up to more that 10% for a single user. –  richard Aug 24 at 12:28
    
@richard Thanks Richard for all of these pretty useful comments! They have helped me greatly! Your suggestion to use cpulimit is way better than just killing the process since it can be restarted by the user later on (as pointed in one of your comments). Thank you! –  Giovanni Mounir Aug 24 at 12:31

4 Answers 4

up vote 9 down vote accepted

While it can be an abuse for memory, it isn't for CPU: when a CPU is idle, a running process (by "running", I mean that the process isn't waiting for I/O or something else) will take 100% CPU time by default. And there's no reason to enforce a limit.

Now, you can set up priorities thanks to nice. If you want them to apply to all processes for a given user, you just need to make sure that his login shell is run with nice: the child processes will inherit the nice value. This depends on how the users log in. See Prioritise ssh logins (nice) for instance.

Alternatively, you can set up virtual machines. Indeed setting a per-process limit doesn't make much sense since the user can start many processes, abusing the system. With a virtual machine, all the limits will be global to the virtual machine.

Another solution is to set /etc/security/limits.conf limits; see the limits.conf(5) man page. For instance, you can set the maximum CPU time per login and/or the maximum number of processes per login. You can also set maxlogins to 1 for each user.

share|improve this answer
    
Thanks for the answer! This is indeed a virtual machine, I noticed that the CPU only goes up when the process is actually using resources, not idle or anything like that; I didn't have the chance to try nice yet, but I achieved what I was trying to do by programming a bash script and scheduled it to run every 5 minutes. Thank you however! –  Giovanni Mounir Aug 24 at 12:15
1  
@GiovanniMounir I meant: one virtual machine per user. –  vinc17 Aug 24 at 12:24
    
I see, but unfortunately this will be resource-consuming and not really useful for my purpose, as the users may require the usage of some common development packages, and I won't be installing this on every single new machine; I think it's better to leave it that way and do the monitoring automatically by a bash script. –  Giovanni Mounir Aug 24 at 12:26
1  
@GiovanniMounir You can share a partition between several virtual machines. –  vinc17 Aug 24 at 12:35
    
Won't really work the way I like it, but thanks for the suggestion! I guess I will just modify my script to address the suggestions pointed out by richard and leave that to run automatically! –  Giovanni Mounir Aug 24 at 12:37

Did you look at cgroups? There is some information on the Arch Wiki about them. Read the section about cpu.shares, it looks like it's doing what you need, and they can operate on a user-level, so you can limit all user processes at once.

share|improve this answer
    
Thank you for taking time to write this very informative answer, Paul! But this will require me to set up a specific group to target these who I want to limit; I think the best way to do what I'm trying to achieve is by running a bash script every 5 minutes to check the usage and kill the process if it's more than 10% for example? This way I will be able to detect if that specific user is abusing or not, because it's not probable that a process should be running with over 10% CPU usage during 5 minutes on my system. I will post my script as soon as it's complete! –  Giovanni Mounir Aug 24 at 10:58
    
CGroups is the way to go, though. I also run (many) shared computer servers and we use cgroups to limit the maximum number of cores an entire login session can use. This way, if the person keeps starting new processes, each one gets a smaller slice. Same for memory use. You can have users automatically put into a cgroup with pam_cgroups and the cgrulesengd service. You can use a 'template' in the cgconfig file to put each user into their own cgroup. cgrulesengd acts like your script, except instead of killing processes, it just makes sure each process is in the right cgroup. –  jsbillings Aug 24 at 14:28
    
Even if you don't use cgroups to limit resource use, you can use it to evaluate how much resources an individual is using, by looking at the 'stat' file for each resource, then use that information for your 5 minute script. –  jsbillings Aug 24 at 14:31

For memory, what you are looking for is ulimit -v. Note that ulimit is inherited by child processes, so if you apply it to the login shell of the user at the time of login, it applies to all his processes.

If your users all use bash as login shell, putting the following line in /etc/profile should cause all user processes to have a hard limit of 1 gigabyte (more exactly, one million kilobytes):

ulimit -vH 1000000

The option H makes sure it's a hard limit, that is, the user cannot set it back up afterwards. Of course the user can still fill memory by starting sufficiently many processes at once.

For other shells, you'll have to find out what initialization files they read instead (and what other command instead of ulimit they use).

For CPU, what you wish for doesn't seem to make sense for me. What would be the use of letting 90% of the CPU unused when only one process is running? I think what you really want is nice (and possibly ionice). Note that, like ulimit, nice values are inherited by child processes, so applying it to the login shell at login time suffices. I guess that also applies to ionice but I'm not sure.

share|improve this answer
    
Thanks for the memory suggestion! Is there any chance you can show me an example to apply this to the login shell of the user at the time of login? I'm not really sure how to do this. I'm also sorry for not being clear enough; what I'm trying to do is not allow any process to use more than 10% of the CPU. So do you think that nice will be nice enough to do this? If so, do you think you can show me an example to achieve this? –  Giovanni Mounir Aug 24 at 10:04
    
I still don't get the point of keeping the CPU 90% idle when only one process is running. –  celtschk Aug 24 at 10:07
    
No, this will not be only one process running, as I said earlier; the machine has a lot of users, probably more than 20 users and I can't keep monitoring them manually. What I basically do is ps aux and then monitor the CPU used by every process, if I notice a process using more than 10.0, I kill it using kill $pid or kill -9 $pid but I would like an automated way to do this, or to limit future processes to use not more than 10.0 CPU only. Do you think this is possible? –  Giovanni Mounir Aug 24 at 10:09
1  
If there are currently less than 10 processes running concurrently (and by running I mean really running, not just waiting for user input or disk I/O), then it is virtually guaranteed that one of them will have more than 10% of CPU. Otherwise the CPU would be virtually idling. And if you just kill any process that goes above 10%, I'm sure you'll have many users who will want to kill you. Or at least, will try to get you replaced by someone who has a clue about what those numbers mean, because you don't seem to. –  celtschk Aug 24 at 10:19
    
Thanks for editing the post and taking time to answer my question; but unfortunately that doesn't suit my needs. In fact I do know what the numbers mean, and this is actually a public system provided for educational purposes, and the system specifications are high enough to make regular processes use less than 1% of the CPU usage, so using 10% is a huge number. Anyways I think I will just use bash to do this, meanwhile upvoting both of the answers. Thanks for your efforts! –  Giovanni Mounir Aug 24 at 10:24

Since you are stating that cpulimit would not be practical in your case, then I suggest you look at nice, renice, and taskset, which may come close to what you want to achieve, although taskset allows to set a processes’s CPU affinity, so it might be not immediately helpful in your case.

share|improve this answer
    
nice and renice? That's nice! I have looked at their manual pages, but I still don't think they can help with this as you still have to set a process ID. If you could however give me an example which involves these packages to apply the limit on all running processes/future processes that would be awesome! –  Giovanni Mounir Aug 24 at 9:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.