[libvirt] [PATCH v2 1/8] LXC: Introduce New XML element for user namespace

Daniel P. Berrange berrange at redhat.com
Fri May 10 10:24:27 UTC 2013


On Fri, May 10, 2013 at 05:58:10PM +0800, Gao feng wrote:
> This patch introduces new element <idmap> for
> user namespace. for example
> <idmap>
>     <uid start='0' target='1000' count='10'/>
>     <gid start='0' target='1000' count='10'/>
> </idmap>
> 
> this new element is used for setting proc files
> /proc/<pid>/{uid_map,gid_map}.
> 
> This patch also supports multiple uid/gid elements
> setting in XML configuration.
> 
> Signed-off-by: Gao feng <gaofeng at cn.fujitsu.com>
> ---
>  docs/formatdomain.html.in     | 23 +++++++++++
>  docs/schemas/domaincommon.rng | 28 ++++++++++++++
>  src/conf/domain_conf.c        | 88 +++++++++++++++++++++++++++++++++++++++++++
>  src/conf/domain_conf.h        | 19 ++++++++++
>  4 files changed, 158 insertions(+)
> 
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 572d7ee..7a5c1ed 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -285,6 +285,29 @@
>      </pre>
>  
>  
> +    <p>
> +      If you want to enable user namespace,set the <code>idmap</code> element.
> +      the <code>uid</code> and <code>gid</code> elements have three attributes:
> +    </p>
> +
> +    <dl>
> +      <dt><code>start</code></dt>
> +      <dd>First user id in container.</dd>
> +      <dt><code>target</code></dt>
> +      <dd>The first user id in container will be mapped to this target user
> +          id in host.</dd>
> +      <dt><code>count</code></dt>
> +      <dd>How many users in container being allowed to map to host's user.</dd>
> +    </dl>
> +
> +    <pre>
> +  <idmap>
> +    <uid start='0' target='1000' count='10'/>
> +    <gid start='0' target='1000' count='10'/>
> +  </idmap>
> +    </pre>
> +
> +
>      <h3><a name="elementsSysinfo">SMBIOS System Information</a></h3>
>  
>      <p>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 10596dc..dffb103 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -465,6 +465,34 @@
>        </optional>
>      </interleave>
>    </define>
> +  <define name="map">
> +    <optional>
> +      <element name="idmap">

<zeroOrMore>

> +        <element name="uid">
> +          <attribute name="start">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +          <attribute name="target">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +          <attribute name="count">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +        </element>

</zeroOrMore>
<zeroOrMore>

> +        <element name="gid">
> +          <attribute name="start">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +          <attribute name="target">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +          <attribute name="count">
> +            <ref name="unsignedInt"/>
> +          </attribute>
> +        </element>

</zeroOrMore>

> +      </element>
> +    </optional>
> +  </define>

You don't seem to have used this new 'map' define anywhere
in the schema.


> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index b7e253e..46be458 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1944,6 +1944,9 @@ void virDomainDefFree(virDomainDefPtr def)
>  
>      virDomainTPMDefFree(def->tpm);
>  
> +    VIR_FREE(def->idmap.uidmap);
> +    VIR_FREE(def->idmap.gidmap);
> +
>      VIR_FREE(def->os.type);
>      VIR_FREE(def->os.machine);
>      VIR_FREE(def->os.init);
> @@ -9798,6 +9801,40 @@ cleanup:
>      return ret;
>  }
>  
> +
> +/* Parse the XML definition for user namespace id map.
> + *
> + * idmap has the form of
> + *
> + *   <uid start='0' target='1000' count='10'/>
> + *   <gid start='0' target='1000' count='10'/>
> + */
> +static struct idmap *
> +virDomainIdmapDefParseXML(const xmlNodePtr *node,
> +                          xmlXPathContextPtr ctxt,
> +                          ssize_t num)
> +{
> +    int i;
> +    struct idmap *idmap = NULL;
> +    xmlNodePtr save_ctxt = ctxt->node;
> +
> +    if (VIR_ALLOC_N(idmap, num) < 0) {
> +        virReportOOMError();
> +        goto error;
> +    }
> +
> +    for (i = 0; i < num ; i++) {
> +        ctxt->node = node[i];
> +        virXPathUInt("string(./@start)", ctxt, &idmap[i].start);
> +        virXPathUInt("string(./@target)", ctxt, &idmap[i].target);
> +        virXPathUInt("string(./@count)", ctxt, &idmap[i].count);
> +    }
> + error:
> +    ctxt->node = save_ctxt;
> +    return idmap;
> +}
> +
> +
>  /* Parse the XML definition for a vcpupin or emulatorpin.
>   *
>   * vcpupin has the form of
> @@ -11544,6 +11581,36 @@ virDomainDefParseXML(xmlDocPtr xml,
>      }
>      VIR_FREE(nodes);
>  
> +    /* analysis of the user namespace mapping */
> +    def->idmap.nuidmap = 0;
> +    def->idmap.uidmap = NULL;
> +    if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
> +        goto error;
> +
> +    if (n) {
> +        def->idmap.uidmap = virDomainIdmapDefParseXML(nodes, ctxt, n);
> +        if (!def->idmap.uidmap)
> +            goto error;
> +
> +        def->idmap.nuidmap = n;
> +    }
> +    VIR_FREE(nodes);
> +
> +    def->idmap.ngidmap = 0;
> +    def->idmap.gidmap = NULL;
> +
> +    if  ((n = virXPathNodeSet("./idmap/gid", ctxt, &nodes)) < 0)
> +        goto error;
> +
> +    if (n) {
> +        def->idmap.gidmap =  virDomainIdmapDefParseXML(nodes, ctxt, n);
> +        if (!def->idmap.gidmap)
> +            goto error;
> +
> +        def->idmap.ngidmap = n;
> +    }
> +    VIR_FREE(nodes);
> +
>      /* analysis of cpu handling */
>      if ((node = virXPathNode("./cpu[1]", ctxt)) != NULL) {
>          xmlNodePtr oldnode = ctxt->node;
> @@ -15696,6 +15763,27 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>  
>      virBufferAddLit(buf, "  </os>\n");
>  
> +
> +    if (def->idmap.uidmap || def->idmap.gidmap) {
> +        virBufferAddLit(buf, "  <idmap>\n");
> +        for (i = 0 ; i < def->idmap.nuidmap; i++) {
> +            virBufferAsprintf(buf,
> +                              "    <uid start='%u' target='%u' count='%u'/>\n",
> +                              def->idmap.uidmap[i].start,
> +                              def->idmap.uidmap[i].target,
> +                              def->idmap.uidmap[i].count);
> +        }
> +        for (i = 0 ; i < def->idmap.ngidmap; i++) {
> +            virBufferAsprintf(buf,
> +                              "    <gid start='%u' target='%u' count='%u'/>\n",
> +                              def->idmap.gidmap[i].start,
> +                              def->idmap.gidmap[i].target,
> +                              def->idmap.gidmap[i].count);
> +        }
> +        virBufferAddLit(buf, "  </idmap>\n");
> +    }
> +
> +
>      if (def->features) {
>          virBufferAddLit(buf, "  <features>\n");
>          for (i = 0 ; i < VIR_DOMAIN_FEATURE_LAST ; i++) {
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 21f7ce2..b21d567 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -120,6 +120,9 @@ typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
>  typedef struct _virDomainRNGDef virDomainRNGDef;
>  typedef virDomainRNGDef *virDomainRNGDefPtr;
>  
> +typedef struct _virDomainIdmapDef virDomainIdmapDef;
> +typedef virDomainIdmapDef *virDomainIdmapDefPtr;

Missing

   typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
   typedef virDomainIdMapEntry *virDomainIdMapEntryPtr;


> +
>  /* Flags for the 'type' field in virDomainDeviceDef */
>  typedef enum {
>      VIR_DOMAIN_DEVICE_NONE = 0,
> @@ -1803,6 +1806,21 @@ struct _virDomainRNGDef {
>      virDomainDeviceInfo info;
>  };
>  
> +struct idmap {

s/idmap/_virDomainIdMapEntry/

> +    unsigned int start;
> +    unsigned int target;
> +    unsigned int count;
> +};
> +
> +struct _virDomainIdmapDef {

s/_virDomainIdmapDef/_virDomainIdMapDef/

> +    size_t nuidmap;
> +    struct idmap *uidmap;
> +
> +    size_t ngidmap;
> +    struct idmap *gidmap;
> +};


Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list