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:
parent
4ff075f72b
commit
d14bf584dd
@ -6,9 +6,10 @@
|
|||||||
* See the file COPYING.LIB
|
* See the file COPYING.LIB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef FUSE_I_H
|
||||||
|
#define FUSE_I_H
|
||||||
|
|
||||||
#define FUSE_USE_VERSION 31
|
#define FUSE_USE_VERSION 31
|
||||||
|
|
||||||
|
|
||||||
#include "fuse.h"
|
#include "fuse.h"
|
||||||
#include "fuse_lowlevel.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 */
|
/* room needed in buffer to accommodate header */
|
||||||
#define FUSE_BUFFER_HEADER_SIZE 0x1000
|
#define FUSE_BUFFER_HEADER_SIZE 0x1000
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "standard-headers/linux/fuse.h"
|
#include "standard-headers/linux/fuse.h"
|
||||||
#include "fuse_misc.h"
|
#include "fuse_misc.h"
|
||||||
#include "fuse_opt.h"
|
#include "fuse_opt.h"
|
||||||
|
#include "fuse_virtio.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -2202,6 +2203,11 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
|
|||||||
goto out4;
|
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;
|
se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() + FUSE_BUFFER_HEADER_SIZE;
|
||||||
|
|
||||||
list_init_req(&se->list);
|
list_init_req(&se->list);
|
||||||
@ -2224,54 +2230,7 @@ out1:
|
|||||||
|
|
||||||
int fuse_session_mount(struct fuse_session *se)
|
int fuse_session_mount(struct fuse_session *se)
|
||||||
{
|
{
|
||||||
int fd;
|
return virtio_session_mount(se);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fuse_session_fd(struct fuse_session *se)
|
int fuse_session_fd(struct fuse_session *se)
|
||||||
|
79
tools/virtiofsd/fuse_virtio.c
Normal file
79
tools/virtiofsd/fuse_virtio.c
Normal 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;
|
||||||
|
}
|
23
tools/virtiofsd/fuse_virtio.h
Normal file
23
tools/virtiofsd/fuse_virtio.h
Normal 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
|
Loading…
Reference in New Issue
Block a user