Commit be94d44e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] posix message queues: implementation

From: Manfred Spraul <manfred@colorfullife.com>

Actual implementation of the posix message queues, written by Krzysztof
Benedyczak and Michal Wronski.  The complete implementation is dependant on
CONFIG_POSIX_MQUEUE.

It passed the openposix test suite with two exceptions: one mq_unlink test
was bad and tested undefined behavior.  And Linux succeeds
mq_close(open(,,,)).  The spec mandates EBADF, but we have decided to ignore
that: we would have to add a new syscall just for the right error code.

The patch intentionally doesn't use all helpers from fs/libfs for kernel-only
filesystems: step 5 allows user space mounts of the file system.



Signal changes:

The patch redefines SI_MESGQ using __SI_CODE: The generic Linux ABI uses
a negative value (i.e.  from user) for SI_MESGQ, but the kernel internal
value must be posive to pass check_kill_value.  Additionally, the patch
adds support into copy_siginfo_to_user to copy the "new" signal type to
user space.



Changes in signal code caused by POSIX message queues patch:

General & rationale:

  mqueues generated signals (only upon notification) must have si_code
  == SI_MESGQ.  In fact such a signal is send from one process which
  caused notification (== sent message to empty message queue) to
  another which requested it.  Both processes can be of course unrelated
  in terms of uids/euids.  So SI_MESGQ signals must be classified as
  SI_FROMKERNEL to pass check_kill_permissions (not need to say that
  this signals ARE from kernel).

  Signals generated by message queues notification need the same
  fields in siginfo struct's union _sifields as POSIX.1b signals and we
  can reuse its union entry.

  SI_MESGQ was previously defined to -3 in kernel and also in glibc. 
  So in userspace SI_MESGQ must be still visible as -3.

Solution:

  SI_MESGQ is defined in the same style as SI_TIMER using __SI_CODE macro.

  Details:

    Fortunately copy_siginfo_to_user copies si_code as short.  So we
    can use remaining part of int value freely.  __SI_CODE does the
    work.  SI_MESGQ is in kernel:

 		6<<16 | (-3 & 0xffff) what is > 0

    but to userspace is copied

 		(short) SI_MESGQ == -3

Actual changes:

  Changes in include/asm-generic/siginfo.h

  __SI_MESGQ added in signal.h to represent inside-kernel prefix of
  SI_MESGQ.  SI_MESGQ is redefined from -3 to __SI_CODE(__SI_MESGQ, -3)

  Except mips architecture those changes should be arch independent
  (asm-generic/siginfo.h is included in arch versions).  On mips
  SI_MESGQ is redefined to -4 in order to be compatible with IRIX.  But
  the same schema can be used.

  Change in copy_siginfo_to_user: We only add one line to order the
  same copy semantics as for _SI_RT.

  This change isn't very portable - some arch have its own
  copy_siginfo_to_user.  All those should have similar change (but
  possibly not one-line as _SI_RT case was sometimes ignored because i
  wasn't used yet, e.g.  see ia64 signal.c).

Update:
mq: only fail with invalid timespec if mq_timed{send,receive} needs to block
From: Jakub Jelinek <jakub@redhat.com>

POSIX requires EINVAL to be set if:
"The process or thread would have blocked, and the abs_timeout parameter
specified a nanoseconds field value less than zero or greater than or equal
to 1000 million."
but 2.6.5-mm3 returns -EINVAL even if the process or thread would not block
(if the queue is not empty for timedreceive or not full for timedsend).
parent c50142a5
...@@ -289,6 +289,15 @@ S: Via Delle Palme, 9 ...@@ -289,6 +289,15 @@ S: Via Delle Palme, 9
S: Terni 05100 S: Terni 05100
S: Italy S: Italy
N: Krzysztof Benedyczak
E: golbi@mat.uni.torun.pl
W: http://www.mat.uni.torun.pl/~golbi
D: POSIX message queues fs (with M. Wronski)
S: ul. Podmiejska 52
S: Radunica
S: 83-000 Pruszcz Gdanski
S: Poland
N: Randolph Bentson N: Randolph Bentson
E: bentson@grieg.seaslug.org E: bentson@grieg.seaslug.org
W: http://www.aa.net/~bentson/ W: http://www.aa.net/~bentson/
...@@ -3485,6 +3494,14 @@ S: 12725 SW Millikan Way, Suite 400 ...@@ -3485,6 +3494,14 @@ S: 12725 SW Millikan Way, Suite 400
S: Beaverton, OR 97005 S: Beaverton, OR 97005
S: USA S: USA
N: Michal Wronski
E: wrona@mat.uni.torun.pl
W: http://www.mat.uni.torun.pl/~wrona
D: POSIX message queues fs (with K. Benedyczak)
S: ul. Teczowa 23/12
S: 80-680 Gdansk-Sobieszewo
S: Poland
N: Frank Xia N: Frank Xia
E: qx@math.columbia.edu E: qx@math.columbia.edu
D: Xiafs filesystem [defunct] D: Xiafs filesystem [defunct]
......
...@@ -38,6 +38,7 @@ Table of Contents ...@@ -38,6 +38,7 @@ Table of Contents
2.8 /proc/sys/net/ipv4 - IPV4 settings 2.8 /proc/sys/net/ipv4 - IPV4 settings
2.9 Appletalk 2.9 Appletalk
2.10 IPX 2.10 IPX
2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Preface Preface
...@@ -1814,6 +1815,30 @@ The /proc/net/ipx_route table holds a list of IPX routes. For each route it ...@@ -1814,6 +1815,30 @@ The /proc/net/ipx_route table holds a list of IPX routes. For each route it
gives the destination network, the router node (or Directly) and the network gives the destination network, the router node (or Directly) and the network
address of the router (or Connected) for internal networks. address of the router (or Connected) for internal networks.
2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
----------------------------------------------------------
The "mqueue" filesystem provides the necessary kernel features to enable the
creation of a user space library that implements the POSIX message queues
API (as noted by the MSG tag in the POSIX 1003.1-2001 version of the System
Interfaces specification.)
The "mqueue" filesystem contains values for determining/setting the amount of
resources used by the file system.
/proc/sys/fs/mqueue/queues_max is a read/write file for setting/getting the
maximum number of message queues allowed on the system.
/proc/sys/fs/mqueue/msg_max is a read/write file for setting/getting the
maximum number of messages in a queue value. In fact it is the limiting value
for another (user) limit which is set in mq_open invocation. This attribute of
a queue must be less or equal then msg_max.
/proc/sys/fs/mqueue/msgsize_max is a read/write file for setting/getting the
maximum message size value (it is every message queue's attribute set during
its creation).
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Summary Summary
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
......
...@@ -123,6 +123,7 @@ typedef struct siginfo { ...@@ -123,6 +123,7 @@ typedef struct siginfo {
#define __SI_FAULT (3 << 16) #define __SI_FAULT (3 << 16)
#define __SI_CHLD (4 << 16) #define __SI_CHLD (4 << 16)
#define __SI_RT (5 << 16) #define __SI_RT (5 << 16)
#define __SI_MESGQ (6 << 16)
#define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) #define __SI_CODE(T,N) ((T) | ((N) & 0xffff))
#else #else
#define __SI_KILL 0 #define __SI_KILL 0
...@@ -131,6 +132,7 @@ typedef struct siginfo { ...@@ -131,6 +132,7 @@ typedef struct siginfo {
#define __SI_FAULT 0 #define __SI_FAULT 0
#define __SI_CHLD 0 #define __SI_CHLD 0
#define __SI_RT 0 #define __SI_RT 0
#define __SI_MESGQ 0
#define __SI_CODE(T,N) (N) #define __SI_CODE(T,N) (N)
#endif #endif
...@@ -142,7 +144,7 @@ typedef struct siginfo { ...@@ -142,7 +144,7 @@ typedef struct siginfo {
#define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */
#define SI_QUEUE -1 /* sent by sigqueue */ #define SI_QUEUE -1 /* sent by sigqueue */
#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */ #define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
#define SI_MESGQ -3 /* sent by real time mesq state change */ #define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
#define SI_ASYNCIO -4 /* sent by AIO completion */ #define SI_ASYNCIO -4 /* sent by AIO completion */
#define SI_SIGIO -5 /* sent by queued SIGIO */ #define SI_SIGIO -5 /* sent by queued SIGIO */
#define SI_TKILL -6 /* sent by tkill system call */ #define SI_TKILL -6 /* sent by tkill system call */
......
...@@ -90,6 +90,24 @@ config SYSVIPC ...@@ -90,6 +90,24 @@ config SYSVIPC
section 6.4 of the Linux Programmer's Guide, available from section 6.4 of the Linux Programmer's Guide, available from
<http://www.tldp.org/guides.html>. <http://www.tldp.org/guides.html>.
config POSIX_MQUEUE
bool "POSIX Message Queues"
depends on EXPERIMENTAL
---help---
POSIX variant of message queues is a part of IPC. In POSIX message
queues every message has a priority which decides about succession
of receiving it by a process. If you want to compile and run
programs written e.g. for Solaris with use of its POSIX message
queues (functions mq_*) say Y here. To use this feature you will
also need mqueue library, available from
<http://www.mat.uni.torun.pl/~wrona/posix_ipc/>
POSIX message queues are visible as a filesystem called 'mqueue'
and can be mounted somewhere if you want to do filesystem
operations on message queues.
If unsure, say Y.
config BSD_PROCESS_ACCT config BSD_PROCESS_ACCT
bool "BSD Process Accounting" bool "BSD Process Accounting"
help help
......
...@@ -4,3 +4,5 @@ ...@@ -4,3 +4,5 @@
obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o
obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o
This diff is collapsed.
...@@ -2047,6 +2047,7 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) ...@@ -2047,6 +2047,7 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_stime, &to->si_stime);
break; break;
case __SI_RT: /* This is not generated by the kernel as of now. */ case __SI_RT: /* This is not generated by the kernel as of now. */
case __SI_MESGQ: /* But this is */
err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_pid, &to->si_pid);
err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_int, &to->si_int); err |= __put_user(from->si_int, &to->si_int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment