zsh-workers
 help / color / mirror / code / Atom feed
* Bug in ulimit ?
@ 2007-04-17  9:00 David Peer
  2007-04-17  9:30 ` Micah Cowan
  0 siblings, 1 reply; 21+ messages in thread
From: David Peer @ 2007-04-17  9:00 UTC (permalink / raw)
  To: zsh-workers

Hi,


I'm using zsh 4.3.2-25 on debian, and noticed that when any user run: 
ulimit -t 0

from its shell, he manages to disable the cputime limitation if any.


for example:

I have a debian system that has cpu time limitation of 1 minute soft, 
and 2 minutes hard.

If the user run: ulimit -t 0, he can run jobs without any cputime 
limitation:


The soft limit:

<2|0>dib@mafalda:~> limit | grep cputime
cputime      1:00


The hard limit:

<5|0>dib@mafalda:~> ulimit -t unlimited

<6|0>dib@mafalda:~> limit | grep cputime

cputime      2:00


So far so good.

But:


<7|0>dib@mafalda:~> ulimit -t 0

<8|0>dib@mafalda:~> limit | grep cputime

cputime         0:00:00


Now the user can run processes without cpu time limitation.

You can see the output from "top" command, that it ran the job 
"testload" for more then 6 minutes.


4754 dib       30   5  1556  336  276 R 97.0  0.1   6:16.52 testload


Thanks in advanced,

David Peer.




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17  9:00 Bug in ulimit ? David Peer
@ 2007-04-17  9:30 ` Micah Cowan
  2007-04-17  9:33   ` David Peer
                     ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Micah Cowan @ 2007-04-17  9:30 UTC (permalink / raw)
  To: davidpeer; +Cc: zsh-workers

David Peer wrote:
> If the user run: ulimit -t 0, he can run jobs without any cputime
> limitation:

This sounds more like a kernel problem to me than a zsh bug. I get the
same behavior on my Ubuntu 7.04 (beta) system, in _bash_.

I note that getrlimit(2) says:

 In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
 treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17, set‐
 ting a limit of 0 does have an effect, but is  actually  treated  as  a
 limit of 1 second.

However, I'm running 2.6.20(-14-generic), and still experiencing that
symptom.

-- 
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17  9:30 ` Micah Cowan
@ 2007-04-17  9:33   ` David Peer
  2007-04-17  9:42   ` Stephane Chazelas
  2007-04-17 14:15   ` Tom Alsberg
  2 siblings, 0 replies; 21+ messages in thread
From: David Peer @ 2007-04-17  9:33 UTC (permalink / raw)
  To: Micah Cowan; +Cc: zsh-workers

Micah Cowan wrote:

> David Peer wrote:
>   
>> If the user run: ulimit -t 0, he can run jobs without any cputime
>> limitation:
>>     
>
> This sounds more like a kernel problem to me than a zsh bug. I get the
> same behavior on my Ubuntu 7.04 (beta) system, in _bash_.
>
> I note that getrlimit(2) says:
>
>  In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
>  treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17, set‐
>  ting a limit of 0 does have an effect, but is  actually  treated  as  a
>  limit of 1 second.
>
> However, I'm running 2.6.20(-14-generic), and still experiencing that
> symptom.
>
>   
I'll check if it's fixed in 2.6.21... but I forgot to mention that I use 
kernel 2.6.20.3


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17  9:30 ` Micah Cowan
  2007-04-17  9:33   ` David Peer
@ 2007-04-17  9:42   ` Stephane Chazelas
  2007-04-17 10:04     ` Micah Cowan
  2007-04-17 14:15   ` Tom Alsberg
  2 siblings, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17  9:42 UTC (permalink / raw)
  To: Micah Cowan; +Cc: davidpeer, zsh-workers

On Tue, Apr 17, 2007 at 02:30:40AM -0700, Micah Cowan wrote:
> David Peer wrote:
> > If the user run: ulimit -t 0, he can run jobs without any cputime
> > limitation:
> 
> This sounds more like a kernel problem to me than a zsh bug. I get the
> same behavior on my Ubuntu 7.04 (beta) system, in _bash_.
> 
> I note that getrlimit(2) says:
> 
>  In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
>  treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17, set???
>  ting a limit of 0 does have an effect, but is  actually  treated  as  a
>  limit of 1 second.
> 
> However, I'm running 2.6.20(-14-generic), and still experiencing that
> symptom.
[...]

(note that there's a lot a modern CPU can do in 1 second).

Works as I'd expect from your man page quote here:

$ time zsh -c 'ulimit -t 0; while :; do :; done'
zsh: cpu limit exceeded  zsh -c 'ulimit -t 0; while :; do :; done'
zsh -c 'ulimit -t 0; while :; do :; done'  0.72s user 0.28s system 95% cpu 1.050 total
$ time bash -c 'ulimit -t 0; while :; do :; done'
zsh: killed     bash -c 'ulimit -t 0; while :; do :; done'
bash -c 'ulimit -t 0; while :; do :; done'  1.00s user 0.00s system 95% cpu 1.047 total
$ uname -a
Linux sc.homeunix.net 2.6.21-rc4 #1 PREEMPT Sun Mar 25 15:39:31 BST 2007 i686 GNU/Linux
~$ uname -rs
Linux 2.6.21-rc4


The abnormally high system time with zsh seems to be due to (according to
strace):

rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [CHLD], [CHLD], 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [CHLD], [CHLD], 8) = 0
[...]

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17  9:42   ` Stephane Chazelas
@ 2007-04-17 10:04     ` Micah Cowan
  2007-04-17 10:43       ` Stephane Chazelas
  2007-04-17 10:49       ` Micah Cowan
  0 siblings, 2 replies; 21+ messages in thread
From: Micah Cowan @ 2007-04-17 10:04 UTC (permalink / raw)
  To: davidpeer, zsh-workers

Stephane Chazelas wrote:
> On Tue, Apr 17, 2007 at 02:30:40AM -0700, Micah Cowan wrote:
>> David Peer wrote:
>>> If the user run: ulimit -t 0, he can run jobs without any cputime
>>> limitation:
>> This sounds more like a kernel problem to me than a zsh bug. I get the
>> same behavior on my Ubuntu 7.04 (beta) system, in _bash_.
>>
>> I note that getrlimit(2) says:
>>
>>  In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
>>  treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17, set???
>>  ting a limit of 0 does have an effect, but is  actually  treated  as  a
>>  limit of 1 second.
>>
>> However, I'm running 2.6.20(-14-generic), and still experiencing that
>> symptom.
> [...]
> 
> (note that there's a lot a modern CPU can do in 1 second).
> 
> Works as I'd expect from your man page quote here:
> 
> $ time zsh -c 'ulimit -t 0; while :; do :; done'
> zsh: cpu limit exceeded  zsh -c 'ulimit -t 0; while :; do :; done'
> zsh -c 'ulimit -t 0; while :; do :; done'  0.72s user 0.28s system 95% cpu 1.050 total
> $ time bash -c 'ulimit -t 0; while :; do :; done'
> zsh: killed     bash -c 'ulimit -t 0; while :; do :; done'
> bash -c 'ulimit -t 0; while :; do :; done'  1.00s user 0.00s system 95% cpu 1.047 total
> $ uname -a
> Linux sc.homeunix.net 2.6.21-rc4 #1 PREEMPT Sun Mar 25 15:39:31 BST 2007 i686 GNU/Linux
> ~$ uname -rs
> Linux 2.6.21-rc4

Yes, I get those same results. However, in an interactive shell:

% ulimit -t 0
% ( ulimit -t; while :; do :; done )
0
<< watch the CPU time used climb in top >>
^C
%
...
% ulimit -Ht 0
% ( ulimit -t; while :; do :; done )
0
zsh: killed     (; ulimit -t; while :; do; :; done; )
%

My first thought was: is zsh blocking SIGXCPU in some circumstances? But
killing the process with kill -XCPU worked fine.

It therefore appears  that while the manpage is correct for hard limits,
soft limits of 0 are still treated as unlimited.

-- 
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 10:04     ` Micah Cowan
@ 2007-04-17 10:43       ` Stephane Chazelas
  2007-04-17 10:55         ` Micah Cowan
  2007-04-17 10:49       ` Micah Cowan
  1 sibling, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 10:43 UTC (permalink / raw)
  To: Micah Cowan; +Cc: davidpeer, zsh-workers

On Tue, Apr 17, 2007 at 03:04:55AM -0700, Micah Cowan wrote:
[...]
> % ulimit -t 0
> % ( ulimit -t; while :; do :; done )
> 0
> << watch the CPU time used climb in top >>
> ^C
[...]
> It therefore appears  that while the manpage is correct for hard limits,
> soft limits of 0 are still treated as unlimited.
[...]

ulimit -t

doesn't set the limit to 0 but to infinity (in effect, to the
hard limit).

It's ulimit -t 0
to set the limit to 0 (well actually, 1 second in that case).

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 10:04     ` Micah Cowan
  2007-04-17 10:43       ` Stephane Chazelas
@ 2007-04-17 10:49       ` Micah Cowan
  1 sibling, 0 replies; 21+ messages in thread
From: Micah Cowan @ 2007-04-17 10:49 UTC (permalink / raw)
  To: Micah Cowan; +Cc: davidpeer, zsh-workers

Micah Cowan wrote:
> Stephane Chazelas wrote:
>> Works as I'd expect from your man page quote here:
>>
>> $ time zsh -c 'ulimit -t 0; while :; do :; done'
>> zsh: cpu limit exceeded  zsh -c 'ulimit -t 0; while :; do :; done'
>> zsh -c 'ulimit -t 0; while :; do :; done'  0.72s user 0.28s system 95% cpu 1.050 total
> 
> Yes, I get those same results. However, in an interactive shell:

<snip>

Of course, this doesn't explain why you got your results for /soft/
limits above. I'm having some trouble isolating what the exact
difference is, but there does seem to be a difference between current
process's set limit, and child process whose limit was set by parent.


$ bash -c 'ulimit -t 0; ulimit -Ht; while :; do :; done'
0
Killed
$ bash -c 'ulimit -t 0; ulimit -Ht; (while :; do :; done)'
0
<loops forever>
$ bash -c 'ulimit -St 0; while :; do :; done'
CPU time limit exceeded (core dumped)
$ bash -c 'ulimit -St 0; (while :; do :; done)'
<loops forever>

We can see that for both hard and soft limits, the child is not stopped.
(Note that bash's default is to set the hard limit, unlike zsh which
sets soft. POSIX gives very little specification to ulimit whatsoever). But:

$ zsh -c 'ulimit -Ht 0; ulimit -Ht; while :; do :; done'
0
<loops>
$ zsh -c 'ulimit -Ht 0; (ulimit -Ht; while :; do :; done)'
0
<loops>
$ zsh -c 'ulimit -St 0; ulimit -St; while :; do :; done'
0
CPU time limit exceeded (core dumped)
$ zsh -c 'ulimit -St 0; (ulimit -St; while :; do :; done)'
0
CPU time limit exceeded (core dumped)

Note that zsh's behavior seems to depend more on whether it's hard or
soft, rather than whether it's the child or the original.

I can't make heads nor tails of it, but /something/'s definitely screwy.

-- 
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 10:43       ` Stephane Chazelas
@ 2007-04-17 10:55         ` Micah Cowan
  2007-04-17 12:53           ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Micah Cowan @ 2007-04-17 10:55 UTC (permalink / raw)
  To: zsh-workers

Stephane Chazelas wrote:
> On Tue, Apr 17, 2007 at 03:04:55AM -0700, Micah Cowan wrote:
> [...]
>> % ulimit -t 0
>> % ( ulimit -t; while :; do :; done )
>> 0
>> << watch the CPU time used climb in top >>
>> ^C
> [...]
>> It therefore appears  that while the manpage is correct for hard limits,
>> soft limits of 0 are still treated as unlimited.
> [...]
> 
> ulimit -t
> 
> doesn't set the limit to 0 but to infinity (in effect, to the
> hard limit).
> 
> It's ulimit -t 0
> to set the limit to 0 (well actually, 1 second in that case).
> 
Originally responded to this directly, but then realized that the
veracity of this statement is pertinent to the next message I sent as
well, so it's worth addressing on-list, in case it isn't clear to others.

ulimit -t

doesn't set the limit _at_all_; it prints it (hence the "0", above).

-- 
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 10:55         ` Micah Cowan
@ 2007-04-17 12:53           ` Stephane Chazelas
  2007-04-17 13:03             ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 12:53 UTC (permalink / raw)
  To: Micah Cowan; +Cc: zsh-workers

On Tue, Apr 17, 2007 at 03:55:27AM -0700, Micah Cowan wrote:
[...]
> > ulimit -t
> > 
> > doesn't set the limit to 0 but to infinity (in effect, to the
> > hard limit).
> > 
> > It's ulimit -t 0
> > to set the limit to 0 (well actually, 1 second in that case).
> > 
> Originally responded to this directly, but then realized that the
> veracity of this statement is pertinent to the next message I sent as
> well, so it's worth addressing on-list, in case it isn't clear to others.
> 
> ulimit -t
> 
> doesn't set the limit _at_all_; it prints it (hence the "0", above).
[...]

Indeed sorry.

I can now see the same behavior as you did, and it doesn't seem
to be linked to zsh indeed.

The limit doesn't seem to get inherited by the child process:

~$ perl -MBSD::Resource -le 'setrlimit(RLIMIT_CPU,0,RLIM_INFINITY); print for getrlimit(RLIMIT_CPU); while (1) { ; }'
0
-1
zsh: cpu limit exceeded  perl -MBSD::Resource -le
(152)~$ perl -MBSD::Resource -le 'setrlimit(RLIMIT_CPU,0,RLIM_INFINITY); print for getrlimit(RLIMIT_CPU); if (fork) {wait} else {while (1) { ; }}'
0
-1
<Ctrl-C>

Which contradicts this note in setrlimit(2):

NOTES
       A child process created via fork(2) inherits its parents
       resource limits.  Resource limits are preserved across
       execve(2).


Though strictly speaking, stracing perl, there's no fork() system
call but a clone(). There is a call to libc's fork() function
(verified using ltrace), so it may be a libc issue. Maybe the
limits should be dupplicated in user space by glibc's fork()?

$ getconf GNU_LIBC_VERSION
glibc 2.3.6

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 12:53           ` Stephane Chazelas
@ 2007-04-17 13:03             ` Stephane Chazelas
  2007-04-17 13:24               ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 13:03 UTC (permalink / raw)
  To: Micah Cowan, zsh-workers

On Tue, Apr 17, 2007 at 01:53:55PM +0100, Stephane Chazelas wrote:
[...]
> The limit doesn't seem to get inherited by the child process:
> 
> ~$ perl -MBSD::Resource -le 'setrlimit(RLIMIT_CPU,0,RLIM_INFINITY); print for getrlimit(RLIMIT_CPU); while (1) { ; }'
> 0
> -1
> zsh: cpu limit exceeded  perl -MBSD::Resource -le
> (152)~$ perl -MBSD::Resource -le 'setrlimit(RLIMIT_CPU,0,RLIM_INFINITY); print for getrlimit(RLIMIT_CPU); if (fork) {wait} else {while (1) { ; }}'
> 0
> -1
> <Ctrl-C>
[...]

That doesn't explain everything though.

In 

zsh -c 'ulimit -t 0; (while :; do :; done)'

we get the SIGXCPU, but that's because of zsh's optimisation not
to fork() for the () that is the last statement of the inline
script.

zsh -c 'ulimit -t 0; (while :; do :; done); :'

lasts more than 1 second.

$ sh -c 'ulimit -t 0; sh -c "ulimit -t"; :'
0

So it would seem that the limit is inherited but not applied in
the child (and I couldn't see any signal being blocked or
ignored). So that's probably not a libc issue, rather a Linux
issue.

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 13:03             ` Stephane Chazelas
@ 2007-04-17 13:24               ` Stephane Chazelas
  2007-04-17 13:34                 ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 13:24 UTC (permalink / raw)
  To: Micah Cowan, zsh-workers

On Tue, Apr 17, 2007 at 02:03:16PM +0100, Stephane Chazelas wrote:
[...]
> So it would seem that the limit is inherited but not applied in
> the child (and I couldn't see any signal being blocked or
> ignored). So that's probably not a libc issue, rather a Linux
> issue.
[...]

The Linux code for setrlimit gives a hint:

        if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
                unsigned long rlim_cur = new_rlim.rlim_cur;
                cputime_t cputime;

                if (rlim_cur == 0) {
                        /*
                         * The caller is asking for an immediate RLIMIT_CPU
                         * expiry.  But we use the zero value to mean "it was
                         * never set".  So let's cheat and make it one second
                         * instead
                         */
                        rlim_cur = 1;
                }

It's stored as being "0" and armed with a 1 second delay. And on a fork,
obviously, for the new process, there's no way to distinguish
between a 0 that means "not set" and a 0 that means exit
immediately.

And one can verify that it_prof_expires will be set to 0 in
copy_signal during the fork and that 0 means not armed in
check_process_timers.

But what's the point of setting a cputime of 0 anyway?

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 13:24               ` Stephane Chazelas
@ 2007-04-17 13:34                 ` Stephane Chazelas
  2007-04-17 13:54                   ` David Peer
  2007-04-17 15:02                   ` [OT] " Stephane Chazelas
  0 siblings, 2 replies; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 13:34 UTC (permalink / raw)
  To: Micah Cowan, zsh-workers

On Tue, Apr 17, 2007 at 02:24:46PM +0100, Stephane Chazelas wrote:
> On Tue, Apr 17, 2007 at 02:03:16PM +0100, Stephane Chazelas wrote:
> [...]
> > So it would seem that the limit is inherited but not applied in
> > the child (and I couldn't see any signal being blocked or
> > ignored). So that's probably not a libc issue, rather a Linux
> > issue.
> [...]

Please ignore this email, I was talking rubbish again, I should
probably get back to sleep....

> The Linux code for setrlimit gives a hint:
> 
>         if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
>                 unsigned long rlim_cur = new_rlim.rlim_cur;
>                 cputime_t cputime;
> 
>                 if (rlim_cur == 0) {
>                         /*
>                          * The caller is asking for an immediate RLIMIT_CPU
>                          * expiry.  But we use the zero value to mean "it was
>                          * never set".  So let's cheat and make it one second
>                          * instead
>                          */
>                         rlim_cur = 1;
>                 }
> 
> It's stored as being "0" and armed with a 1 second delay. And on a fork,
> obviously, for the new process, there's no way to distinguish
> between a 0 that means "not set" and a 0 that means exit
> immediately.
> 
> And one can verify that it_prof_expires will be set to 0 in
> copy_signal during the fork and that 0 means not armed in
> check_process_timers.
> 
> But what's the point of setting a cputime of 0 anyway?


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 13:34                 ` Stephane Chazelas
@ 2007-04-17 13:54                   ` David Peer
  2007-04-17 13:57                     ` David Peer
  2007-04-17 15:02                   ` [OT] " Stephane Chazelas
  1 sibling, 1 reply; 21+ messages in thread
From: David Peer @ 2007-04-17 13:54 UTC (permalink / raw)
  To: Micah Cowan, zsh-workers

I hope kernel people will add it to the next kernel release,

but here is one rapid fix that solves the problem.

(you will not see the new limit of 1 sec but you'll still see it set to 
0, but its 1 sec - believe me && try,

 if you want to see it, fork another any shell and you'll see it....bug 
or feature?!)


Before the line: *old_rlim = new_rlim;


add:


if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
            /*
             * The caller is asking for an immediate RLIMIT_CPU
             * expiry.  But we use the zero value to mean "it was
             * never set".  So let's cheat and make it one second
             * instead
             */
            new_rlim.rlim_cur = 1;
        }


You can remove the dumb if statement that does nothing cause the 
assignment occurs(*old_rlim = new_rlim) before

so it has no meaning! : if (rlim_cur == 0) {....}


David



Stephane Chazelas wrote:

> On Tue, Apr 17, 2007 at 02:24:46PM +0100, Stephane Chazelas wrote:
>   
>> On Tue, Apr 17, 2007 at 02:03:16PM +0100, Stephane Chazelas wrote:
>> [...]
>>     
>>> So it would seem that the limit is inherited but not applied in
>>> the child (and I couldn't see any signal being blocked or
>>> ignored). So that's probably not a libc issue, rather a Linux
>>> issue.
>>>       
>> [...]
>>     
>
> Please ignore this email, I was talking rubbish again, I should
> probably get back to sleep....
>
>   
>> The Linux code for setrlimit gives a hint:
>>
>>         if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
>>                 unsigned long rlim_cur = new_rlim.rlim_cur;
>>                 cputime_t cputime;
>>
>>                 if (rlim_cur == 0) {
>>                         /*
>>                          * The caller is asking for an immediate RLIMIT_CPU
>>                          * expiry.  But we use the zero value to mean "it was
>>                          * never set".  So let's cheat and make it one second
>>                          * instead
>>                          */
>>                         rlim_cur = 1;
>>                 }
>>
>> It's stored as being "0" and armed with a 1 second delay. And on a fork,
>> obviously, for the new process, there's no way to distinguish
>> between a 0 that means "not set" and a 0 that means exit
>> immediately.
>>
>> And one can verify that it_prof_expires will be set to 0 in
>> copy_signal during the fork and that 0 means not armed in
>> check_process_timers.
>>
>> But what's the point of setting a cputime of 0 anyway?
>>     
>
>   


-- 
David Peer <!> davidpeer@cs.huji.ac.il
CS System Group | Phone: 02 - 6586942
School of Computer Science and Engineering
Hebrew University of Jerusalem - Israel
Edmund Safra Campus - Givat Ram


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 13:54                   ` David Peer
@ 2007-04-17 13:57                     ` David Peer
  0 siblings, 0 replies; 21+ messages in thread
From: David Peer @ 2007-04-17 13:57 UTC (permalink / raw)
  To: zsh-workers

I forgot:

The file that needs to be changed, of-course is: kernel/sys.c

It was check on kernel 2.6.20.3


David

David Peer wrote:

> I hope kernel people will add it to the next kernel release,
>
> but here is one rapid fix that solves the problem.
>
> (you will not see the new limit of 1 sec but you'll still see it set 
> to 0, but its 1 sec - believe me && try,
>
> if you want to see it, fork another any shell and you'll see it....bug 
> or feature?!)
>
>
> Before the line: *old_rlim = new_rlim;
>
>
> add:
>
>
> if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
>            /*
>             * The caller is asking for an immediate RLIMIT_CPU
>             * expiry.  But we use the zero value to mean "it was
>             * never set".  So let's cheat and make it one second
>             * instead
>             */
>            new_rlim.rlim_cur = 1;
>        }
>
>
> You can remove the dumb if statement that does nothing cause the 
> assignment occurs(*old_rlim = new_rlim) before
>
> so it has no meaning! : if (rlim_cur == 0) {....}
>
>
> David
>
>
>
> Stephane Chazelas wrote:
>
>> On Tue, Apr 17, 2007 at 02:24:46PM +0100, Stephane Chazelas wrote:
>>  
>>> On Tue, Apr 17, 2007 at 02:03:16PM +0100, Stephane Chazelas wrote:
>>> [...]
>>>    
>>>> So it would seem that the limit is inherited but not applied in
>>>> the child (and I couldn't see any signal being blocked or
>>>> ignored). So that's probably not a libc issue, rather a Linux
>>>> issue.
>>>>       
>>> [...]
>>>     
>>
>> Please ignore this email, I was talking rubbish again, I should
>> probably get back to sleep....
>>
>>  
>>> The Linux code for setrlimit gives a hint:
>>>
>>>         if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
>>>                 unsigned long rlim_cur = new_rlim.rlim_cur;
>>>                 cputime_t cputime;
>>>
>>>                 if (rlim_cur == 0) {
>>>                         /*
>>>                          * The caller is asking for an immediate 
>>> RLIMIT_CPU
>>>                          * expiry.  But we use the zero value to 
>>> mean "it was
>>>                          * never set".  So let's cheat and make it 
>>> one second
>>>                          * instead
>>>                          */
>>>                         rlim_cur = 1;
>>>                 }
>>>
>>> It's stored as being "0" and armed with a 1 second delay. And on a 
>>> fork,
>>> obviously, for the new process, there's no way to distinguish
>>> between a 0 that means "not set" and a 0 that means exit
>>> immediately.
>>>
>>> And one can verify that it_prof_expires will be set to 0 in
>>> copy_signal during the fork and that 0 means not armed in
>>> check_process_timers.
>>>
>>> But what's the point of setting a cputime of 0 anyway?
>>>     
>>
>>   
>
>


-- 
David Peer <!> davidpeer@cs.huji.ac.il
CS System Group | Phone: 02 - 6586942
School of Computer Science and Engineering
Hebrew University of Jerusalem - Israel
Edmund Safra Campus - Givat Ram


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17  9:30 ` Micah Cowan
  2007-04-17  9:33   ` David Peer
  2007-04-17  9:42   ` Stephane Chazelas
@ 2007-04-17 14:15   ` Tom Alsberg
  2007-04-17 15:48     ` David Peer
       [not found]     ` <20070417151501.GH4955@sc.homeunix.net>
  2 siblings, 2 replies; 21+ messages in thread
From: Tom Alsberg @ 2007-04-17 14:15 UTC (permalink / raw)
  To: Micah Cowan; +Cc: David Peer, Zsh Workers List

[-- Attachment #1: Type: text/plain, Size: 1946 bytes --]

I checked the problem earlier today (by reference of David who pointed
it out to me - thanks, David).  The problem is apparently in the Linux
kernel, where the check for trying to set RLIMIT_CPU = 0 is done a bit
too late, and has nothing to do with zsh.  Specifically, the same
symptoms were visible with other shells (ash, bash) too.

I checked the Linux kernel sources and found the solution in
kernel/sys.c.  Attached is a copy of my message with the patch to the
Linux-Kernel Mailing List.

One issue that may be relevant within zsh, though, is that it appears
that zsh caches the limits set, and since that check in Linux "cheats"
by setting the value to 1 when 0 is requested, entering "ulimit -a"
does not call getrlimit(...) at all and does show 0 after issuing the
command "ulimit -t 0", although getrlimit(RLIMIT_CPU, ...) would
return 1.  The correct limit is seen in a subshell where this is not
yet cached.

I expect my patch to be in the next Linux 2.6.21 release candidate.

  Cheers,
  -- Tom

On Tue, Apr 17, 2007 at 02:30:40AM -0700, Micah Cowan wrote:
> David Peer wrote:
> > If the user run: ulimit -t 0, he can run jobs without any cputime
> > limitation:
> 
> This sounds more like a kernel problem to me than a zsh bug. I get the
> same behavior on my Ubuntu 7.04 (beta) system, in _bash_.
> 
> I note that getrlimit(2) says:
> 
>  In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
>  treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17, set‐
>  ting a limit of 0 does have an effect, but is  actually  treated  as  a
>  limit of 1 second.
> 
> However, I'm running 2.6.20(-14-generic), and still experiencing that
> symptom.

-- 
  Tom Alsberg - hacker (being the best description fitting this space)
  Web page:	http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.

[-- Attachment #2: lkml-cpulimit.mail --]
[-- Type: message/rfc822, Size: 4265 bytes --]

[-- Attachment #2.1.1: Type: text/plain, Size: 2092 bytes --]

Hi there.

As discovered here today, the change in Kernel 2.6.17 intended to
inhibit users from setting RLIMIT_CPU to 0 (as that is equivalent to
unlimited) by "cheating" and setting it to 1 in such a case, does not
make a difference, as the check is done in the wrong place (too late),
and only applies to the profiling code.

On all systems I checked running kernels above 2.6.17, no matter what
the hard and soft CPU time limits were before, a user could escape
them by issuing in the shell (sh/bash/zsh) "ulimit -t 0", and then the
user's process was not ever killed.

Attached is a trivial patch to fix that.  Simply moving the check to a
slightly earlier location (specifically, before the line that actually
assigns the limit - *old_rlim = new_rlim), does the trick.

Do note that at least the zsh (but not ash, dash, or bash) shell has
the problem of "caching" the limits set by the ulimit command, so when
running zsh the fix will not immediately be evident - after entering
"ulimit -t 0", "ulimit -a" will show "-t: cpu time (seconds) 0", even
though the actual limit as returned by getrlimit(...) will be 1.  It
can be verified by opening a subshell (which will not have the values
of the parent shell in cache) and checking in it, or just by running a
CPU intensive command like "echo '65536^1048576' | bc" and verifying
that it dumps core after one second.

Regardless of whether that is a misfeature in the shell, perhaps it
would be better to return -EINVAL from setrlimit in such a case
instead of cheating and setting to 1, as that does not really reflect
the actual state of the process anymore.  I do not however know what
the ground for that decision was in the original 2.6.17 change, and
whether there would be any "backward" compatibility issues, so I
preferred not to touch that right now.

  Cheers,
  -- Tom

-- 
  Tom Alsberg - hacker (being the best description fitting this space)
  Web page:	http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.

[-- Attachment #2.1.2: linux-2.6.20.3-cpulimit.diff --]
[-- Type: text/x-diff, Size: 1186 bytes --]

Follows a trivial patch to check for RLIMIT_CPU to 0 in the right place.

diff -urN linux-2.6.20.3.orig/kernel/sys.c linux-2.6.20.3/kernel/sys.c
--- linux-2.6.20.3.orig/kernel/sys.c	2007-03-13 20:27:08.000000000 +0200
+++ linux-2.6.20.3/kernel/sys.c	2007-04-17 16:38:51.651236000 +0300
@@ -1916,6 +1916,16 @@
 	if (retval)
 		return retval;
 
+	if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
+		/*
+		 * The caller is asking for an immediate RLIMIT_CPU
+		 * expiry.  But we use the zero value to mean "it was
+		 * never set".  So let's cheat and make it one second
+		 * instead
+		 */
+		new_rlim.rlim_cur = 1;
+	}
+
 	task_lock(current->group_leader);
 	*old_rlim = new_rlim;
 	task_unlock(current->group_leader);
@@ -1937,15 +1947,6 @@
 		unsigned long rlim_cur = new_rlim.rlim_cur;
 		cputime_t cputime;
 
-		if (rlim_cur == 0) {
-			/*
-			 * The caller is asking for an immediate RLIMIT_CPU
-			 * expiry.  But we use the zero value to mean "it was
-			 * never set".  So let's cheat and make it one second
-			 * instead
-			 */
-			rlim_cur = 1;
-		}
 		cputime = secs_to_cputime(rlim_cur);
 		read_lock(&tasklist_lock);
 		spin_lock_irq(&current->sighand->siglock);

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [OT] Bug in ulimit ?
  2007-04-17 13:34                 ` Stephane Chazelas
  2007-04-17 13:54                   ` David Peer
@ 2007-04-17 15:02                   ` Stephane Chazelas
  1 sibling, 0 replies; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-17 15:02 UTC (permalink / raw)
  To: Micah Cowan, zsh-workers

On Tue, Apr 17, 2007 at 02:34:16PM +0100, Stephane Chazelas wrote:
> On Tue, Apr 17, 2007 at 02:24:46PM +0100, Stephane Chazelas wrote:
> > On Tue, Apr 17, 2007 at 02:03:16PM +0100, Stephane Chazelas wrote:
> > [...]
> > > So it would seem that the limit is inherited but not applied in
> > > the child (and I couldn't see any signal being blocked or
> > > ignored). So that's probably not a libc issue, rather a Linux
> > > issue.
> > [...]
> 
> Please ignore this email, I was talking rubbish again, I should
> probably get back to sleep....

Not that rubbish though,

the comment about it_prof_expires is valid I think. But what
that means is that the processing of the process CPU timers is
not scheduled.

In:


perl -W -MTime::HiRes -MBSD::Resource -le '
  setrlimit(RLIMIT_CPU,0,RLIM_INFINITY);
  if (fork) {wait} else {
   Time::HiRes::setitimer(2, 0.5); while (1) { ; }}'

The child process gets the SIGXCPU (not a SIGPROF) after half a
second because the check_process_timers has been scheduled
because of the itimer.

So I beleive the statement about

> But we use the zero value to mean "it was never set"

is not accurate. the soft limit is initialised to infinity
 so there should be no reason AFAICT to treat 0 specially, so
 that this "1 second" cheating shouldn't be necessary (and I'd
 bet if there's a itimer due to fire sooner than 1 second from
 now, the SIGXCPU will be delivered earlier).

So scheduling a check_process_timer for the next tick in
sys_setitimer and for the first tick if rlim_cur is 0 in
copy_signal should do it, I beleive.

> 
> > The Linux code for setrlimit gives a hint:
> > 
> >         if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
> >                 unsigned long rlim_cur = new_rlim.rlim_cur;
> >                 cputime_t cputime;
> > 
> >                 if (rlim_cur == 0) {
> >                         /*
> >                          * The caller is asking for an immediate RLIMIT_CPU
> >                          * expiry.  But we use the zero value to mean "it was
> >                          * never set".  So let's cheat and make it one second
> >                          * instead
> >                          */
> >                         rlim_cur = 1;
> >                 }
> > 
> > It's stored as being "0" and armed with a 1 second delay. And on a fork,
> > obviously, for the new process, there's no way to distinguish
> > between a 0 that means "not set" and a 0 that means exit
> > immediately.
> > 
> > And one can verify that it_prof_expires will be set to 0 in
> > copy_signal during the fork and that 0 means not armed in
> > check_process_timers.
> > 
> > But what's the point of setting a cputime of 0 anyway?
> 

-- 
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Bug in ulimit ?
  2007-04-17 14:15   ` Tom Alsberg
@ 2007-04-17 15:48     ` David Peer
       [not found]     ` <20070417151501.GH4955@sc.homeunix.net>
  1 sibling, 0 replies; 21+ messages in thread
From: David Peer @ 2007-04-17 15:48 UTC (permalink / raw)
  To: Tom Alsberg; +Cc: Micah Cowan, David Peer, Zsh Workers List

Thanks Tom for quick, fast fix and for sending me and others the kernel
patch.
Lets hope kernel developers will apply it in the next release, although
they know about it since 2.6.17.

Thanks!
David

On Tue, April 17, 2007 5:15 pm, Tom Alsberg wrote:
> I checked the problem earlier today (by reference of David who pointed
> it out to me - thanks, David).  The problem is apparently in the Linux
> kernel, where the check for trying to set RLIMIT_CPU = 0 is done a bit too
> late, and has nothing to do with zsh.  Specifically, the same symptoms
> were visible with other shells (ash, bash) too.
>
> I checked the Linux kernel sources and found the solution in
> kernel/sys.c.  Attached is a copy of my message with the patch to the
> Linux-Kernel Mailing List.
>
>
> One issue that may be relevant within zsh, though, is that it appears
> that zsh caches the limits set, and since that check in Linux "cheats" by
> setting the value to 1 when 0 is requested, entering "ulimit -a" does not
> call getrlimit(...) at all and does show 0 after issuing the command
> "ulimit -t 0", although getrlimit(RLIMIT_CPU, ...) would
> return 1.  The correct limit is seen in a subshell where this is not yet
> cached.
>
> I expect my patch to be in the next Linux 2.6.21 release candidate.
>
>
> Cheers,
> -- Tom
>
>
> On Tue, Apr 17, 2007 at 02:30:40AM -0700, Micah Cowan wrote:
>
>> David Peer wrote:
>>
>>> If the user run: ulimit -t 0, he can run jobs without any cputime
>>> limitation:
>>>
>>
>> This sounds more like a kernel problem to me than a zsh bug. I get the
>> same behavior on my Ubuntu 7.04 (beta) system, in _bash_.
>>
>> I note that getrlimit(2) says:
>>
>>
>> In 2.6.x kernels before 2.6.17, a RLIMIT_CPU  limit  of  0  is  wrongly
>>  treated  as "no limit" (like RLIM_INFINITY).  Since kernel 2.6.17,
>> set‐ ting a limit of 0 does have an effect, but is  actually  treated
>> as  a limit of 1 second.
>>
>> However, I'm running 2.6.20(-14-generic), and still experiencing that
>> symptom.
>
> --
> Tom Alsberg - hacker (being the best description fitting this space)
> Web page:	http://www.cs.huji.ac.il/~alsbergt/
> DISCLAIMER:  The above message does not even necessarily represent what
> my fingers have typed on the keyboard, save anything further.
>



^ permalink raw reply	[flat|nested] 21+ messages in thread

* (Off-Topic)  Re: Bug in ulimit ?
       [not found]     ` <20070417151501.GH4955@sc.homeunix.net>
@ 2007-04-18  7:46       ` Tom Alsberg
  2007-04-18  8:22         ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Tom Alsberg @ 2007-04-18  7:46 UTC (permalink / raw)
  To: Stephane Chazelas; +Cc: Zsh Workers List

(Repost top zsh-workers in case it may be of interest, original
 address was misspelled)

On Tue, Apr 17, 2007 at 04:15:01PM +0100, Stephane Chazelas wrote:
> Hi Tom,
> 
> I couldn't find the attachment,

That is weird - I checked and did attach it, and it even appears in
the zsh-workers archives at:

http://www.zsh.org/mla/workers/2007/msg00215.html

> but I could find your message to linux kernel mailing list on google
> groups.

> Your fix will solve the problem but change the value of the
> current of the soft limit and make it different from what the
> user requested.

Indeed - as I mentioned in my message to LKML.

This is not really due to my "fix", however.  This code was there
already since Linux 2.6.17, and was inserted as a "cheat" with the
(apparently unsuccessful) intention of inhibiting users from
overrunning the CPU time limit.  I just moved it to where it will have
the (presumably) intended effect.

> I guess you'll find that this is breaking some standard.

May be - I am not sure right now whether the standards specify any
specific meaning to a RLIMIT_CPU of 0 and how strict the behaviour of
setrlimit(...) is defined.

On the other hand, considering it is not impossible or inconceivable
that the limits of a process might at some point change externally
without the process calling setrlimit(...) by itself (for example, if
some interface is provided for users or administrators to change those
limits from a central control; or in case of some flexible/dynamic
economy-resource based multi-user systems - I know several groups of
people working on such projects).  In such a case, caching the limits
for the ulimit command may be undesirable as the cache may be
inconsistent of the actual limits.

> I beleive this "cheat" is not necessary at all.

I am not quite sure about this either.  As I noted, what looks to be
the obvious thing to do is simply fail with -EINVAL in such a case.
However, it was not my idea to change it to 1 second - there might
have been some reason of backward compatibility for whoever conceived
this "cheat".

> I don't have time to try it, but I think an easy fix would be to
> change the sys_setrlimit() code to still keep the value of the
> cpu-limit timer as 0 as before, but to schedule the processing of
> CPU timers for the next tick instead of for the next second (which
> was wrong as it would delay an itimer),

Since the scheduling is done somewhere else in the code, that may
require saving some other piece of information to differentiate
between a zero value meaning "limit not set" and a zero value meaning
"break immediately".  Thinking of it now, I am not quite sure why a
value of zero is necessary at all to denote the limit was never set
(where is that information necessary?), and whether the initial value
could not be set to infinity or the hard limit.  But again, this logic
was there already, and is beyond the scope of this small fix.

> and at the time of the fork, make sure the it_prof_expirer in
> copy_signal is not set to zero (for instance, schedule it for the
> first tick, as in the code in copy_process).

I have very little with the profiling code in Linux, so I am not sure
whether this alone will do.

> Cheers,
> Stéphane

  Regards,
  -- Tom

-- 
  Tom Alsberg - hacker (being the best description fitting this space)
  Web page:	http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: (Off-Topic)  Re: Bug in ulimit ?
  2007-04-18  7:46       ` (Off-Topic) " Tom Alsberg
@ 2007-04-18  8:22         ` Stephane Chazelas
  2007-04-18  9:23           ` (Off-Topic) Bug in ulimit? Tom Alsberg
  0 siblings, 1 reply; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-18  8:22 UTC (permalink / raw)
  To: Tom Alsberg; +Cc: Zsh Workers List

[-- Attachment #1: Type: text/plain, Size: 462 bytes --]

On Wed, Apr 18, 2007 at 10:46:56AM +0300, Tom Alsberg wrote:
> (Repost top zsh-workers in case it may be of interest, original
>  address was misspelled)
[...]

Hi Tom.

Have you got trouble posting to the list as well? At least one
of the emails I posted yesterday didn't make it (the one
attached). Did you receive it (as I think you were in copy)? I
eventually received the email attachment with the patch the
lkml, but as a separate email!

Cheers,
Stéphane

[-- Attachment #2: Type: message/rfc822, Size: 5922 bytes --]

From: Stephane Chazelas <Stephane_Chazelas@yahoo.fr>
To: Tom Alsberg <alsbergt@cs.huji.ac.il>
Cc: Zsh Workers List <zsh-workers@zsh.org>
Subject: Re: (Off-Topic)  Re: Bug in ulimit ?
Date: Tue, 17 Apr 2007 20:53:09 +0100
Message-ID: <20070417195309.GA4976@sc.homeunix.net>

On Tue, Apr 17, 2007 at 09:59:25PM +0300, Tom Alsberg wrote:
> On Tue, Apr 17, 2007 at 04:15:01PM +0100, Stephane Chazelas wrote:
> > Hi Tom,
> > 
> > I couldn't find the attachment,
> 
> That is weird - I checked and did attach it, and it even appears in
> the zsh-workers archives at:

Could very well be on my side. I think I've already had issues
like that in the past. Could be yahoo or fetchmail or mutt, I'll
investigate.

Sorry about that.

[...]
> > I don't have time to try it, but I think an easy fix would be to
> > change the sys_setrlimit() code to still keep the value of the
> > cpu-limit timer as 0 as before, but to schedule the processing of
> > CPU timers for the next tick instead of for the next second (which
> > was wrong as it would delay an itimer),
> 
> Since the scheduling is done somewhere else in the code, that may
> require saving some other piece of information to differentiate
> between a zero value meaning "limit not set" and a zero value meaning
> "break immediately".  Thinking of it now, I am not quite sure why a
> value of zero is necessary at all to denote the limit was never set
> (where is that information necessary?), and whether the initial value
> could not be set to infinity or the hard limit.  But again, this logic
> was there already, and is beyond the scope of this small fix.

Sorry, I wasn't very clear. I didn't mean scheduling as in
process/task scheduling, but as in sceduling of the function
that will check the timers to be fired. The "cheat" wasn't
modifying the current value of the rlimit from 0 to 1 second, it
was just scheduling the next checking for whether that limit is
reached or not to 1 second from now. So that the process would
keep running for 1 second of CPU time with a pending SIGXCPU
largely overdue.

That's why I mentionned the setitimer(ITIMER_PROF). If you
install such a timer, you rescedule the function that checks the
timers to be fired (at least the timers that work in CPU time
such as those "PROF" timers and the cpu rlimit). If you install
such an itimer with a very small timeout just after a ulimit -t
0, you'll find that the process receives the SIGXCPU upon the
expiry of that timer, not after the 1 second delay, I don't know
if that was intentional or not.

> 
> > and at the time of the fork, make sure the it_prof_expirer in
> > copy_signal is not set to zero (for instance, schedule it for the
> > first tick, as in the code in copy_process).
> 
> I have very little with the profiling code in Linux, so I am not sure
> whether this alone will do.
[...]

My understanding is that if one does ulimit -t 0, he wants the
process to get a SIGCPU as soon as it uses the CPU.

The fix I had in mind is below:

--- kernel/fork.c~	2007-04-17 20:23:29.000000000 +0100
+++ kernel/fork.c	2007-04-17 20:14:32.000000000 +0100
@@ -830,6 +830,7 @@ static inline int copy_signal(unsigned l
 {
 	struct signal_struct *sig;
 	int ret;
+	unsigned long cpu_rlimit;
 
 	if (clone_flags & CLONE_THREAD) {
 		atomic_inc(&current->signal->count);
@@ -884,13 +885,16 @@ static inline int copy_signal(unsigned l
 	memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
 	task_unlock(current->group_leader);
 
-	if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
+	cpu_rlimit = sig->rlim[RLIMIT_CPU].rlim_cur;
+	if (cpu_rlimit != RLIM_INFINITY) {
 		/*
 		 * New sole thread in the process gets an expiry time
 		 * of the whole CPU time limit.
 		 */
-		tsk->it_prof_expires =
-			secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
+		if (cpu_rlimit == 0)
+			tsk->it_prof_expires = jiffies_to_cputime(1);
+		else
+			tsk->it_prof_expires = secs_to_cputime(cpu_rlimit);
 	}
 	acct_init_pacct(&sig->pacct);
 
--- kernel/sys.c~	2007-04-17 20:09:28.000000000 +0100
+++ kernel/sys.c	2007-04-17 20:16:02.000000000 +0100
@@ -1941,19 +1941,13 @@ asmlinkage long sys_setrlimit(unsigned i
 
 	it_prof_secs = cputime_to_secs(current->signal->it_prof_expires);
 	if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
-		unsigned long rlim_cur = new_rlim.rlim_cur;
 		cputime_t cputime;
 
-		if (rlim_cur == 0) {
-			/*
-			 * The caller is asking for an immediate RLIMIT_CPU
-			 * expiry.  But we use the zero value to mean "it was
-			 * never set".  So let's cheat and make it one second
-			 * instead
-			 */
-			rlim_cur = 1;
-		}
-		cputime = secs_to_cputime(rlim_cur);
+		if (new_rlim.rlim_cur == 0)
+			cputime = jiffies_to_cputime(1);
+		else
+			cputime = secs_to_cputime(new_rlim.rlim_cur);
+		
 		read_lock(&tasklist_lock);
 		spin_lock_irq(&current->sighand->siglock);
 		set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);

instead of scheduling it for in one seconds, it schedules it for
the next tick (jiffy), which is kind of more consistent with my
idea of what ulimit -t does, and doesn't explicitely modify what
the user requested.

To get back on topic (slightly :)), with that patch applied, I
get:

$ zsh -c 'float SECONDS; trap "" XCPU; ulimit -t 0
  (trap "echo \$SECONDS" XCPU; while :; do :; done); echo done'
3.253000000e-03
1.009181000e+00
2.019183000e+00
....


(when SIGXCPU is intercepted, Linux resends it every second
until the hard limit is reached).

-- 
Stéphane

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: (Off-Topic) Bug in ulimit?
  2007-04-18  8:22         ` Stephane Chazelas
@ 2007-04-18  9:23           ` Tom Alsberg
  2007-04-18 10:10             ` Stephane Chazelas
  0 siblings, 1 reply; 21+ messages in thread
From: Tom Alsberg @ 2007-04-18  9:23 UTC (permalink / raw)
  To: Zsh Workers List

On Wed, Apr 18, 2007 at 09:22:05AM +0100, Stephane Chazelas wrote:
> Hi Tom.
> 
> Have you got trouble posting to the list as well?

Uh, well...  Yeah, I had trouble.  But it was my fault - I used the
wrong address (@zsh.org instead of @sunsite.dk).

> At least one of the emails I posted yesterday didn't make it (the
> one attached).

Apparently (as seen in the headers) you used the same wrong address I
used (probably automatically because it was in my Cc:).

> Did you receive it (as I think you were in copy)?

Yes, it was also sent directly to me.

> I eventually received the email attachment with the patch the
> lkml, but as a separate email!

That is weird.  May have something to do with your mail forwarding,
though.  I have seen the attachment in the message.

> Cheers,
> Stéphane

  -- Tom

-- 
  Tom Alsberg - hacker (being the best description fitting this space)
  Web page:	http://www.cs.huji.ac.il/~alsbergt/
DISCLAIMER:  The above message does not even necessarily represent what
my fingers have typed on the keyboard, save anything further.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: (Off-Topic) Bug in ulimit?
  2007-04-18  9:23           ` (Off-Topic) Bug in ulimit? Tom Alsberg
@ 2007-04-18 10:10             ` Stephane Chazelas
  0 siblings, 0 replies; 21+ messages in thread
From: Stephane Chazelas @ 2007-04-18 10:10 UTC (permalink / raw)
  To: Tom Alsberg; +Cc: Zsh Workers List

On Wed, Apr 18, 2007 at 12:23:11PM +0300, Tom Alsberg wrote:
> On Wed, Apr 18, 2007 at 09:22:05AM +0100, Stephane Chazelas wrote:
> > Hi Tom.
> > 
> > Have you got trouble posting to the list as well?
> 
> Uh, well...  Yeah, I had trouble.  But it was my fault - I used the
> wrong address (@zsh.org instead of @sunsite.dk).
> 
> > At least one of the emails I posted yesterday didn't make it (the
> > one attached).
> 
> Apparently (as seen in the headers) you used the same wrong address I
> used (probably automatically because it was in my Cc:).

Oops yes, brain slow in the morning again.

[...]
> > I eventually received the email attachment with the patch the
> > lkml, but as a separate email!
> 
> That is weird.  May have something to do with your mail forwarding,
> though.  I have seen the attachment in the message.
[...]

It is probably either mutt or yahoo (on my end). The
attached email follows your email in my mailbox. It looks like
the "\nFrom " has not been escaped as "\n>From " and the
"Lines:" and "Content-Length" headers in your email don't
englobe the attachment, so that mutt sees it as 2 messages.
That's an old version of mutt, I just probably need to upgrade.

So it seems to be exclusively on my end.

Sorry for noise.

Cheers,
Stéphane


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2007-04-18 10:11 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-17  9:00 Bug in ulimit ? David Peer
2007-04-17  9:30 ` Micah Cowan
2007-04-17  9:33   ` David Peer
2007-04-17  9:42   ` Stephane Chazelas
2007-04-17 10:04     ` Micah Cowan
2007-04-17 10:43       ` Stephane Chazelas
2007-04-17 10:55         ` Micah Cowan
2007-04-17 12:53           ` Stephane Chazelas
2007-04-17 13:03             ` Stephane Chazelas
2007-04-17 13:24               ` Stephane Chazelas
2007-04-17 13:34                 ` Stephane Chazelas
2007-04-17 13:54                   ` David Peer
2007-04-17 13:57                     ` David Peer
2007-04-17 15:02                   ` [OT] " Stephane Chazelas
2007-04-17 10:49       ` Micah Cowan
2007-04-17 14:15   ` Tom Alsberg
2007-04-17 15:48     ` David Peer
     [not found]     ` <20070417151501.GH4955@sc.homeunix.net>
2007-04-18  7:46       ` (Off-Topic) " Tom Alsberg
2007-04-18  8:22         ` Stephane Chazelas
2007-04-18  9:23           ` (Off-Topic) Bug in ulimit? Tom Alsberg
2007-04-18 10:10             ` Stephane Chazelas

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).