mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
smartcard: add domain conf support
* 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.
This commit is contained in:
parent
ffdf478be2
commit
c1be1a2e0e
1
cfg.mk
1
cfg.mk
@ -100,6 +100,7 @@ useless_free_options = \
|
|||||||
--name=virDomainInputDefFree \
|
--name=virDomainInputDefFree \
|
||||||
--name=virDomainNetDefFree \
|
--name=virDomainNetDefFree \
|
||||||
--name=virDomainObjFree \
|
--name=virDomainObjFree \
|
||||||
|
--name=virDomainSmartcardDefFree \
|
||||||
--name=virDomainSnapshotDefFree \
|
--name=virDomainSnapshotDefFree \
|
||||||
--name=virDomainSnapshotObjFree \
|
--name=virDomainSnapshotObjFree \
|
||||||
--name=virDomainSoundDefFree \
|
--name=virDomainSoundDefFree \
|
||||||
|
@ -109,7 +109,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
|||||||
"none",
|
"none",
|
||||||
"pci",
|
"pci",
|
||||||
"drive",
|
"drive",
|
||||||
"virtio-serial")
|
"virtio-serial",
|
||||||
|
"ccid")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
||||||
"block",
|
"block",
|
||||||
@ -159,7 +160,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
|
|||||||
"fdc",
|
"fdc",
|
||||||
"scsi",
|
"scsi",
|
||||||
"sata",
|
"sata",
|
||||||
"virtio-serial")
|
"virtio-serial",
|
||||||
|
"ccid")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
||||||
"auto",
|
"auto",
|
||||||
@ -232,6 +234,11 @@ VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST,
|
|||||||
"telnets",
|
"telnets",
|
||||||
"tls")
|
"tls")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainSmartcard, VIR_DOMAIN_SMARTCARD_TYPE_LAST,
|
||||||
|
"host",
|
||||||
|
"host-certificates",
|
||||||
|
"passthrough")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
|
VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
|
||||||
"sb16",
|
"sb16",
|
||||||
"es1370",
|
"es1370",
|
||||||
@ -693,6 +700,35 @@ void virDomainChrDefFree(virDomainChrDefPtr def)
|
|||||||
VIR_FREE(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)
|
void virDomainSoundDefFree(virDomainSoundDefPtr def)
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -834,6 +870,10 @@ void virDomainDefFree(virDomainDefPtr def)
|
|||||||
virDomainNetDefFree(def->nets[i]);
|
virDomainNetDefFree(def->nets[i]);
|
||||||
VIR_FREE(def->nets);
|
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++)
|
for (i = 0 ; i < def->nserials ; i++)
|
||||||
virDomainChrDefFree(def->serials[i]);
|
virDomainChrDefFree(def->serials[i]);
|
||||||
VIR_FREE(def->serials);
|
VIR_FREE(def->serials);
|
||||||
@ -1198,6 +1238,9 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
|
|||||||
for (i = 0; i < def->ncontrollers ; i++)
|
for (i = 0; i < def->ncontrollers ; i++)
|
||||||
if (cb(def, &def->controllers[i]->info, opaque) < 0)
|
if (cb(def, &def->controllers[i]->info, opaque) < 0)
|
||||||
return -1;
|
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++)
|
for (i = 0; i < def->nserials ; i++)
|
||||||
if (cb(def, &def->serials[i]->info, opaque) < 0)
|
if (cb(def, &def->serials[i]->info, opaque) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1240,16 +1283,11 @@ void virDomainDefClearDeviceAliases(virDomainDefPtr def)
|
|||||||
/* Generate a string representation of a device address
|
/* Generate a string representation of a device address
|
||||||
* @param address Device address to stringify
|
* @param address Device address to stringify
|
||||||
*/
|
*/
|
||||||
static int virDomainDeviceInfoFormat(virBufferPtr buf,
|
static int ATTRIBUTE_NONNULL(2)
|
||||||
virDomainDeviceInfoPtr info,
|
virDomainDeviceInfoFormat(virBufferPtr buf,
|
||||||
int flags)
|
virDomainDeviceInfoPtr info,
|
||||||
|
int flags)
|
||||||
{
|
{
|
||||||
if (!info) {
|
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("missing device information"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->alias &&
|
if (info->alias &&
|
||||||
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
!(flags & VIR_DOMAIN_XML_INACTIVE)) {
|
||||||
virBufferVSprintf(buf, " <alias name='%s'/>\n", info->alias);
|
virBufferVSprintf(buf, " <alias name='%s'/>\n", info->alias);
|
||||||
@ -1285,6 +1323,12 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf,
|
|||||||
info->addr.vioserial.port);
|
info->addr.vioserial.port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
|
||||||
|
virBufferVSprintf(buf, " controller='%d' slot='%d'",
|
||||||
|
info->addr.ccid.controller,
|
||||||
|
info->addr.ccid.slot);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("unknown address type '%d'"), info->type);
|
_("unknown address type '%d'"), info->type);
|
||||||
@ -1458,6 +1502,40 @@ cleanup:
|
|||||||
return ret;
|
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
|
/* Parse the XML definition for a device address
|
||||||
* @param node XML nodeset to parse for device address definition
|
* @param node XML nodeset to parse for device address definition
|
||||||
*/
|
*/
|
||||||
@ -1526,6 +1604,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
|
||||||
|
if (virDomainDeviceCcidAddressParseXML(address, &info->addr.ccid) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Should not happen */
|
/* Should not happen */
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -3185,6 +3268,128 @@ error:
|
|||||||
goto cleanup;
|
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 */
|
/* Parse the XML definition for a network interface */
|
||||||
static virDomainInputDefPtr
|
static virDomainInputDefPtr
|
||||||
virDomainInputDefParseXML(const char *ostype,
|
virDomainInputDefParseXML(const char *ostype,
|
||||||
@ -5258,6 +5463,26 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
|||||||
VIR_FREE(nodes);
|
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 */
|
/* analysis of the character devices */
|
||||||
if ((n = virXPathNodeSet("./devices/parallel", ctxt, &nodes)) < 0) {
|
if ((n = virXPathNodeSet("./devices/parallel", ctxt, &nodes)) < 0) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
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,
|
* Based on the declared <address/> info for any devices,
|
||||||
* add neccessary drive controllers which are not already present
|
* add neccessary drive controllers which are not already present
|
||||||
@ -5962,6 +6226,9 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def)
|
|||||||
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
|
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (virDomainDefMaybeAddSmartcardController(def) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6740,6 +7007,56 @@ virDomainChrDefFormat(virBufferPtr buf,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
virDomainSoundDefFormat(virBufferPtr buf,
|
virDomainSoundDefFormat(virBufferPtr buf,
|
||||||
virDomainSoundDefPtr def,
|
virDomainSoundDefPtr def,
|
||||||
@ -7546,6 +7863,10 @@ char *virDomainDefFormat(virDomainDefPtr def,
|
|||||||
if (virDomainNetDefFormat(&buf, def->nets[n], flags) < 0)
|
if (virDomainNetDefFormat(&buf, def->nets[n], flags) < 0)
|
||||||
goto cleanup;
|
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++)
|
for (n = 0 ; n < def->nserials ; n++)
|
||||||
if (virDomainChrDefFormat(&buf, def->serials[n], flags) < 0)
|
if (virDomainChrDefFormat(&buf, def->serials[n], flags) < 0)
|
||||||
goto cleanup;
|
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,
|
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
|
||||||
bool allowProbing,
|
bool allowProbing,
|
||||||
bool ignoreOpenFailure,
|
bool ignoreOpenFailure,
|
||||||
|
@ -73,6 +73,7 @@ enum virDomainDeviceAddressType {
|
|||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
|
||||||
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID,
|
||||||
|
|
||||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
||||||
};
|
};
|
||||||
@ -102,6 +103,13 @@ struct _virDomainDeviceVirtioSerialAddress {
|
|||||||
unsigned int port;
|
unsigned int port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress;
|
||||||
|
typedef virDomainDeviceCcidAddress *virDomainDeviceCcidAddressPtr;
|
||||||
|
struct _virDomainDeviceCcidAddress {
|
||||||
|
unsigned int controller;
|
||||||
|
unsigned int slot;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
|
typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
|
||||||
typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
|
typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
|
||||||
struct _virDomainDeviceInfo {
|
struct _virDomainDeviceInfo {
|
||||||
@ -111,6 +119,7 @@ struct _virDomainDeviceInfo {
|
|||||||
virDomainDevicePCIAddress pci;
|
virDomainDevicePCIAddress pci;
|
||||||
virDomainDeviceDriveAddress drive;
|
virDomainDeviceDriveAddress drive;
|
||||||
virDomainDeviceVirtioSerialAddress vioserial;
|
virDomainDeviceVirtioSerialAddress vioserial;
|
||||||
|
virDomainDeviceCcidAddress ccid;
|
||||||
} addr;
|
} addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,6 +229,7 @@ enum virDomainControllerType {
|
|||||||
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
|
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
|
||||||
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
|
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
|
||||||
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
|
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
|
||||||
|
VIR_DOMAIN_CONTROLLER_TYPE_CCID,
|
||||||
|
|
||||||
VIR_DOMAIN_CONTROLLER_TYPE_LAST
|
VIR_DOMAIN_CONTROLLER_TYPE_LAST
|
||||||
};
|
};
|
||||||
@ -461,6 +471,33 @@ struct _virDomainChrDef {
|
|||||||
virDomainDeviceInfo info;
|
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 {
|
enum virDomainInputType {
|
||||||
VIR_DOMAIN_INPUT_TYPE_MOUSE,
|
VIR_DOMAIN_INPUT_TYPE_MOUSE,
|
||||||
VIR_DOMAIN_INPUT_TYPE_TABLET,
|
VIR_DOMAIN_INPUT_TYPE_TABLET,
|
||||||
@ -1032,6 +1069,9 @@ struct _virDomainDef {
|
|||||||
int nhostdevs;
|
int nhostdevs;
|
||||||
virDomainHostdevDefPtr *hostdevs;
|
virDomainHostdevDefPtr *hostdevs;
|
||||||
|
|
||||||
|
int nsmartcards;
|
||||||
|
virDomainSmartcardDefPtr *smartcards;
|
||||||
|
|
||||||
int nserials;
|
int nserials;
|
||||||
virDomainChrDefPtr *serials;
|
virDomainChrDefPtr *serials;
|
||||||
|
|
||||||
@ -1110,6 +1150,7 @@ void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
|
|||||||
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
||||||
void virDomainFSDefFree(virDomainFSDefPtr def);
|
void virDomainFSDefFree(virDomainFSDefPtr def);
|
||||||
void virDomainNetDefFree(virDomainNetDefPtr def);
|
void virDomainNetDefFree(virDomainNetDefPtr def);
|
||||||
|
void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def);
|
||||||
void virDomainChrDefFree(virDomainChrDefPtr def);
|
void virDomainChrDefFree(virDomainChrDefPtr def);
|
||||||
void virDomainChrSourceDefFree(virDomainChrSourceDefPtr def);
|
void virDomainChrSourceDefFree(virDomainChrSourceDefPtr def);
|
||||||
void virDomainSoundDefFree(virDomainSoundDefPtr def);
|
void virDomainSoundDefFree(virDomainSoundDefPtr def);
|
||||||
@ -1258,6 +1299,15 @@ int virDomainObjListGetInactiveNames(virDomainObjListPtr doms,
|
|||||||
char **const names,
|
char **const names,
|
||||||
int maxnames);
|
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,
|
typedef int (*virDomainChrDefIterator)(virDomainDefPtr def,
|
||||||
virDomainChrDefPtr dev,
|
virDomainChrDefPtr dev,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
@ -1267,7 +1317,6 @@ int virDomainChrDefForeach(virDomainDefPtr def,
|
|||||||
virDomainChrDefIterator iter,
|
virDomainChrDefIterator iter,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
|
||||||
|
|
||||||
typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
|
typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
|
||||||
const char *path,
|
const char *path,
|
||||||
size_t depth,
|
size_t depth,
|
||||||
@ -1306,6 +1355,7 @@ VIR_ENUM_DECL(virDomainNetBackend)
|
|||||||
VIR_ENUM_DECL(virDomainChrDevice)
|
VIR_ENUM_DECL(virDomainChrDevice)
|
||||||
VIR_ENUM_DECL(virDomainChrChannelTarget)
|
VIR_ENUM_DECL(virDomainChrChannelTarget)
|
||||||
VIR_ENUM_DECL(virDomainChrConsoleTarget)
|
VIR_ENUM_DECL(virDomainChrConsoleTarget)
|
||||||
|
VIR_ENUM_DECL(virDomainSmartcard)
|
||||||
VIR_ENUM_DECL(virDomainChr)
|
VIR_ENUM_DECL(virDomainChr)
|
||||||
VIR_ENUM_DECL(virDomainChrTcpProtocol)
|
VIR_ENUM_DECL(virDomainChrTcpProtocol)
|
||||||
VIR_ENUM_DECL(virDomainSoundModel)
|
VIR_ENUM_DECL(virDomainSoundModel)
|
||||||
|
@ -283,6 +283,10 @@ virDomainRemoveInactive;
|
|||||||
virDomainSaveConfig;
|
virDomainSaveConfig;
|
||||||
virDomainSaveStatus;
|
virDomainSaveStatus;
|
||||||
virDomainSaveXML;
|
virDomainSaveXML;
|
||||||
|
virDomainSmartcardDefForeach;
|
||||||
|
virDomainSmartcardDefFree;
|
||||||
|
virDomainSmartcardTypeFromString;
|
||||||
|
virDomainSmartcardTypeToString;
|
||||||
virDomainSnapshotAssignDef;
|
virDomainSnapshotAssignDef;
|
||||||
virDomainSnapshotDefFormat;
|
virDomainSnapshotDefFormat;
|
||||||
virDomainSnapshotDefFree;
|
virDomainSnapshotDefFree;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user