
On Thu, Jan 13, 2011 at 05:34:36PM -0700, Eric Blake wrote:
* src/conf/domain_conf.h (virDomainSmartcardType): New enum. (virDomainSmartcardDef): New struct. (virDomainDef): Include smartcards. (virDomainSmartcardDefIterator): New typedef. (virDomainSmartcardDefFree, virDomainSmartcardDefForeach): New prototypes. * src/conf/domain_conf.c (virDomainSmartcard): Convert between enum and string. (virDomainSmartcardDefParseXML, virDomainSmartcardDefFormat) (virDomainSmartcardDefFree): New functions. (virDomainDefParseXML): Parse the new XML. (virDomainDefFormat): Convert back to XML. (virDomainDefFree): Clean up. (virDomainDeviceInfoIterate): Iterate over passthrough aliases. * src/libvirt_private.syms (domain_conf.h): New exports. * cfg.mk (useless_free_options): List new function. --- cfg.mk | 1 + src/conf/domain_conf.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 40 ++++++++- src/libvirt_private.syms | 4 + 4 files changed, 268 insertions(+), 1 deletions(-)
+static virDomainSmartcardDefPtr +virDomainSmartcardDefParseXML(xmlNodePtr node, + int flags) +{ + xmlNodePtr cur; + char *mode = NULL; + char *type = NULL; + virDomainSmartcardDefPtr def; + int i; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(); + return NULL; + } + + mode = virXMLPropString(node, "mode"); + if (mode == NULL) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("missing smartcard device mode")); + goto error; + } + if ((def->type = virDomainSmartcardTypeFromString(mode)) < 0) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("unknown smartcard device mode: %s"), + mode); + goto error; + } + + switch (def->type) { + case VIR_DOMAIN_SMARTCARD_TYPE_HOST: + break; + + case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES: + i = 0; + for (cur = node->children; + cur && cur->type == XML_ELEMENT_NODE && + xmlStrEqual(cur->name, BAD_CAST "certificate"); + cur = cur->next) { + def->data.cert.file[i++] = (char *)xmlNodeGetContent(cur); + }
I think xmlNodeGetContent can return NULL. We should likely also validate that it starts with a '/', so people can't just supply whitespace or random garbage.
+ if (i != 3 || cur->next) { + virDomainReportError(VIR_ERR_XML_ERROR, "%s", + _("host-certificates mode needs exactly " + "three certificates")); + goto error; + } + break; + + case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: + type = virXMLPropString(node, "type"); + if (type == NULL) + def->data.passthru.type = VIR_DOMAIN_CHR_TYPE_TCP;
I'm not sure that we should be defaulting to TCP here, rather than making 'type' compulsory.
+ else if ((def->data.passthru.type = virDomainChrTypeFromString(type)) + < 0) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("unknown type presented to host for " + "character device: %s"), type); + goto error; + } + + cur = node->children; + i = virDomainChrSourceDefParseXML(&def->data.passthru, cur); + if (i < 0) + goto error; + if (i) { + if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + goto error; + /* An active domain may have an alias, but no address. */ + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virDomainReportError(VIR_ERR_XML_ERROR, + _("smartcard should not have an " + "<address> element")); + goto error; + } + } + break; + + default: + virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unknown smartcard mode")); + goto error; + }
Daniel