[libvirt] [PATCH] Added new attribute accessmode to filesystem element

Harsh Bora harsh at linux.vnet.ibm.com
Thu Oct 14 11:15:23 UTC 2010


On 10/14/2010 04:38 PM, Daniel P. Berrange wrote:
> On Thu, Oct 14, 2010 at 04:24:45PM +0530, Harsh Prateek Bora wrote:
>> This patch introduces new attribute to filesystem element
>> to support customizable access mode for mount type.
>> Valid accessmode are: passthrough, mapped and squash.
>>
>> Usage:
>> 	<filesystem type='mount' accessmode='passthrough'>
>> 	<source dir='/export/to/guest'/>
>> 	<target dir='mount_tag'/>
>> 	</filesystem>
>>
>> Here is the detailed explanation on these access modes:
>>
>> Access mode: mapped
>> --------------------
>>
>> Fileserver intercepts and maps all the file object create requests.
>> Files on the fileserver will be created with Fileserver's user credentials
>> and the
>> client-user's credentials are stored in extended attributes.
>> During getattr() server extracts the client-user's credentials from extended
>> attributes and sends to the client.
>>
>> This adds a great deal of security in the cloud environments where the
>> guest's(client) user space is kept completely isolated from host's user
>> space.
>>
>>
>> Access mode : passthrough
>> --------------------------
>>
>> In this security model, Fileserver passes down all requests to the
>> underlying filesystem. File system objects on the fileserver will be created
>> with client-user's credentials. This is done by setting setuid()/setgid()
>> during creation or chmod/chown after file creation. At the end of create
>> protocol
>> request, files on the fileserver will be owned by cleint-user's uid/gid.
>> This model mimic's current NFSv3 level of security.
>>
>> Access mode: squash
>> --------------------
>>
>> In 'squash' mode, the (filesystem) server attempts to preserve user/group
>> ownership from guest, however:
>> - If the server is running as root this mode is equivalent to passthrough.
>> - If the server is running as non-root, all files just have uid/gid matching
>>    the server process.
>>
>>
>> Note: This patch is based on Daniel's patch to support 9pfs.
>> It shall be applied after applying Daniel's patch to support 9pfs.
>>
>> Signed-off-by: Harsh Prateek Bora<harsh at linux.vnet.ibm.com>
>> ---
>>   docs/schemas/domain.rng |    7 +++++++
>>   src/conf/domain_conf.c  |   30 ++++++++++++++++++++++++++++--
>>   src/conf/domain_conf.h  |   11 +++++++++++
>>   src/qemu/qemu_conf.c    |   10 ++++++++--
>>   4 files changed, 54 insertions(+), 4 deletions(-)
>>
>> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
>> index ccb8cf3..c0e5149 100644
>> --- a/docs/schemas/domain.rng
>> +++ b/docs/schemas/domain.rng
>> @@ -761,6 +761,13 @@
>>         </choice>
>>         <optional>
>>           <ref name="address"/>
>> +<attribute name="accessmode">
>> +<choice>
>> +<value>passthrough</value>
>> +<value>mapped</value>
>> +<value>squash</value>
>> +</choice>
>> +</attribute>
>>         </optional>
>>       </element>
>>     </define>
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index e05d5d7..68c8441 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(virDomainFSAccessMode, VIR_DOMAIN_FS_SECURITY_LAST,
>> +              "passthrough",
>> +              "mapped",
>> +              "squash")
>> +
>> +
>>   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 *accessmode = NULL;
>>
>>       if (VIR_ALLOC(def)<  0) {
>>           virReportOOMError();
>> @@ -1864,6 +1871,17 @@ virDomainFSDefParseXML(xmlNodePtr node,
>>           def->type = VIR_DOMAIN_FS_TYPE_MOUNT;
>>       }
>>
>> +    accessmode = virXMLPropString(node, "accessmode");
>> +    if (accessmode) {
>> +        if ((def->accessmode = virDomainFSAccessModeTypeFromString(accessmode))<  0) {
>> +            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
>> +                                 _("unknown accessmode '%s'"), accessmode);
>> +            goto error;
>> +        }
>> +    } else {
>> +        def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_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 *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
>>
>>       if (!type) {
>>           virDomainReportError(VIR_ERR_INTERNAL_ERROR,
>> @@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf,
>>           return -1;
>>       }
>>
>> +   if (!accessmode) {
>> +        virDomainReportError(VIR_ERR_INTERNAL_ERROR,
>> +                             _("unexpected accessmode %d"), def->accessmode);
>> +        return -1;
>> +    }
>> +
>> +
>>       virBufferVSprintf(buf,
>> -                      "<filesystem type='%s'>\n",
>> -                      type);
>> +                      "<filesystem type='%s' accessmode='%s'>\n",
>> +                      type, accessmode);
>>
>>       if (def->src) {
>>           switch (def->type) {
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index 7195c04..0668ce5 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 access mode  */
>> +enum virDomainFSAccessMode {
>> +    VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH,
>> +    VIR_DOMAIN_FS_ACCESSMODE_MAPPED,
>> +    VIR_DOMAIN_FS_ACCESSMODE_SQUASH,
>> +
>> +    VIR_DOMAIN_FS_ACCESSMODE_LAST
>> +};
>> +
>>   typedef struct _virDomainFSDef virDomainFSDef;
>>   typedef virDomainFSDef *virDomainFSDefPtr;
>>   struct _virDomainFSDef {
>>       int type;
>> +    int accessmode;
>>       char *src;
>>       char *dst;
>>       unsigned int readonly : 1;
>> @@ -1167,6 +1177,7 @@ VIR_ENUM_DECL(virDomainDiskErrorPolicy)
>>   VIR_ENUM_DECL(virDomainController)
>>   VIR_ENUM_DECL(virDomainControllerModel)
>>   VIR_ENUM_DECL(virDomainFS)
>> +VIR_ENUM_DECL(virDomainFSAccessMode)
>>   VIR_ENUM_DECL(virDomainNet)
>>   VIR_ENUM_DECL(virDomainChrDevice)
>>   VIR_ENUM_DECL(virDomainChrChannelTarget)
>> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
>> index 18a302a..0961d8a 100644
>> --- a/src/qemu/qemu_conf.c
>> +++ b/src/qemu/qemu_conf.c
>> @@ -2783,11 +2783,17 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
>>
>>       if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
>>           qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
>> -                        _("can only passthrough directories"));
>> +                        _("only supports mount filesystem type"));
>>           goto error;
>>       }
>>
>> -    virBufferAddLit(&opt, "local,security_model=passthrough");
>> +    virBufferAddLit(&opt, "local");
>> +    if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
>> +        virBufferAddLit(&opt, ",security_model=none");
>> +    } else {
>> +        virBufferAddLit(&opt, ",security_model=%s",
>> +                        virDomainFSAccessModeTypeToString(fs->accessmode));
>> +    }
>>       virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
>>       virBufferVSprintf(&opt, ",path=%s", fs->src);
>
>
> ACK, this gets my vote now.
>
Thanks Daniel, but extremely sorry that v1 has few errors which i missed 
in hurry, just sent v2 (tested).

Regards,
Harsh
> Daniel




More information about the libvir-list mailing list