
On Fri, Aug 31, 2012 at 12:51:51 +0800, Daniel Veillard wrote:
On Thu, Aug 30, 2012 at 09:39:03PM -0300, Marcelo Cerri wrote:
With this patch libvirt tries to assign a model to a single seclabel when model is missing. Libvirt will look up at host's capabilities and assign the first model to seclabel.
This patch fixes:
1. The problem with existing guests that have a seclabel defined in its XML. 2. A XML parse error when a guest is restored.
Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com> --- src/conf/domain_conf.c | 64 +++++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 224aec5..42c3900 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3102,22 +3102,10 @@ virSecurityLabelDefParseXML(xmlXPathContextPtr 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(./@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; - } + /* Always parse model */ + p = virXPathStringLimit("string(./@model)", + VIR_SECURITY_MODEL_BUFLEN-1, ctxt); + def->model = p;
return def;
@@ -3129,10 +3117,12 @@ error: static int virSecurityLabelDefsParseXML(virDomainDefPtr def, xmlXPathContextPtr ctxt, + virCapsPtr caps, unsigned int flags) { int i = 0, n; xmlNodePtr *list = NULL, saved_node; + virCapsHostPtr host = &caps->host;
/* Check args and save context */ if (def == NULL || ctxt == NULL) @@ -3159,18 +3149,38 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def, 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; - } + /* libvirt versions prior to 0.10.0 support just a single seclabel element + * in guest's XML and model attribute can be suppressed if type is none or + * type is dynamic, baselabel is not defined and INACTIVE flag is set. + * + * To avoid compatibility issues, for this specific case the first model + * defined in host's capabilities is used as model for the seclabel. + */ + if (def->nseclabels == 1 && + def->seclabels[0]->model == NULL && + def->seclabels[0]->type != VIR_DOMAIN_SECLABEL_STATIC && + def->seclabels[0]->baselabel == NULL && + (flags & VIR_DOMAIN_XML_INACTIVE) && + host->nsecModels > 0) { + + /* Copy model from host. */ + def->seclabels[0]->model = strdup(host->secModels[0].model); ... Fails "make check"
thinkpad:~/libvirt/tests -> export VIR_TEST_DEBUG=2 thinkpad:~/libvirt/tests -> ./qemuxml2argvtest ... 219) QEMU XML-2-ARGV seclabel-none ... libvir: Domain Config error : XML error: missing security model when using multiple labels FAILED ... thinkpad:~/libvirt/tests -> grep -C2 seclabel qemuxml2argvdata/qemuxml2argv-seclabel-none.xml <memballoon model='virtio'/> </devices> <seclabel type='none'/> </domain> thinkpad:~/libvirt/tests ->
So the new code following your patch is unable to parse the construct <seclabel type='none'/>
This is most likely because the above condition is missing the (type is none) part, i.e., it should be if (def->nseclabels == 1 && !def->seclabels[0]->model && (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE || (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC && !def->seclabels[0]->baselabel && (flags & VIR_DOMAIN_XML_INACTIVE))) && host->nsecModels > 0) { ... Heh, that looks awful :-) Actually if (def->nseclabels == 1 && !def->seclabels[0]->model && host->nsecModels > 0) { if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE || (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC && !def->seclabels[0]->baselabel && (flags & VIR_DOMAIN_XML_INACTIVE))) { def->seclabels[0]->model = strdup(host->secModels[0].model); } else { virReportError(VIR_ERR_XML_ERROR, "%s", "missing security model"); goto error; } } would be a bit more readable and would also avoid confusing error message when the model is missing but only one seclabel is used. I will try to do some testing with this changes... Jirka