diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-01-24 09:59:11 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-01-24 09:59:11 +0000 |
| commit | a43efa34c7d7b628cbf1ec0fe60043e5c91043ea (patch) | |
| tree | 244116ae14402ea336fd32de0d4c07fa5409eb09 /tools/virtiofsd/fuse_signals.c | |
| parent | c0248b36d8d190933a43919b9f71013a255e866c (diff) | |
| parent | 1d59b1b210d7c3b0bdf4b10ebe0bb1fccfcb8b95 (diff) | |
| download | focaccia-qemu-a43efa34c7d7b628cbf1ec0fe60043e5c91043ea.tar.gz focaccia-qemu-a43efa34c7d7b628cbf1ec0fe60043e5c91043ea.zip | |
Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200123b' into staging
virtiofsd first pull v2 Import our virtiofsd. This pulls in the daemon to drive a file system connected to the existing qemu virtiofsd device. It's derived from upstream libfuse with lots of changes (and a lot trimmed out). The daemon lives in the newly created qemu/tools/virtiofsd Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> v2 drop the docs while we discuss where they should live and we need to redo the manpage in anything but texi # gpg: Signature made Thu 23 Jan 2020 16:45:18 GMT # gpg: using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7 # gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full] # Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A 9FA9 0516 331E BC5B FDE7 * remotes/dgilbert-gitlab/tags/pull-virtiofs-20200123b: (108 commits) virtiofsd: add some options to the help message virtiofsd: stop all queue threads on exit in virtio_loop() virtiofsd/passthrough_ll: Pass errno to fuse_reply_err() virtiofsd: Convert lo_destroy to take the lo->mutex lock itself virtiofsd: add --thread-pool-size=NUM option virtiofsd: fix lo_destroy() resource leaks virtiofsd: prevent FUSE_INIT/FUSE_DESTROY races virtiofsd: process requests in a thread pool virtiofsd: use fuse_buf_writev to replace fuse_buf_write for better performance virtiofsd: add definition of fuse_buf_writev() virtiofsd: passthrough_ll: Use cache_readdir for directory open virtiofsd: Fix data corruption with O_APPEND write in writeback mode virtiofsd: Reset O_DIRECT flag during file open virtiofsd: convert more fprintf and perror to use fuse log infra virtiofsd: do not always set FUSE_FLOCK_LOCKS virtiofsd: introduce inode refcount to prevent use-after-free virtiofsd: passthrough_ll: fix refcounting on remove/rename libvhost-user: Fix some memtable remap cases virtiofsd: rename inode->refcount to inode->nlookup virtiofsd: prevent races with lo_dirp_put() ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tools/virtiofsd/fuse_signals.c')
| -rw-r--r-- | tools/virtiofsd/fuse_signals.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/tools/virtiofsd/fuse_signals.c b/tools/virtiofsd/fuse_signals.c new file mode 100644 index 0000000000..f18625b6e2 --- /dev/null +++ b/tools/virtiofsd/fuse_signals.c @@ -0,0 +1,98 @@ +/* + * FUSE: Filesystem in Userspace + * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> + * + * Utility functions for setting signal handlers. + * + * This program can be distributed under the terms of the GNU LGPLv2. + * See the file COPYING.LIB + */ + +#include "qemu/osdep.h" +#include "fuse_i.h" +#include "fuse_lowlevel.h" + +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static struct fuse_session *fuse_instance; + +static void exit_handler(int sig) +{ + if (fuse_instance) { + fuse_session_exit(fuse_instance); + if (sig <= 0) { + fuse_log(FUSE_LOG_ERR, "assertion error: signal value <= 0\n"); + abort(); + } + fuse_instance->error = sig; + } +} + +static void do_nothing(int sig) +{ + (void)sig; +} + +static int set_one_signal_handler(int sig, void (*handler)(int), int remove) +{ + struct sigaction sa; + struct sigaction old_sa; + + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_handler = remove ? SIG_DFL : handler; + sigemptyset(&(sa.sa_mask)); + sa.sa_flags = 0; + + if (sigaction(sig, NULL, &old_sa) == -1) { + fuse_log(FUSE_LOG_ERR, "fuse: cannot get old signal handler: %s\n", + strerror(errno)); + return -1; + } + + if (old_sa.sa_handler == (remove ? handler : SIG_DFL) && + sigaction(sig, &sa, NULL) == -1) { + fuse_log(FUSE_LOG_ERR, "fuse: cannot set signal handler: %s\n", + strerror(errno)); + return -1; + } + return 0; +} + +int fuse_set_signal_handlers(struct fuse_session *se) +{ + /* + * If we used SIG_IGN instead of the do_nothing function, + * then we would be unable to tell if we set SIG_IGN (and + * thus should reset to SIG_DFL in fuse_remove_signal_handlers) + * or if it was already set to SIG_IGN (and should be left + * untouched. + */ + if (set_one_signal_handler(SIGHUP, exit_handler, 0) == -1 || + set_one_signal_handler(SIGINT, exit_handler, 0) == -1 || + set_one_signal_handler(SIGTERM, exit_handler, 0) == -1 || + set_one_signal_handler(SIGPIPE, do_nothing, 0) == -1) { + return -1; + } + + fuse_instance = se; + return 0; +} + +void fuse_remove_signal_handlers(struct fuse_session *se) +{ + if (fuse_instance != se) { + fuse_log(FUSE_LOG_ERR, + "fuse: fuse_remove_signal_handlers: unknown session\n"); + } else { + fuse_instance = NULL; + } + + set_one_signal_handler(SIGHUP, exit_handler, 1); + set_one_signal_handler(SIGINT, exit_handler, 1); + set_one_signal_handler(SIGTERM, exit_handler, 1); + set_one_signal_handler(SIGPIPE, do_nothing, 1); +} |