virtio-9p: paravirtual file system passthrough
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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 _WIN32if (daemonize) {
Signature · 1 line
1.7.0.4.360.g11766c
PATCH 2/21 virtio-9p: Add a virtio 9p device to qemu
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 3/21 virtio-9p: pdu processing support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 4/21 virtio-9p: Add string manipulation support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 5/21 virtio-9p: Add minimal set of FileOperations
In reply to Aneesh Kumar K.VFrom: 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
@@ -27,6 +27,11 @@ typedef struct FsContexttypedef 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
PATCH 6/21 virtio-9p: Add fid and qid management support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 7/21 virtio-9p: Add stat and mode related helper functions.
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 8/21 virtio-9p: Add sg helper functions
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 9/21 virtio-9p: Add P9_TVERSION support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 10/21 virtio-9p: Add P9_TATTACH support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 11/21 virtio-9p: Add P9_TSTAT support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 12/21 virtio-9p: Add P9_TWALK support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 13/21 virtio-9p: Add P9_TOPEN support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -32,6 +32,8 @@ typedef struct FileOperationsint (*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
@@ -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
PATCH 14/21 virtio-9p: Add P9_TREAD support
In reply to Aneesh Kumar K.VFrom: 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
@@ -34,6 +34,12 @@ typedef struct FileOperationsint (*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
@@ -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
PATCH 15/21 virtio-9p: Add P9_TCLUNK support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 16/21 virtio-9p: Add P9_TWRITE support
In reply to Aneesh Kumar K.VFrom: 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
@@ -39,6 +39,7 @@ typedef struct FileOperationsstruct 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
@@ -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
PATCH 17/21 virtio-9p: Add P9_TCREATE support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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 FileOperationsssize_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
PATCH 18/21 virtio-9p: Add P9_TWSTAT support
In reply to Aneesh Kumar K.VFrom: 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
@@ -30,8 +30,10 @@ typedef struct FileOperationsint (*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 FileOperationsoff_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
PATCH 19/21 virtio-9p: Add P9_TREMOVE support.
In reply to Aneesh Kumar K.VFrom: 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
@@ -34,6 +34,7 @@ typedef struct FileOperationsint (*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
@@ -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
PATCH 20/21 virtio-9p: Add P9_TFLUSH support
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
PATCH 21/21 virtio-9p: Create a syntactic shortcut for the file-system pass-thru
In reply to Aneesh Kumar K.VFrom: 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
@@ -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
@@ -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
@@ -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