diff --git a/po/POTFILES.in b/po/POTFILES.in index 5a7ecae757..35ddf83a35 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -134,6 +134,7 @@ src/util/virnetdevvportprofile.c src/util/virnetlink.c src/util/virnodesuspend.c src/util/virpidfile.c +src/util/virrandom.c src/util/virsocketaddr.c src/util/virterror.c src/util/virtime.c diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index d9dc9ac777..c21150d772 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -37,6 +37,7 @@ #include "buf.h" #include "uuid.h" #include "pci.h" +#include "virrandom.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV @@ -63,19 +64,12 @@ VIR_ENUM_IMPL(virNodeDevHBACap, VIR_NODE_DEV_CAP_HBA_LAST, static int virNodeDevCapsDefParseString(const char *xpath, xmlXPathContextPtr ctxt, - char **string, - virNodeDeviceDefPtr def, - const char *missing_error_fmt) + char **string) { char *s; - s = virXPathString(xpath, ctxt); - if (s == NULL) { - virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, - missing_error_fmt, - def->name); + if (!(s = virXPathString(xpath, ctxt))) return -1; - } *string = s; return 0; @@ -717,7 +711,8 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, xmlNodePtr node, union _virNodeDevCapData *data, - int create) + int create, + const char *virt_type) { xmlNodePtr orignode, *nodes = NULL; int ret = -1, n = 0, i; @@ -763,18 +758,26 @@ virNodeDevCapScsiHostParseXML(xmlXPathContextPtr ctxt, if (virNodeDevCapsDefParseString("string(./wwnn[1])", ctxt, - &data->scsi_host.wwnn, - def, - _("no WWNN supplied for '%s'")) < 0) { - goto out; + &data->scsi_host.wwnn) < 0) { + if (virRandomGenerateWWN(&data->scsi_host.wwnn, virt_type) < 0) { + virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, + _("no WWNN supplied for '%s', and " + "auto-generation failed"), + def->name); + goto out; + } } if (virNodeDevCapsDefParseString("string(./wwpn[1])", ctxt, - &data->scsi_host.wwpn, - def, - _("no WWPN supplied for '%s'")) < 0) { - goto out; + &data->scsi_host.wwpn) < 0) { + if (virRandomGenerateWWN(&data->scsi_host.wwpn, virt_type) < 0) { + virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR, + _("no WWPN supplied for '%s', and " + "auto-generation failed"), + def->name); + goto out; + } } ctxt->node = orignode2; @@ -1060,7 +1063,8 @@ static virNodeDevCapsDefPtr virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDefPtr def, xmlNodePtr node, - int create) + int create, + const char *virt_type) { virNodeDevCapsDefPtr caps; char *tmp; @@ -1104,7 +1108,10 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapNetParseXML(ctxt, def, node, &caps->data); break; case VIR_NODE_DEV_CAP_SCSI_HOST: - ret = virNodeDevCapScsiHostParseXML(ctxt, def, node, &caps->data, create); + ret = virNodeDevCapScsiHostParseXML(ctxt, def, node, + &caps->data, + create, + virt_type); break; case VIR_NODE_DEV_CAP_SCSI_TARGET: ret = virNodeDevCapScsiTargetParseXML(ctxt, def, node, &caps->data); @@ -1133,7 +1140,9 @@ error: } static virNodeDeviceDefPtr -virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create) +virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, + int create, + const char *virt_type) { virNodeDeviceDefPtr def; virNodeDevCapsDefPtr *next_cap; @@ -1180,7 +1189,10 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create) next_cap = &def->caps; for (i = 0 ; i < n ; i++) { - *next_cap = virNodeDevCapsDefParseXML(ctxt, def, nodes[i], create); + *next_cap = virNodeDevCapsDefParseXML(ctxt, def, + nodes[i], + create, + virt_type); if (!*next_cap) { VIR_FREE(nodes); goto error; @@ -1200,7 +1212,8 @@ virNodeDeviceDefParseXML(xmlXPathContextPtr ctxt, int create) virNodeDeviceDefPtr virNodeDeviceDefParseNode(xmlDocPtr xml, xmlNodePtr root, - int create) + int create, + const char *virt_type) { xmlXPathContextPtr ctxt = NULL; virNodeDeviceDefPtr def = NULL; @@ -1220,7 +1233,7 @@ virNodeDeviceDefParseNode(xmlDocPtr xml, } ctxt->node = root; - def = virNodeDeviceDefParseXML(ctxt, create); + def = virNodeDeviceDefParseXML(ctxt, create, virt_type); cleanup: xmlXPathFreeContext(ctxt); @@ -1230,13 +1243,15 @@ cleanup: static virNodeDeviceDefPtr virNodeDeviceDefParse(const char *str, const char *filename, - int create) + int create, + const char *virt_type) { xmlDocPtr xml; virNodeDeviceDefPtr def = NULL; if ((xml = virXMLParse(filename, str, _("(node_device_definition)")))) { - def = virNodeDeviceDefParseNode(xml, xmlDocGetRootElement(xml), create); + def = virNodeDeviceDefParseNode(xml, xmlDocGetRootElement(xml), + create, virt_type); xmlFreeDoc(xml); } @@ -1245,16 +1260,18 @@ virNodeDeviceDefParse(const char *str, virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str, - int create) + int create, + const char *virt_type) { - return virNodeDeviceDefParse(str, NULL, create); + return virNodeDeviceDefParse(str, NULL, create, virt_type); } virNodeDeviceDefPtr virNodeDeviceDefParseFile(const char *filename, - int create) + int create, + const char *virt_type) { - return virNodeDeviceDefParse(NULL, filename, create); + return virNodeDeviceDefParse(NULL, filename, create, virt_type); } /* diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index a1833a0e62..4aaf4c878b 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -234,12 +234,15 @@ void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def); virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str, - int create); + int create, + const char *virt_type); virNodeDeviceDefPtr virNodeDeviceDefParseFile(const char *filename, - int create); + int create, + const char *virt_type); virNodeDeviceDefPtr virNodeDeviceDefParseNode(xmlDocPtr xml, xmlNodePtr root, - int create); + int create, + const char *virt_type); int virNodeDeviceGetWWNs(virNodeDeviceDefPtr def, char **wwnn, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a5f9433da9..0c22dec0b5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1373,6 +1373,7 @@ virPidFileDeletePath; # virrandom.h virRandomBits; +virRandomGenerateWWN; virRandomInitialize; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 681655e512..b0a29cdd46 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -558,12 +558,14 @@ nodeDeviceCreateXML(virConnectPtr conn, char *wwnn = NULL, *wwpn = NULL; int parent_host = -1; virNodeDevicePtr dev = NULL; + const char *virt_type = NULL; virCheckFlags(0, NULL); + virt_type = virConnectGetType(conn); nodeDeviceLock(driver); - def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE); + def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type); if (def == NULL) { goto cleanup; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 45c4100c42..160cb37efb 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9045,7 +9045,7 @@ qemudNodeDeviceGetPciInfo (virNodeDevicePtr dev, if (!xml) goto out; - def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE); + def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL); if (!def) goto out; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index bf6b14835b..39fd63dea7 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -608,7 +608,7 @@ static int testOpenDefault(virConnectPtr conn) { virStoragePoolObjUnlock(poolobj); /* Init default node device */ - if (!(nodedef = virNodeDeviceDefParseString(defaultNodeXML, 0))) + if (!(nodedef = virNodeDeviceDefParseString(defaultNodeXML, 0, NULL))) goto error; if (!(nodeobj = virNodeDeviceAssignDef(&privconn->devs, nodedef))) { @@ -1057,12 +1057,12 @@ static int testOpenFromFile(virConnectPtr conn, goto error; } - def = virNodeDeviceDefParseFile(absFile, 0); + def = virNodeDeviceDefParseFile(absFile, 0, NULL); VIR_FREE(absFile); if (!def) goto error; } else { - if ((def = virNodeDeviceDefParseNode(xml, devs[i], 0)) == NULL) + if ((def = virNodeDeviceDefParseNode(xml, devs[i], 0, NULL)) == NULL) goto error; } if (!(dev = virNodeDeviceAssignDef(&privconn->devs, def))) { @@ -5285,7 +5285,7 @@ testNodeDeviceCreateXML(virConnectPtr conn, testDriverLock(driver); - def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE); + def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, NULL); if (def == NULL) { goto cleanup; } diff --git a/src/util/virrandom.c b/src/util/virrandom.c index ec0cf0336a..630bc003af 100644 --- a/src/util/virrandom.c +++ b/src/util/virrandom.c @@ -22,10 +22,20 @@ #include #include +#include #include "virrandom.h" #include "threads.h" #include "count-one-bits.h" +#include "util.h" +#include "virterror_internal.h" +#include "conf/domain_conf.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +#define virRandomError(code, ...) \ + virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) static char randomState[128]; static struct random_data randomData; @@ -79,3 +89,45 @@ uint64_t virRandomBits(int nbits) virMutexUnlock(&randomLock); return ret; } + +#define QUMRANET_OUI "001a4a" +#define VMWARE_OUI "000569" +#define MICROSOFT_OUI "0050f2" +#define XEN_OUI "00163e" + +int +virRandomGenerateWWN(char **wwn, + const char *virt_type) { + const char *oui = NULL; + + if (!virt_type) { + virRandomError(VIR_ERR_INVALID_ARG, "%s", + _("argument virt_type must not be NULL")); + return -1; + } + + if (STREQ(virt_type, "QEMU")) { + oui = QUMRANET_OUI; + } else if (STREQ(virt_type, "Xen") || + STREQ(virt_type, "xenlight") || + STREQ(virt_type, "XenAPI")) { + oui = XEN_OUI; + } else if (STREQ(virt_type, "ESX") || + STREQ(virt_type, "VMWARE")) { + oui = VMWARE_OUI; + } else if (STREQ(virt_type, "HYPER-V")) { + oui = MICROSOFT_OUI; + } else { + virRandomError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Unsupported virt type")); + return -1; + } + + if (virAsprintf(wwn, "5" "%s%09" PRIx64, + oui, virRandomBits(36)) < 0) { + virReportOOMError(); + return -1; + } + + return 0; +} diff --git a/src/util/virrandom.h b/src/util/virrandom.h index e180a2fb8a..24ab0b14f8 100644 --- a/src/util/virrandom.h +++ b/src/util/virrandom.h @@ -27,5 +27,6 @@ int virRandomInitialize(uint32_t seed) ATTRIBUTE_RETURN_CHECK; uint64_t virRandomBits(int nbits); +int virRandomGenerateWWN(char **wwn, const char *virt_type); #endif /* __VIR_RANDOM_H__ */ diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 94cafde166..635f4685b0 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -1950,7 +1950,7 @@ xenUnifiedNodeDeviceGetPciInfo (virNodeDevicePtr dev, if (!xml) goto out; - def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE); + def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL); if (!def) goto out; diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index ad93161144..c002eadd6e 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -24,7 +24,7 @@ testCompareXMLToXMLFiles(const char *xml) if (virtTestLoadFile(xml, &xmlData) < 0) goto fail; - if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE))) + if (!(dev = virNodeDeviceDefParseString(xmlData, EXISTING_DEVICE, NULL))) goto fail; if (!(actual = virNodeDeviceDefFormat(dev)))