dinkelk
dinkelk

Reputation: 2786

Setting System V message queue size on Mac OSX

I am currently using System V message queues on Mac OSX and am having trouble setting the queue size to a value larger than 2048 bytes. Here is a compile-able example test.c:

#include <stdio.h>
#include <sys/msg.h>
#include <stdlib.h>

int main() {
  // get a message queue id
  int id = msgget(IPC_PRIVATE,IPC_CREAT|0600);
  if (-1 == id)
      exit(1);

  // get message queue data structure
  struct msqid_ds buf;
  if (-1 == msgctl(id, IPC_STAT, &buf))
      exit(1);
  printf("size is %lu bytes\n", buf.msg_qbytes);

  // set new buffer size
  buf.msg_qbytes = 2750;
  printf("setting size to %lu bytes\n", buf.msg_qbytes);
  if (-1 == msgctl(id, IPC_SET, &buf))
      exit(1);

  // check updated message queue data structure
  if (-1 == msgctl(id, IPC_STAT, &buf))
      exit(1);
  printf("size is %lu bytes\n", buf.msg_qbytes);
}

Compile with:

clang -Wall -pedantic -o test test.c

And run with:

sudo ./test

Note: You have run the above code with sudo to ensure that the msgcntl calls succeed.

The output of this program snippet is:

size is 2048 bytes
setting size to 2750 bytes
size is 2048 bytes

Why isn't the queue size getting changed?

EDIT: The output of ipcs -Q shows:

IPC status from <running system> as of Tue Dec  1 10:06:39 PST 2015
msginfo:
    msgmax:  16384  (max characters in a message)
    msgmni:     40  (# of message queues)
    msgmnb:   2048  (max characters in a message queue)
    msgtql:     40  (max # of messages in system)
    msgssz:      8  (size of a message segment)
    msgseg:   2048  (# of message segments in system)

Can msgmnb be made larger, or am I stuck?

Upvotes: 12

Views: 5772

Answers (3)

terence hill
terence hill

Reputation: 3454

It seems that OS X does not permit to increase the message queue size. The system V implementation is old and not documented at all. I also found strange that the define MSGMNB, MSGMAX are missing from message.h whereas you can find it in Linux and other Unix implementation.

I also find this:

OS X is the worst of the lot. Each queue is limited to 2048 bytes and OS X silently ignores attempts to increase this (just like FreeBSD). To add insult to injury, there appears to be no way to increase this limit short of recompiling the kernel. I'm guessing at this based on the Darwin message queue limits. (http://semanchuk.com/philip/sysv_ipc/)

The document was updated on Sept 2014 and confirms the post in the apple mailing list:

http://lists.apple.com/archives/unix-porting/2008/Jan/msg00033.html

Pointed out by @Mark Setchell in the comment.

Also, a recent Ruby Wrapper implementation is not supported on OS X as the author states that:

The messages are handled by the kernel of your computer. Not all kernels have support for POSIX message queues, a notably example is Darwin (OS X). Darwin implements the older System V IPC API. (https://github.com/Sirupsen/posix-mqueue)

On the web there are other sources (mostly old) that indicate that there is no way other than recompiling the kernel to increase the message queue limits.

UPDATE: Apple's position is to discourage the use of System V IPC here:

Some System V primitives are supported, but their use is discouraged in favor of POSIX equivalents.

Side suggestion, add: msgctl(id, IPC_RMID, NULL); at the end of the test code, someone (like me, sigh!) could forget that each queue must be closed.

Upvotes: 9

John Bollinger
John Bollinger

Reputation: 180103

I'm having trouble finding Mac-specific documentation, but POSIX says that when a message queue is created via msgget(), its "msg_qbytes shall be set equal to the system limit." The BSD manual page for msgget() says the same, and that's OS X's closest relative. For what it's worth, Linux man pages seem universally to agree.

That's all pretty consistent in indicating that if your initial queue size is not large enough then you are hosed. You can (maybe) shrink it, but you cannot grow it beyond its initial value.

Upvotes: 1

user3629249
user3629249

Reputation: 16540

the man page for msgctl()

the field the code is changing is the current number of bytes in the queue and not the maximum number of bytes in the queue.

Suggest looking at: msglen_t msg_qbytes which is the maximum number of bytes allowed in the queue.

Upvotes: -1

Related Questions