virtiofsd: Open vhost connection instead of mounting

When run with vhost-user options we conect to the QEMU instead
via a socket.  Start this off by creating the socket.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
Dr. David Alan Gilbert 2018-06-07 20:11:14 +01:00
parent 4ff075f72b
commit d14bf584dd
4 changed files with 114 additions and 50 deletions

View File

@ -6,9 +6,10 @@
* See the file COPYING.LIB
*/
#ifndef FUSE_I_H
#define FUSE_I_H
#define FUSE_USE_VERSION 31
#include "fuse.h"
#include "fuse_lowlevel.h"
@ -101,3 +102,5 @@ void fuse_session_process_buf_int(struct fuse_session *se,
/* room needed in buffer to accommodate header */
#define FUSE_BUFFER_HEADER_SIZE 0x1000
#endif

View File

@ -14,6 +14,7 @@
#include "standard-headers/linux/fuse.h"
#include "fuse_misc.h"
#include "fuse_opt.h"
#include "fuse_virtio.h"
#include <assert.h>
#include <errno.h>
@ -2202,6 +2203,11 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
goto out4;
}
if (!se->vu_socket_path) {
fprintf(stderr, "fuse: missing -o vhost_user_socket option\n");
goto out4;
}
se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() + FUSE_BUFFER_HEADER_SIZE;
list_init_req(&se->list);
@ -2224,54 +2230,7 @@ out1:
int fuse_session_mount(struct fuse_session *se)
{
int fd;
/*
* Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
* would ensue.
*/
do {
fd = open("/dev/null", O_RDWR);
if (fd > 2) {
close(fd);
}
} while (fd >= 0 && fd <= 2);
/*
* To allow FUSE daemons to run without privileges, the caller may open
* /dev/fuse before launching the file system and pass on the file
* descriptor by specifying /dev/fd/N as the mount point. Note that the
* parent process takes care of performing the mount in this case.
*/
fd = fuse_mnt_parse_fuse_fd(mountpoint);
if (fd != -1) {
if (fcntl(fd, F_GETFD) == -1) {
fuse_log(FUSE_LOG_ERR, "fuse: Invalid file descriptor /dev/fd/%u\n",
fd);
return -1;
}
se->fd = fd;
return 0;
}
/* Open channel */
fd = fuse_kern_mount(mountpoint, se->mo);
if (fd == -1) {
return -1;
}
se->fd = fd;
/* Save mountpoint */
se->mountpoint = strdup(mountpoint);
if (se->mountpoint == NULL) {
goto error_out;
}
return 0;
error_out:
fuse_kern_unmount(mountpoint, fd);
return -1;
return virtio_session_mount(se);
}
int fuse_session_fd(struct fuse_session *se)

View File

@ -0,0 +1,79 @@
/*
* virtio-fs glue for FUSE
* Copyright (C) 2018 Red Hat, Inc. and/or its affiliates
*
* Authors:
* Dave Gilbert <dgilbert@redhat.com>
*
* Implements the glue between libfuse and libvhost-user
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB
*/
#include "fuse_i.h"
#include "standard-headers/linux/fuse.h"
#include "fuse_misc.h"
#include "fuse_opt.h"
#include "fuse_virtio.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
/* From spec */
struct virtio_fs_config {
char tag[36];
uint32_t num_queues;
};
int virtio_session_mount(struct fuse_session *se)
{
struct sockaddr_un un;
mode_t old_umask;
if (strlen(se->vu_socket_path) >= sizeof(un.sun_path)) {
fuse_log(FUSE_LOG_ERR, "Socket path too long\n");
return -1;
}
se->fd = -1;
/*
* Create the Unix socket to communicate with qemu
* based on QEMU's vhost-user-bridge
*/
unlink(se->vu_socket_path);
strcpy(un.sun_path, se->vu_socket_path);
size_t addr_len = sizeof(un);
int listen_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (listen_sock == -1) {
fuse_log(FUSE_LOG_ERR, "vhost socket creation: %m\n");
return -1;
}
un.sun_family = AF_UNIX;
/*
* Unfortunately bind doesn't let you set the mask on the socket,
* so set umask to 077 and restore it later.
*/
old_umask = umask(0077);
if (bind(listen_sock, (struct sockaddr *)&un, addr_len) == -1) {
fuse_log(FUSE_LOG_ERR, "vhost socket bind: %m\n");
umask(old_umask);
return -1;
}
umask(old_umask);
if (listen(listen_sock, 1) == -1) {
fuse_log(FUSE_LOG_ERR, "vhost socket listen: %m\n");
return -1;
}
return -1;
}

View File

@ -0,0 +1,23 @@
/*
* virtio-fs glue for FUSE
* Copyright (C) 2018 Red Hat, Inc. and/or its affiliates
*
* Authors:
* Dave Gilbert <dgilbert@redhat.com>
*
* Implements the glue between libfuse and libvhost-user
*
* This program can be distributed under the terms of the GNU LGPLv2.
* See the file COPYING.LIB
*/
#ifndef FUSE_VIRTIO_H
#define FUSE_VIRTIO_H
#include "fuse_i.h"
struct fuse_session;
int virtio_session_mount(struct fuse_session *se);
#endif