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:
Daniel P. Berrange 2010-06-02 15:05:09 +01:00
parent 458c99b121
commit a5c646a770
5 changed files with 132 additions and 0 deletions

View File

@ -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)) {

View File

@ -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);

View 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

View 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>

View File

@ -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 |