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)