From: Alex Dubov <alex.dubov@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: alex.dubov@gmail.com, Alex Dubov <oakad@yahoo.com>
Subject: [PATCH 1/2] fs: introduce sendfd() syscall
Date: Tue, 2 Dec 2014 15:35:18 +1100 [thread overview]
Message-ID: <1417494919-4577-2-git-send-email-oakad@yahoo.com> (raw)
In-Reply-To: <1417494919-4577-1-git-send-email-oakad@yahoo.com>
Present patch introduces exceptionally easy to use, low latency and low
overhead mechanism for transferring file descriptors between cooperating
processes:
int sendfd(pid_t pid, int sig, int fd)
Given a target process pid, the sendfd() syscall will create a duplicate
file descriptor in a target task's (referred by pid) file table pointing to
the file references by descriptor fd. Then, it will attempt to notify the
target task by issuing a Posix.1b real-time signal (sig), carrying the new
file descriptor as integer payload. If real-time signal can not be enqueued
at the destination signal queue, the newly created file descriptor will be
promptly closed.
Signed-off-by: Alex Dubov <oakad@yahoo.com>
---
fs/Makefile | 1 +
fs/sendfd.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
init/Kconfig | 11 ++++++++
3 files changed, 94 insertions(+)
create mode 100644 fs/sendfd.c
diff --git a/fs/Makefile b/fs/Makefile
index da0bbb4..bed05a8 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_ANON_INODES) += anon_inodes.o
obj-$(CONFIG_SIGNALFD) += signalfd.o
obj-$(CONFIG_TIMERFD) += timerfd.o
obj-$(CONFIG_EVENTFD) += eventfd.o
+obj-$(CONFIG_SENDFD) += sendfd.o
obj-$(CONFIG_AIO) += aio.o
obj-$(CONFIG_FILE_LOCKING) += locks.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
diff --git a/fs/sendfd.c b/fs/sendfd.c
new file mode 100644
index 0000000..1e85484
--- /dev/null
+++ b/fs/sendfd.c
@@ -0,0 +1,82 @@
+/*
+ * fs/sendfd.c
+ *
+ * Copyright (C) 2014 Alex Dubov <oakad@yahoo.com>
+ *
+ */
+
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/syscalls.h>
+
+SYSCALL_DEFINE3(sendfd, pid_t, pid, int, sig, int, fd)
+{
+ struct siginfo s_info = {
+ .si_signo = sig,
+ .si_errno = 0,
+ .si_code = __SI_RT
+ };
+ struct file *src_file = NULL;
+ struct task_struct *dst_task = NULL;
+ struct files_struct *dst_files = NULL;
+ unsigned long rlim = 0;
+ unsigned long flags = 0;
+ int rc = 0;
+
+ if ((sig < SIGRTMIN) || (sig > SIGRTMAX))
+ return -EINVAL;
+
+ s_info.si_pid = task_pid_vnr(current);
+ s_info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
+ s_info.si_int = -1;
+
+ src_file = fget(fd);
+ if (!src_file)
+ return -EBADF;
+
+ rcu_read_lock();
+ dst_task = find_task_by_vpid(pid);
+
+ if (!dst_task) {
+ rc = -ESRCH;
+ goto out_put_src_file;
+ }
+ get_task_struct(dst_task);
+ rcu_read_unlock();
+
+ dst_files = get_files_struct(dst_task);
+ if (!dst_files) {
+ rc = -EMFILE;
+ goto out_put_dst_task;
+ }
+
+ if (!lock_task_sighand(dst_task, &flags)) {
+ rc = -EMFILE;
+ goto out_put_dst_files;
+ }
+
+ rlim = task_rlimit(dst_task, RLIMIT_NOFILE);
+
+ unlock_task_sighand(dst_task, &flags);
+
+ rc = __alloc_fd(dst_task->files, 0, rlim, O_CLOEXEC);
+ if (rc < 0)
+ goto out_put_dst_files;
+
+ s_info.si_int = rc;
+
+ get_file(src_file);
+ __fd_install(dst_files, rc, src_file);
+ rc = kill_pid_info(sig, &s_info, task_pid(dst_task));
+
+ if (rc < 0)
+ __close_fd(dst_files, s_info.si_int);
+
+out_put_dst_files:
+ put_files_struct(dst_files);
+out_put_dst_task:
+ put_task_struct(dst_task);
+out_put_src_file:
+ fput(src_file);
+ return rc;
+}
diff --git a/init/Kconfig b/init/Kconfig
index 2081a4d..dfe8b6f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1525,6 +1525,17 @@ config EVENTFD
If unsure, say Y.
+config SENDFD
+ bool "Enable sendfd() system call" if EXPERT
+ default y
+ help
+ Enable the sendfd() system call that allows rapid duplication
+ of file descriptor across process boundaries. The target process
+ will receive a duplicate file descriptor delivered with one of
+ Posix.1b real-time signals.
+
+ If unsure, say Y.
+
# syscall, maps, verifier
config BPF_SYSCALL
bool "Enable bpf() system call" if EXPERT
--
1.8.3.2
next prev parent reply other threads:[~2014-12-02 4:35 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-02 4:35 Minimal effort/low overhead file descriptor duplication over Posix.1b s Alex Dubov
2014-12-02 4:35 ` Alex Dubov [this message]
2014-12-02 12:50 ` [PATCH 1/2] fs: introduce sendfd() syscall Eric Dumazet
2014-12-02 14:47 ` Alex Dubov
2014-12-02 15:33 ` Eric Dumazet
2014-12-02 16:23 ` Alex Dubov
2014-12-02 16:42 ` Eric Dumazet
2014-12-03 2:11 ` Alex Dubov
2014-12-03 6:48 ` Eric Dumazet
2014-12-02 17:00 ` Al Viro
2014-12-03 2:22 ` Alex Dubov
2014-12-03 3:40 ` Al Viro
2014-12-03 4:14 ` Alex Dubov
2014-12-03 6:50 ` Eric Dumazet
2014-12-03 8:08 ` Richard Cochran
2014-12-03 8:17 ` Richard Weinberger
2014-12-03 10:41 ` Richard Cochran
2014-12-03 14:08 ` Alex Dubov
2014-12-05 13:37 ` One Thousand Gnomes
2014-12-02 4:35 ` [PATCH 2/2] fs: Wire up sendfd() syscall (all architectures) Alex Dubov
2014-12-02 8:01 ` Geert Uytterhoeven
2014-12-02 8:31 ` Alex Dubov
2014-12-02 11:42 ` Michal Simek
2014-12-02 14:31 ` Alex Dubov
2014-12-02 14:38 ` Geert Uytterhoeven
2014-12-02 15:26 ` Minimal effort/low overhead file descriptor duplication over Posix.1b s Jonathan Corbet
2014-12-02 16:15 ` Alex Dubov
2014-12-17 13:11 ` Kevin Easton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1417494919-4577-2-git-send-email-oakad@yahoo.com \
--to=alex.dubov@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=oakad@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox