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(a)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 :|