POSIX POSIX 1003.1b-1993 in Section Section 3.1.1.2(14) requires that the fork() system call must clone all currently open message queue descriptors into the child process. Currently, the FreeBSD kernel is evidently failing to do this, as is illustrated by the following simple test program: https://pastebin.com/raw/Dya0XEhf (Note that the test program works fine and produces the desired and expected results when compiled and run under Ubuntu 18.04 LTS.) I am NOT the first person to have noticed this very serious and fundamental kernel non-conformance with the POSIX standard: https://stackoverflow.com/questions/19500194/freebsd-doesnt-preserve-posix-message-queue-descriptions-over-forks https://forums.freebsd.org/threads/fork-does-not-properly-copy-posix-message-queue-descriptions.42678/ P.S. If it were possible to do so, I would mark this as "URGENT". For me, this particular non-feature in the kernel is likely to cause great difficulties.
Try diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index b738dbc77b4..913f03e12d5 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -229,7 +229,7 @@ static uma_zone_t mqueue_zone; static uma_zone_t mvdata_zone; static uma_zone_t mqnoti_zone; static struct vop_vector mqfs_vnodeops; -static struct fileops mqueueops; +static struct fileops mqueueops = {.fo_flags = DFLAG_PASSABLE}; static unsigned mqfs_osd_jail_slot; /*
Wow! Thanks! I had not anticipated quite such a quick turaround on a kernel bug. And on a Saturday night no less! Seriously, thanks much. I do not wish to be impertinent, and I certainly intend to try this out, but it is much more important to me to have the bug fixed for everyone, than just for me, personally, so that I can, in future, give people either sources or pre-compiled binaries and say to them "Here, just run this on your FreeBSD system." and have faith that it will work. So I have to ask, is it your intention to do a commit on this fix?
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index b738dbc77b4..07346701857 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -2669,6 +2669,7 @@ static struct fileops mqueueops = { .fo_chown = mqf_chown, .fo_sendfile = invfo_sendfile, .fo_fill_kinfo = mqf_fill_kinfo, + .fo_flags = DFLAG_PASSABLE, }; static struct vop_vector mqfs_vnodeops = { may work better... It compiles, but I've not tested it.
(In reply to Ronald F. Guilmette from comment #2) My intent is to commit a verified working fix that passes the review process. Since I only have your simple test caee, I can get that working, but if it fails in your more complex application, only you can tell me that. I posted my fix quickly so you can test while I sort out a minor snafu with my testing machine
snafu sorted, my patch makes the test case work.
This bug appears to date back to r110908 (2003) where alfred failed to tag mqueue as a passable fd type and then r223866 (2011) by jonathan used the new flag in fdcopy, which fork uses which is where mqueuefs actually broke this test case. so FreeBSD 8 had it still working but FreeBSD 9 and newer didn't.
https://reviews.freebsd.org/D23038
Amazing. I guess that there aren't a lot of people out there using these message queues to try to pass messages between related familial processes.
Ah, my mistake. Alfred didn't miss this, but it was this way from when it was committed in r152825 in 2005.
A commit references this bug: Author: imp Date: Mon Jan 27 22:36:54 UTC 2020 New revision: 357183 URL: https://svnweb.freebsd.org/changeset/base/357183 Log: Make mqueue objects work across a fork again. In r110908 (2003) alfred added DFLAG_PASSABLE to tag those types of FD that can be passed via unix pipes, but mqueuefs didn't exist yet. Later, in r152825 (2005) davidxu neglected to include DFLAG_PASSABLE since people don't normally pass these things via unix sockets (it's a FreeBSD implementation detail that it's a file descriptor, nobody noticed). Then r223866 (2011) by jonathan used the new flag in fdcopy, which fork uses. Due to that, mqueuefs actually broke mqueue objects being propagated by fork. No mention of mqueuefs was made in r223866, so I think it was an unintended consequence. Fix this by tagging mqueuefs as passable as well. They were prior to alfred's change (and it's clear there's no intent in his change to change this behavior), and POSIX requires this to be the case as well. PR: 243103 Reviewed by: kib@, jiles@ Differential Revision: https://reviews.freebsd.org/D23038 Changes: head/sys/kern/uipc_mqueue.c
^Triage: committed back in 2020.