This patch introduces a new attribute security_model to <filesystem> tag, which can have any of the following three values: passthrough, mapped or none. This patch is based on Daniel's patch to support 9pfs qemu commandline options. Usage: <filesystem type='mount' security_model='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem> --- docs/schemas/domain.rng | 7 +++ src/conf/domain_conf.c | 30 +++++++++++++- src/conf/domain_conf.h | 10 +++++ src/qemu/qemu_conf.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_conf.h | 5 ++ 5 files changed, 153 insertions(+), 2 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index ccb8cf3..43a292d 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -761,6 +761,13 @@ </choice> <optional> <ref name="address"/> + <attribute name="security_model"> + <choice> + <value>passthrough</value> + <value>mapped</value> + <value>none</value> + </choice> + </attribute> </optional> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e05d5d7..a9881d1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -161,6 +161,12 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "file", "template") +VIR_ENUM_IMPL(virDomainFSSecurityModel, VIR_DOMAIN_FS_SECURITY_LAST, + "passthrough", + "mapped", + "none") + + VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, "user", "ethernet", @@ -1847,6 +1853,7 @@ virDomainFSDefParseXML(xmlNodePtr node, char *type = NULL; char *source = NULL; char *target = NULL; + char *security_model; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -1864,6 +1871,17 @@ virDomainFSDefParseXML(xmlNodePtr node, def->type = VIR_DOMAIN_FS_TYPE_MOUNT; } + security_model = virXMLPropString(node, "security_model"); + if (security_model) { + if ((def->security_model = virDomainFSSecurityModelTypeFromString(security_model)) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown security model '%s'"), security_model); + goto error; + } + } else { + def->security_model = VIR_DOMAIN_FS_SECURITY_PASSTHROUGH; + } + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { @@ -5602,6 +5620,7 @@ virDomainFSDefFormat(virBufferPtr buf, int flags) { const char *type = virDomainFSTypeToString(def->type); + const char *sec_model = virDomainFSSecurityModelTypeToString(def->security_model); if (!type) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf, return -1; } + if (!sec_model) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected security model %d"), def->security_model); + return -1; + } + + virBufferVSprintf(buf, - " <filesystem type='%s'>\n", - type); + " <filesystem type='%s' security_model='%s'>\n", + type, sec_model); if (def->src) { switch (def->type) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7195c04..6adf027 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -236,10 +236,20 @@ enum virDomainFSType { VIR_DOMAIN_FS_TYPE_LAST }; +/* Filesystem mount security model */ +enum virDomainFSSecurityModel { + VIR_DOMAIN_FS_SECURITY_PASSTHROUGH, + VIR_DOMAIN_FS_SECURITY_MAPPED, + VIR_DOMAIN_FS_SECURITY_NONE, + + VIR_DOMAIN_FS_SECURITY_LAST +}; + typedef struct _virDomainFSDef virDomainFSDef; typedef virDomainFSDef *virDomainFSDefPtr; struct _virDomainFSDef { int type; + int security_model; char *src; char *dst; unsigned int readonly : 1; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 7a37c70..a637dee 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,11 @@ 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 +2378,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 +2777,70 @@ 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", + _("only supports mount filesystem type")); + goto error; + } + + virBufferAddLit(&opt, "local"); + if (fs->security_model == VIR_DOMAIN_FS_SECURITY_PASSTHROUGH) + virBufferAddLit(&opt, ",security_model=passthrough"); + else if (fs->security_model == VIR_DOMAIN_FS_SECURITY_MAPPED) + virBufferAddLit(&opt, ",security_model=mapped"); + else if (fs->security_model == VIR_DOMAIN_FS_SECURITY_NONE) + virBufferAddLit(&opt, ",security_model=none"); + 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 +4457,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..7005466 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); -- 1.7.1.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list