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@xxxxxxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list