Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to increase buffer for IPC message queue in OpenWRT

I'm just learning how to use message queues, and I am having a little difficulty with them. I am using two completely separate applications to do the testing -- one is the "sender", and the other is the "receiver".

When I run the sender, it sends 15 strings to the pipe, but then afterward fails with a "Resource temporarily unavailable" error. I just need to consume the messages on the receiver side, but why only 15 messages? I might be sending lots of messages, so I'd like to increase this to a much larger number, like 1000 or so.

I tried to set the message queue size to 32767, so I was expecting 31 at least, but apparently msg_qbytes is not related to the number of messages that can be buffered.

The sender code looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>

#define MESSAGE_SIZE 1024

typedef struct msgbuf
{
    long mtype;
    char mtext[MESSAGE_SIZE];
};

int main(int argc, char *argv[]) {
    int msgid;
    int ret;
    struct msqid_ds msg_settings;
    long key;
        struct msgbuf msg;

    key = strtol(argv[1], NULL, 10);
    // print the message queue ID for reading via msgrcv
    printf( "Getting message queue with key = %ld\n", key);
    usleep( 1000000);

    msgid = msgget( (key_t)key, 0666 | IPC_CREAT);

    if (msgid == -1) {
        perror("msgget failed with error");
        exit(EXIT_FAILURE);
    }

    // read in current queue settings and then set the new
    // queue size.
    ret = msgctl(msgid, IPC_STAT, &msg_settings);
    msg_settings.msg_qbytes = 32767;
    msgctl( msgid, IPC_SET, &msg_settings);

    while( 1) {
        msg.mtype = 1; // we'll always leave this as 1
        memset( &(msg.mtext), 0, MESSAGE_SIZE);
        sprintf( msg.mtext, "hi");
        printf( "Sending data: %s\n", msg.mtext);
        ret = msgsnd( 1, &msg, MESSAGE_SIZE, IPC_NOWAIT);
        usleep( 500000);
        if( ret == -1) {
            perror( "msgsnd failed\n");
    }

    printf( "leaving...\n");

    return EXIT_SUCCESS;
}

The receiver code looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define MESSAGE_SIZE 1024

typedef struct msgbuf
{
    long mtype;
    char mtext[MESSAGE_SIZE];
};

int main(int argc, char *argv[]) {
    long int msgtyp = 1;
    int ret;
    size_t msgsz;
    struct msgbuf mymsg;

    int msgid;
    msgid = strtol(argv[1], NULL, 10);
    printf( "Reading message queue with ID = %d\n", msgid);
    usleep( 1000000);
    while( 1) {
        msgsz = (size_t)MESSAGE_SIZE;
        ret = msgrcv( msgid, &mymsg, msgsz, msgtyp, IPC_NOWAIT);
        if( ret == ENOMSG) {
            usleep( 100000);
            continue;
        }

        if( ret == -1) {
            perror( "msgrcv failed");
        } else {
            printf( "Read data: %s", mymsg.mtext);
            }

        usleep( 100000);
    }
    return EXIT_SUCCESS;
}
like image 483
Dave Avatar asked Jun 01 '13 15:06

Dave


1 Answers

I finally found the information: http://wiki.openwrt.org/doc/uci/system

You just have to modify /etc/config/system and add `option buffersize 65535'. Unfortunately, you can't go higher than 64k.

I made the change and it's definitely better, but not perfect. I'm going to pare down my message size to try to accommodate more messages.

like image 134
Dave Avatar answered Oct 18 '22 13:10

Dave