mq_open() - too many open files

13,001

Solution 1

I hit this problem this week - that I could only open a max of 10 mqs.

My intent is to use mqs to pass notification of events to threads. In my case an event_id is just an int. By using specifying non-default attributes in the call to mq_open like so:

char mq_name[128];
sprintf(mq_name, "%s.%d", MQ_NAME, nnid);

struct mq_attr attrib;
attrib.mq_flags = 0;
attrib.mq_maxmsg = 4;
attrib.mq_msgsize = sizeof(int);
attrib.mq_curmsgs = 0;

retval = mq = mq_open(mq_name, O_RDWR | O_CREAT | O_EXCL, 0644, &attrib);

I am now able to open up to 256 mqs before mq_open() fails.

Solution 2

There are a number of limits that you might be hitting here.

Assuming you are on Linux:

Since you are passing NULL in as the last argument to mq_open, you get default number of messages and max message size per queue. These are set from

/proc/sys/fs/mqueue/msg_default and

/proc/sys/fs/mqueue/msgsize_default

You can view these limits with

cat /proc/sys/fs/mqueue/msg_default

and change them with

sudo echo myNewLimit > /proc/sys/fs/mqueue/msg_default

There is also a limit on the total number of message queues that can be created on a system. This is stored at /proc/sys/fs/mqueue/queues_max Documentation for these and other limits is in MQ_OVERVIEW(7)

There is also a limit on how much memory your process can allocate to message queues. This memory is at least (Num_Messages * Message_Length + book keeping overhead) per message queue. A Detailed description of this limit is available here GETRLIMIT(2)

I would advise writing a small test program to create multiple message queues to experiment with these limits. Also remember to check for the existence of queues before you start by using

ls -l /dev/mqueue/ 

And also remember to delete your queues with mq_unlink at the end of your program, else they will persist between runs.

Solution 3

Usually, Too Many Open files means that your are trying to open file descriptors while you already opened the maximum number of files allowed by the system.

cat /proc/sys/fs/file-max

show you the maximum number of file descriptors allowed on your system. You can try to increase this value for your current running session with:

sysctl fs.file-max = new_value

or permanently by editing /etc/sysctl.conf by adding the following line:

fs.file-max = new_value

To be sure that this limit is the one you are reaching you can run

cat /proc/sys/fs/file-nr

The third column nnumber is the same as the one reported by file-max. The first column is the number of allocated file handles and the second one is the number of unused but allocated file handles. If substracting of the first number by the second one gives you the third one (or a number close to the third one) you are reaching the limit.

As suggested by @nos in a comment, in the precise case of mq_open as specified by the man page (*ENOSPC Insufficient space for the creation of a new message queue. This probably occurred because the queues_max limit was encountered; see mq_overview(7)*) you 'll need also to check in the same way the value of fs.mqueue.queues_max

/proc/sys/fs/mqueue/queues_max

to get current value and

sysctl fs.mqueue.queues_max = new_value

to change it.

Share:
13,001
aburak
Author by

aburak

Updated on July 21, 2022

Comments

  • aburak
    aburak almost 2 years

    I'm trying to write a client and server which are going to exchange data by using POSIX message queue. I tried to do it by looking at the examples I saw in the Internet and the documents of the course. But, I am stuck in. When I run it, I get "Too many open files" error. Here is my code:

    Client:

    int main( int argc, char *argv[]) {
    
        //Open its queue, which is client queue
        char cq_name[10];
        sprintf( cq_name, "/cq%i", getpid());
        printf( "Client Queue name: %s\n", cq_name);
    
        mqd_t cq_id = mq_open( cq_name, O_CREAT | O_RDWR, 0666, NULL);
        if( cq_id == -1) {
    
                printf( "Error in cq: %s\n", strerror( errno));
                return -1;
        }
    
        printf( "Name: %s\n", argv[1]);
    
        //Connect to the server message queue
        mqd_t sq_id = mq_open( argv[1], O_RDWR);
    
        if( sq_id == -1) {
    
                printf( "Error in sq: %s\n", strerror( errno));
                return -1;
        }
    

    ...

    Server:

    int main( int argc, char *argv[]) {
    
        //The server message queue
        struct mq_attr attr;
        attr.mq_flags = 0;
        attr.mq_curmsgs = 0;
    
        printf( "Name: %s\n", argv[1]);
    
        mqd_t id = mq_open( argv[1], O_CREAT | O_RDWR, 0666, NULL);
    
        //Check the message queue
        if( id == -1) {
    
                printf( "Error: %s\n", strerror(errno));
        }
    
        printf( "Check Point 1 - %i\n", id);
    

    ...

    Can you help me to figure out what the problem is. Thanks in advance..

  • nos
    nos about 10 years
    You'll need fs.mqueue.queues_max too, it's a lot lower than fs.file-max. The next problem might be the per process limit on file descriptors (look with ulimit -n )
  • Muneeb Zulfiqar
    Muneeb Zulfiqar about 10 years
    doesnt the message will be null after reader have recieved the message?
  • Manuel Selva
    Manuel Selva about 10 years
    the message can't be sent at all because the ms_send function needs the mqd returned by mq_open which is failling