<optional>
<ref name="pm"/>
</optional>
+ <optional>
+ <ref name="idmap"/>
+ </optional>
<optional>
<ref name="devices"/>
</optional>
</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.
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);
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
}
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;
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++) {
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,
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);
virNumaTuneDef numatune;
virDomainResourceDefPtr resource;
+ virDomainIdMapDef idmap;
/* These 3 are based on virDomainLifeCycleAction enum flags */
int onReboot;