Number of POSIX queues in the system

721 views Asked by At

I have a strange discrepancy between documentation and reality. The man 7 mq_overview states:

  /proc/sys/fs/mqueue/queues_max
         This  file  can  be  used  to  view and change the system-wide limit
         on the number of message queues that can be created.
         The default value for queues_max is 256.

I checked, on my systems (real Linux and WSL2 same results) - the number in the queues_max is indeed 256.

But a simple stress test shows that total number of queues in the system is 9. Here is a code for testing I used:

#include <stdio.h>
#include <mqueue.h>

int main(int argc, char **argv) {
    for(int i=0; i<100; i++) {
        char name[32];
        snprintf(name, sizeof(name), "/%s%d", argv[1], i);

        mqd_t mqd = mq_open(name, O_RDONLY | O_NONBLOCK | O_CREAT, S_IRUSR, NULL);
        if (mqd == -1) {
            printf("Opening %s failed with: %m\n", name);
            return 1;
        }
        printf("Opened %s, mqd=%d\n", name, mqd);

        if (mq_close(mqd)) {
            printf("Failed to close %s: %m\n", name);
            return 1;
        }

        /* this removes the queue from the system
        if (mq_unlink(name)) {
            printf("Failed to delete %s: %m\n", name);
            return 1;
        }*/
    }
    return 0;
}

executed as:

$ gcc mqtest.c -lrt
$ a.out a
Opened /a0, mqd=3
Opened /a1, mqd=3
Opened /a2, mqd=3
Opened /a3, mqd=3
Opened /a4, mqd=3
Opened /a5, mqd=3
Opened /a6, mqd=3
Opened /a7, mqd=3
Opened /a8, mqd=3
Opening /a9 failed with: Too many open files
$ a.out b
Opening /b0 failed with: Too many open files
$

So the number 9 is not per-process, it is per-system.

What am I missing?

1

There are 1 answers

1
White Owl On BEST ANSWER

As soon as I posted a question, I had en epiphany...

The error message given by the OS is wrong. The problem is not with a number of files, but with a memory. The POSIX queue is based on a shared memory (owned by the mqueue module) - application creates a named segment in a system-wide memory and all mq_send()/mq_receive() just read this segment. But total memory used by all queues is limited.

So instead of EMFILE (errno=24), the error should be ENOMEM (12).

Tested by introducing a limit on the opened queue:

    struct mq_attr attribs;
    attribs.mq_maxmsg  = 10;
    attribs.mq_msgsize = 1024;
    attribs.mq_flags   = 0;

Now, I can open 72 queues in total. Please note, it is not per-process (as stated in documentation), but per-system.