According to documentation, /proc/sys/fs/mqueue/msg_max
can be used in order to increase the limit of messages in the queue. The documentation also says, that the limit should not exceed HARD_MSGMAX
, which is 65,536
since Linux 3.5.
However, trying to open queue even with 500 elements fails with EMFILE
:
#include <stdio.h>
#include <mqueue.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
int message_size = argc > 1 ? atoi(argv[1]) : 16;
int queue_size = argc > 2 ? atoi(argv[2]) : 10000;
printf("Trying to open queue with msgsize: %d, and maxmsg: %d\n", message_size, queue_size);
struct mq_attr initial_attributes = (struct mq_attr){
.mq_msgsize = message_size,
.mq_maxmsg = queue_size
};
int open_flags = O_RDWR | O_CREAT | O_EXCL;
int permissions = S_IWUSR | S_IRUSR;
const char* name = "/message_queue_name;";
mqd_t queue = mq_open(name, open_flags, permissions, &initial_attributes);
if(queue == -1)
{
printf("Cannot open message queue\n");
printf("Errno: %d [%s]\n", errno, strerror(errno));
return 1;
}
else
{
printf("Queue has been opened successfully. Closing...\n");
mq_close(queue);
mq_unlink(name);
}
return 0;
}
Tests:
$ cat /proc/sys/fs/mqueue/msg_max
65536
$ ./main 16 300
Trying to open queue with msgsize: 16, and maxmsg: 300
Queue has been opened successfully. Closing...
$ ./main 16 500
Trying to open queue with msgsize: 16, and maxmsg: 500
Cannot open message queue
Errno: 24 [Too many open files]
According to documentation, EMFILE
error code means, that process already has the maximum number of files and message queues open, though this program does not open any other files.
So, my question is: how to open message queue with huge number of elements?
This is my system limits:
$ ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-m: resident set size (kbytes) unlimited
-u: processes 62820
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) unlimited
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 62820
-q: bytes in POSIX msg queues 819200
-e: max nice 30
-r: max rt priority 99
-N 15: unlimited
You have encountered RLIMIT_MSGQUEUE
limit, see mq_overview(7)
:
Resource limit
The
RLIMIT_MSGQUEUE
resource limit, which places a limit on the amount of space that can be consumed by all of the message queues belonging to a process's real user ID, is described ingetrlimit(2)
.
Increase it before calling mq_open()
, e.g. like this:
...
#include <sys/resource.h>
int main(int argc, char** argv)
{
struct rlimit rlim;
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_MSGQUEUE, &rlim) == -1) {
perror("setrlimit");
return 1;
}
...
You need root privileges for that (or CAP_SYS_RESOURCE
capability, I guess).
Linux kernel really returns EMFILE
for this case, check it here:
if (u->mq_bytes + mq_bytes < u->mq_bytes ||
u->mq_bytes + mq_bytes > rlimit(RLIMIT_MSGQUEUE)) {
spin_unlock(&mq_lock);
/* mqueue_evict_inode() releases info->messages */
ret = -EMFILE;
goto out_inode;
}
The reason for EMFILE
here is probably that it's the most close error code from those specified in POSIX; EMFILE
is the only error code that reflects reaching a per-process limitation.
POSIX doesn't specify a more precise error code for RLIMIT_MSGQUEUE
because it is Linux-specific.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With