]> xenbits.xensource.com Git - libvirt.git/commitdiff
npiv: Auto-generate WWN if it's not specified
authorOsier Yang <jyang@redhat.com>
Fri, 10 Feb 2012 04:51:47 +0000 (12:51 +0800)
committerOsier Yang <jyang@redhat.com>
Fri, 10 Feb 2012 04:53:25 +0000 (12:53 +0800)
The auto-generated WWN comply with the new addressing schema of WWN:

<quote>
the first nibble is either hex 5 or 6 followed by a 3-byte vendor
identifier and 36 bits for a vendor-specified serial number.
</quote>

We choose hex 5 for the first nibble. And for the 3-bytes vendor ID,
we uses the OUI according to underlying hypervisor type, (invoking
virConnectGetType to get the virt type). e.g. If virConnectGetType
returns "QEMU", we use Qumranet's OUI (00:1A:4A), if returns
ESX|VMWARE, we use VMWARE's OUI (00:05:69). Currently it only
supports qemu|xen|libxl|xenapi|hyperv|esx|vmware drivers. The last
36 bits are auto-generated.

po/POTFILES.in
src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/libvirt_private.syms
src/node_device/node_device_driver.c
src/qemu/qemu_driver.c
src/test/test_driver.c
src/util/virrandom.c
src/util/virrandom.h
src/xen/xen_driver.c
tests/nodedevxml2xmltest.c

index 5a7ecae7578ac26785922ed8933c247dc9faf2f9..35ddf83a350dd58bc574127de9d2272855b5fea1 100644 (file)
@@ -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
index d9dc9ac7778e5d6e3974faa793f3afe6db69c434..c21150d7720711e23b9c282ed344d0792418d092 100644 (file)
@@ -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);
 }
 
 /*
index a1833a0e62b3810b79e45d480ef081b7f3ae5356..4aaf4c878b7c64739d250b308e90d0d6ccc4d614 100644 (file)
@@ -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,
index a5f9433da92651ed310daa1ee5e01e1b50adff92..0c22dec0b513e38d3dea1d5f9a08af9a395cd36c 100644 (file)
@@ -1373,6 +1373,7 @@ virPidFileDeletePath;
 
 # virrandom.h
 virRandomBits;
+virRandomGenerateWWN;
 virRandomInitialize;
 
 
index 681655e5123152e3db6d0a283ac3e4bafc878547..b0a29cdd4674fa3a31cf116f986be04a390d0e7a 100644 (file)
@@ -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;
     }
index 45c4100c42655c4c5ad94ca981a44e0ee87af298..160cb37efbeea243a66b3cd1345c399cf9c188cb 100644 (file)
@@ -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;
 
index bf6b14835b3155dd9269de0acb11165517cc70fb..39fd63dea7d366ceb53dc75f36d83ac6a9f895fe 100644 (file)
@@ -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;
     }
index ec0cf0336aafd9d39dc66a4f8f7e7ee8711b4884..630bc003af1360e8d3293da6f463d7efb518eaa4 100644 (file)
 #include <config.h>
 
 #include <stdlib.h>
+#include <inttypes.h>
 
 #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;
+}
index e180a2fb8a4cbd25e845a9975626b437c7964fe4..24ab0b14f82392a7b1030e6b1a62e1e3d7fa841e 100644 (file)
@@ -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__ */
index 94cafde166de9364fd17a71c41b54d817b68a085..635f4685b07fd0a07ce59ca9e806d04590378f55 100644 (file)
@@ -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;
 
index ad931611440c083aa89d9021869eb224676b717e..c002eadd6e7560a7f4dc2a6fe2ba2e8db415a8d8 100644 (file)
@@ -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)))