• getrlimit RLMIT_NPROC

    From Kenny McCormack@21:1/5 to All on Tue Aug 29 14:13:37 2023
    I have the following C program:

    --- Cut Here ---
    #include <stdio.h>
    #include <sys/time.h>
    #include <sys/resource.h>

    int main(void)
    {
    struct rlimit rlim;
    printf("Result: %d\n",getrlimit(RLIMIT_NPROC, &rlim));
    printf("cur = %lu, max = %lu\n",rlim.rlim_cur,rlim.rlim_max);
    printf("RLIM_INFINITY = %ld\n",RLIM_INFINITY);
    return 0;
    }
    --- Cut Here ---

    When run on system A (Ubuntu - x64), the output is:

    Result: 0
    cur = 31411, max = 31411
    RLIM_INFINITY = -1

    What the heck is 31411???


    When run on system B (Raspberry PiOS - ARM32), the output is:

    Result: 0
    cur = 6807, max = 6807
    RLIM_INFINITY = -1

    What the heck is 6807???

    Neither of these results seem reasonable or tied to anything.

    What is going on?

    --
    Kenny, I'll ask you to stop using quotes of mine as taglines.

    - Rick C Hodgin -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Kalevi Kolttonen on Tue Aug 29 15:45:06 2023
    Kalevi Kolttonen <[email protected]> wrote:
    Using grep, I was unable to find where 60988 is set
    on my Fedora 38. So my best guess is that this value
    has been set when compiling the kernel.

    I downloaded the current Fedora 38 kernel sources. The
    value 60988 is nowhere to be found. Some possible reasons:

    1) Maybe 60988 value was given as a command line parameter
    when running "make". I suppose this is quite unlikely and
    I did not investigate the Makefiles to see whether that
    is even supported.

    2) Maybe the Linux kernel sets the default value based
    on how much RAM is available.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Kalevi Kolttonen on Tue Aug 29 16:01:38 2023
    Kalevi Kolttonen <[email protected]> wrote:
    2) Maybe the Linux kernel sets the default value based
    on how much RAM is available.

    Inspecting kernel/fork.c, we see:

    static void set_max_threads(unsigned int max_threads_suggested)
    {
    u64 threads;
    unsigned long nr_pages = totalram_pages();

    /*
    * The number of threads shall be limited such that the thread
    * structures may only consume a small part of the available memory.
    */
    if (fls64(nr_pages) + fls64(PAGE_SIZE) > 64)
    threads = MAX_THREADS;
    else
    threads = div64_u64((u64) nr_pages * (u64) PAGE_SIZE,
    (u64) THREAD_SIZE * 8UL);

    if (threads > max_threads_suggested)
    threads = max_threads_suggested;

    max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
    }

    It seems to me that that eventually sets "max_threads" based on
    available RAM, with the limitation that "max_threads_suggested"
    must not be exceeded.

    Further, fork_init() we have:

    init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
    init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;

    It looks like RLIMIT_NRPOC limits are based on the value of max_threads/2.

    In conclusion, I believe the values you and I saw are based on how much
    RAM our Linux systems have.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Kenny McCormack on Tue Aug 29 15:24:08 2023
    Kenny McCormack <[email protected]> wrote:
    Neither of these results seem reasonable or tied to anything.

    On my Fedora 38 amd64 "uname -a" shows e.g.

    6.4.12-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 23 17:46:49 UTC 2023 x86_64 GNU/Linux

    and the result of running your program is:

    Result: 0
    cur = 60988, max = 60988
    RLIM_INFINITY = -1

    What is going on?

    You used "%lu" and that is correct based on the Linux
    headers. On my Fedora 38 we have these:

    struct rlimit {
    __kernel_ulong_t rlim_cur;
    __kernel_ulong_t rlim_max;
    };

    #define RLIM64_INFINITY (~0ULL)

    struct rlimit64 {
    __u64 rlim_cur;
    __u64 rlim_max;
    };


    Using grep, I was unable to find where 60988 is set
    on my Fedora 38. So my best guess is that this value
    has been set when compiling the kernel.

    Have you tried using a recursive grep invocation
    to find the values you mentioned?

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Kalevi Kolttonen on Tue Aug 29 17:08:01 2023
    [email protected] (Kalevi Kolttonen) writes:
    Kenny McCormack <[email protected]> wrote:
    Neither of these results seem reasonable or tied to anything.

    On my Fedora 38 amd64 "uname -a" shows e.g.

    6.4.12-200.fc38.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 23 17:46:49 UTC 2023 x86_64 GNU/Linux

    and the result of running your program is:

    Result: 0
    cur = 60988, max = 60988
    RLIM_INFINITY = -1

    What is going on?

    You used "%lu" and that is correct based on the Linux
    headers. On my Fedora 38 we have these:

    struct rlimit {
    __kernel_ulong_t rlim_cur;
    __kernel_ulong_t rlim_max;
    };

    #define RLIM64_INFINITY (~0ULL)

    struct rlimit64 {
    __u64 rlim_cur;
    __u64 rlim_max;
    };


    Using grep, I was unable to find where 60988 is set
    on my Fedora 38. So my best guess is that this value
    has been set when compiling the kernel.

    Have you tried using a recursive grep invocation
    to find the values you mentioned?

    While the defaults are compiled into the kernel, the
    login values are generally specified in
    /etc/security/limits.conf on systems that use PAM authentication.

    $ man pam_limits

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Kalevi Kolttonen on Tue Aug 29 17:30:55 2023
    Kalevi Kolttonen <[email protected]> wrote:
    Scott Lurndal <[email protected]> wrote:

    the login values are generally specified in
    /etc/security/limits.conf on systems that use PAM authentication.

    Yes, I know that very well. But in this case they
    are irrelevant to the problem discussed.

    That was perhaps too strong a statement, because
    I have no access to Kenny's system, so I cannot
    be 100% sure whether they are specified there.

    But certainly my Fedora 38 gets the values from
    the Linux kernel and not from the PAM configuration
    files.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Lew Pitcher on Tue Aug 29 17:43:06 2023
    Lew Pitcher <[email protected]> wrote:
    I would disagree; Scott's point is quite relevant to Kenny's
    (very information free) quesion.

    More specifically, Kenny only mentioned the values obtained
    (31411 and 6807), and asked "What is going on?" Each of those
    two values occur in two places: the "curr" limit and the "max"
    limit. While others have discussed how the "max" limit is
    derived, no one (other than Scott) has mentioned how the "curr"
    limit may (or may not) have been set.

    Yes, I already posted a new message telling that this
    information *could* indeed be relevant in Kenny's case.

    But it was not really relevant to my Fedora 38. The values
    were not set there, but came from the Linux kernel based
    on the amount of available RAM.

    So I cannot know for the certain whether Kenny's values
    came from the PAM configuration files or from the Linux
    kernel, but I suspect the latter.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lew Pitcher@21:1/5 to Kalevi Kolttonen on Tue Aug 29 17:39:17 2023
    On Tue, 29 Aug 2023 17:22:52 +0000, Kalevi Kolttonen wrote:

    Scott Lurndal <[email protected]> wrote:
    While the defaults are compiled into the kernel,

    I just checked out some of the Linux kernel
    sources and I am pretty convinced that the
    RLIMIT_PROC defaults are actually dynamically
    calculated based on available RAM.

    the login values are generally specified in
    /etc/security/limits.conf on systems that use PAM authentication.

    Yes, I know that very well. But in this case they
    are irrelevant to the problem discussed.

    I would disagree; Scott's point is quite relevant to Kenny's
    (very information free) quesion.

    More specifically, Kenny only mentioned the values obtained
    (31411 and 6807), and asked "What is going on?" Each of those
    two values occur in two places: the "curr" limit and the "max"
    limit. While others have discussed how the "max" limit is
    derived, no one (other than Scott) has mentioned how the "curr"
    limit may (or may not) have been set.

    AFAICT, Kenny's question was open-ended enough that Scott's
    answer is as on-topic as the rest of the discussion.

    FWIW, as Kenny asked "What the heck is 31411???" and
    "What the heck is 6807???", /I/ was tempted to answer literally,
    and tell him that those values are the current (soft-limit) maximum,
    and hard maximum of the number of processes/threads a single UID
    can launch. But, then again, if Kenny has already coded the
    getrlimit() call for RLIMIT_NPROC, he probably already knows this.


    --
    Lew Pitcher
    "In Skills We Trust"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Scott Lurndal on Tue Aug 29 17:22:52 2023
    Scott Lurndal <[email protected]> wrote:
    While the defaults are compiled into the kernel,

    I just checked out some of the Linux kernel
    sources and I am pretty convinced that the
    RLIMIT_PROC defaults are actually dynamically
    calculated based on available RAM.

    the login values are generally specified in
    /etc/security/limits.conf on systems that use PAM authentication.

    Yes, I know that very well. But in this case they
    are irrelevant to the problem discussed.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Kenny McCormack on Tue Aug 29 18:39:29 2023
    On 2023-08-29, Kenny McCormack <[email protected]> wrote:
    I have the following C program:

    --- Cut Here ---
    #include <stdio.h>
    #include <sys/time.h>
    #include <sys/resource.h>

    int main(void)
    {
    struct rlimit rlim;
    printf("Result: %d\n",getrlimit(RLIMIT_NPROC, &rlim));
    printf("cur = %lu, max = %lu\n",rlim.rlim_cur,rlim.rlim_max);
    printf("RLIM_INFINITY = %ld\n",RLIM_INFINITY);
    return 0;
    }

    That's a waste of time; the existing "ulimit" tool reads these
    limits. "ulimit -a" gives you all of them; "ulimit -u" gives
    us that one ([u]ser processes).

    What the heck is 31411???

    What the heck is 6807???

    Pre-release version of Motrola 6809? ;)

    Good question; do these valuas come from some boot scripts on that
    system, or are they in the kernel?

    Ubuntu 18, 32 bit:

    $ ulimit -u
    15791

    Indeed, weird numbers; it's as if they are concocted by some formula
    applied to various other system parameters.

    I think you have to hunt down the kernel code where the initial/default
    values are prepared.

    It could be the work of a boot script, or ... dare I utter it ... systemd.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Kalevi Kolttonen on Tue Aug 29 19:01:25 2023
    On 2023-08-29, Kalevi Kolttonen <[email protected]> wrote:
    Kalevi Kolttonen <[email protected]> wrote:
    Using grep, I was unable to find where 60988 is set
    on my Fedora 38. So my best guess is that this value
    has been set when compiling the kernel.

    I downloaded the current Fedora 38 kernel sources. The
    value 60988 is nowhere to be found. Some possible reasons:

    1) Maybe 60988 value was given as a command line parameter
    when running "make". I suppose this is quite unlikely and
    I did not investigate the Makefiles to see whether that
    is even supported.

    Pretty much nobody is going to do

    #define DEFAULT_THING 60988 // or other weird number.

    Plus, we are seeing different numbers on different systems

    2) Maybe the Linux kernel sets the default value based
    on how much RAM is available.

    Precisely. It looks calculated. You have to find the area of the kernel
    where the rlimit sysdcalls are implemented. Find out which fields in the
    task struct they are coming from, then search where those are set up.

    I'm looking at 4.9.211 (a kernel I work with in in my embedded work).

    In kernel/fork.c, there is a fork_init() function with these lines:

    init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
    init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;

    max_threads is a tunable global variable initialized earlier
    in that same function by call to set_max_threads(MAX_THREADS).
    That function only uses the parameter as an upper bound clamp.

    It perpetrates a complex calculation from totalram_pages and
    thread context size:

    static void set_max_threads(unsigned int max_threads_suggested)
    {
    u64 threads;

    /*
    * The number of threads shall be limited such that the thread
    * structures may only consume a small part of the available memory.
    */
    if (fls64(totalram_pages) + fls64(PAGE_SIZE) > 64)
    threads = MAX_THREADS;
    else
    threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
    (u64) THREAD_SIZE * 8UL);

    if (threads > max_threads_suggested)
    threads = max_threads_suggested;

    max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
    }

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kalevi Kolttonen@21:1/5 to Kaz Kylheku on Tue Aug 29 19:25:21 2023
    Kaz Kylheku <[email protected]> wrote:
    On 2023-08-29, Kalevi Kolttonen <[email protected]> wrote:
    Kalevi Kolttonen <[email protected]> wrote:
    Using grep, I was unable to find where 60988 is set
    on my Fedora 38. So my best guess is that this value
    has been set when compiling the kernel.

    I downloaded the current Fedora 38 kernel sources. The
    value 60988 is nowhere to be found. Some possible reasons:

    1) Maybe 60988 value was given as a command line parameter
    when running "make". I suppose this is quite unlikely and
    I did not investigate the Makefiles to see whether that
    is even supported.

    Pretty much nobody is going to do

    #define DEFAULT_THING 60988 // or other weird number.

    If you read closely, that is not what I suggested. I only
    suggested that the weird value 60988 was maybe specified
    for "make" using command-line. So the #define:d value in the
    source tree could have been something saner.

    In any case, I pretty much rejected the idea anyway. It
    is not likely that Red Hat/Fedora maintainers would
    specify anything using "make" command-lines.

    Plus, we are seeing different numbers on different systems

    Yes, but that does not disprove my theory above. Different
    numbers could easily be explained by different distros
    having different maintainers. They could have set different
    default values. But again, I did not take that case
    very seriously.

    2) Maybe the Linux kernel sets the default value based
    on how much RAM is available.

    Precisely. It looks calculated. You have to find the area
    of the kernel where [...]

    I already did and posted the results, but Usenet being
    the way it is, my article has not reached you yet.

    Your findings seem pretty much identical to mine.

    The only question that remains is whether Kenny's
    /etc/security/limits.conf has any active settings,
    but somehow I doubt it.

    br,
    KK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Tue Aug 29 21:07:55 2023
    In article <[email protected]>,
    Kaz Kylheku <[email protected]> wrote:
    ...
    That's a waste of time; the existing "ulimit" tool reads these
    limits. "ulimit -a" gives you all of them; "ulimit -u" gives
    us that one ([u]ser processes).

    I think I wrote the C program (it was quite a while ago) because I had been investigating the shell "ulimit" command and it seemed to be displaying a
    bogus result (31411), which I didn't trust. As most of us now see, these numbers just don't look "normal" (in the computer-ish sense).

    So, I wrote the C program, and got the same (bogus-looking) result as the
    shell command.

    What the heck is 31411???

    What the heck is 6807???

    Pre-release version of Motrola 6809? ;)

    Good question; do these valuas come from some boot scripts on that
    system, or are they in the kernel?

    Ubuntu 18, 32 bit:

    $ ulimit -u
    15791

    Indeed, weird numbers; it's as if they are concocted by some formula
    applied to various other system parameters.

    Yup.

    I think you have to hunt down the kernel code where the initial/default >values are prepared.

    It could be the work of a boot script, or ... dare I utter it ... systemd.

    Heh heh...

    --
    The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL:
    http://user.xmission.com/~gazelle/Sigs/God

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)