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