---
src/conf/capabilities.c | 17 ++-
src/conf/capabilities.h | 6 +-
src/conf/domain_audit.c | 14 ++-
src/conf/domain_conf.c | 310 +++++++++++++++++++++++++++++++++++------------
src/conf/domain_conf.h | 18 +++-
5 files changed, 272 insertions(+), 93 deletions(-)
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 542bf03..7e786c5 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -181,8 +181,13 @@ virCapabilitiesFree(virCapsPtr caps) {
VIR_FREE(caps->host.migrateTrans);
VIR_FREE(caps->host.arch);
- VIR_FREE(caps->host.secModel.model);
- VIR_FREE(caps->host.secModel.doi);
+
+ for (i = 0; i < caps->host.nsecModels; i++) {
+ VIR_FREE(caps->host.secModels[i].model);
+ VIR_FREE(caps->host.secModels[i].doi);
+ }
+ VIR_FREE(caps->host.secModels);
+
virCPUDefFree(caps->host.cpu);
VIR_FREE(caps);
@@ -767,10 +772,12 @@ virCapabilitiesFormatXML(virCapsPtr caps)
virBufferAddLit(&xml, " </topology>\n");
}
- if (caps->host.secModel.model) {
+ for (i = 0; i < caps->host.nsecModels; i++) {
virBufferAddLit(&xml, " <secmodel>\n");
- virBufferAsprintf(&xml, " <model>%s</model>\n",
caps->host.secModel.model);
- virBufferAsprintf(&xml, " <doi>%s</doi>\n",
caps->host.secModel.doi);
+ virBufferAsprintf(&xml, " <model>%s</model>\n",
+ caps->host.secModels[i].model);
+ virBufferAsprintf(&xml, " <doi>%s</doi>\n",
+ caps->host.secModels[i].doi);
virBufferAddLit(&xml, " </secmodel>\n");
}
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 421030d..9a0092d 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -93,6 +93,7 @@ struct _virCapsHostNUMACell {
};
typedef struct _virCapsHostSecModel virCapsHostSecModel;
+typedef virCapsHostSecModel *virCapsHostSecModelPtr;
struct _virCapsHostSecModel {
char *model;
char *doi;
@@ -116,7 +117,10 @@ struct _virCapsHost {
size_t nnumaCell;
size_t nnumaCell_max;
virCapsHostNUMACellPtr *numaCell;
- virCapsHostSecModel secModel;
+
+ size_t nsecModels;
+ virCapsHostSecModelPtr secModels;
+
virCPUDefPtr cpu;
unsigned char host_uuid[VIR_UUID_BUFLEN];
};
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 653657b..ac296d5 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -619,6 +619,7 @@ virDomainAuditSecurityLabel(virDomainObjPtr vm, bool success)
char uuidstr[VIR_UUID_STRING_BUFLEN];
char *vmname;
const char *virt;
+ int i;
virUUIDFormat(vm->def->uuid, uuidstr);
if (!(vmname = virAuditEncode("vm", vm->def->name))) {
@@ -631,11 +632,14 @@ virDomainAuditSecurityLabel(virDomainObjPtr vm, bool success)
virt = "?";
}
- VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_ID, success,
- "virt=%s %s uuid=%s vm-ctx=%s img-ctx=%s",
- virt, vmname, uuidstr,
- VIR_AUDIT_STR(vm->def->seclabel.label),
- VIR_AUDIT_STR(vm->def->seclabel.imagelabel));
+ for (i = 0; i < vm->def->nseclabels; i++) {
+ VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_ID, success,
+ "virt=%s %s uuid=%s vm-ctx=%s img-ctx=%s model=%s",
+ virt, vmname, uuidstr,
+ VIR_AUDIT_STR(vm->def->seclabels[i]->label),
+ VIR_AUDIT_STR(vm->def->seclabels[i]->imagelabel),
+ VIR_AUDIT_STR(vm->def->seclabels[i]->model));
+ }
VIR_FREE(vmname);
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9def71d..91ffb6f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -852,12 +852,13 @@ virDomainGraphicsListenDefClear(virDomainGraphicsListenDefPtr def)
}
static void
-virSecurityLabelDefClear(virSecurityLabelDefPtr def)
+virSecurityLabelDefFree(virSecurityLabelDefPtr def)
{
VIR_FREE(def->model);
VIR_FREE(def->label);
VIR_FREE(def->imagelabel);
VIR_FREE(def->baselabel);
+ VIR_FREE(def);
}
@@ -866,6 +867,7 @@ virSecurityDeviceLabelDefFree(virSecurityDeviceLabelDefPtr def)
{
if (!def)
return;
+ VIR_FREE(def->model);
VIR_FREE(def->label);
VIR_FREE(def);
}
@@ -951,7 +953,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
virStorageEncryptionFree(def->encryption);
virDomainDeviceInfoClear(&def->info);
- virSecurityDeviceLabelDefFree(def->seclabel);
+ for (i = 0; i < def->nseclabels; i++)
+ virSecurityDeviceLabelDefFree(def->seclabels[i]);
+ VIR_FREE(def->seclabels);
for (i = 0 ; i < def->nhosts ; i++)
virDomainDiskHostDefFree(&def->hosts[i]);
@@ -1617,7 +1621,9 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainMemballoonDefFree(def->memballoon);
- virSecurityLabelDefClear(&def->seclabel);
+ for (i = 0; i < def->nseclabels; i++)
+ virSecurityLabelDefFree(def->seclabels[i]);
+ VIR_FREE(def->seclabels);
virCPUDefFree(def->cpu);
@@ -3071,10 +3077,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
{
char *p;
- if (virXPathNode("./seclabel", ctxt) == NULL)
- return 0;
-
- p = virXPathStringLimit("string(./seclabel/@type)",
+ p = virXPathStringLimit("string(./@type)",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p == NULL) {
def->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
@@ -3088,7 +3091,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
}
}
- p = virXPathStringLimit("string(./seclabel/@relabel)",
+ p = virXPathStringLimit("string(./@relabel)",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p != NULL) {
if (STREQ(p, "yes")) {
@@ -3105,13 +3108,15 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
def->norelabel) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("dynamic label type must use
resource relabeling"));
+ "%s", _("dynamic label type must use
"
+ "resource relabeling"));
goto error;
}
if (def->type == VIR_DOMAIN_SECLABEL_NONE &&
!def->norelabel) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("resource relabeling is not
compatible with 'none' label type"));
+ "%s", _("resource relabeling is not
"
+ "compatible with 'none' label
type"));
goto error;
}
} else {
@@ -3128,7 +3133,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
(!(flags & VIR_DOMAIN_XML_INACTIVE) &&
def->type != VIR_DOMAIN_SECLABEL_NONE)) {
- p = virXPathStringLimit("string(./seclabel/label[1])",
+ p = virXPathStringLimit("string(./label[1])",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p == NULL) {
virDomainReportError(VIR_ERR_XML_ERROR,
@@ -3143,7 +3148,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
if (!def->norelabel &&
(!(flags & VIR_DOMAIN_XML_INACTIVE) &&
def->type != VIR_DOMAIN_SECLABEL_NONE)) {
- p = virXPathStringLimit("string(./seclabel/imagelabel[1])",
+ p = virXPathStringLimit("string(./imagelabel[1])",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p == NULL) {
virDomainReportError(VIR_ERR_XML_ERROR,
@@ -3155,93 +3160,166 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
/* Only parse baselabel for dynamic label type */
if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
- p = virXPathStringLimit("string(./seclabel/baselabel[1])",
+ p = virXPathStringLimit("string(./baselabel[1])",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
def->baselabel = p;
}
- /* Only parse model, if static labelling, or a base
- * label is set, or doing active XML
- */
- if (def->type == VIR_DOMAIN_SECLABEL_STATIC ||
- def->baselabel ||
- (!(flags & VIR_DOMAIN_XML_INACTIVE) &&
- def->type != VIR_DOMAIN_SECLABEL_NONE)) {
- p = virXPathStringLimit("string(./seclabel/@model)",
- VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
- if (p == NULL) {
- virDomainReportError(VIR_ERR_XML_ERROR,
- "%s", _("missing security model"));
- goto error;
- }
- def->model = p;
+ /* TODO: check */
+ /* Always parse model */
+ p = virXPathStringLimit("string(./@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ if (p == NULL) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ "%s", _("missing security model"));
+ goto error;
}
+ def->model = p;
return 0;
error:
- virSecurityLabelDefClear(def);
return -1;
}
-
static int
-virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def,
- virSecurityLabelDefPtr vmDef,
- xmlXPathContextPtr ctxt)
+virSecurityLabelDefsParseXML(virDomainDefPtr def,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
{
- char *p;
+ int i, n;
+ xmlNodePtr *list, saved_node;
- *def = NULL;
+ /* Check args and save context */
+ if (def == NULL || ctxt == NULL)
+ return 0;
+ saved_node = ctxt->node;
- if (virXPathNode("./seclabel", ctxt) == NULL)
+ /* Allocate a security labels based on XML */
+ if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
return 0;
- /* Can't use overrides if top-level doesn't allow relabeling. */
- if (vmDef && vmDef->norelabel) {
- virDomainReportError(VIR_ERR_XML_ERROR, "%s",
- _("label overrides require relabeling to be "
- "enabled at the domain level"));
+ if (VIR_ALLOC_N(def->seclabels, n) < 0) {
+ virReportOOMError();
return -1;
}
+ for (i = 0; i < n; i++) {
+ if (VIR_ALLOC(def->seclabels[i]) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+
+ /* Parse each "seclabel" tag */
+ for (i = 0; i < n; i++) {
+ ctxt->node = list[i];
+ if (virSecurityLabelDefParseXML(def->seclabels[i], ctxt, flags))
+ goto error;
+ }
+ def->nseclabels = n;
+ ctxt->node = saved_node;
+ return 0;
- if (VIR_ALLOC(*def) < 0) {
+error:
+ ctxt->node = saved_node;
+ for (i = 0; i < n; i++) {
+ virSecurityLabelDefFree(def->seclabels[i]);
+ }
+ VIR_FREE(def->seclabels);
+ return -1;
+}
+
+static int
+virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
+ virSecurityLabelDefPtr *vmSeclabels,
+ int nvmSeclabels, xmlXPathContextPtr ctxt)
+{
+ int n, i, j;
+ xmlNodePtr *list;
+ virSecurityLabelDefPtr vmDef = NULL;
+ char *model, *relabel, *label;
+
+ if (def == NULL)
+ return 0;
+
+ if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
+ return 0;
+
+ def->nseclabels = n;
+ if (VIR_ALLOC_N(def->seclabels, n) < 0) {
virReportOOMError();
return -1;
}
+ for (i = 0; i < n; i++) {
+ if (VIR_ALLOC(def->seclabels[i]) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ }
- p = virXPathStringLimit("string(./seclabel/@relabel)",
- VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
- if (p != NULL) {
- if (STREQ(p, "yes")) {
- (*def)->norelabel = false;
- } else if (STREQ(p, "no")) {
- (*def)->norelabel = true;
+ for (i = 0; i < n; i++) {
+ /* get model associated to this override */
+ model = virXMLPropString(list[i], "model");
+ if (model == NULL) {
+ // TODO primary ?
+ // vmDef = ?
} else {
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("invalid security relabel value %s"), p);
- VIR_FREE(p);
- VIR_FREE(*def);
- return -1;
+ /* find the security label that it's being overrided */
+ for (j = 0; j < nvmSeclabels; j++) {
+ if (STREQ(vmSeclabels[j]->model, model)) {
+ vmDef = vmSeclabels[j];
+ break;
+ }
+ }
+ VIR_FREE(model);
}
- VIR_FREE(p);
- } else {
- (*def)->norelabel = false;
- }
- p = virXPathStringLimit("string(./seclabel/label[1])",
- VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
- (*def)->label = p;
+ /* Can't use overrides if top-level doesn't allow relabeling. */
+ if (vmDef && vmDef->norelabel) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("label overrides require relabeling to be "
+ "enabled at the domain level"));
+ goto error;
+ }
- if ((*def)->label && (*def)->norelabel) {
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("Cannot specify a label if relabelling is turned
off"));
- VIR_FREE((*def)->label);
- VIR_FREE(*def);
- return -1;
- }
+ relabel = virXMLPropString(list[i], "relabel");
+ if (relabel != NULL) {
+ if (STREQ(relabel, "yes")) {
+ def->seclabels[i]->norelabel = false;
+ } else if (STREQ(relabel, "no")) {
+ def->seclabels[i]->norelabel = true;
+ } else {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("invalid security relabel value %s"),
+ relabel);
+ VIR_FREE(relabel);
+ goto error;
+ }
+ VIR_FREE(relabel);
+ } else {
+ def->seclabels[i]->norelabel = false;
+ }
+ ctxt->node = list[i];
+ label = virXPathStringLimit("string(./seclabel/label[1])",
+ VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+ def->seclabels[i]->label = label;
+
+ if (label && def->seclabels[i]->norelabel) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("Cannot specify a label if relabelling is "
+ "turned off"));
+ goto error;
+ }
+ }
return 0;
+
+error:
+ for (i = 0; i < n; i++) {
+ virSecurityDeviceLabelDefFree(def->seclabels[i]);
+ }
+ VIR_FREE(def->seclabels);
+ return -1;
}
@@ -3325,7 +3403,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
xmlNodePtr node,
xmlXPathContextPtr ctxt,
virBitmapPtr bootMap,
- virSecurityLabelDefPtr vmSeclabel,
+ virSecurityLabelDefPtr* vmSeclabels,
+ int nvmSeclabels,
unsigned int flags)
{
virDomainDiskDefPtr def;
@@ -3663,9 +3742,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
if (sourceNode) {
xmlNodePtr saved_node = ctxt->node;
ctxt->node = sourceNode;
- if (virSecurityDeviceLabelDefParseXML(&def->seclabel,
- vmSeclabel,
- ctxt) < 0)
+ if (virSecurityDeviceLabelDefParseXML(def, vmSeclabels,
+ nvmSeclabels, ctxt) < 0)
goto error;
ctxt->node = saved_node;
}
@@ -7011,7 +7089,9 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
dev->type = VIR_DOMAIN_DEVICE_DISK;
if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt,
- NULL, &def->seclabel,
flags)))
+ NULL, def->seclabels,
+ def->nseclabels,
+ flags)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
dev->type = VIR_DOMAIN_DEVICE_LEASE;
@@ -7939,7 +8019,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
/* analysis of security label, done early even though we format it
* late, so devices can refer to this for defaults */
- if (virSecurityLabelDefParseXML(&def->seclabel, ctxt, flags) == -1)
+ if (virSecurityLabelDefsParseXML(def, ctxt, flags) == -1)
goto error;
/* Extract domain memory */
@@ -8538,7 +8618,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
nodes[i],
ctxt,
bootMap,
- &def->seclabel,
+ def->seclabels,
+ def->nseclabels,
flags);
if (!disk)
goto error;
@@ -10843,6 +10924,8 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr
def)
virBufferAsprintf(buf, " relabel='%s'",
def->norelabel ? "no" : "yes");
+VIR_DEBUG("FMT %s: %s %s %s", def->model, def->label, def->imagelabel,
def->baselabel); // TODO remove
+
if (def->label || def->imagelabel || def->baselabel) {
virBufferAddLit(buf, ">\n");
@@ -10911,6 +10994,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *copy_on_read =
virDomainVirtioEventIdxTypeToString(def->copy_on_read);
const char *startupPolicy =
virDomainStartupPolicyTypeToString(def->startupPolicy);
+ int n;
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!type) {
@@ -11006,10 +11090,11 @@ virDomainDiskDefFormat(virBufferPtr buf,
if (def->startupPolicy)
virBufferEscapeString(buf, " startupPolicy='%s'",
startupPolicy);
- if (def->seclabel) {
+ if (def->nseclabels) {
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 8);
- virSecurityDeviceLabelDefFormat(buf, def->seclabel);
+ for (n = 0; n < def->nseclabels; n++)
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
virBufferAdjustIndent(buf, -8);
virBufferAddLit(buf, " </source>\n");
} else {
@@ -11019,10 +11104,11 @@ virDomainDiskDefFormat(virBufferPtr buf,
case VIR_DOMAIN_DISK_TYPE_BLOCK:
virBufferEscapeString(buf, " <source dev='%s'",
def->src);
- if (def->seclabel) {
+ if (def->nseclabels) {
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 8);
- virSecurityDeviceLabelDefFormat(buf, def->seclabel);
+ for (n = 0; n < def->nseclabels; n++)
+ virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
virBufferAdjustIndent(buf, -8);
virBufferAddLit(buf, " </source>\n");
} else {
@@ -13020,7 +13106,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, " </devices>\n");
virBufferAdjustIndent(buf, 2);
- virSecurityLabelDefFormat(buf, &def->seclabel);
+ for (n = 0; n < def->nseclabels; n++)
+ virSecurityLabelDefFormat(buf, def->seclabels[n]);
virBufferAdjustIndent(buf, -2);
if (def->namespaceData && def->ns.format) {
@@ -15217,3 +15304,66 @@ cleanup:
VIR_FREE(xmlStr);
return ret;
}
+
+virSecurityLabelDefPtr
+virDomainDefGetSecurityLabelDef(virDomainDefPtr def, const char *model)
+{
+ int i;
+
+ if (def == NULL || model == NULL)
+ return NULL;
+
+ for (i = 0; i < def->nseclabels; i++) {
+ if (def->seclabels[i]->model == NULL)
+ continue;
+ if (STREQ(def->seclabels[i]->model, model))
+ return def->seclabels[i];
+ }
+
+ return virDomainDefAddSecurityLabelDef(def, model);
+}
+
+virSecurityDeviceLabelDefPtr
+virDomainDiskDefGetSecurityLabelDef(virDomainDiskDefPtr def, const char *model)
+{
+ int i;
+
+ if (def == NULL)
+ return NULL;
+
+ for (i = 0; i < def->nseclabels; i++) {
+ if (STREQ(def->seclabels[i]->model, model))
+ return def->seclabels[i];
+ }
+ return NULL;
+}
+
+virSecurityLabelDefPtr
+virDomainDefAddSecurityLabelDef(virDomainDefPtr def, const char *model)
+{
+ virSecurityLabelDefPtr seclabel = NULL;
+
+ if (VIR_ALLOC(seclabel) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if (model) {
+ seclabel->model = strdup(model);
+ if (seclabel->model == NULL) {
+ virReportOOMError();
+ virSecurityLabelDefFree(seclabel);
+ return NULL;
+ }
+ }
+
+ if (VIR_EXPAND_N(def->seclabels, def->nseclabels, 1) < 0) {
+ virReportOOMError();
+ virSecurityLabelDefFree(seclabel);
+ return NULL;
+ }
+ def->seclabels[def->nseclabels - 1] = seclabel;
+
+ return seclabel;
+}
+
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4c56902..49a7120 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -309,6 +309,7 @@ struct _virSecurityLabelDef {
typedef struct _virSecurityDeviceLabelDef virSecurityDeviceLabelDef;
typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr;
struct _virSecurityDeviceLabelDef {
+ char *model;
char *label; /* image label string */
bool norelabel;
};
@@ -553,7 +554,6 @@ struct _virDomainDiskDef {
int device;
int bus;
char *src;
- virSecurityDeviceLabelDefPtr seclabel;
char *dst;
int tray_status;
int protocol;
@@ -593,6 +593,9 @@ struct _virDomainDiskDef {
virStorageEncryptionPtr encryption;
bool rawio_specified;
int rawio; /* no = 0, yes = 1 */
+
+ size_t nseclabels;
+ virSecurityDeviceLabelDefPtr *seclabels;
};
@@ -1662,8 +1665,10 @@ struct _virDomainDef {
int nhubs;
virDomainHubDefPtr *hubs;
+ size_t nseclabels;
+ virSecurityLabelDefPtr *seclabels;
+
/* Only 1 */
- virSecurityLabelDef seclabel;
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
virCPUDefPtr cpu;
@@ -2139,6 +2144,15 @@ virDomainState
virDomainObjGetState(virDomainObjPtr obj, int *reason)
ATTRIBUTE_NONNULL(1);
+virSecurityLabelDefPtr
+virDomainDefGetSecurityLabelDef(virDomainDefPtr def, const char *model);
+
+virSecurityDeviceLabelDefPtr
+virDomainDiskDefGetSecurityLabelDef(virDomainDiskDefPtr def, const char *model);
+
+virSecurityLabelDefPtr
+virDomainDefAddSecurityLabelDef(virDomainDefPtr def, const char *model);
+
typedef const char* (*virLifecycleToStringFunc)(int type);
typedef int (*virLifecycleFromStringFunc)(const char *type);
--
1.7.1