diff options
author | Masayoshi Mizuma <m.mizuma@jp.fujitsu.com> | 2019-08-13 16:06:45 -0400 |
---|---|---|
committer | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2020-01-23 16:41:37 +0000 |
commit | 96814800d2b49d18737c36e021c387697ec40c62 (patch) | |
tree | 67ed626200c562ca1439da75b2f386b780239626 /tools/virtiofsd | |
parent | 18a69cbbb6a4caa7c2040c6db4a33b044a32be7e (diff) |
virtiofsd: Prevent multiply running with same vhost_user_socket
virtiofsd can run multiply even if the vhost_user_socket is same path.
]# ./virtiofsd -o vhost_user_socket=/tmp/vhostqemu -o source=/tmp/share &
[1] 244965
virtio_session_mount: Waiting for vhost-user socket connection...
]# ./virtiofsd -o vhost_user_socket=/tmp/vhostqemu -o source=/tmp/share &
[2] 244966
virtio_session_mount: Waiting for vhost-user socket connection...
]#
The user will get confused about the situation and maybe the cause of the
unexpected problem. So it's better to prevent the multiple running.
Create a regular file under localstatedir directory to exclude the
vhost_user_socket. To create and lock the file, use qemu_write_pidfile()
because the API has some sanity checks and file lock.
Signed-off-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Applied fixes from Stefan's review and moved osdep include
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'tools/virtiofsd')
-rw-r--r-- | tools/virtiofsd/fuse_lowlevel.c | 1 | ||||
-rw-r--r-- | tools/virtiofsd/fuse_virtio.c | 49 |
2 files changed, 49 insertions, 1 deletions
diff --git a/tools/virtiofsd/fuse_lowlevel.c b/tools/virtiofsd/fuse_lowlevel.c index 440508a6ec..aac282f278 100644 --- a/tools/virtiofsd/fuse_lowlevel.c +++ b/tools/virtiofsd/fuse_lowlevel.c @@ -18,6 +18,7 @@ #include <assert.h> #include <errno.h> +#include <glib.h> #include <limits.h> #include <stdbool.h> #include <stddef.h> diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c index e7bd772805..b7948def27 100644 --- a/tools/virtiofsd/fuse_virtio.c +++ b/tools/virtiofsd/fuse_virtio.c @@ -13,11 +13,12 @@ #include "qemu/osdep.h" #include "qemu/iov.h" -#include "fuse_virtio.h" +#include "qapi/error.h" #include "fuse_i.h" #include "standard-headers/linux/fuse.h" #include "fuse_misc.h" #include "fuse_opt.h" +#include "fuse_virtio.h" #include <assert.h> #include <errno.h> @@ -743,6 +744,42 @@ int virtio_loop(struct fuse_session *se) return 0; } +static void strreplace(char *s, char old, char new) +{ + for (; *s; ++s) { + if (*s == old) { + *s = new; + } + } +} + +static bool fv_socket_lock(struct fuse_session *se) +{ + g_autofree gchar *sk_name = NULL; + g_autofree gchar *pidfile = NULL; + g_autofree gchar *dir = NULL; + Error *local_err = NULL; + + dir = qemu_get_local_state_pathname("run/virtiofsd"); + + if (g_mkdir_with_parents(dir, S_IRWXU) < 0) { + fuse_log(FUSE_LOG_ERR, "%s: Failed to create directory %s: %s", + __func__, dir, strerror(errno)); + return false; + } + + sk_name = g_strdup(se->vu_socket_path); + strreplace(sk_name, '/', '.'); + pidfile = g_strdup_printf("%s/%s.pid", dir, sk_name); + + if (!qemu_write_pidfile(pidfile, &local_err)) { + error_report_err(local_err); + return false; + } + + return true; +} + static int fv_create_listen_socket(struct fuse_session *se) { struct sockaddr_un un; @@ -758,6 +795,16 @@ static int fv_create_listen_socket(struct fuse_session *se) return -1; } + if (!strlen(se->vu_socket_path)) { + fuse_log(FUSE_LOG_ERR, "Socket path is empty\n"); + return -1; + } + + /* Check the vu_socket_path is already used */ + if (!fv_socket_lock(se)) { + return -1; + } + /* * Create the Unix socket to communicate with qemu * based on QEMU's vhost-user-bridge |