[libvirt] [PATCH] npiv: Auto-generate WWN if it's not specified

Osier Yang jyang at redhat.com
Tue Jan 10 04:43:52 UTC 2012


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 use Qumranet's OUI
(00:1A:4A) as the 3-byte vendor indentifier. The last 36 bits
are auto-generated.
---
 src/conf/node_device_conf.c |   35 ++++++++++++++++++-----------------
 src/libvirt_private.syms    |    1 +
 src/util/util.c             |   20 ++++++++++++++++++++
 src/util/util.h             |    1 +
 4 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index d9dc9ac..e7cc243 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -63,19 +63,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;
@@ -763,18 +756,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 (virGenerateWWN(&data->scsi_host.wwnn) < 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 (virGenerateWWN(&data->scsi_host.wwpn) < 0) {
+                    virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+                                             _("no WWPN supplied for '%s', and "
+                                               "auto-generation failed"),
+                                             def->name);
+                    goto out;
+                }
             }
 
             ctxt->node = orignode2;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ac2c52e..3b3b322 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1100,6 +1100,7 @@ virFileWriteStr;
 virFindFileInPath;
 virFormatMacAddr;
 virGenerateMacAddr;
+virGenerateWWN;
 virGetGroupID;
 virGetHostname;
 virGetUserDirectory;
diff --git a/src/util/util.c b/src/util/util.c
index 6f46d53..e6f4559 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1837,6 +1837,26 @@ void virGenerateMacAddr(const unsigned char *prefix,
     addr[5] = virRandom(256);
 }
 
+#define QUMRANET_OUI "001a4a"
+
+int virGenerateWWN(char **wwn) {
+   int suffix[5];
+
+   suffix[0] = virRandom(16);
+   suffix[1] = virRandom(256);
+   suffix[2] = virRandom(256);
+   suffix[3] = virRandom(256);
+   suffix[4] = virRandom(256);
+
+   if (virAsprintf(wwn, "%x%s%x%02x%02x%02x%02x", 0x5, QUMRANET_OUI,
+                   suffix[0], suffix[1], suffix[2],
+                   suffix[3], suffix[4]) < 0) {
+       virReportOOMError();
+       return -1;
+   }
+
+   return 0;
+}
 
 int virEnumFromString(const char *const*types,
                       unsigned int ntypes,
diff --git a/src/util/util.h b/src/util/util.h
index c9c785b..d7a0840 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -186,6 +186,7 @@ void virFormatMacAddr(const unsigned char *addr,
                       char *str);
 void virGenerateMacAddr(const unsigned char *prefix,
                         unsigned char *addr);
+int virGenerateWWN(char **wwn);
 
 int virDiskNameToIndex(const char* str);
 char *virIndexToDiskName(int idx, const char *prefix);
-- 
1.7.7.3




More information about the libvir-list mailing list