[libvirt] [PATCH] Implement support for virtio plan9fs filesystem passthrough in QEMU (v2)

Rebased version of my original patch, changing to use 'passthrough' security model by default. Support for other models can be added in a follow up patch Make use of the existing <filesystem> element to support plan9fs filesystem passthrough in the QEMU driver <filesystem type='mount'> <source dir='/export/to/guest'/> <target dir='/import/from/host'/> </filesystem> NB, the target is not actually a directory, it is merely a arbitrary string tag that is exported to the guest as a hint for where to mount it. --- src/qemu/qemu_conf.c | 96 +++++++++++++++++++++++++ src/qemu/qemu_conf.h | 5 ++ tests/qemuxml2argvdata/qemuxml2argv-fs9p.args | 1 + tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml | 28 +++++++ tests/qemuxml2argvtest.c | 2 + 5 files changed, 132 insertions(+), 0 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fs9p.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 7a37c70..18a302a 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1212,6 +1212,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_TDF; if (strstr(help, ",menu=on")) flags |= QEMUD_CMD_FLAG_BOOT_MENU; + if (strstr(help, "-fsdev")) + flags |= QEMUD_CMD_FLAG_FSDEV; /* Keep disabled till we're actually ready to turn on netdev mode * The plan is todo it in 0.13.0 QEMU, but lets wait & see... */ @@ -2008,6 +2010,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, unsigned long long qemuCmdFlags) if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) return 0; + for (i = 0; i < def->nfss ; i++) { + if (virAsprintf(&def->fss[i]->info.alias, "fs%d", i) < 0) + goto no_memory; + } for (i = 0; i < def->nsounds ; i++) { if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0) goto no_memory; @@ -2371,6 +2377,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) goto error; } } + for (i = 0; i < def->nfss ; i++) { + if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + + /* Only support VirtIO-9p-pci so far. If that changes, + * we might need to skip devices here */ + if (qemuDomainPCIAddressSetNextAddr(addrs, &def->fss[i]->info) < 0) + goto error; + } /* Network interfaces */ for (i = 0; i < def->nnets ; i++) { @@ -2761,6 +2776,64 @@ error: } +char *qemuBuildFSStr(virDomainFSDefPtr fs, + unsigned long long qemuCmdFlags ATTRIBUTE_UNUSED) +{ + virBuffer opt = VIR_BUFFER_INITIALIZER; + + if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("can only passthrough directories")); + goto error; + } + + virBufferAddLit(&opt, "local,security_model=passthrough"); + virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); + virBufferVSprintf(&opt, ",path=%s", fs->src); + + if (virBufferError(&opt)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&opt); + +error: + virBufferFreeAndReset(&opt); + return NULL; +} + + +char * +qemuBuildFSDevStr(virDomainFSDefPtr fs) +{ + virBuffer opt = VIR_BUFFER_INITIALIZER; + + if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("can only passthrough directories")); + goto error; + } + + virBufferAddLit(&opt, "virtio-9p-pci"); + virBufferVSprintf(&opt, ",id=%s", fs->info.alias); + virBufferVSprintf(&opt, ",fsdev=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); + virBufferVSprintf(&opt, ",mount_tag=%s", fs->dst); + qemuBuildDeviceAddressStr(&opt, &fs->info); + + if (virBufferError(&opt)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&opt); + +error: + virBufferFreeAndReset(&opt); + return NULL; +} + + char * qemuBuildControllerDevStr(virDomainControllerDefPtr def) { @@ -4377,6 +4450,29 @@ int qemudBuildCommandLine(virConnectPtr conn, } } + if (qemuCmdFlags & QEMUD_CMD_FLAG_FSDEV) { + for (i = 0 ; i < def->nfss ; i++) { + char *optstr; + virDomainFSDefPtr fs = def->fss[i]; + + ADD_ARG_LIT("-fsdev"); + if (!(optstr = qemuBuildFSStr(fs, qemuCmdFlags))) + goto error; + ADD_ARG(optstr); + + ADD_ARG_LIT("-device"); + if (!(optstr = qemuBuildFSDevStr(fs))) + goto error; + ADD_ARG(optstr); + } + } else { + if (def->nfss) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("filesystem passthrough not supported by this QEMU")); + goto error; + } + } + if (!def->nnets) { /* If we have -device, then we set -nodefault already */ if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 2c9e608..fbd89de 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -93,6 +93,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_NODEFCONFIG = (1LL << 37), /* -nodefconfig */ QEMUD_CMD_FLAG_BOOT_MENU = (1LL << 38), /* -boot menu=on support */ QEMUD_CMD_FLAG_ENABLE_KQEMU = (1LL << 39), /* -enable-kqemu flag */ + QEMUD_CMD_FLAG_FSDEV = (1LL << 40), /* -fstype filesystem passthrough */ }; /* Main driver state */ @@ -188,6 +189,7 @@ struct _qemuDomainCmdlineDef { # define QEMU_DRIVE_HOST_PREFIX "drive-" # define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial" +# define QEMU_FSDEV_HOST_PREFIX "fsdev-" # define qemuReportError(code, ...) \ virReportErrorHelper(NULL, VIR_FROM_QEMU, code, __FILE__, \ @@ -248,9 +250,12 @@ char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk, char *qemuBuildDriveStr(virDomainDiskDefPtr disk, int bootable, unsigned long long qemuCmdFlags); +char *qemuBuildFSStr(virDomainFSDefPtr fs, + unsigned long long qemuCmdFlags); /* Current, best practice */ char * qemuBuildDriveDevStr(virDomainDiskDefPtr disk); +char * qemuBuildFSDevStr(virDomainFSDefPtr fs); /* Current, best practice */ char * qemuBuildControllerDevStr(virDomainControllerDefPtr def); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args new file mode 100644 index 0000000..995ffc0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/to/guest -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=/import/from/host,bus=pci.0,addr=0x2 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml new file mode 100644 index 0000000..9072ead --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml @@ -0,0 +1,28 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + <filesystem type='mount'> + <source dir='/export/to/guest'/> + <target dir='/import/from/host'/> + </filesystem> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7b9df09..92d5b18 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -368,6 +368,8 @@ mymain(int argc, char **argv) DO_TEST("sound", 0); DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG); + DO_TEST("fs9p", QEMUD_CMD_FLAG_DEVICE | + QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_FSDEV); DO_TEST("hostdev-usb-address", 0); DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE | -- 1.7.2.3

On Wed, Sep 22, 2010 at 06:04:48PM +0100, Daniel P. Berrange wrote:
Rebased version of my original patch, changing to use 'passthrough' security model by default. Support for other models can be added in a follow up patch
Make use of the existing <filesystem> element to support plan9fs filesystem passthrough in the QEMU driver
<filesystem type='mount'> <source dir='/export/to/guest'/> <target dir='/import/from/host'/> </filesystem>
NB, the target is not actually a directory, it is merely a arbitrary string tag that is exported to the guest as a hint for where to mount it.
ACK, looks fine to me (I had to chase a bit to find out where alias where freed). The patch may need a small rebase when applied due to option 40 being already in use too if the other patch is applied first. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Wed, Sep 22, 2010 at 06:04:48PM +0100, Daniel P. Berrange wrote:
Rebased version of my original patch, changing to use 'passthrough' security model by default. Support for other models can be added in a follow up patch
Make use of the existing <filesystem> element to support plan9fs filesystem passthrough in the QEMU driver
<filesystem type='mount'> <source dir='/export/to/guest'/> <target dir='/import/from/host'/> </filesystem>
NB, the target is not actually a directory, it is merely a arbitrary string tag that is exported to the guest as a hint for where to mount it.
I have committed this patch now. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (2)
-
Daniel P. Berrange
-
Daniel Veillard