From: Daniel P. Berrange Date: Wed, 2 Jun 2010 14:05:09 +0000 (+0100) Subject: Implement support for virtio plan9fs filesystem passthrough in QEMU X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a5c646a770769179a46f8157cfb7d526ac5efc81;p=libvirt.git Implement support for virtio plan9fs filesystem passthrough in QEMU Make use of the existing element to support plan9fs filesystem passthrough in the QEMU driver 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. --- diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 95b97842ba..16145b01f3 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1213,6 +1213,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... */ @@ -2012,6 +2014,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; @@ -2375,6 +2381,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++) { @@ -2765,6 +2780,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) { @@ -4381,6 +4454,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 2c9e608358..fbd89de22e 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 0000000000..995ffc009e --- /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 0000000000..9072ead424 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7b9df09b29..92d5b18c9d 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 |