Linux – How is a message queue implemented in the Linux kernel
kernellinux
I would like to know how Message Queues are implemented in the Linux Kernel.
Best Answer
The Linux kernel (2.6) implements two message queues: (rather 'message lists', as the implementation is done by using a linked list not strictly following the FIFO principle)
System V IPC messages
The message queue from System V.
A process can invoke msgsnd() to send a message. He needs to pass the IPC identifier of the receiving message queue, the size of the message and a message structure, including the message type and text.
On the other side, a process invokes msgrcv() to receive a message, passing the IPC identifier of the message queue, where the message should get stored, the size and a value t.
t specifies the message returned from the queue, a positive value means the first message with its type equal to t is returned, a negative value returns the last message equal to type t and zero returns the first message of the queue.
unfs3 is dead as far as I know; Ganesha is the most active userspace NFS server project right now, though it is not completely mature.
Although it serves different protocols, Samba is an example of a successful
file server that operates in userspace.
I haven't seen a recent performance comparison.
Some other issues:
Ordinary applications look files up by pathname, but nfsd needs to be able to
look them up by filehandle. This is tricky and requires support from the
filesystem (and not all filesystems can support it). In the past it was not
possible to do this from userspace, but more recent kernels have added
name_to_handle_at(2) and open_by_handle_at(2) system calls.
I seem to recall blocking file-locking calls being a problem; I'm not sure
how userspace servers handle them these days. (Do you tie up a server thread
waiting on the lock, or do you poll?)
Newer file system semantics (change attributes, delegations, share locks)
may be implemented
more easily in kernel first (in theory--they mostly haven't been yet).
You don't want to have to check permissions, quotas, etc., by hand--instead
you want to change your uid and rely on the common kernel vfs code to do
that. And Linux has a system call (setfsuid(2)) that should do that. For
reasons I forget, I think that's proved more complicated to use in servers
than it should be.
In general, a kernel server's strengths are closer integration with the vfs and the exported filesystem. We can make up for that by providing more kernel interfaces (such as the filehandle system calls), but that's not easy. On the other hand, some of the filesystems people want to export these days (like gluster) actually live mainly in userspace. Those can be exported by the kernel nfsd using FUSE--but again extensions to the FUSE interfaces may be required for newer features, and there may be performance issues.
Best Answer
The Linux kernel (2.6) implements two message queues:
(rather 'message lists', as the implementation is done by using a linked list not strictly following the FIFO principle)
System V IPC messages
The message queue from System V.
A process can invoke
msgsnd()
to send a message. He needs to pass the IPC identifier of the receiving message queue, the size of the message and a message structure, including the message type and text.On the other side, a process invokes
msgrcv()
to receive a message, passing the IPC identifier of the message queue, where the message should get stored, the size and a value t.t specifies the message returned from the queue, a positive value means the first message with its type equal to t is returned, a negative value returns the last message equal to type t and zero returns the first message of the queue.
Those functions are defined in include/linux/msg.h and implemented in ipc/msg.c
There are limitations upon the size of a message (max), the total number of messages (mni) and the total size of all messages in the queue (mnb):
The output above is from a Ubuntu 10.10 system, the defaults are defined in msg.h.
More incredibly old System V message queue stuff explained here.
POSIX Message Queue
The POSIX standard defines a message queue mechanism based on System V IPC's message queue, extending it by some functionalities:
See ipc/mqueue.c
Example
util-linux
provides some programs for analyzing and modifying message queues and the POSIX specification gives some C examples:Create a message queue with
ipcmk
; generally you would do this by calling C functions likeftok()
andmsgget()
:Lets see what happened by using
ipcs
or with acat /proc/sysvipc/msg
:Now fill the queue with some messages:
Again, you generally do not hardcode the msqid in the code.
And the other side, which will be receiving the messages:
See what happens:
After two receives, the queue is empty again.
Remove it afterwards by specifying the key (
-Q
) or msqid (-q
):