mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Implement support for virtio plan9fs filesystem passthrough in QEMU
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.
This commit is contained in:
parent
458c99b121
commit
a5c646a770
@ -1213,6 +1213,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
|
|||||||
flags |= QEMUD_CMD_FLAG_TDF;
|
flags |= QEMUD_CMD_FLAG_TDF;
|
||||||
if (strstr(help, ",menu=on"))
|
if (strstr(help, ",menu=on"))
|
||||||
flags |= QEMUD_CMD_FLAG_BOOT_MENU;
|
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
|
/* 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... */
|
* 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))
|
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))
|
||||||
return 0;
|
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++) {
|
for (i = 0; i < def->nsounds ; i++) {
|
||||||
if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0)
|
if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
@ -2375,6 +2381,15 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
|||||||
goto error;
|
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 */
|
/* Network interfaces */
|
||||||
for (i = 0; i < def->nnets ; i++) {
|
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 *
|
char *
|
||||||
qemuBuildControllerDevStr(virDomainControllerDefPtr def)
|
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 (!def->nnets) {
|
||||||
/* If we have -device, then we set -nodefault already */
|
/* If we have -device, then we set -nodefault already */
|
||||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
|
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
|
||||||
|
@ -93,6 +93,7 @@ enum qemud_cmd_flags {
|
|||||||
QEMUD_CMD_FLAG_NODEFCONFIG = (1LL << 37), /* -nodefconfig */
|
QEMUD_CMD_FLAG_NODEFCONFIG = (1LL << 37), /* -nodefconfig */
|
||||||
QEMUD_CMD_FLAG_BOOT_MENU = (1LL << 38), /* -boot menu=on support */
|
QEMUD_CMD_FLAG_BOOT_MENU = (1LL << 38), /* -boot menu=on support */
|
||||||
QEMUD_CMD_FLAG_ENABLE_KQEMU = (1LL << 39), /* -enable-kqemu flag */
|
QEMUD_CMD_FLAG_ENABLE_KQEMU = (1LL << 39), /* -enable-kqemu flag */
|
||||||
|
QEMUD_CMD_FLAG_FSDEV = (1LL << 40), /* -fstype filesystem passthrough */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Main driver state */
|
/* Main driver state */
|
||||||
@ -188,6 +189,7 @@ struct _qemuDomainCmdlineDef {
|
|||||||
|
|
||||||
# define QEMU_DRIVE_HOST_PREFIX "drive-"
|
# define QEMU_DRIVE_HOST_PREFIX "drive-"
|
||||||
# define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial"
|
# define QEMU_VIRTIO_SERIAL_PREFIX "virtio-serial"
|
||||||
|
# define QEMU_FSDEV_HOST_PREFIX "fsdev-"
|
||||||
|
|
||||||
# define qemuReportError(code, ...) \
|
# define qemuReportError(code, ...) \
|
||||||
virReportErrorHelper(NULL, VIR_FROM_QEMU, code, __FILE__, \
|
virReportErrorHelper(NULL, VIR_FROM_QEMU, code, __FILE__, \
|
||||||
@ -248,9 +250,12 @@ char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
|
|||||||
char *qemuBuildDriveStr(virDomainDiskDefPtr disk,
|
char *qemuBuildDriveStr(virDomainDiskDefPtr disk,
|
||||||
int bootable,
|
int bootable,
|
||||||
unsigned long long qemuCmdFlags);
|
unsigned long long qemuCmdFlags);
|
||||||
|
char *qemuBuildFSStr(virDomainFSDefPtr fs,
|
||||||
|
unsigned long long qemuCmdFlags);
|
||||||
|
|
||||||
/* Current, best practice */
|
/* Current, best practice */
|
||||||
char * qemuBuildDriveDevStr(virDomainDiskDefPtr disk);
|
char * qemuBuildDriveDevStr(virDomainDiskDefPtr disk);
|
||||||
|
char * qemuBuildFSDevStr(virDomainFSDefPtr fs);
|
||||||
/* Current, best practice */
|
/* Current, best practice */
|
||||||
char * qemuBuildControllerDevStr(virDomainControllerDefPtr def);
|
char * qemuBuildControllerDevStr(virDomainControllerDefPtr def);
|
||||||
|
|
||||||
|
1
tests/qemuxml2argvdata/qemuxml2argv-fs9p.args
Normal file
1
tests/qemuxml2argvdata/qemuxml2argv-fs9p.args
Normal file
@ -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
|
28
tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml
Normal file
28
tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml
Normal file
@ -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>
|
@ -368,6 +368,8 @@ mymain(int argc, char **argv)
|
|||||||
DO_TEST("sound", 0);
|
DO_TEST("sound", 0);
|
||||||
DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE |
|
DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE |
|
||||||
QEMUD_CMD_FLAG_NODEFCONFIG);
|
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", 0);
|
||||||
DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE |
|
DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE |
|
||||||
|
Loading…
Reference in New Issue
Block a user