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

Daniel P. Berrange berrange at redhat.com
Thu Oct 14 11:08:11 UTC 2010


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.

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list