5

On a shared server (Debian Jessie), there are some memory limits (and other limits, like number of processes) that apply for a group of users, configured in /etc/security/limits.conf.

It seems that those limits do not apply to processes started by cron, though, and sometimes people's cron job accidentally screw up performance for all others.

Is there any way to apply the limits from limits.conf to cron jobs too? Or, if that's not possible, at least enforce some limits to all users' cron jobs?

Cron seems to run all the jobs in the cron cgroup, not in the users' cgroup, so that's not an easy approach either :(

moritz
  • 151
  • 1
  • 5
  • include pam_limits in session modules in /etc/pam.d/crond, in this the limits.conf will be used. – c4f4t0r Aug 04 '15 at 23:10
  • `/etc/pam.d/cron` already includes `pam_limits.so`, with a comment `Sets up user limits, please define limits for cron tasks through /etc/security/limits.conf`, but I have no idea how to do that; the normal limits don't seem to apply, and `man limits.conf` doesn't tell how to set up limits for a specific service. Any ideas? – moritz Aug 05 '15 at 08:03
  • cgroups can do this. – mzhaase Nov 22 '16 at 16:21
  • @mzhaase how? It's not all obvious to me where they are configured. – moritz Nov 24 '16 at 11:12

1 Answers1

2

I'm pretty sure you cant set up limits on a service via the limits.conf but only on a user space.

Crontab executes scripts in the appointed user space defined either from /etc/crontab via username or from the users own personal crontab. So limits has to be applied on a user-space level or from inside the script it self. But it's correct you need to enable the limits under pam.d/cron as this enables cron to apply the user limits when executing the script.

I setup a little test scenario so we can check how to limit a users cronjobs.

1) Made a user called crontest

2) Added one line to limits.conf

crontest        hard    as              50000

3) Made a quick little test script to allocate memory. You can properly find source example around the Internet that is way better than mine, but it works.

#include <malloc.h>
#include <unistd.h>
#include <memory.h>
#define MB 1024 * 1024
int main() {
        int size;
        size = 0;
    while (1) {
        void *p = malloc( 10*MB );
        memset(p,0, 10*MB );
        size = 10+size;
        printf("Using %d MB\n",size);
        sleep(1);
    }
}

Save the above source code into mem.c and type the following to compile it.

gcc mem.c -o mem
cp mem /bin/mem

Now to test

As root i ran the mem test script and this is the output. As you can see i can allocate more than 50MB RAM (AddressSpace)

# mem
Using 10 MB
Using 20 MB
Using 30 MB
Using 40 MB
Using 50 MB
Using 60 MB
^C

I then changed to my new test user and tried the same.

$ mem
Using 10 MB
Using 20 MB
Using 30 MB
Using 40 MB
Segmentation fault

As you can see the system cut me off as i tried to allocate the next 10MB that would have hit 50MB (my limit).

Next i added the following to /etc/crontab

* * * * * crontest /bin/mem

Saved the crontab and waited for the cron to spawn my user-space script under crontest user. I could now see that the same things applied to my users crontab script just fine.

Output from cron.log showing the script started

Nov 22 16:52:01 server CRON[31460]: (crontest) CMD (/bin/mem)

Output from syslog showing the script dieing again..

Nov 22 16:52:05 server kernel: [624832.216083] mem[31464]: segfault at 8 ip 00007f87868f51b8 sp 00007ffce83fa058 error 6 in libc-2.24.so[7f8786871000+195000]

So as you can see the limit applies both to the user environment when logging in and to the cronjobs. So i think you need to take a look at your limits.conf file i don't think it's correct.

davidbl
  • 76
  • 5