Skip to contentSkip to conversation

virtio-9p: paravirtual file system passthrough

PATCH New Aneesh Kumar K.V 1 participant 22 messages Apr 9, 2010 Kbuild

lore
Share & tools
lore
#0 lore raw

cover virtio-9p: paravirtual file system passthrough

This patch series adds VirtFS to QEMU. VirtFS is code named for a 9P filesystem server in QEMU enabling paravirtual filesystem pass-trhough between KVM host and guest.

VirtFS is intended to offer an alternative to using NFS/CIFS to share host filesystems on guest and provides better performance. Initial tests showed significantly better performance than NFS and CIFS. Performance numbers are provided towards end of the mail.

With the current implementation, all I/O is implemented in the VCPU thread. We've modified the protocol handlers so that we can support dispatch I/O in a thread pool. The actual thread pool implementation will be posted later.

This patch set should work with any recent Linux kernel as virtio-9p has been supported for a few kernel releases now. Export dir is specified using the below Qemu option.

-fsdev fstype,id=ID,path=path/to/share \
           -device virtio-9p-pci,fsdev=ID,mount_tag=tag \

or

-virtfs fstype,path=path/to/share,mount_tag=tag

Only supported fstype currently is "local". mount_tag is used to identify the mount point in the kernel. This will be available in Linux kernel via /sys/devices/virtio-pci/virtio1/mount_tag file.

Changes from V3:
1) Makefiles are modified so that this code is compiled only on Linux.
2) Replaced vasprintf() with qemu_malloc() followed by sprintf().
3) Formatting changes per QEMU coding standards.
4) Folded bug fixes to original patches
c) configure option to enable/disable virtfs

Changes from V2:
1) Added new method for specifying export dir. This new method should be more flexible.
2) rebased to qemu master bedd2912c83b1a87a6bfe3f59a892fd65cda7084

Changes from V1:
1) fsstress test suite runs successfully with the patches. That should indicate patches are stable enough to be merged.
2) Added proper error handling to all posix_* calls.
3) Fixed code to follow Qemu coding style.
4) Other bug fixes most of which are folded back into the original patches
5) rebased to qemu master 0aef4261ac0ec9089ade0e3a92f986cb4ba7317e

Performance details:

# Host

* 3650M2
* 16 CPU, 32 GB RAM
* 28 JBOD disks (18G each)
* DM striped to make a single 400GB disk/filesystem
* 400 GB ext3 filesystem exported/serving data in the host
* RHEL5.5, QEMU + 9p Server patches

# Guest

* 1 vCPU, 4GB memory
* virtio network access for CIFS, NFS
* virtio transport for virtfs mount
* 2.6.33-rc8 + v9 fixes (either on mainline or on 9p-devel list)

# Tests:

* Created 16 20-GB files on the filesystem
* Guest mounts filesystem through v9 (virtio), NFS (virtio), CIFS (virtio)
* Perform sequential read and sequential write tests on these 16 20-GB files from the guest
* Repeat the tests with various threads/processes (dd) counts
* Between each test host and guest unmounts and mounts the filesystem to eliminate any caching affects.

# read tests (sample):
for i in 1 2 3 4 5 6 7 8 do; time dd of=/dev/null if=./file$i bs=2M count=10240 & ; done 

#of Threads | 1 2 4 8
----------------------------------------------------

VirtFs(MB/S) |  172        170       168       162
CIFS(MB/S)   |  10         12        22        35
NFS(MB/S)    |  80         70        62        42
# write tests (sample):
for i in 1 2 3 4 5 6 7 8 do; time dd if=/dev/zero of=./file$i bs=2M count=10240 & ; done 

#of Threads | 1 2 4 8
-------------------------------------------------------

VirtFs(MB/S) |  190        182       150       138
CIFS(MB/S)   |  30         38        78        100
NFS(MB/S)    |  35         35        38        37
#1 lore raw

PATCH 1/21 virtio-9p: Create a commandline option -fsdev

From: Gautham R Shenoy <[email protected]>

This patch creates a new command line option named -fsdev to hold any file system specific information.

The option will currently hold the following attributes:
-fsdev fstype id=id,path=path_to_share
where

fstype: Type of the file system.
id:     Identifier used to refer to this fsdev
path:   The path on the host that is identified by this fsdev.
---
 Makefile.objs      |    5 +++-
 configure          |   25 ++++++++++++++++++-
 fsdev/qemu-fsdev.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fsdev/qemu-fsdev.h |   53 +++++++++++++++++++++++++++++++++++++++
 hw/file-op-9p.h    |   32 +++++++++++++++++++++++
 qemu-config.c      |   18 +++++++++++++
 qemu-config.h      |    3 ++
 qemu-options.hx    |   33 ++++++++++++++++++++++++
 vl.c               |   27 ++++++++++++++++++++
 9 files changed, 264 insertions(+), 2 deletions(-)
 create mode 100644 fsdev/qemu-fsdev.c
 create mode 100644 fsdev/qemu-fsdev.h
 create mode 100644 hw/file-op-9p.h
Makefile.objs +4 -1
index 281f7a6..41c3c6c 100644
@@ -35,6 +35,9 @@ net-nested-$(CONFIG_SLIRP) += slirp.o
 net-nested-$(CONFIG_VDE) += vde.o
 net-obj-y += $(addprefix net/, $(net-nested-y))
 
+fsdev-nested-$(CONFIG_LINUX_VIRTFS) = qemu-fsdev.o
+fsdev-obj-$(CONFIG_LINUX_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y))
+
 ######################################################################
 # libqemu_common.a: Target independent part of system emulation. The
 # long term path is to suppress *all* target specific code in case of
@@ -44,8 +47,8 @@ net-obj-y += $(addprefix net/, $(net-nested-y))
 common-obj-y = $(block-obj-y)
 common-obj-y += $(net-obj-y)
 common-obj-y += $(qobject-obj-y)
+common-obj-$(CONFIG_LINUX_VIRTFS) += $(fsdev-obj-$(CONFIG_LINUX_VIRTFS))
 common-obj-y += readline.o console.o async.o qemu-error.o
-
 common-obj-y += tcg-runtime.o host-utils.o
 common-obj-y += irq.o ioport.o input.o
 common-obj-$(CONFIG_PTIMER) += ptimer.o
configure +24 -1
index 6bc40a3..171c1f0 100755
@@ -263,6 +263,7 @@ vnc_tls=""
 vnc_sasl=""
 xen=""
 linux_aio=""
+linux_virtfs=""
 
 gprof="no"
 debug_tcg="no"
@@ -651,6 +652,11 @@ for opt do
   ;;
   --enable-docs) docs="yes"
   ;;
+  --disable-linux-virtfs) linux_virtfs="no"
+  ;;
+  --enable-linux-virtfs) linux_virtfs="yes"
+
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -806,6 +812,8 @@ echo "  --disable-blobs          disable installing provided firmware blobs"
 echo "  --kerneldir=PATH         look for kernel includes in PATH"
 echo "  --enable-docs            enable documentation build"
 echo "  --disable-docs           disable documentation build"
+echo "  --disable-linux-virtfs   disable Linux VIRTFS support"
+echo "  --enable-linux-virtfs    enable Linux VIRTFS support"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -1541,7 +1549,18 @@ EOF
     linux_aio=no
   fi
 fi
-
+########################################
+# linux-virtfs probe
+if test "$linux_virtfs" != "no" ; then
+    if test "$linux" = "no" ; then
+	if test "$linux_virtfs" = "yes" ; then
+	    feature_not_found "linux virtfs"
+	fi
+	linux_virtfs="no"
+    else
+	linux_virtfs="yes"
+    fi
+fi
 ##########################################
 # iovec probe
 cat > $TMPC <<EOF
@@ -1968,6 +1987,7 @@ echo "fdt support       $fdt"
 echo "preadv support    $preadv"
 echo "fdatasync         $fdatasync"
 echo "uuid support      $uuid"
+echo "Linux VIRTFS      $linux_virtfs"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2183,6 +2203,9 @@ fi
 if test "$fdatasync" = "yes" ; then
   echo "CONFIG_FDATASYNC=y" >> $config_host_mak
 fi
+if test "$linux_virtfs" = "yes" ; then
+  echo "CONFIG_LINUX_VIRTFS=y" >> $config_host_mak
+fi
 
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
fsdev/qemu-fsdev.c new file +70 -0

70 lines not on this page · raw message

fsdev/qemu-fsdev.h new file +53 -0

53 lines not on this page · raw message

hw/file-op-9p.h new file +32 -0
new file mode 100644
index 0000000..7cde63c
@@ -0,0 +1,32 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#ifndef _FILEOP_H
+#define _FILEOP_H
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <utime.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+typedef struct FsContext
+{
+    char *fs_root;
+    uid_t uid;
+} FsContext;
+
+typedef struct FileOperations
+{
+    void *opaque;
+} FileOperations;
+#endif
qemu-config.c +18 -0
index 150157c..0fb5105 100644
@@ -151,6 +151,24 @@ QemuOptsList qemu_chardev_opts = {
     },
 };
 
+#ifdef CONFIG_LINUX_VIRTFS
+QemuOptsList qemu_fsdev_opts = {
+    .name = "fsdev",
+    .implied_opt_name = "fstype",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_fsdev_opts.head),
+    .desc = {
+        {
+            .name = "fstype",
+            .type = QEMU_OPT_STRING,
+        }, {
+            .name = "path",
+            .type = QEMU_OPT_STRING,
+        },
+        { /*End of list */ }
+    },
+};
+#endif
+
 QemuOptsList qemu_device_opts = {
     .name = "device",
     .implied_opt_name = "driver",
qemu-config.h +3 -0
index f217c58..d85bde7 100644
@@ -3,6 +3,9 @@
 
 extern QemuOptsList qemu_drive_opts;
 extern QemuOptsList qemu_chardev_opts;
+#ifdef CONFIG_LINUX_VIRTFS
+extern QemuOptsList qemu_fsdev_opts;
+#endif
 extern QemuOptsList qemu_device_opts;
 extern QemuOptsList qemu_netdev_opts;
 extern QemuOptsList qemu_net_opts;
qemu-options.hx +33 -0
index 8450b45..e007df8 100644
@@ -469,6 +469,39 @@ To get a help on possible @var{driver}s, @var{option}s or @var{value}s, use
 @code{-device @var{driver},@var{option}=?}. 
 ETEXI
 
+#ifdef CONFIG_LINUX_VIRTFS
+DEFHEADING(File system options:)
+
+DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
+    "-fsdev local,id=id,path=path\n")
+
+STEXI
+
+The general form of a File system device option is:
+@table @option
+
+@item -fsdev @var{fstype} ,id=@var{id} [,@var{options}]
+@findex -fsdev
+Fstype is one of:
+@option{local},
+The specific Fstype will determine the applicable options.
+
+Options to each backend are described below.
+
+@item -fsdev local ,id=@var{id} ,path=@var{path}
+
+Create a file-system-"device" for local-filesystem.
+
+@option{local} is only available on Linux.
+
+@option{path} specifies the path to be exported. @option{path} is required.
+
+@end table
+ETEXI
+#endif
+
+DEFHEADING()
+
 DEF("name", HAS_ARG, QEMU_OPTION_name,
     "-name string1[,process=string2]\n"
     "                set the name of the guest\n"
vl.c +27 -0
index d69250c..4359825 100644
@@ -150,6 +150,9 @@ int main(int argc, char **argv)
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "qemu-objects.h"
+#ifdef CONFIG_LINUX_VIRTFS
+#include "fsdev/qemu-fsdev.h"
+#endif
 
 #include "disas.h"
 
@@ -3461,6 +3464,16 @@ static int chardev_init_func(QemuOpts *opts, void *opaque)
     return 0;
 }
 
+#ifdef CONFIG_LINUX_VIRTFS
+static int fsdev_init_func(QemuOpts *opts, void *opaque)
+{
+    int ret;
+    ret = qemu_fsdev_add(opts);
+
+    return ret;
+}
+#endif
+
 static int mon_init_func(QemuOpts *opts, void *opaque)
 {
     CharDriverState *chr;
@@ -4256,6 +4269,15 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+#ifdef CONFIG_LINUX_VIRTFS
+            case QEMU_OPTION_fsdev:
+                opts = qemu_opts_parse(&qemu_fsdev_opts, optarg, 1);
+                if (!opts) {
+                    fprintf(stderr, "parse error: %s\n", optarg);
+                    exit(1);
+                }
+                break;
+#endif
             case QEMU_OPTION_serial:
                 add_device_config(DEV_SERIAL, optarg);
                 default_serial = 0;
@@ -4625,6 +4647,11 @@ int main(int argc, char **argv, char **envp)
 
     if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0)
         exit(1);
+#ifdef CONFIG_LINUX_VIRTFS
+    if (qemu_opts_foreach(&qemu_fsdev_opts, fsdev_init_func, NULL, 1) != 0) {
+        exit(1);
+    }
+#endif
 
 #ifndef _WIN32
     if (daemonize) {
Signature · 1 line
1.7.0.4.360.g11766c
#2 lore raw

PATCH 2/21 virtio-9p: Add a virtio 9p device to qemu

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

This patch doesn't implement the 9p protocol handling code. It adds a simple device which dump the protocol data.

[[email protected]: Little-Endian to host format conversion] [[email protected]: Multiple-mounts support]

---
 Makefile.target      |    1 +
 fsdev/qemu-fsdev.c   |    2 +-
 fsdev/qemu-fsdev.h   |    1 +
 hw/9p.h              |   26 +++
 hw/virtio-9p-debug.c |  484 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/virtio-9p-local.c |   17 ++
 hw/virtio-9p.c       |  329 ++++++++++++++++++++++++++++++++++
 hw/virtio-9p.h       |  166 +++++++++++++++++
 hw/virtio-pci.c      |   32 ++++
 hw/virtio.h          |    7 +
 10 files changed, 1064 insertions(+), 1 deletions(-)
 create mode 100644 hw/9p.h
 create mode 100644 hw/virtio-9p-debug.c
 create mode 100644 hw/virtio-9p-local.c
 create mode 100644 hw/virtio-9p.c
 create mode 100644 hw/virtio-9p.h
Makefile.target +1 -0
index eb4d010..b7f8965 100644
@@ -166,6 +166,7 @@ obj-y += qemu-timer.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
+obj-$(CONFIG_LINUX_VIRTFS) += virtio-9p.o virtio-9p-debug.o virtio-9p-local.o
 obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 LIBS+=-lz
fsdev/qemu-fsdev.c +1 -1
index 48bbfd9..813e1f7 100644
@@ -21,7 +21,7 @@ static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries =
     QTAILQ_HEAD_INITIALIZER(fstype_entries);
 
 static FsTypeTable FsTypes[] = {
-    { .name = "local", .ops = NULL},
+    { .name = "local", .ops = &local_ops},
 };
 
 int qemu_fsdev_add(QemuOpts *opts)
fsdev/qemu-fsdev.h +1 -0
index 7fa4f60..b50fbe0 100644
@@ -50,4 +50,5 @@ typedef struct FsTypeListEntry {
 
 extern int qemu_fsdev_add(QemuOpts *opts);
 extern FsTypeEntry *get_fsdev_fsentry(char *id);
+extern FileOperations local_ops;
 #endif
hw/9p.h new file +26 -0
new file mode 100644
index 0000000..5fdd770
@@ -0,0 +1,26 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_9P_H
+#define QEMU_9P_H
+
+#include <stdbool.h>
+
+typedef struct V9fsConf
+{
+    /* tag name for the device */
+    char *tag;
+    char *fsdev_id;
+} V9fsConf;
+
+#endif
hw/virtio-9p-debug.c new file +484 -0

484 lines not on this page · raw message

hw/virtio-9p-local.c new file +17 -0
new file mode 100644
index 0000000..379af60
@@ -0,0 +1,17 @@
+/*
+ * Virtio 9p Posix callback
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Anthony Liguori   <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#include "virtio.h"
+#include "virtio-9p.h"
+
+FileOperations local_ops = {
+};
hw/virtio-9p.c new file +329 -0

329 lines not on this page · raw message

hw/virtio-9p.h new file +166 -0

166 lines not on this page · raw message

hw/virtio-pci.c +32 -0
index 6eb19cd..042cf26 100644
@@ -96,6 +96,9 @@ typedef struct {
     BlockConf block;
     NICConf nic;
     uint32_t host_features;
+#ifdef CONFIG_LINUX_VIRTFS
+    V9fsConf fsconf;
+#endif
     /* Max. number of ports we can have for a the virtio-serial device */
     uint32_t max_virtserial_ports;
 } VirtIOPCIProxy;
@@ -552,6 +555,23 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev)
     return 0;
 }
 
+#ifdef CONFIG_LINUX_VIRTFS
+static int virtio_9p_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
+    virtio_init_pci(proxy, vdev,
+                    PCI_VENDOR_ID_REDHAT_QUMRANET,
+                    0x1009,
+                    0x2,
+                    0x00);
+
+    return 0;
+}
+#endif
+
 static PCIDeviceInfo virtio_info[] = {
     {
         .qdev.name = "virtio-blk-pci",
@@ -606,6 +626,18 @@ static PCIDeviceInfo virtio_info[] = {
         },
         .qdev.reset = virtio_pci_reset,
     },{
+#ifdef CONFIG_LINUX_VIRTFS
+        .qdev.name = "virtio-9p-pci",
+        .qdev.size = sizeof(VirtIOPCIProxy),
+        .init      = virtio_9p_init_pci,
+        .qdev.props = (Property[]) {
+            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+            DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+            DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+            DEFINE_PROP_END_OF_LIST(),
+        },
+    }, {
+#endif
         /* end of list */
     }
 };
hw/virtio.h +7 -0
index 3baa2a3..41d0538 100644
@@ -19,6 +19,9 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "block_int.h"
+#ifdef CONFIG_LINUX_VIRTFS
+#include "9p.h"
+#endif
 
 /* from Linux's linux/virtio_config.h */
 
@@ -174,6 +177,10 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
 VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
 VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports);
 VirtIODevice *virtio_balloon_init(DeviceState *dev);
+#ifdef CONFIG_LINUX_VIRTFS
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
+#endif
+
 
 void virtio_net_exit(VirtIODevice *vdev);
 
Signature · 1 line
1.7.0.4.360.g11766c
#3 lore raw

PATCH 3/21 virtio-9p: pdu processing support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Add helpers to process the PDUs.

[[email protected]: malloc to qemu_malloc coversion]

---
 hw/virtio-9p-debug.h |    7 ++
 hw/virtio-9p.c       |  243 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 250 insertions(+), 0 deletions(-)
 create mode 100644 hw/virtio-9p-debug.h
hw/virtio-9p-debug.h new file +7 -0
new file mode 100644
index 0000000..0104be5
@@ -0,0 +1,7 @@
+#ifndef _QEMU_VIRTIO_9P_DEBUG_H
+#define _QEMU_VIRTIO_9P_DEBUG_H
+
+extern int dotu;
+void pprint_pdu(V9fsPDU *pdu);
+
+#endif
hw/virtio-9p.c +243 -0

255 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#4 lore raw

PATCH 4/21 virtio-9p: Add string manipulation support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Add helpers to do string manipulation.

---
 hw/virtio-9p.c |  127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 127 insertions(+), 0 deletions(-)
hw/virtio-9p.c +127 -0
index 0b95eeb..08df084 100644
@@ -21,6 +21,126 @@
 int dotu = 1;
 int debug_9p_pdu;
 
+static void v9fs_string_init(V9fsString *str)
+{
+    str->data = NULL;
+    str->size = 0;
+}
+
+static void v9fs_string_free(V9fsString *str)
+{
+    qemu_free(str->data);
+    str->data = NULL;
+    str->size = 0;
+}
+
+static void v9fs_string_null(V9fsString *str)
+{
+    v9fs_string_free(str);
+}
+
+static int number_to_string(void *arg, char type)
+{
+    unsigned int ret = 0;
+
+    switch (type) {
+    case 'u': {
+        unsigned int num = *(unsigned int *)arg;
+
+        do {
+            ret++;
+            num = num/10;
+        } while (num);
+        break;
+    }
+    default:
+        printf("Number_to_string: Unknown number format\n");
+        return -1;
+    }
+
+    return ret;
+}
+
+static int v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
+{
+    va_list ap2;
+    char *iter = (char *)fmt;
+    int len = 0;
+    int nr_args = 0;
+    char *arg_char_ptr;
+    unsigned int arg_uint;
+
+    /* Find the number of %'s that denotes an argument */
+    for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) {
+        nr_args++;
+        iter++;
+    }
+
+    len = strlen(fmt) - 2*nr_args;
+
+    if (!nr_args) {
+        goto alloc_print;
+    }
+
+    va_copy(ap2, ap);
+
+    iter = (char *)fmt;
+
+    /* Now parse the format string */
+    for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) {
+        iter++;
+        switch (*iter) {
+        case 'u':
+            arg_uint = va_arg(ap2, unsigned int);
+            len += number_to_string((void *)&arg_uint, 'u');
+            break;
+        case 's':
+            arg_char_ptr = va_arg(ap2, char *);
+            len += strlen(arg_char_ptr);
+            break;
+        case 'c':
+            len += 1;
+            break;
+        default:
+            fprintf(stderr,
+		    "v9fs_string_alloc_printf:Incorrect format %c", *iter);
+            return -1;
+        }
+        iter++;
+    }
+
+alloc_print:
+    *strp = qemu_malloc((len + 1) * sizeof(**strp));
+
+    return vsprintf(*strp, fmt, ap);
+}
+
+static void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
+{
+    va_list ap;
+    int err;
+
+    v9fs_string_free(str);
+
+    va_start(ap, fmt);
+    err = v9fs_string_alloc_printf(&str->data, fmt, ap);
+    BUG_ON(err == -1);
+    va_end(ap);
+
+    str->size = err;
+}
+
+static void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs)
+{
+    v9fs_string_free(lhs);
+    v9fs_string_sprintf(lhs, "%s", rhs->data);
+}
+
+static size_t v9fs_string_size(V9fsString *str)
+{
+    return str->size;
+}
+
 static V9fsPDU *alloc_pdu(V9fsState *s)
 {
     V9fsPDU *pdu = NULL;
@@ -313,6 +433,13 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
      * They will be removed in the subsequent patches */
     (void)pdu_unmarshal;
     (void) complete_pdu;
+    (void) v9fs_string_init;
+    (void) v9fs_string_free;
+    (void) v9fs_string_null;
+    (void) v9fs_string_sprintf;
+    (void) v9fs_string_copy;
+    (void) v9fs_string_size;
+
 
 }
 static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#5 lore raw

PATCH 5/21 virtio-9p: Add minimal set of FileOperations

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Add minimal set of FileOperations and the corresponding implementations for local fstype. These will be required for the FID management patches later on.

---
 hw/file-op-9p.h      |    5 +++
 hw/virtio-9p-local.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/virtio-9p.c       |   43 ++++++++++++++++++++++++++-
 3 files changed, 124 insertions(+), 2 deletions(-)
hw/file-op-9p.h +5 -0
index 7cde63c..461df9e 100644
@@ -27,6 +27,11 @@ typedef struct FsContext
 
 typedef struct FileOperations
 {
+    int (*lstat)(FsContext *, const char *, struct stat *);
+    ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
+    int (*setuid)(FsContext *, uid_t);
+    int (*close)(FsContext *, int);
+    int (*closedir)(FsContext *, DIR *);
     void *opaque;
 } FileOperations;
 #endif
hw/virtio-9p-local.c +78 -0

84 lines not on this page · raw message

hw/virtio-9p.c +41 -2

56 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#6 lore raw

PATCH 6/21 virtio-9p: Add fid and qid management support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Helper APIs for FID and QID management.

---
 hw/virtio-9p.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 123 insertions(+), 0 deletions(-)
hw/virtio-9p.c +123 -0
index 528c9cc..7db157a 100644
@@ -176,6 +176,126 @@ static size_t v9fs_string_size(V9fsString *str)
     return str->size;
 }
 
+static V9fsFidState *lookup_fid(V9fsState *s, int32_t fid)
+{
+    V9fsFidState *f;
+
+    for (f = s->fid_list; f; f = f->next) {
+        if (f->fid == fid) {
+            v9fs_do_setuid(s, f->uid);
+            return f;
+        }
+    }
+
+    return NULL;
+}
+
+static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
+{
+    V9fsFidState *f;
+
+    f = lookup_fid(s, fid);
+    if (f) {
+        return NULL;
+    }
+
+    f = qemu_mallocz(sizeof(V9fsFidState));
+
+    f->fid = fid;
+    f->fd = -1;
+    f->dir = NULL;
+
+    f->next = s->fid_list;
+    s->fid_list = f;
+
+    return f;
+}
+
+static int free_fid(V9fsState *s, int32_t fid)
+{
+    V9fsFidState **fidpp, *fidp;
+
+    for (fidpp = &s->fid_list; *fidpp; fidpp = &(*fidpp)->next) {
+        if ((*fidpp)->fid == fid) {
+            break;
+        }
+    }
+
+    if (*fidpp == NULL) {
+        return -ENOENT;
+    }
+
+    fidp = *fidpp;
+    *fidpp = fidp->next;
+
+    if (fidp->fd != -1) {
+        v9fs_do_close(s, fidp->fd);
+    }
+    if (fidp->dir) {
+        v9fs_do_closedir(s, fidp->dir);
+    }
+    v9fs_string_free(&fidp->path);
+    qemu_free(fidp);
+
+    return 0;
+}
+
+#define P9_QID_TYPE_DIR         0x80
+#define P9_QID_TYPE_SYMLINK     0x02
+
+#define P9_STAT_MODE_DIR        0x80000000
+#define P9_STAT_MODE_APPEND     0x40000000
+#define P9_STAT_MODE_EXCL       0x20000000
+#define P9_STAT_MODE_MOUNT      0x10000000
+#define P9_STAT_MODE_AUTH       0x08000000
+#define P9_STAT_MODE_TMP        0x04000000
+#define P9_STAT_MODE_SYMLINK    0x02000000
+#define P9_STAT_MODE_LINK       0x01000000
+#define P9_STAT_MODE_DEVICE     0x00800000
+#define P9_STAT_MODE_NAMED_PIPE 0x00200000
+#define P9_STAT_MODE_SOCKET     0x00100000
+#define P9_STAT_MODE_SETUID     0x00080000
+#define P9_STAT_MODE_SETGID     0x00040000
+#define P9_STAT_MODE_SETVTX     0x00010000
+
+#define P9_STAT_MODE_TYPE_BITS (P9_STAT_MODE_DIR |          \
+                                P9_STAT_MODE_SYMLINK |      \
+                                P9_STAT_MODE_LINK |         \
+                                P9_STAT_MODE_DEVICE |       \
+                                P9_STAT_MODE_NAMED_PIPE |   \
+                                P9_STAT_MODE_SOCKET)
+
+/* This is the algorithm from ufs in spfs */
+static void stat_to_qid(const struct stat *stbuf, V9fsQID *qidp)
+{
+    size_t size;
+
+    size = MIN(sizeof(stbuf->st_ino), sizeof(qidp->path));
+    memcpy(&qidp->path, &stbuf->st_ino, size);
+    qidp->version = stbuf->st_mtime ^ (stbuf->st_size << 8);
+    qidp->type = 0;
+    if (S_ISDIR(stbuf->st_mode)) {
+        qidp->type |= P9_QID_TYPE_DIR;
+    }
+    if (S_ISLNK(stbuf->st_mode)) {
+        qidp->type |= P9_QID_TYPE_SYMLINK;
+    }
+}
+
+static int fid_to_qid(V9fsState *s, V9fsFidState *fidp, V9fsQID *qidp)
+{
+    struct stat stbuf;
+    int err;
+
+    err = v9fs_do_lstat(s, &fidp->path, &stbuf);
+    if (err) {
+        return err;
+    }
+
+    stat_to_qid(&stbuf, qidp);
+    return 0;
+}
+
 static V9fsPDU *alloc_pdu(V9fsState *s)
 {
     V9fsPDU *pdu = NULL;
@@ -479,6 +599,9 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
     (void) v9fs_do_readlink;
     (void) v9fs_do_close;
     (void) v9fs_do_closedir;
+    (void) alloc_fid;
+    (void) free_fid;
+    (void) fid_to_qid;
 }
 
 static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#7 lore raw

PATCH 7/21 virtio-9p: Add stat and mode related helper functions.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Add helpers to obtain file stat and mode details.

---
 hw/virtio-9p.c |  186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 186 insertions(+), 0 deletions(-)
hw/virtio-9p.c +186 -0
index 7db157a..4b3ce2f 100644
@@ -582,6 +582,188 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len)
     free_pdu(s, pdu);
 }
 
+static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension)
+{
+    mode_t ret;
+
+    ret = mode & 0777;
+    if (mode & P9_STAT_MODE_DIR) {
+        ret |= S_IFDIR;
+    }
+
+    if (dotu) {
+        if (mode & P9_STAT_MODE_SYMLINK) {
+            ret |= S_IFLNK;
+        }
+        if (mode & P9_STAT_MODE_SOCKET) {
+            ret |= S_IFSOCK;
+        }
+        if (mode & P9_STAT_MODE_NAMED_PIPE) {
+            ret |= S_IFIFO;
+        }
+        if (mode & P9_STAT_MODE_DEVICE) {
+            if (extension && extension->data[0] == 'c') {
+                ret |= S_IFCHR;
+            } else {
+                ret |= S_IFBLK;
+            }
+        }
+    }
+
+    if (!(ret&~0777)) {
+        ret |= S_IFREG;
+    }
+
+    if (mode & P9_STAT_MODE_SETUID) {
+        ret |= S_ISUID;
+    }
+    if (mode & P9_STAT_MODE_SETGID) {
+        ret |= S_ISGID;
+    }
+    if (mode & P9_STAT_MODE_SETVTX) {
+        ret |= S_ISVTX;
+    }
+
+    return ret;
+}
+
+static int donttouch_stat(V9fsStat *stat)
+{
+    if (stat->type == -1 &&
+        stat->dev == -1 &&
+        stat->qid.type == -1 &&
+        stat->qid.version == -1 &&
+        stat->qid.path == -1 &&
+        stat->mode == -1 &&
+        stat->atime == -1 &&
+        stat->mtime == -1 &&
+        stat->length == -1 &&
+        !stat->name.size &&
+        !stat->uid.size &&
+        !stat->gid.size &&
+        !stat->muid.size &&
+        stat->n_uid == -1 &&
+        stat->n_gid == -1 &&
+        stat->n_muid == -1) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void v9fs_stat_free(V9fsStat *stat)
+{
+    v9fs_string_free(&stat->name);
+    v9fs_string_free(&stat->uid);
+    v9fs_string_free(&stat->gid);
+    v9fs_string_free(&stat->muid);
+    v9fs_string_free(&stat->extension);
+}
+
+static uint32_t stat_to_v9mode(const struct stat *stbuf)
+{
+    uint32_t mode;
+
+    mode = stbuf->st_mode & 0777;
+    if (S_ISDIR(stbuf->st_mode)) {
+        mode |= P9_STAT_MODE_DIR;
+    }
+
+    if (dotu) {
+        if (S_ISLNK(stbuf->st_mode)) {
+            mode |= P9_STAT_MODE_SYMLINK;
+        }
+
+        if (S_ISSOCK(stbuf->st_mode)) {
+            mode |= P9_STAT_MODE_SOCKET;
+        }
+
+        if (S_ISFIFO(stbuf->st_mode)) {
+            mode |= P9_STAT_MODE_NAMED_PIPE;
+        }
+
+        if (S_ISBLK(stbuf->st_mode) || S_ISCHR(stbuf->st_mode)) {
+            mode |= P9_STAT_MODE_DEVICE;
+        }
+
+        if (stbuf->st_mode & S_ISUID) {
+            mode |= P9_STAT_MODE_SETUID;
+        }
+
+        if (stbuf->st_mode & S_ISGID) {
+            mode |= P9_STAT_MODE_SETGID;
+        }
+
+        if (stbuf->st_mode & S_ISVTX) {
+            mode |= P9_STAT_MODE_SETVTX;
+        }
+    }
+
+    return mode;
+}
+
+static int stat_to_v9stat(V9fsState *s, V9fsString *name,
+                            const struct stat *stbuf,
+                            V9fsStat *v9stat)
+{
+    int err;
+    const char *str;
+
+    memset(v9stat, 0, sizeof(*v9stat));
+
+    stat_to_qid(stbuf, &v9stat->qid);
+    v9stat->mode = stat_to_v9mode(stbuf);
+    v9stat->atime = stbuf->st_atime;
+    v9stat->mtime = stbuf->st_mtime;
+    v9stat->length = stbuf->st_size;
+
+    v9fs_string_null(&v9stat->uid);
+    v9fs_string_null(&v9stat->gid);
+    v9fs_string_null(&v9stat->muid);
+
+    if (dotu) {
+        v9stat->n_uid = stbuf->st_uid;
+        v9stat->n_gid = stbuf->st_gid;
+        v9stat->n_muid = 0;
+
+        v9fs_string_null(&v9stat->extension);
+
+        if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
+            err = v9fs_do_readlink(s, name, &v9stat->extension);
+            if (err == -1) {
+                err = -errno;
+                return err;
+            }
+            v9stat->extension.data[err] = 0;
+            v9stat->extension.size = err;
+        } else if (v9stat->mode & P9_STAT_MODE_DEVICE) {
+            v9fs_string_sprintf(&v9stat->extension, "%c %u %u",
+                    S_ISCHR(stbuf->st_mode) ? 'c' : 'b',
+                    major(stbuf->st_rdev), minor(stbuf->st_rdev));
+        } else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) {
+            v9fs_string_sprintf(&v9stat->extension, "%s %u",
+                    "HARDLINKCOUNT", stbuf->st_nlink);
+        }
+    }
+
+    str = strrchr(name->data, '/');
+    if (str) {
+        str += 1;
+    } else {
+        str = name->data;
+    }
+
+    v9fs_string_sprintf(&v9stat->name, "%s", str);
+
+    v9stat->size = 61 +
+        v9fs_string_size(&v9stat->name) +
+        v9fs_string_size(&v9stat->uid) +
+        v9fs_string_size(&v9stat->gid) +
+        v9fs_string_size(&v9stat->muid) +
+        v9fs_string_size(&v9stat->extension);
+    return 0;
+}
+
 static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
 {
     /* Note: The following have been added to prevent GCC from complaining
@@ -602,6 +784,10 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
     (void) alloc_fid;
     (void) free_fid;
     (void) fid_to_qid;
+    (void) v9mode_to_mode;
+    (void) donttouch_stat;
+    (void) v9fs_stat_free;
+    (void) stat_to_v9stat;
 }
 
 static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#8 lore raw

PATCH 8/21 virtio-9p: Add sg helper functions

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Add scatter-gather helper functions.

---
 hw/virtio-9p.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)
hw/virtio-9p.c +53 -0
index 4b3ce2f..5dab1d3 100644
@@ -764,6 +764,56 @@ static int stat_to_v9stat(V9fsState *s, V9fsString *name,
     return 0;
 }
 
+static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt)
+{
+    while (len && *iovcnt) {
+        if (len < sg->iov_len) {
+            sg->iov_len -= len;
+            sg->iov_base += len;
+            len = 0;
+        } else {
+            len -= sg->iov_len;
+            sg++;
+            *iovcnt -= 1;
+        }
+    }
+
+    return sg;
+}
+
+static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt)
+{
+    int i;
+    int total = 0;
+
+    for (i = 0; i < *cnt; i++) {
+        if ((total + sg[i].iov_len) > cap) {
+            sg[i].iov_len -= ((total + sg[i].iov_len) - cap);
+            i++;
+            break;
+        }
+        total += sg[i].iov_len;
+    }
+
+    *cnt = i;
+
+    return sg;
+}
+
+static void print_sg(struct iovec *sg, int cnt)
+{
+    int i;
+
+    printf("sg[%d]: {", cnt);
+    for (i = 0; i < cnt; i++) {
+        if (i) {
+            printf(", ");
+        }
+        printf("(%p, %zd)", sg[i].iov_base, sg[i].iov_len);
+    }
+    printf("}\n");
+}
+
 static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
 {
     /* Note: The following have been added to prevent GCC from complaining
@@ -788,6 +838,9 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
     (void) donttouch_stat;
     (void) v9fs_stat_free;
     (void) stat_to_v9stat;
+    (void) adjust_sg;
+    (void) cap_sg;
+    (void) print_sg;
 }
 
 static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#9 lore raw

PATCH 9/21 virtio-9p: Add P9_TVERSION support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TVERSION support.

[[email protected]: Handle unknown 9P versions as per the standards]

---
 hw/virtio-9p.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)
hw/virtio-9p.c +13 -2
index 5dab1d3..ccc45a3 100644
@@ -845,9 +845,20 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
 
 static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
+    int32_t msize;
+    V9fsString version;
+    size_t offset = 7;
+
+    pdu_unmarshal(pdu, offset, "ds", &msize, &version);
+
+    if (strcmp(version.data, "9P2000.u")) {
+        v9fs_string_sprintf(&version, "unknown");
     }
+
+    offset += pdu_marshal(pdu, offset, "ds", msize, &version);
+    complete_pdu(s, pdu, offset);
+
+    v9fs_string_free(&version);
 }
 
 static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#10 lore raw

PATCH 10/21 virtio-9p: Add P9_TATTACH support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TATTACH support.

---
 hw/virtio-9p.c |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)
hw/virtio-9p.c +31 -2
index ccc45a3..4ab4f9a 100644
@@ -863,9 +863,38 @@ static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
 
 static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
+    int32_t fid, afid, n_uname;
+    V9fsString uname, aname;
+    V9fsFidState *fidp;
+    V9fsQID qid;
+    size_t offset = 7;
+    ssize_t err;
+
+    pdu_unmarshal(pdu, offset, "ddssd", &fid, &afid, &uname, &aname, &n_uname);
+
+    fidp = alloc_fid(s, fid);
+    if (fidp == NULL) {
+        err = -EINVAL;
+        goto out;
     }
+
+    fidp->uid = n_uname;
+
+    v9fs_string_sprintf(&fidp->path, "%s", "/");
+    err = fid_to_qid(s, fidp, &qid);
+    if (err) {
+        err = -EINVAL;
+        free_fid(s, fid);
+        goto out;
+    }
+
+    offset += pdu_marshal(pdu, offset, "Q", &qid);
+
+    err = offset;
+out:
+    complete_pdu(s, pdu, err);
+    v9fs_string_free(&uname);
+    v9fs_string_free(&aname);
 }
 
 static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#11 lore raw

PATCH 11/21 virtio-9p: Add P9_TSTAT support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TSTAT support. This get the mount to work on the guest.

[[email protected]: malloc to qemu_malloc conversion]

---
 hw/virtio-9p.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 53 insertions(+), 2 deletions(-)
hw/virtio-9p.c +53 -2
index 4ab4f9a..342eb5e 100644
@@ -897,11 +897,62 @@ out:
     v9fs_string_free(&aname);
 }
 
+typedef struct V9fsStatState {
+    V9fsPDU *pdu;
+    size_t offset;
+    V9fsStat v9stat;
+    V9fsFidState *fidp;
+    struct stat stbuf;
+} V9fsStatState;
+
+static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
+{
+    if (err == -1) {
+        err = -errno;
+        goto out;
+    }
+
+    err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
+    if (err) {
+        goto out;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat);
+    err = vs->offset;
+
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_stat_free(&vs->v9stat);
+    qemu_free(vs);
+}
+
 static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
+    int32_t fid;
+    V9fsStatState *vs;
+    ssize_t err = 0;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    memset(&vs->v9stat, 0, sizeof(vs->v9stat));
+
+    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
+
+    vs->fidp = lookup_fid(s, fid);
+    if (vs->fidp == NULL) {
+        err = -ENOENT;
+        goto out;
     }
+
+    err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
+    v9fs_stat_post_lstat(s, vs, err);
+    return;
+
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_stat_free(&vs->v9stat);
+    qemu_free(vs);
 }
 
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#12 lore raw

PATCH 12/21 virtio-9p: Add P9_TWALK support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TWALK support.

---
 hw/virtio-9p.c |  173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 171 insertions(+), 2 deletions(-)
hw/virtio-9p.c +171 -2
index 342eb5e..572f341 100644
@@ -955,11 +955,180 @@ out:
     qemu_free(vs);
 }
 
+typedef struct V9fsWalkState {
+    V9fsPDU *pdu;
+    size_t offset;
+    int16_t nwnames;
+    int name_idx;
+    V9fsQID *qids;
+    V9fsFidState *fidp;
+    V9fsFidState *newfidp;
+    V9fsString path;
+    V9fsString *wnames;
+    struct stat stbuf;
+} V9fsWalkState;
+
+static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
+{
+    complete_pdu(s, vs->pdu, err);
+
+    if (vs->nwnames) {
+        for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++) {
+            v9fs_string_free(&vs->wnames[vs->name_idx]);
+        }
+
+        qemu_free(vs->wnames);
+        qemu_free(vs->qids);
+    }
+}
+
+static void v9fs_walk_marshal(V9fsWalkState *vs)
+{
+    int i;
+    vs->offset = 7;
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "w", vs->nwnames);
+
+    for (i = 0; i < vs->nwnames; i++) {
+        vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qids[i]);
+    }
+}
+
+static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
+                                                                int err)
+{
+    if (err == -1) {
+        free_fid(s, vs->newfidp->fid);
+        v9fs_string_free(&vs->path);
+        err = -ENOENT;
+        goto out;
+    }
+
+    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
+
+    vs->name_idx++;
+    if (vs->name_idx < vs->nwnames) {
+        v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
+                                            vs->wnames[vs->name_idx].data);
+        v9fs_string_copy(&vs->newfidp->path, &vs->path);
+
+        err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
+        v9fs_walk_post_newfid_lstat(s, vs, err);
+        return;
+    }
+
+    v9fs_string_free(&vs->path);
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
+}
+
+static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
+        int err)
+{
+    if (err == -1) {
+        v9fs_string_free(&vs->path);
+        err = -ENOENT;
+        goto out;
+    }
+
+    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
+    vs->name_idx++;
+    if (vs->name_idx < vs->nwnames) {
+
+        v9fs_string_sprintf(&vs->path, "%s/%s",
+                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
+        v9fs_string_copy(&vs->fidp->path, &vs->path);
+
+        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
+        v9fs_walk_post_oldfid_lstat(s, vs, err);
+        return;
+    }
+
+    v9fs_string_free(&vs->path);
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
+}
+
 static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
+    int32_t fid, newfid;
+    V9fsWalkState *vs;
+    int err = 0;
+    int i;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->wnames = NULL;
+    vs->qids = NULL;
+    vs->offset = 7;
+
+    vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
+                                            &newfid, &vs->nwnames);
+
+    if (vs->nwnames) {
+        vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames);
+
+        vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames);
+
+        for (i = 0; i < vs->nwnames; i++) {
+            vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
+                                            &vs->wnames[i]);
+        }
+    }
+
+    vs->fidp = lookup_fid(s, fid);
+    if (vs->fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    /* FIXME: is this really valid? */
+    if (fid == newfid) {
+
+        BUG_ON(vs->fidp->fd != -1);
+        BUG_ON(vs->fidp->dir);
+        v9fs_string_init(&vs->path);
+        vs->name_idx = 0;
+
+        if (vs->name_idx < vs->nwnames) {
+            v9fs_string_sprintf(&vs->path, "%s/%s",
+                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
+            v9fs_string_copy(&vs->fidp->path, &vs->path);
+
+            err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
+            v9fs_walk_post_oldfid_lstat(s, vs, err);
+            return;
+        }
+    } else {
+        vs->newfidp = alloc_fid(s, newfid);
+        if (vs->newfidp == NULL) {
+            err = -EINVAL;
+            goto out;
+        }
+
+        vs->newfidp->uid = vs->fidp->uid;
+        v9fs_string_init(&vs->path);
+        vs->name_idx = 0;
+        v9fs_string_copy(&vs->newfidp->path, &vs->fidp->path);
+
+        if (vs->name_idx < vs->nwnames) {
+            v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
+                                vs->wnames[vs->name_idx].data);
+            v9fs_string_copy(&vs->newfidp->path, &vs->path);
+
+            err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
+            v9fs_walk_post_newfid_lstat(s, vs, err);
+            return;
+        }
     }
+
+    v9fs_walk_marshal(vs);
+    err = vs->offset;
+out:
+    v9fs_walk_complete(s, vs, err);
 }
 
 static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
Signature · 1 line
1.7.0.4.360.g11766c
#13 lore raw

PATCH 13/21 virtio-9p: Add P9_TOPEN support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TOPEN support.

---
 hw/file-op-9p.h      |    2 +
 hw/virtio-9p-local.c |   12 ++++
 hw/virtio-9p.c       |  153 ++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 162 insertions(+), 5 deletions(-)
hw/file-op-9p.h +2 -0
index 461df9e..715f2d0 100644
@@ -32,6 +32,8 @@ typedef struct FileOperations
     int (*setuid)(FsContext *, uid_t);
     int (*close)(FsContext *, int);
     int (*closedir)(FsContext *, DIR *);
+    DIR *(*opendir)(FsContext *, const char *);
+    int (*open)(FsContext *, const char *, int);
     void *opaque;
 } FileOperations;
 #endif
hw/virtio-9p-local.c +12 -0
index 880cd0a..3788d4e 100644
@@ -86,10 +86,22 @@ static int local_closedir(FsContext *ctx, DIR *dir)
     return closedir(dir);
 }
 
+static int local_open(FsContext *ctx, const char *path, int flags)
+{
+    return open(rpath(ctx, path), flags);
+}
+
+static DIR *local_opendir(FsContext *ctx, const char *path)
+{
+    return opendir(rpath(ctx, path));
+}
+
 FileOperations local_ops = {
     .lstat = local_lstat,
     .setuid = local_setuid,
     .readlink = local_readlink,
     .close = local_close,
     .closedir = local_closedir,
+    .open = local_open,
+    .opendir = local_opendir,
 };
hw/virtio-9p.c +148 -5

171 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#14 lore raw

PATCH 14/21 virtio-9p: Add P9_TREAD support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TREAD support.

---
 hw/file-op-9p.h      |    6 ++
 hw/virtio-9p-local.c |   37 ++++++++
 hw/virtio-9p.c       |  234 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 275 insertions(+), 2 deletions(-)
hw/file-op-9p.h +6 -0
index 715f2d0..c1f5e45 100644
@@ -34,6 +34,12 @@ typedef struct FileOperations
     int (*closedir)(FsContext *, DIR *);
     DIR *(*opendir)(FsContext *, const char *);
     int (*open)(FsContext *, const char *, int);
+    void (*rewinddir)(FsContext *, DIR *);
+    off_t (*telldir)(FsContext *, DIR *);
+    struct dirent *(*readdir)(FsContext *, DIR *);
+    void (*seekdir)(FsContext *, DIR *, off_t);
+    ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
+    off_t (*lseek)(FsContext *, int, off_t, int);
     void *opaque;
 } FileOperations;
 #endif
hw/virtio-9p-local.c +37 -0
index 3788d4e..81d1971 100644
@@ -96,6 +96,37 @@ static DIR *local_opendir(FsContext *ctx, const char *path)
     return opendir(rpath(ctx, path));
 }
 
+static void local_rewinddir(FsContext *ctx, DIR *dir)
+{
+    return rewinddir(dir);
+}
+
+static off_t local_telldir(FsContext *ctx, DIR *dir)
+{
+    return telldir(dir);
+}
+
+static struct dirent *local_readdir(FsContext *ctx, DIR *dir)
+{
+    return readdir(dir);
+}
+
+static void local_seekdir(FsContext *ctx, DIR *dir, off_t off)
+{
+    return seekdir(dir, off);
+}
+
+static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov,
+                            int iovcnt)
+{
+    return readv(fd, iov, iovcnt);
+}
+
+static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence)
+{
+    return lseek(fd, offset, whence);
+}
+
 FileOperations local_ops = {
     .lstat = local_lstat,
     .setuid = local_setuid,
@@ -104,4 +135,10 @@ FileOperations local_ops = {
     .closedir = local_closedir,
     .open = local_open,
     .opendir = local_opendir,
+    .rewinddir = local_rewinddir,
+    .telldir = local_telldir,
+    .readdir = local_readdir,
+    .seekdir = local_seekdir,
+    .readv = local_readv,
+    .lseek = local_lseek,
 };
hw/virtio-9p.c +232 -2

249 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#15 lore raw

PATCH 15/21 virtio-9p: Add P9_TCLUNK support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TCLUNK support.
This patch gets ls -al to work.

---
 hw/virtio-9p.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)
hw/virtio-9p.c +14 -2
index e702c5c..480f68b 100644
@@ -1313,9 +1313,21 @@ out:
 
 static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
 {
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
+    int32_t fid;
+    size_t offset = 7;
+    int err;
+
+    pdu_unmarshal(pdu, offset, "d", &fid);
+
+    err = free_fid(s, fid);
+    if (err < 0) {
+        goto out;
     }
+
+    offset = 7;
+    err = offset;
+out:
+    complete_pdu(s, pdu, err);
 }
 
 typedef struct V9fsReadState {
Signature · 1 line
1.7.0.4.360.g11766c
#16 lore raw

PATCH 16/21 virtio-9p: Add P9_TWRITE support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TWRITE support.
This gets write to file to work

---
 hw/file-op-9p.h      |    1 +
 hw/virtio-9p-local.c |    7 +++
 hw/virtio-9p.c       |  112 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 118 insertions(+), 2 deletions(-)
hw/file-op-9p.h +1 -0
index c1f5e45..12503c1 100644
@@ -39,6 +39,7 @@ typedef struct FileOperations
     struct dirent *(*readdir)(FsContext *, DIR *);
     void (*seekdir)(FsContext *, DIR *, off_t);
     ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
+    ssize_t (*writev)(FsContext *, int, const struct iovec *, int);
     off_t (*lseek)(FsContext *, int, off_t, int);
     void *opaque;
 } FileOperations;
hw/virtio-9p-local.c +7 -0
index 81d1971..87aeba8 100644
@@ -127,6 +127,12 @@ static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence)
     return lseek(fd, offset, whence);
 }
 
+static ssize_t local_writev(FsContext *ctx, int fd, const struct iovec *iov,
+                            int iovcnt)
+{
+    return writev(fd, iov, iovcnt);
+}
+
 FileOperations local_ops = {
     .lstat = local_lstat,
     .setuid = local_setuid,
@@ -141,4 +147,5 @@ FileOperations local_ops = {
     .seekdir = local_seekdir,
     .readv = local_readv,
     .lseek = local_lseek,
+    .writev = local_writev,
 };
hw/virtio-9p.c +110 -2

127 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#17 lore raw

PATCH 17/21 virtio-9p: Add P9_TCREATE support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TCREATE support. [[email protected]: strdup to qemu_strdup conversion]

---
 hw/file-op-9p.h      |    8 ++
 hw/virtio-9p-local.c |   87 +++++++++++++++++
 hw/virtio-9p.c       |  264 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 357 insertions(+), 2 deletions(-)
hw/file-op-9p.h +8 -0
index 12503c1..5049b2e 100644
@@ -29,11 +29,17 @@ typedef struct FileOperations
 {
     int (*lstat)(FsContext *, const char *, struct stat *);
     ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
+    int (*chmod)(FsContext *, const char *, mode_t);
+    int (*mknod)(FsContext *, const char *, mode_t, dev_t);
+    int (*mksock)(FsContext *, const char *);
+    int (*symlink)(FsContext *, const char *, const char *);
+    int (*link)(FsContext *, const char *, const char *);
     int (*setuid)(FsContext *, uid_t);
     int (*close)(FsContext *, int);
     int (*closedir)(FsContext *, DIR *);
     DIR *(*opendir)(FsContext *, const char *);
     int (*open)(FsContext *, const char *, int);
+    int (*open2)(FsContext *, const char *, int, mode_t);
     void (*rewinddir)(FsContext *, DIR *);
     off_t (*telldir)(FsContext *, DIR *);
     struct dirent *(*readdir)(FsContext *, DIR *);
@@ -41,6 +47,8 @@ typedef struct FileOperations
     ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
     ssize_t (*writev)(FsContext *, int, const struct iovec *, int);
     off_t (*lseek)(FsContext *, int, off_t, int);
+    int (*mkdir)(FsContext *, const char *, mode_t);
+    int (*fstat)(FsContext *, int, struct stat *);
     void *opaque;
 } FileOperations;
 #endif
hw/virtio-9p-local.c +87 -0

105 lines not on this page · raw message

hw/virtio-9p.c +262 -2

279 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#18 lore raw

PATCH 18/21 virtio-9p: Add P9_TWSTAT support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TWSTAT support.
This gets file and directory creation to work.

[[email protected]: strdup to qemu_strdup conversion] [[email protected]: v9fs_fix_path]

---
 hw/file-op-9p.h      |    5 +
 hw/virtio-9p-local.c |   50 +++++++++
 hw/virtio-9p.c       |  273 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 326 insertions(+), 2 deletions(-)
hw/file-op-9p.h +5 -0
index 5049b2e..8ba1927 100644
@@ -30,8 +30,10 @@ typedef struct FileOperations
     int (*lstat)(FsContext *, const char *, struct stat *);
     ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
     int (*chmod)(FsContext *, const char *, mode_t);
+    int (*chown)(FsContext *, const char *, uid_t, gid_t);
     int (*mknod)(FsContext *, const char *, mode_t, dev_t);
     int (*mksock)(FsContext *, const char *);
+    int (*utime)(FsContext *, const char *, const struct utimbuf *);
     int (*symlink)(FsContext *, const char *, const char *);
     int (*link)(FsContext *, const char *, const char *);
     int (*setuid)(FsContext *, uid_t);
@@ -49,6 +51,9 @@ typedef struct FileOperations
     off_t (*lseek)(FsContext *, int, off_t, int);
     int (*mkdir)(FsContext *, const char *, mode_t);
     int (*fstat)(FsContext *, int, struct stat *);
+    int (*rename)(FsContext *, const char *, const char *);
+    int (*truncate)(FsContext *, const char *, off_t);
+    int (*fsync)(FsContext *, int);
     void *opaque;
 } FileOperations;
 #endif
hw/virtio-9p-local.c +50 -0

60 lines not on this page · raw message

hw/virtio-9p.c +271 -2

294 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#19 lore raw

PATCH 19/21 virtio-9p: Add P9_TREMOVE support.

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Implement P9_TREMOVE support.
This gets file deletion to work.

[[email protected]: Fix truncate to use the relative path]

---
 hw/file-op-9p.h      |    1 +
 hw/virtio-9p-local.c |    6 +++++
 hw/virtio-9p.c       |   54 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 59 insertions(+), 2 deletions(-)
hw/file-op-9p.h +1 -0
index 8ba1927..f84767f 100644
@@ -34,6 +34,7 @@ typedef struct FileOperations
     int (*mknod)(FsContext *, const char *, mode_t, dev_t);
     int (*mksock)(FsContext *, const char *);
     int (*utime)(FsContext *, const char *, const struct utimbuf *);
+    int (*remove)(FsContext *, const char *);
     int (*symlink)(FsContext *, const char *, const char *);
     int (*link)(FsContext *, const char *, const char *);
     int (*setuid)(FsContext *, uid_t);
hw/virtio-9p-local.c +6 -0
index 5a011f3..1afb731 100644
@@ -252,6 +252,11 @@ static int local_utime(FsContext *ctx, const char *path,
     return utime(rpath(ctx, path), buf);
 }
 
+static int local_remove(FsContext *ctx, const char *path)
+{
+    return remove(rpath(ctx, path));
+}
+
 static int local_fsync(FsContext *ctx, int fd)
 {
     return fsync(fd);
@@ -284,5 +289,6 @@ FileOperations local_ops = {
     .rename = local_rename,
     .chown = local_chown,
     .utime = local_utime,
+    .remove = local_remove,
     .fsync = local_fsync,
 };
hw/virtio-9p.c +52 -2

69 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c
#20 lore raw

PATCH 20/21 virtio-9p: Add P9_TFLUSH support

In reply to Aneesh Kumar K.V

From: Anthony Liguori <[email protected]>

Don't do anything special for flush.

---
 hw/virtio-9p.c |   35 ++---------------------------------
 1 files changed, 2 insertions(+), 33 deletions(-)
hw/virtio-9p.c +2 -33
index a2a9cd8..9a97d4a 100644
@@ -934,35 +934,6 @@ static void print_sg(struct iovec *sg, int cnt)
     printf("}\n");
 }
 
-static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu)
-{
-    /* Note: The following have been added to prevent GCC from complaining
-     * They will be removed in the subsequent patches */
-    (void)pdu_unmarshal;
-    (void) complete_pdu;
-    (void) v9fs_string_init;
-    (void) v9fs_string_free;
-    (void) v9fs_string_null;
-    (void) v9fs_string_sprintf;
-    (void) v9fs_string_copy;
-    (void) v9fs_string_size;
-    (void) v9fs_do_lstat;
-    (void) v9fs_do_setuid;
-    (void) v9fs_do_readlink;
-    (void) v9fs_do_close;
-    (void) v9fs_do_closedir;
-    (void) alloc_fid;
-    (void) free_fid;
-    (void) fid_to_qid;
-    (void) v9mode_to_mode;
-    (void) donttouch_stat;
-    (void) v9fs_stat_free;
-    (void) stat_to_v9stat;
-    (void) adjust_sg;
-    (void) cap_sg;
-    (void) print_sg;
-}
-
 static void v9fs_fix_path(V9fsString *dst, V9fsString *src, int len)
 {
     V9fsString str;
@@ -1961,10 +1932,8 @@ out:
 
 static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
 {
-    v9fs_dummy(s, pdu);
-    if (debug_9p_pdu) {
-        pprint_pdu(pdu);
-    }
+    /* A nop call with no return */
+    complete_pdu(s, pdu, 7);
 }
 
 typedef struct V9fsRemoveState {
Signature · 1 line
1.7.0.4.360.g11766c
#21 lore raw

PATCH 21/21 virtio-9p: Create a syntactic shortcut for the file-system pass-thru

In reply to Aneesh Kumar K.V

From: Gautham R Shenoy <[email protected]>

Currently the commandline to create a virtual-filesystem pass-through between the guest and the host is as follows:

#qemu -fsdev fstype,id=ID,path=path/to/share \
      -device virtio-9p-pci,fsdev=ID,mount_tag=tag \

This patch provides a syntactic short-cut to achieve the same as follows:
#qemu -virtfs fstype,path=path/to/share,mount_tag=tag

This will be internally expanded as:

#qemu -fsdev fstype,id=tag,path=path/to/share, \
      -device virtio-9p-pci,fsdev=tag,mount_tag=tag \
---
 qemu-config.c   |   22 +++++++++++++++++++++
 qemu-config.h   |    1 +
 qemu-options.hx |   34 +++++++++++++++++++++++++++++++++
 vl.c            |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 0 deletions(-)
qemu-config.c +22 -0
index 0fb5105..06a59eb 100644
@@ -169,6 +169,28 @@ QemuOptsList qemu_fsdev_opts = {
 };
 #endif
 
+#ifdef CONFIG_LINUX_VIRTFS
+QemuOptsList qemu_virtfs_opts = {
+    .name = "virtfs",
+    .implied_opt_name = "fstype",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_virtfs_opts.head),
+    .desc = {
+        {
+            .name = "fstype",
+            .type = QEMU_OPT_STRING,
+        }, {
+            .name = "path",
+            .type = QEMU_OPT_STRING,
+        }, {
+            .name = "mount_tag",
+            .type = QEMU_OPT_STRING,
+        },
+
+        { /*End of list */ }
+    },
+};
+#endif
+
 QemuOptsList qemu_device_opts = {
     .name = "device",
     .implied_opt_name = "driver",
qemu-config.h +1 -0
index d85bde7..546fc01 100644
@@ -5,6 +5,7 @@ extern QemuOptsList qemu_drive_opts;
 extern QemuOptsList qemu_chardev_opts;
 #ifdef CONFIG_LINUX_VIRTFS
 extern QemuOptsList qemu_fsdev_opts;
+extern QemuOptsList qemu_virtfs_opts;
 #endif
 extern QemuOptsList qemu_device_opts;
 extern QemuOptsList qemu_netdev_opts;
qemu-options.hx +34 -0
index e007df8..5da36c6 100644
@@ -500,6 +500,40 @@ Create a file-system-"device" for local-filesystem.
 ETEXI
 #endif
 
+#ifdef CONFIG_LINUX_VIRTFS
+DEFHEADING(Virtual File system pass-through options:)
+
+DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
+    "-virtfs local,path=path,mount_tag=tag\n")
+
+STEXI
+
+The general form of a Virtual File system pass-through option is:
+@table @option
+
+@item -virtfs @var{fstype} [,@var{options}]
+@findex -virtfs
+Fstype is one of:
+@option{local},
+The specific Fstype will determine the applicable options.
+
+Options to each backend are described below.
+
+@item -virtfs local ,path=@var{path} ,mount_tag=@var{mount_tag}
+
+Create a Virtual file-system-pass through for local-filesystem.
+
+@option{local} is only available on Linux.
+
+@option{path} specifies the path to be exported. @option{path} is required.
+
+@option{mount_tag} specifies the tag with which the exported file is mounted.
+@option{mount_tag} is required.
+
+@end table
+ETEXI
+#endif
+
 DEFHEADING()
 
 DEF("name", HAS_ARG, QEMU_OPTION_name,
vl.c +56 -0

62 lines not on this page · raw message

Signature · 1 line
1.7.0.4.360.g11766c