[Virtio-fs] [PATCH v3] virtiofsd: Prevent multiply running with same vhost_user_socket
Masayoshi Mizuma
msys.mizuma at gmail.com
Tue Aug 13 20:06:45 UTC 2019
From: Masayoshi Mizuma <m.mizuma at jp.fujitsu.com>
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 at jp.fujitsu.com>
Reviewed-by: Jun Piao <piaojun at huawei.com>
---
contrib/virtiofsd/fuse_i.h | 1 +
contrib/virtiofsd/fuse_lowlevel.c | 6 ++++
contrib/virtiofsd/fuse_virtio.c | 51 +++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/contrib/virtiofsd/fuse_i.h b/contrib/virtiofsd/fuse_i.h
index ff6e1b75ba..89cc20a787 100644
--- a/contrib/virtiofsd/fuse_i.h
+++ b/contrib/virtiofsd/fuse_i.h
@@ -72,6 +72,7 @@ struct fuse_session {
char *vu_socket_path;
int vu_listen_fd;
int vu_socketfd;
+ char *vu_socket_lock;
struct fv_VuDev *virtio_dev;
};
diff --git a/contrib/virtiofsd/fuse_lowlevel.c b/contrib/virtiofsd/fuse_lowlevel.c
index 8adc4b1ab8..9d41b48d73 100644
--- a/contrib/virtiofsd/fuse_lowlevel.c
+++ b/contrib/virtiofsd/fuse_lowlevel.c
@@ -16,6 +16,7 @@
#include "fuse_misc.h"
#include "fuse_virtio.h"
+#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -2587,6 +2588,11 @@ void fuse_session_destroy(struct fuse_session *se)
free(se->vu_socket_path);
se->vu_socket_path = NULL;
+ if (se->vu_socket_lock) {
+ g_free(se->vu_socket_lock);
+ se->vu_socket_lock = NULL;
+ }
+
free(se);
}
diff --git a/contrib/virtiofsd/fuse_virtio.c b/contrib/virtiofsd/fuse_virtio.c
index 083e4fc317..927f379f7a 100644
--- a/contrib/virtiofsd/fuse_virtio.c
+++ b/contrib/virtiofsd/fuse_virtio.c
@@ -32,6 +32,9 @@
#include "contrib/libvhost-user/libvhost-user.h"
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+
struct fv_VuDev;
struct fv_QueueInfo {
pthread_t thread;
@@ -862,6 +865,43 @@ 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 int fv_socket_lock(struct fuse_session *se)
+{
+ char *dir, *sk_name;
+ Error *local_err = NULL;
+ int ret = -1;
+
+ dir = qemu_get_local_state_pathname("run/virtiofsd");
+
+ if (g_mkdir_with_parents(dir, S_IRWXU) < -1) {
+ fuse_err("%s: Failed to create directory %s: %s",
+ __func__, dir, strerror(errno));
+ return ret;
+ }
+
+ sk_name = g_strdup(se->vu_socket_path);
+ strreplace(sk_name, '/', '.');
+ se->vu_socket_lock = g_strdup_printf("%s/%s.pid", dir, sk_name);
+
+ if (!qemu_write_pidfile(se->vu_socket_lock, &local_err)) {
+ error_report_err(local_err);
+ } else {
+ ret = 0;
+ }
+
+ g_free(sk_name);
+ g_free(dir);
+
+ return ret;
+}
+
static int fv_create_listen_socket(struct fuse_session *se)
{
struct sockaddr_un un;
@@ -876,6 +916,17 @@ static int fv_create_listen_socket(struct fuse_session *se)
return -1;
}
+ if (!strlen(se->vu_socket_path)) {
+ fuse_err("Socket path is NULL\n");
+ return -1;
+ }
+
+ /* Check the vu_socket_path is already used */
+ if (fv_socket_lock(se) == -1) {
+ fuse_err("%s: Socket lock file creation failed\n", __func__);
+ return -1;
+ }
+
/* Create the Unix socket to communicate with qemu
* based on QEMU's vhost-user-bridge
*/
--
2.18.1
More information about the Virtio-fs
mailing list