* src/conf/domain_conf.h (virDomainSmartcardType): New enum.
(virDomainSmartcardDef, virDomainDeviceCcidAddress): New structs.
(virDomainDef): Include smartcards.
(virDomainSmartcardDefIterator): New typedef.
(virDomainSmartcardDefFree, virDomainSmartcardDefForeach): New
prototypes.
(virDomainControllerType, virDomainDeviceAddressType): Add ccid
enum values.
(virDomainDeviceInfo): Add ccid address type.
* src/conf/domain_conf.c (virDomainSmartcard): Convert between
enum and string.
(virDomainSmartcardDefParseXML, virDomainSmartcardDefFormat)
(virDomainSmartcardDefFree, virDomainDeviceCcidAddressParseXML)
(virDomainDefMaybeAddSmartcardController): New functions.
(virDomainDefParseXML): Parse the new XML.
(virDomainDefFormat): Convert back to XML.
(virDomainDefFree): Clean up.
(virDomainDeviceInfoIterate): Iterate over passthrough aliases.
(virDomainController, virDomainDeviceAddress)
(virDomainDeviceInfoParseXML, virDomainDeviceInfoFormat)
(virDomainDefAddImplicitControllers): Support new values.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): List new function.
---
Notes:
v2: first version of patch (v1 was xml proposal only)
v3: add controller type='ccid' support, extra smartcard element support
v4: remove host/dev, relax host-certificates/cert to be any string, define
default host-certificates/database value
v5: no change
cfg.mk | 1 +
src/conf/domain_conf.c | 366 ++++++++++++++++++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 52 +++++++-
src/libvirt_private.syms | 4 +
4 files changed, 411 insertions(+), 12 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 2cc6f90..7664bdf 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -100,6 +100,7 @@ useless_free_options = \
--name=virDomainInputDefFree \
--name=virDomainNetDefFree \
--name=virDomainObjFree \
+ --name=virDomainSmartcardDefFree \
--name=virDomainSnapshotDefFree \
--name=virDomainSnapshotObjFree \
--name=virDomainSoundDefFree \
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index aba4223..b1c775b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -109,7 +109,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
"pci",
"drive",
- "virtio-serial")
+ "virtio-serial",
+ "ccid")
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block",
@@ -159,7 +160,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"fdc",
"scsi",
"sata",
- "virtio-serial")
+ "virtio-serial",
+ "ccid")
VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
"auto",
@@ -232,6 +234,11 @@ VIR_ENUM_IMPL(virDomainChrTcpProtocol,
VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST,
"telnets",
"tls")
+VIR_ENUM_IMPL(virDomainSmartcard, VIR_DOMAIN_SMARTCARD_TYPE_LAST,
+ "host",
+ "host-certificates",
+ "passthrough")
+
VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
"sb16",
"es1370",
@@ -693,6 +700,35 @@ void virDomainChrDefFree(virDomainChrDefPtr def)
VIR_FREE(def);
}
+void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def)
+{
+ size_t i;
+ if (!def)
+ return;
+
+ switch (def->type) {
+ case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
+ break;
+
+ case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
+ for (i = 0; i < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; i++)
+ VIR_FREE(def->data.cert.file[i]);
+ VIR_FREE(def->data.cert.database);
+ break;
+
+ case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
+ virDomainChrSourceDefClear(&def->data.passthru);
+ break;
+
+ default:
+ break;
+ }
+
+ virDomainDeviceInfoClear(&def->info);
+
+ VIR_FREE(def);
+}
+
void virDomainSoundDefFree(virDomainSoundDefPtr def)
{
if (!def)
@@ -834,6 +870,10 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainNetDefFree(def->nets[i]);
VIR_FREE(def->nets);
+ for (i = 0 ; i < def->nsmartcards ; i++)
+ virDomainSmartcardDefFree(def->smartcards[i]);
+ VIR_FREE(def->smartcards);
+
for (i = 0 ; i < def->nserials ; i++)
virDomainChrDefFree(def->serials[i]);
VIR_FREE(def->serials);
@@ -1198,6 +1238,9 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
for (i = 0; i < def->ncontrollers ; i++)
if (cb(def, &def->controllers[i]->info, opaque) < 0)
return -1;
+ for (i = 0; i < def->nsmartcards ; i++)
+ if (cb(def, &def->smartcards[i]->info, opaque) < 0)
+ return -1;
for (i = 0; i < def->nserials ; i++)
if (cb(def, &def->serials[i]->info, opaque) < 0)
return -1;
@@ -1240,16 +1283,11 @@ void virDomainDefClearDeviceAliases(virDomainDefPtr def)
/* Generate a string representation of a device address
* @param address Device address to stringify
*/
-static int virDomainDeviceInfoFormat(virBufferPtr buf,
- virDomainDeviceInfoPtr info,
- int flags)
+static int ATTRIBUTE_NONNULL(2)
+virDomainDeviceInfoFormat(virBufferPtr buf,
+ virDomainDeviceInfoPtr info,
+ int flags)
{
- if (!info) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("missing device information"));
- return -1;
- }
-
if (info->alias &&
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
virBufferVSprintf(buf, " <alias name='%s'/>\n",
info->alias);
@@ -1285,6 +1323,12 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.vioserial.port);
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
+ virBufferVSprintf(buf, " controller='%d' slot='%d'",
+ info->addr.ccid.controller,
+ info->addr.ccid.slot);
+ break;
+
default:
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown address type '%d'"),
info->type);
@@ -1458,6 +1502,40 @@ cleanup:
return ret;
}
+static int
+virDomainDeviceCcidAddressParseXML(xmlNodePtr node,
+ virDomainDeviceCcidAddressPtr addr)
+{
+ char *controller, *slot;
+ int ret = -1;
+
+ memset(addr, 0, sizeof(*addr));
+
+ controller = virXMLPropString(node, "controller");
+ slot = virXMLPropString(node, "slot");
+
+ if (controller &&
+ virStrToLong_ui(controller, NULL, 10, &addr->controller) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <address> 'controller'
attribute"));
+ goto cleanup;
+ }
+
+ if (slot &&
+ virStrToLong_ui(slot, NULL, 10, &addr->slot) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <address> 'slot'
attribute"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(controller);
+ VIR_FREE(slot);
+ return ret;
+}
+
/* Parse the XML definition for a device address
* @param node XML nodeset to parse for device address definition
*/
@@ -1526,6 +1604,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
goto cleanup;
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
+ if (virDomainDeviceCcidAddressParseXML(address, &info->addr.ccid) < 0)
+ goto cleanup;
+ break;
+
default:
/* Should not happen */
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3185,6 +3268,128 @@ error:
goto cleanup;
}
+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;
+ cur = node->children;
+ while (cur) {
+ if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "certificate")) {
+ if (i == 3) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("host-certificates mode needs "
+ "exactly three certificates"));
+ goto error;
+ }
+ def->data.cert.file[i] = (char *)xmlNodeGetContent(cur);
+ if (!def->data.cert.file[i]) {
+ virReportOOMError();
+ goto error;
+ }
+ i++;
+ } else if (cur->type == XML_ELEMENT_NODE &&
+ xmlStrEqual(cur->name, BAD_CAST "database")
&&
+ !def->data.cert.database) {
+ def->data.cert.database = (char *)xmlNodeGetContent(cur);
+ if (!def->data.cert.database) {
+ virReportOOMError();
+ goto error;
+ }
+ if (*def->data.cert.database != '/') {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("expecting absolute path: %s"),
+ def->data.cert.database);
+ goto error;
+ }
+ }
+ cur = cur->next;
+ }
+ if (i < 3) {
+ 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) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("passthrough mode requires a character "
+ "device type attribute"));
+ goto error;
+ }
+ 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;
+ if (virDomainChrSourceDefParseXML(&def->data.passthru, cur) < 0)
+ goto error;
+ break;
+
+ default:
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unknown smartcard mode"));
+ goto error;
+ }
+
+ if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
+ goto error;
+ if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+ def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Controllers must use the 'ccid' address
type"));
+ goto error;
+ }
+
+cleanup:
+ VIR_FREE(mode);
+ VIR_FREE(type);
+
+ return def;
+
+error:
+ virDomainSmartcardDefFree(def);
+ def = NULL;
+ goto cleanup;
+}
+
/* Parse the XML definition for a network interface */
static virDomainInputDefPtr
virDomainInputDefParseXML(const char *ostype,
@@ -5258,6 +5463,26 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
VIR_FREE(nodes);
+ /* analysis of the smartcard devices */
+ if ((n = virXPathNodeSet("./devices/smartcard", ctxt, &nodes)) < 0)
{
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot extract smartcard
devices"));
+ goto error;
+ }
+ if (n && VIR_ALLOC_N(def->smartcards, n) < 0)
+ goto no_memory;
+
+ for (i = 0 ; i < n ; i++) {
+ virDomainSmartcardDefPtr card = virDomainSmartcardDefParseXML(nodes[i],
+ flags);
+ if (!card)
+ goto error;
+
+ def->smartcards[def->nsmartcards++] = card;
+ }
+ VIR_FREE(nodes);
+
+
/* analysis of the character devices */
if ((n = virXPathNodeSet("./devices/parallel", ctxt, &nodes)) < 0)
{
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5936,6 +6161,45 @@ static int
virDomainDefMaybeAddVirtioSerialController(virDomainDefPtr def)
}
+static int
+virDomainDefMaybeAddSmartcardController(virDomainDefPtr def)
+{
+ /* Look for any smartcard devs */
+ int i;
+
+ for (i = 0 ; i < def->nsmartcards ; i++) {
+ virDomainSmartcardDefPtr smartcard = def->smartcards[i];
+ int idx = 0;
+
+ if (smartcard->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID) {
+ idx = smartcard->info.addr.ccid.controller;
+ } else if (smartcard->info.type
+ == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ int j;
+ int max = -1;
+
+ for (j = 0; j < def->nsmartcards; j++) {
+ virDomainDeviceInfoPtr info = &def->smartcards[j]->info;
+ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID &&
+ info->addr.ccid.controller == 0 &&
+ (int) info->addr.ccid.slot > max)
+ max = info->addr.ccid.slot;
+ }
+ smartcard->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID;
+ smartcard->info.addr.ccid.controller = 0;
+ smartcard->info.addr.ccid.slot = max + 1;
+ }
+
+ if (virDomainDefMaybeAddController(def,
+ VIR_DOMAIN_CONTROLLER_TYPE_CCID,
+ idx) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
/*
* Based on the declared <address/> info for any devices,
* add neccessary drive controllers which are not already present
@@ -5962,6 +6226,9 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def)
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
return -1;
+ if (virDomainDefMaybeAddSmartcardController(def) < 0)
+ return -1;
+
return 0;
}
@@ -6741,6 +7008,56 @@ virDomainChrDefFormat(virBufferPtr buf,
}
static int
+virDomainSmartcardDefFormat(virBufferPtr buf,
+ virDomainSmartcardDefPtr def,
+ int flags)
+{
+ const char *mode = virDomainSmartcardTypeToString(def->type);
+ size_t i;
+
+ if (!mode) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected smartcard type %d"), def->type);
+ return -1;
+ }
+
+ virBufferVSprintf(buf, " <smartcard mode='%s'", mode);
+ switch (def->type) {
+ case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
+ if (!virDomainDeviceInfoIsSet(&def->info)) {
+ virBufferAddLit(buf, "/>\n");
+ return 0;
+ }
+ break;
+
+ case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
+ virBufferAddLit(buf, ">\n");
+ for (i = 0; i < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; i++)
+ virBufferEscapeString(buf, "
<certificate>%s</certificate>\n",
+ def->data.cert.file[i]);
+ if (def->data.cert.database)
+ virBufferEscapeString(buf, "
<database>%s</database>\n",
+ def->data.cert.database);
+ break;
+
+ case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
+ if (virDomainChrSourceDefFormat(buf, &def->data.passthru, false,
+ flags) < 0)
+ return -1;
+ break;
+
+ default:
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected smartcard type %d"), def->type);
+ return -1;
+ }
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+ virBufferAddLit(buf, " </smartcard>\n");
+ return 0;
+}
+
+static int
virDomainSoundDefFormat(virBufferPtr buf,
virDomainSoundDefPtr def,
int flags)
@@ -7546,6 +7863,10 @@ char *virDomainDefFormat(virDomainDefPtr def,
if (virDomainNetDefFormat(&buf, def->nets[n], flags) < 0)
goto cleanup;
+ for (n = 0 ; n < def->nsmartcards ; n++)
+ if (virDomainSmartcardDefFormat(&buf, def->smartcards[n], flags) < 0)
+ goto cleanup;
+
for (n = 0 ; n < def->nserials ; n++)
if (virDomainChrDefFormat(&buf, def->serials[n], flags) < 0)
goto cleanup;
@@ -8624,6 +8945,29 @@ done:
}
+int virDomainSmartcardDefForeach(virDomainDefPtr def,
+ bool abortOnError,
+ virDomainSmartcardDefIterator iter,
+ void *opaque)
+{
+ int i;
+ int rc = 0;
+
+ for (i = 0 ; i < def->nsmartcards ; i++) {
+ if ((iter)(def,
+ def->smartcards[i],
+ opaque) < 0)
+ rc = -1;
+
+ if (abortOnError && rc != 0)
+ goto done;
+ }
+
+done:
+ return rc;
+}
+
+
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
bool allowProbing,
bool ignoreOpenFailure,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index feae203..81c3f38 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -73,6 +73,7 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
+ VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
};
@@ -102,6 +103,13 @@ struct _virDomainDeviceVirtioSerialAddress {
unsigned int port;
};
+typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress;
+typedef virDomainDeviceCcidAddress *virDomainDeviceCcidAddressPtr;
+struct _virDomainDeviceCcidAddress {
+ unsigned int controller;
+ unsigned int slot;
+};
+
typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
struct _virDomainDeviceInfo {
@@ -111,6 +119,7 @@ struct _virDomainDeviceInfo {
virDomainDevicePCIAddress pci;
virDomainDeviceDriveAddress drive;
virDomainDeviceVirtioSerialAddress vioserial;
+ virDomainDeviceCcidAddress ccid;
} addr;
};
@@ -220,6 +229,7 @@ enum virDomainControllerType {
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
+ VIR_DOMAIN_CONTROLLER_TYPE_CCID,
VIR_DOMAIN_CONTROLLER_TYPE_LAST
};
@@ -461,6 +471,33 @@ struct _virDomainChrDef {
virDomainDeviceInfo info;
};
+enum virDomainSmartcardType {
+ VIR_DOMAIN_SMARTCARD_TYPE_HOST,
+ VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES,
+ VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH,
+
+ VIR_DOMAIN_SMARTCARD_TYPE_LAST,
+};
+
+# define VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES 3
+# define VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE "/etc/pki/nssdb"
+
+typedef struct _virDomainSmartcardDef virDomainSmartcardDef;
+typedef virDomainSmartcardDef *virDomainSmartcardDefPtr;
+struct _virDomainSmartcardDef {
+ int type; /* virDomainSmartcardType */
+ union {
+ /* no extra data for 'host' */
+ struct {
+ char *file[VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES];
+ char *database;
+ } cert; /* 'host-certificates' */
+ virDomainChrSourceDef passthru; /* 'passthrough' */
+ } data;
+
+ virDomainDeviceInfo info;
+};
+
enum virDomainInputType {
VIR_DOMAIN_INPUT_TYPE_MOUSE,
VIR_DOMAIN_INPUT_TYPE_TABLET,
@@ -1032,6 +1069,9 @@ struct _virDomainDef {
int nhostdevs;
virDomainHostdevDefPtr *hostdevs;
+ int nsmartcards;
+ virDomainSmartcardDefPtr *smartcards;
+
int nserials;
virDomainChrDefPtr *serials;
@@ -1110,6 +1150,7 @@ void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
void virDomainControllerDefFree(virDomainControllerDefPtr def);
void virDomainFSDefFree(virDomainFSDefPtr def);
void virDomainNetDefFree(virDomainNetDefPtr def);
+void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def);
void virDomainChrDefFree(virDomainChrDefPtr def);
void virDomainChrSourceDefFree(virDomainChrSourceDefPtr def);
void virDomainSoundDefFree(virDomainSoundDefPtr def);
@@ -1258,6 +1299,15 @@ int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
char **const names,
int maxnames);
+typedef int (*virDomainSmartcardDefIterator)(virDomainDefPtr def,
+ virDomainSmartcardDefPtr dev,
+ void *opaque);
+
+int virDomainSmartcardDefForeach(virDomainDefPtr def,
+ bool abortOnError,
+ virDomainSmartcardDefIterator iter,
+ void *opaque);
+
typedef int (*virDomainChrDefIterator)(virDomainDefPtr def,
virDomainChrDefPtr dev,
void *opaque);
@@ -1267,7 +1317,6 @@ int virDomainChrDefForeach(virDomainDefPtr def,
virDomainChrDefIterator iter,
void *opaque);
-
typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
const char *path,
size_t depth,
@@ -1306,6 +1355,7 @@ VIR_ENUM_DECL(virDomainNetBackend)
VIR_ENUM_DECL(virDomainChrDevice)
VIR_ENUM_DECL(virDomainChrChannelTarget)
VIR_ENUM_DECL(virDomainChrConsoleTarget)
+VIR_ENUM_DECL(virDomainSmartcard)
VIR_ENUM_DECL(virDomainChr)
VIR_ENUM_DECL(virDomainChrTcpProtocol)
VIR_ENUM_DECL(virDomainSoundModel)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3a5aec9..52e44fa 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -283,6 +283,10 @@ virDomainRemoveInactive;
virDomainSaveConfig;
virDomainSaveStatus;
virDomainSaveXML;
+virDomainSmartcardDefForeach;
+virDomainSmartcardDefFree;
+virDomainSmartcardTypeFromString;
+virDomainSmartcardTypeToString;
virDomainSnapshotAssignDef;
virDomainSnapshotDefFormat;
virDomainSnapshotDefFree;
--
1.7.4