mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
LXC: Introduce New XML element for user namespace
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. We don't support the semi configuation, user has to configure uid and gid both. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
This commit is contained in:
parent
cbba3268eb
commit
6c30ea2c35
@ -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>
|
||||
|
@ -55,6 +55,9 @@
|
||||
<optional>
|
||||
<ref name="pm"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="idmap"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="devices"/>
|
||||
</optional>
|
||||
@ -463,6 +466,34 @@
|
||||
</optional>
|
||||
</interleave>
|
||||
</define>
|
||||
<define 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>
|
||||
</define>
|
||||
<!--
|
||||
Resources usage defines the amount of memory (maximum and possibly
|
||||
current usage) and number of virtual CPUs used by that domain.
|
||||
|
@ -1942,6 +1942,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);
|
||||
@ -10221,6 +10224,44 @@ 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 virDomainIdMapEntryPtr
|
||||
virDomainIdmapDefParseXML(xmlXPathContextPtr ctxt,
|
||||
const xmlNodePtr *node,
|
||||
size_t num)
|
||||
{
|
||||
size_t i;
|
||||
virDomainIdMapEntryPtr idmap = NULL;
|
||||
xmlNodePtr save_ctxt = ctxt->node;
|
||||
|
||||
if (VIR_ALLOC_N(idmap, num) < 0) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ctxt->node = node[i];
|
||||
if (virXPathUInt("string(./@start)", ctxt, &idmap[i].start) < 0 ||
|
||||
virXPathUInt("string(./@target)", ctxt, &idmap[i].target) < 0 ||
|
||||
virXPathUInt("string(./@count)", ctxt, &idmap[i].count) < 0) {
|
||||
VIR_FREE(idmap);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
ctxt->node = save_ctxt;
|
||||
return idmap;
|
||||
}
|
||||
|
||||
|
||||
/* Parse the XML definition for a vcpupin or emulatorpin.
|
||||
*
|
||||
* vcpupin has the form of
|
||||
@ -12049,6 +12090,38 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
/* analysis of the user namespace mapping */
|
||||
if ((n = virXPathNodeSet("./idmap/uid", ctxt, &nodes)) < 0)
|
||||
goto error;
|
||||
|
||||
if (n) {
|
||||
def->idmap.uidmap = virDomainIdmapDefParseXML(ctxt, nodes, n);
|
||||
if (!def->idmap.uidmap)
|
||||
goto error;
|
||||
|
||||
def->idmap.nuidmap = n;
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
if ((n = virXPathNodeSet("./idmap/gid", ctxt, &nodes)) < 0)
|
||||
goto error;
|
||||
|
||||
if (n) {
|
||||
def->idmap.gidmap = virDomainIdmapDefParseXML(ctxt, nodes, n);
|
||||
if (!def->idmap.gidmap)
|
||||
goto error;
|
||||
|
||||
def->idmap.ngidmap = n;
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
if ((def->idmap.uidmap && !def->idmap.gidmap) ||
|
||||
(!def->idmap.uidmap && def->idmap.gidmap)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("uid and gid should be mapped both"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* analysis of cpu handling */
|
||||
if ((node = virXPathNode("./cpu[1]", ctxt)) != NULL) {
|
||||
xmlNodePtr oldnode = ctxt->node;
|
||||
@ -16244,6 +16317,27 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||
|
||||
virBufferAddLit(buf, " </os>\n");
|
||||
|
||||
|
||||
if (def->idmap.uidmap) {
|
||||
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++) {
|
||||
|
@ -120,6 +120,12 @@ typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
|
||||
typedef struct _virDomainRNGDef virDomainRNGDef;
|
||||
typedef virDomainRNGDef *virDomainRNGDefPtr;
|
||||
|
||||
typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
|
||||
typedef virDomainIdMapEntry *virDomainIdMapEntryPtr;
|
||||
|
||||
typedef struct _virDomainIdMapDef virDomainIdMapDef;
|
||||
typedef virDomainIdMapDef *virDomainIdMapDefPtr;
|
||||
|
||||
/* Flags for the 'type' field in virDomainDeviceDef */
|
||||
typedef enum {
|
||||
VIR_DOMAIN_DEVICE_NONE = 0,
|
||||
@ -1845,6 +1851,21 @@ struct _virDomainRNGDef {
|
||||
virDomainDeviceInfo info;
|
||||
};
|
||||
|
||||
struct _virDomainIdMapEntry {
|
||||
unsigned int start;
|
||||
unsigned int target;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
struct _virDomainIdMapDef {
|
||||
size_t nuidmap;
|
||||
virDomainIdMapEntryPtr uidmap;
|
||||
|
||||
size_t ngidmap;
|
||||
virDomainIdMapEntryPtr gidmap;
|
||||
};
|
||||
|
||||
|
||||
void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
|
||||
int ndevices);
|
||||
|
||||
@ -1907,6 +1928,7 @@ struct _virDomainDef {
|
||||
|
||||
virNumaTuneDef numatune;
|
||||
virDomainResourceDefPtr resource;
|
||||
virDomainIdMapDef idmap;
|
||||
|
||||
/* These 3 are based on virDomainLifeCycleAction enum flags */
|
||||
int onReboot;
|
||||
|
Loading…
x
Reference in New Issue
Block a user