git: 97add684f530 - main - linux: Support POSIX message queues
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 23 May 2024 19:42:15 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=97add684f5306ebf93be238a0340597ba1898d0e
commit 97add684f5306ebf93be238a0340597ba1898d0e
Author: Ricardo Branco <rbranco@suse.de>
AuthorDate: 2024-05-17 20:31:49 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-05-23 19:40:46 +0000
linux: Support POSIX message queues
Reviewed by: imp, kib
Pull Request: https://github.com/freebsd/freebsd-src/pull/1248
---
sys/amd64/linux/linux_dummy_machdep.c | 6 --
sys/amd64/linux32/linux32_dummy_machdep.c | 6 --
sys/arm64/linux/linux_dummy_machdep.c | 6 --
sys/compat/linux/linux_misc.c | 124 ++++++++++++++++++++++++++++++
sys/i386/linux/linux_machdep.c | 61 ---------------
5 files changed, 124 insertions(+), 79 deletions(-)
diff --git a/sys/amd64/linux/linux_dummy_machdep.c b/sys/amd64/linux/linux_dummy_machdep.c
index 759586d9f1fc..53bdb8099578 100644
--- a/sys/amd64/linux/linux_dummy_machdep.c
+++ b/sys/amd64/linux/linux_dummy_machdep.c
@@ -56,12 +56,6 @@ DUMMY(io_destroy);
DUMMY(io_getevents);
DUMMY(io_submit);
DUMMY(io_cancel);
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
DUMMY(readahead);
DUMMY(restart_syscall);
/* Linux 3.15: */
diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index c2206c81c528..1476d39b9c35 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -55,12 +55,6 @@ DUMMY(olduname);
DUMMY(uname);
DUMMY(bdflush);
DUMMY(ptrace);
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
/* Linux 4.11: */
DUMMY(arch_prctl);
/* Linux 5.0: */
diff --git a/sys/arm64/linux/linux_dummy_machdep.c b/sys/arm64/linux/linux_dummy_machdep.c
index a7a7795f573d..5ff6bfafe2d6 100644
--- a/sys/arm64/linux/linux_dummy_machdep.c
+++ b/sys/arm64/linux/linux_dummy_machdep.c
@@ -42,10 +42,4 @@ LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
* Before adding new stubs to this file, please check if a stub can be added to
* the machine-independent code in sys/compat/linux/linux_dummy.c.
*/
-DUMMY(mq_open);
-DUMMY(mq_unlink);
-DUMMY(mq_timedsend);
-DUMMY(mq_timedreceive);
-DUMMY(mq_notify);
-DUMMY(mq_getsetattr);
DUMMY(kexec_file_load);
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 9b8ab193f2bd..14c36669efc8 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -29,6 +29,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_posix.h"
+
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/jail.h>
@@ -36,6 +38,7 @@
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/msgbuf.h>
+#include <sys/mqueue.h>
#include <sys/mutex.h>
#include <sys/poll.h>
#include <sys/priv.h>
@@ -2963,3 +2966,124 @@ linux_ioprio_set(struct thread *td, struct linux_ioprio_set_args *args)
}
return (error);
}
+
+/* The only flag is O_NONBLOCK */
+#define B2L_MQ_FLAGS(bflags) ((bflags) != 0 ? LINUX_O_NONBLOCK : 0)
+#define L2B_MQ_FLAGS(lflags) ((lflags) != 0 ? O_NONBLOCK : 0)
+
+int
+linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
+{
+ struct mq_attr attr;
+ int error, flags;
+
+ flags = linux_common_openflags(args->oflag);
+ if ((flags & O_ACCMODE) == O_ACCMODE || (flags & O_EXEC) != 0)
+ return (EINVAL);
+ flags = FFLAGS(flags);
+ if ((flags & O_CREAT) != 0 && args->attr != NULL) {
+ error = copyin(args->attr, &attr, sizeof(attr));
+ if (error != 0)
+ return (error);
+ attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
+ }
+
+ return (kern_kmq_open(td, args->name, flags, args->mode,
+ args->attr != NULL ? &attr : NULL));
+}
+
+int
+linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
+{
+ struct kmq_unlink_args bsd_args = {
+ .path = PTRIN(args->name)
+ };
+
+ return (sys_kmq_unlink(td, &bsd_args));
+}
+
+int
+linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
+{
+ struct timespec ts, *abs_timeout;
+ int error;
+
+ if (args->abs_timeout == NULL)
+ abs_timeout = NULL;
+ else {
+ error = linux_get_timespec(&ts, args->abs_timeout);
+ if (error != 0)
+ return (error);
+ abs_timeout = &ts;
+ }
+
+ return (kern_kmq_timedsend(td, args->mqd, PTRIN(args->msg_ptr),
+ args->msg_len, args->msg_prio, abs_timeout));
+}
+
+int
+linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args *args)
+{
+ struct timespec ts, *abs_timeout;
+ int error;
+
+ if (args->abs_timeout == NULL)
+ abs_timeout = NULL;
+ else {
+ error = linux_get_timespec(&ts, args->abs_timeout);
+ if (error != 0)
+ return (error);
+ abs_timeout = &ts;
+ }
+
+ return (kern_kmq_timedreceive(td, args->mqd, PTRIN(args->msg_ptr),
+ args->msg_len, args->msg_prio, abs_timeout));
+}
+
+int
+linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
+{
+ struct sigevent ev, *evp;
+ struct l_sigevent l_ev;
+ int error;
+
+ if (args->sevp == NULL)
+ evp = NULL;
+ else {
+ error = copyin(args->sevp, &l_ev, sizeof(l_ev));
+ if (error != 0)
+ return (error);
+ error = linux_convert_l_sigevent(&l_ev, &ev);
+ if (error != 0)
+ return (error);
+ evp = &ev;
+ }
+
+ return (kern_kmq_notify(td, args->mqd, evp));
+}
+
+int
+linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
+{
+ struct mq_attr attr, oattr;
+ int error;
+
+ if (args->attr != NULL) {
+ error = copyin(args->attr, &attr, sizeof(attr));
+ if (error != 0)
+ return (error);
+ attr.mq_flags = L2B_MQ_FLAGS(attr.mq_flags);
+ }
+
+ error = kern_kmq_setattr(td, args->mqd, args->attr != NULL ? &attr : NULL,
+ &oattr);
+ if (error == 0 && args->oattr != NULL) {
+ oattr.mq_flags = B2L_MQ_FLAGS(oattr.mq_flags);
+ bzero(oattr.__reserved, sizeof(oattr.__reserved));
+ error = copyout(&oattr, args->oattr, sizeof(oattr));
+ }
+
+ return (error);
+}
+
+MODULE_DEPEND(linux, mqueuefs, 1, 1, 1);
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index b5d42dc22162..0e056aadb4b5 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -592,67 +592,6 @@ linux_get_thread_area(struct thread *td, struct linux_get_thread_area_args *args
return (0);
}
-/* XXX: this wont work with module - convert it */
-int
-linux_mq_open(struct thread *td, struct linux_mq_open_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_open(td, (struct kmq_open_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_unlink(struct thread *td, struct linux_mq_unlink_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_unlink(td, (struct kmq_unlink_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_timedsend(struct thread *td, struct linux_mq_timedsend_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_timedsend(td, (struct kmq_timedsend_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_timedreceive(struct thread *td, struct linux_mq_timedreceive_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_timedreceive(td, (struct kmq_timedreceive_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_notify(struct thread *td, struct linux_mq_notify_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_notify(td, (struct kmq_notify_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
-int
-linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
-{
-#ifdef P1003_1B_MQUEUE
- return (sys_kmq_setattr(td, (struct kmq_setattr_args *)args));
-#else
- return (ENOSYS);
-#endif
-}
-
void
bsd_to_linux_regset(const struct reg *b_reg,
struct linux_pt_regset *l_regset)