[libvirt] [PATCH] qemu: patch to support security model for filesystem type

Harsh Bora harsh at linux.vnet.ibm.com
Fri Sep 24 15:51:23 UTC 2010


Mistake, shall repost *only* my changes on top of Dan's changes soon.

Regards,
Harsh

On 09/24/2010 08:21 PM, Venkateswararao Jujjuri (JV) wrote:
> On 9/24/2010 6:23 AM, Harsh Prateek Bora wrote:
>> 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.
>
> Harsh, looks like this patch contains both your changes, and Dan's changes.
> Please post a patch with 'only your changes' which applies on top of
> Dan's patch.
>
> Thanks,
> JV
>>
>> 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);
>>
>
>




More information about the libvir-list mailing list