[libvirt] [PATCH v3 2/5] Multiple security drivers in XML data
Marcelo Cerri
mhcerri at linux.vnet.ibm.com
Fri Aug 3 19:08:51 UTC 2012
Just a note: I will provide a test case for multiple seclabels in XML in
a separated patch.
On 08/03/2012 11:18 AM, Marcelo Cerri wrote:
> This patch updates the domain and capability XML parser and formatter to
> support morethan one "seclabel" element for each domain and device. The
> RNG schema and the tests related to this are also updated by this patch.
>
> Signed-off-by: Marcelo Cerri <mhcerri at linux.vnet.ibm.com>
> ---
> docs/formatdomain.html.in | 11 +-
> docs/schemas/capability.rng | 18 +-
> docs/schemas/domaincommon.rng | 30 ++-
> src/conf/capabilities.c | 6 +-
> src/conf/domain_conf.c | 353 ++++++++++++++------
> src/conf/domain_conf.h | 9 +
> src/libvirt_private.syms | 3 +
> .../qemuxml2argv-seclabel-dynamic-override.xml | 4 +-
> .../qemuxml2argv-seclabel-dynamic.xml | 2 +-
> 9 files changed, 305 insertions(+), 131 deletions(-)
>
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index f97c630..88e0418 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -1273,8 +1273,8 @@
> path to the file holding the disk. If the disk
> <code>type</code> is "block", then the <code>dev</code>
> attribute specifies the path to the host device to serve as
> - the disk. With both "file" and "block", an optional
> - sub-element <code>seclabel</code>, <a href="#seclabel">described
> + the disk. With both "file" and "block", one or more optional
> + sub-elements <code>seclabel</code>, <a href="#seclabel">described
> below</a> (and <span class="since">since 0.9.9</span>), can be
> used to override the domain security labeling policy for just
> that source file. If the disk <code>type</code> is "dir", then the
> @@ -3828,6 +3828,13 @@ qemu-kvm -net nic,model=? /dev/null
> </p>
>
> <p>
> + If more than one security driver is used by libvirt, multiple
> + <code>seclabel</code> tags can be used, one for each driver and
> + the security driver referenced by each tag can be defined using
> + the attribute <code>model</code>
> + </p>
> +
> + <p>
> Valid input XML configurations for the top-level security label
> are:
> </p>
> diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng
> index c392e44..8c928bc 100644
> --- a/docs/schemas/capability.rng
> +++ b/docs/schemas/capability.rng
> @@ -44,20 +44,22 @@
> <optional>
> <ref name='topology'/>
> </optional>
> - <optional>
> + <zeroOrMore>
> <ref name='secmodel'/>
> - </optional>
> + </zeroOrMore>
> </element>
> </define>
>
> <define name='secmodel'>
> <element name='secmodel'>
> - <element name='model'>
> - <text/>
> - </element>
> - <element name='doi'>
> - <text/>
> - </element>
> + <interleave>
> + <element name='model'>
> + <text/>
> + </element>
> + <element name='doi'>
> + <text/>
> + </element>
> + </interleave>
> </element>
> </define>
>
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index c85d763..d1c1683 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -55,9 +55,9 @@
> <optional>
> <ref name="devices"/>
> </optional>
> - <optional>
> + <zeroOrMore>
> <ref name="seclabel"/>
> - </optional>
> + </zeroOrMore>
> <optional>
> <ref name='qemucmdline'/>
> </optional>
> @@ -148,18 +148,32 @@
> <!-- A per-device seclabel override is more limited, either
> relabel=no or a <label> must be present. -->
> <choice>
> - <attribute name='relabel'>
> - <value>no</value>
> - </attribute>
> <group>
> <optional>
> + <attribute name='model'>
> + <text/>
> + </attribute>
> + </optional>
> + <attribute name='relabel'>
> + <value>no</value>
> + </attribute>
> + </group>
> + <group>
> + <optional>
> + <attribute name='model'>
> + <text/>
> + </attribute>
> + </optional>
> + <optional>
> <attribute name='relabel'>
> <value>yes</value>
> </attribute>
> </optional>
> - <element name='label'>
> - <text/>
> - </element>
> + <zeroOrMore>
> + <element name='label'>
> + <text/>
> + </element>
> + </zeroOrMore>
> </group>
> </choice>
> </element>
> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
> index 9a0bc3d..bc6266e 100644
> --- a/src/conf/capabilities.c
> +++ b/src/conf/capabilities.c
> @@ -772,12 +772,12 @@ virCapabilitiesFormatXML(virCapsPtr caps)
> virBufferAddLit(&xml, " </topology>\n");
> }
>
> - if (caps->host.nsecModels) {
> + for (i = 0; i < caps->host.nsecModels; i++) {
> virBufferAddLit(&xml, " <secmodel>\n");
> virBufferAsprintf(&xml, " <model>%s</model>\n",
> - caps->host.secModels[0].model);
> + caps->host.secModels[i].model);
> virBufferAsprintf(&xml, " <doi>%s</doi>\n",
> - caps->host.secModels[0].doi);
> + caps->host.secModels[i].doi);
> virBufferAddLit(&xml, " </secmodel>\n");
> }
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 1c318a0..866df12 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -3078,17 +3078,19 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
> return 0;
> }
>
> -static int
> -virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
> - xmlXPathContextPtr ctxt,
> +static virSecurityLabelDefPtr
> +virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt,
> unsigned int flags)
> {
> char *p;
> + virSecurityLabelDefPtr def = NULL;
>
> - if (virXPathNode("./seclabel[1]", ctxt) == NULL)
> - return 0;
> + if (VIR_ALLOC(def) < 0) {
> + virReportOOMError();
> + goto error;
> + }
>
> - p = virXPathStringLimit("string(./seclabel[1]/@type)",
> + p = virXPathStringLimit("string(./@type)",
> VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> if (p == NULL) {
> def->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
> @@ -3102,7 +3104,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
> }
> }
>
> - p = virXPathStringLimit("string(./seclabel[1]/@relabel)",
> + p = virXPathStringLimit("string(./@relabel)",
> VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> if (p != NULL) {
> if (STREQ(p, "yes")) {
> @@ -3142,7 +3144,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[1]/label[1])",
> + p = virXPathStringLimit("string(./label[1])",
> VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> if (p == NULL) {
> virReportError(VIR_ERR_XML_ERROR,
> @@ -3157,7 +3159,7 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
> if (!def->norelabel &&
> (!(flags & VIR_DOMAIN_XML_INACTIVE) &&
> def->type != VIR_DOMAIN_SECLABEL_NONE)) {
> - p = virXPathStringLimit("string(./seclabel[1]/imagelabel[1])",
> + p = virXPathStringLimit("string(./imagelabel[1])",
> VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> if (p == NULL) {
> virReportError(VIR_ERR_XML_ERROR,
> @@ -3169,93 +3171,179 @@ virSecurityLabelDefParseXML(virSecurityLabelDefPtr def,
>
> /* Only parse baselabel for dynamic label type */
> if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
> - p = virXPathStringLimit("string(./seclabel[1]/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[1]/@model)",
> - VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
> - if (p == NULL) {
> - virReportError(VIR_ERR_XML_ERROR,
> - "%s", _("missing security model"));
> - goto error;
> - }
> - def->model = p;
> + /* Always parse model */
> + p = virXPathStringLimit("string(./@model)",
> + VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
> + if (p == NULL && def->type != VIR_DOMAIN_SECLABEL_NONE) {
> + virReportError(VIR_ERR_XML_ERROR,
> + "%s", _("missing security model"));
> }
> + def->model = p;
>
> - return 0;
> + return def;
>
> error:
> virSecurityLabelDefFree(def);
> + return NULL;
> +}
> +
> +static int
> +virSecurityLabelDefsParseXML(virDomainDefPtr def,
> + xmlXPathContextPtr ctxt,
> + unsigned int flags)
> +{
> + int i, n;
> + xmlNodePtr *list = NULL, saved_node;
> +
> + /* Check args and save context */
> + if (def == NULL || ctxt == NULL)
> + return 0;
> + saved_node = ctxt->node;
> +
> + /* Allocate a security labels based on XML */
> + if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
> + return 0;
> +
> + if (VIR_ALLOC_N(def->seclabels, n) < 0) {
> + virReportOOMError();
> + goto error;
> + }
> +
> + /* Parse each "seclabel" tag */
> + for (i = 0; i < n; i++) {
> + ctxt->node = list[i];
> + def->seclabels[i] = virSecurityLabelDefParseXML(ctxt, flags);
> + if (def->seclabels[i] == NULL)
> + goto error;
> + }
> + def->nseclabels = n;
> + ctxt->node = saved_node;
> + VIR_FREE(list);
> +
> + /* Checking missing model information
> + * when there is more than one seclabel */
> + if (n > 1) {
> + for(; n; n--) {
> + if (def->seclabels[n - 1]->model == NULL) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("missing security model "
> + "when using multiple labels"));
> + goto error;
> + }
> + }
> + }
> + return 0;
> +
> +error:
> + ctxt->node = saved_node;
> + for (; i > 0; i--) {
> + virSecurityLabelDefFree(def->seclabels[i - 1]);
> + }
> + VIR_FREE(def->seclabels);
> + VIR_FREE(list);
> return -1;
> }
>
> -
> static int
> -virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr *def,
> - virSecurityLabelDefPtr vmDef,
> - xmlXPathContextPtr ctxt)
> +virSecurityDeviceLabelDefParseXML(virDomainDiskDefPtr def,
> + virSecurityLabelDefPtr *vmSeclabels,
> + int nvmSeclabels, xmlXPathContextPtr ctxt)
> {
> - char *p;
> + int n, i, j;
> + xmlNodePtr *list = NULL;
> + virSecurityLabelDefPtr vmDef = NULL;
> + char *model, *relabel, *label;
>
> - *def = NULL;
> -
> - if (virXPathNode("./seclabel[1]", ctxt) == NULL)
> + if (def == NULL)
> return 0;
>
> - /* Can't use overrides if top-level doesn't allow relabeling. */
> - if (vmDef && vmDef->norelabel) {
> - virReportError(VIR_ERR_XML_ERROR, "%s",
> - _("label overrides require relabeling to be "
> - "enabled at the domain level"));
> - return -1;
> - }
> + if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) == 0)
> + return 0;
>
> - if (VIR_ALLOC(*def) < 0) {
> + def->nseclabels = n;
> + if (VIR_ALLOC_N(def->seclabels, n) < 0) {
> virReportOOMError();
> - return -1;
> + goto error;
> }
> + for (i = 0; i < n; i++) {
> + if (VIR_ALLOC(def->seclabels[i]) < 0) {
> + virReportOOMError();
> + goto error;
> + }
> + }
> +
> + for (i = 0; i < n; i++) {
> + /* get model associated to this override */
> + model = virXMLPropString(list[i], "model");
> + if (model == NULL) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("invalid security model"));
> + goto error;
> + } else {
> + /* find the security label that it's being overriden */
> + for (j = 0; j < nvmSeclabels; j++) {
> + if (STREQ(vmSeclabels[j]->model, model)) {
> + vmDef = vmSeclabels[j];
> + break;
> + }
> + }
> + def->seclabels[i]->model = model;
> + }
>
> - p = virXPathStringLimit("string(./seclabel[1]/@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;
> + /* Can't use overrides if top-level doesn't allow relabeling. */
> + if (vmDef && vmDef->norelabel) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("label overrides require relabeling to be "
> + "enabled at the domain level"));
> + goto error;
> + }
> +
> + 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 {
> + virReportError(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(./label)",
> + VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> + def->seclabels[i]->label = label;
> +
> + if (label && def->seclabels[i]->norelabel) {
> virReportError(VIR_ERR_XML_ERROR,
> - _("invalid security relabel value %s"), p);
> - VIR_FREE(p);
> - VIR_FREE(*def);
> - return -1;
> + _("Cannot specify a label if relabelling is "
> + "turned off. model=%s"),
> + def->seclabels[i]->model);
> + goto error;
> }
> - VIR_FREE(p);
> - } else {
> - (*def)->norelabel = false;
> }
> -
> - p = virXPathStringLimit("string(./seclabel[1]/label[1])",
> - VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
> - (*def)->label = p;
> -
> - if ((*def)->label && (*def)->norelabel) {
> - virReportError(VIR_ERR_XML_ERROR, "%s",
> - _("Cannot specify a label if relabelling is turned off"));
> - VIR_FREE((*def)->label);
> - VIR_FREE(*def);
> - return -1;
> - }
> -
> + VIR_FREE(list);
> return 0;
> +
> +error:
> + for (i = 0; i < n; i++) {
> + virSecurityDeviceLabelDefFree(def->seclabels[i]);
> + }
> + VIR_FREE(def->seclabels);
> + VIR_FREE(list);
> + return -1;
> }
>
>
> @@ -3339,7 +3427,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> xmlNodePtr node,
> xmlXPathContextPtr ctxt,
> virBitmapPtr bootMap,
> - virSecurityLabelDefPtr vmSeclabel,
> + virSecurityLabelDefPtr* vmSeclabels,
> + int nvmSeclabels,
> unsigned int flags)
> {
> virDomainDiskDefPtr def;
> @@ -3677,16 +3766,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> if (sourceNode) {
> xmlNodePtr saved_node = ctxt->node;
> ctxt->node = sourceNode;
> - if ((VIR_ALLOC(def->seclabels) < 0) ||
> - (VIR_ALLOC(def->seclabels[0]) < 0)) {
> - virReportOOMError();
> - goto error;
> - }
> - if (virSecurityDeviceLabelDefParseXML(&def->seclabels[0],
> - vmSeclabel,
> + if (virSecurityDeviceLabelDefParseXML(def, vmSeclabels,
> + nvmSeclabels,
> ctxt) < 0)
> goto error;
> - def->nseclabels = 1;
> ctxt->node = saved_node;
> }
>
> @@ -7136,16 +7219,11 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
> goto error;
> }
>
> - if ((VIR_ALLOC(def->seclabels) < 0) ||
> - (VIR_ALLOC(def->seclabels[0])) < 0 ) {
> - virReportOOMError();
> - goto error;
> - }
> -
> if (xmlStrEqual(node->name, BAD_CAST "disk")) {
> dev->type = VIR_DOMAIN_DEVICE_DISK;
> if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, ctxt,
> - NULL, def->seclabels[0],
> + NULL, def->seclabels,
> + def->nseclabels,
> flags)))
> goto error;
> } else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
> @@ -8084,13 +8162,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 ((VIR_ALLOC(def->seclabels) < 0) ||
> - (VIR_ALLOC(def->seclabels[0]) < 0)) {
> - virReportOOMError();
> - goto error;
> - }
> - def->nseclabels = 1;
> - if (virSecurityLabelDefParseXML(def->seclabels[0], ctxt, flags) == -1)
> + if (virSecurityLabelDefsParseXML(def, ctxt, flags) == -1)
> goto error;
>
> /* Extract domain memory */
> @@ -8690,7 +8762,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
> nodes[i],
> ctxt,
> bootMap,
> - def->seclabels[0],
> + def->seclabels,
> + def->nseclabels,
> flags);
> if (!disk)
> goto error;
> @@ -11037,13 +11110,15 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
> virBufferAsprintf(buf, "<seclabel type='%s'",
> sectype);
>
> + if (def->model) {
> + virBufferEscapeString(buf, " model='%s'", def->model);
> + }
> +
> if (def->type == VIR_DOMAIN_SECLABEL_NONE) {
> virBufferAddLit(buf, "/>\n");
> return;
> }
>
> - virBufferEscapeString(buf, " model='%s'", def->model);
> -
> virBufferAsprintf(buf, " relabel='%s'",
> def->norelabel ? "no" : "yes");
>
> @@ -11069,8 +11144,8 @@ static void
> virSecurityDeviceLabelDefFormat(virBufferPtr buf,
> virSecurityDeviceLabelDefPtr def)
> {
> - virBufferAsprintf(buf, "<seclabel relabel='%s'",
> - def->norelabel ? "no" : "yes");
> + virBufferAsprintf(buf, "<seclabel model='%s' relabel='%s'",
> + def->model, def->norelabel ? "no" : "yes");
> if (def->label) {
> virBufferAddLit(buf, ">\n");
> virBufferEscapeString(buf, " <label>%s</label>\n",
> @@ -11115,6 +11190,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) {
> @@ -11210,10 +11286,11 @@ virDomainDiskDefFormat(virBufferPtr buf,
> if (def->startupPolicy)
> virBufferEscapeString(buf, " startupPolicy='%s'",
> startupPolicy);
> - if (def->seclabels && def->seclabels[0]) {
> + if (def->nseclabels) {
> virBufferAddLit(buf, ">\n");
> virBufferAdjustIndent(buf, 8);
> - virSecurityDeviceLabelDefFormat(buf, def->seclabels[0]);
> + for (n = 0; n < def->nseclabels; n++)
> + virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
> virBufferAdjustIndent(buf, -8);
> virBufferAddLit(buf, " </source>\n");
> } else {
> @@ -11223,10 +11300,11 @@ virDomainDiskDefFormat(virBufferPtr buf,
> case VIR_DOMAIN_DISK_TYPE_BLOCK:
> virBufferEscapeString(buf, " <source dev='%s'",
> def->src);
> - if (def->seclabels && def->seclabels[0]) {
> + if (def->nseclabels) {
> virBufferAddLit(buf, ">\n");
> virBufferAdjustIndent(buf, 8);
> - virSecurityDeviceLabelDefFormat(buf, def->seclabels[0]);
> + for (n = 0; n < def->nseclabels; n++)
> + virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
> virBufferAdjustIndent(buf, -8);
> virBufferAddLit(buf, " </source>\n");
> } else {
> @@ -13252,11 +13330,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>
> virBufferAddLit(buf, " </devices>\n");
>
> - if (def->nseclabels && def->seclabels) {
> - virBufferAdjustIndent(buf, 2);
> - virSecurityLabelDefFormat(buf, def->seclabels[0]);
> - virBufferAdjustIndent(buf, -2);
> - }
> + virBufferAdjustIndent(buf, 2);
> + for (n = 0; n < def->nseclabels; n++)
> + virSecurityLabelDefFormat(buf, def->seclabels[n]);
> + virBufferAdjustIndent(buf, -2);
>
> if (def->namespaceData && def->ns.format) {
> if ((def->ns.format)(buf, def->namespaceData) < 0)
> @@ -15433,3 +15510,65 @@ 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 db6ef6c..dda6d24 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2161,6 +2161,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);
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 75997fe..be8b610 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -287,6 +287,9 @@ virDomainDefCompatibleDevice;
> virDomainDefFormat;
> virDomainDefFormatInternal;
> virDomainDefFree;
> +virDomainDefGetSecurityLabelDef;
> +virDomainDiskDefGetSecurityLabelDef;
> +virDomainDefAddSecurityLabelDef;
> virDomainDefParseFile;
> virDomainDefParseNode;
> virDomainDefParseString;
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-override.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-override.xml
> index 4de435b..426b663 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-override.xml
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-override.xml
> @@ -16,14 +16,14 @@
> <emulator>/usr/bin/qemu</emulator>
> <disk type='block' device='disk'>
> <source dev='/dev/HostVG/QEMUGuest1'>
> - <seclabel relabel='no'/>
> + <seclabel model='selinux' relabel='no'/>
> </source>
> <target dev='hda' bus='ide'/>
> <address type='drive' controller='0' bus='0' target='0' unit='0'/>
> </disk>
> <disk type='block' device='disk'>
> <source dev='/dev/HostVG/QEMUGuest2'>
> - <seclabel relabel='yes'>
> + <seclabel model='selinux' relabel='yes'>
> <label>system_u:system_r:public_content_t:s0</label>
> </seclabel>
> </source>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic.xml
> index 78a6b6a..36df9d4 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic.xml
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic.xml
> @@ -22,5 +22,5 @@
> <controller type='ide' index='0'/>
> <memballoon model='virtio'/>
> </devices>
> - <seclabel type='dynamic' relabel='yes'/>
> + <seclabel model='selinux' type='dynamic' relabel='yes'/>
> </domain>
More information about the libvir-list
mailing list