diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 98c0cada65..b8ba0e2d0c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -960,6 +960,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) VIR_FREE(def->mirror); VIR_FREE(def->mirrorFormat); VIR_FREE(def->auth.username); + VIR_FREE(def->wwn); if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE) VIR_FREE(def->auth.secret.usage); virStorageEncryptionFree(def->encryption); @@ -3463,6 +3464,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, char *tray = NULL; char *logical_block_size = NULL; char *physical_block_size = NULL; + char *wwn = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -3789,6 +3791,12 @@ virDomainDiskDefParseXML(virCapsPtr caps, } else if (!serial && xmlStrEqual(cur->name, BAD_CAST "serial")) { serial = (char *)xmlNodeGetContent(cur); + } else if (!wwn && + xmlStrEqual(cur->name, BAD_CAST "wwn")) { + wwn = (char *)xmlNodeGetContent(cur); + + if (!virValidateWWN(wwn)) + goto error; } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { /* boot is parsed as part of virDomainDeviceInfoParseXML */ } @@ -4085,6 +4093,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, encryption = NULL; def->serial = serial; serial = NULL; + def->wwn = wwn; + wwn = NULL; if (!def->driverType && caps->defaultDiskDriverType && @@ -4143,6 +4153,7 @@ cleanup: VIR_FREE(startupPolicy); VIR_FREE(logical_block_size); VIR_FREE(physical_block_size); + VIR_FREE(wwn); ctxt->node = save_ctxt; return def; @@ -11742,6 +11753,7 @@ virDomainDiskDefFormat(virBufferPtr buf, if (def->transient) virBufferAddLit(buf, " \n"); virBufferEscapeString(buf, " %s\n", def->serial); + virBufferEscapeString(buf, " %s\n", def->wwn); if (def->encryption) { virBufferAdjustIndent(buf, 6); if (virStorageEncryptionFormat(buf, def->encryption) < 0) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 52c9937cb6..f0dea48bf3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -584,6 +584,7 @@ struct _virDomainDiskDef { virDomainBlockIoTuneInfo blkdeviotune; char *serial; + char *wwn; int cachemode; int error_policy; /* enum virDomainDiskErrorPolicy */ int rerror_policy; /* enum virDomainDiskErrorPolicy */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ad2534b7fa..e8f3fa5b49 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1259,6 +1259,7 @@ virStrToLong_ull; virStrcpy; virStrncpy; virTrimSpaces; +virValidateWWN; virVasprintf; diff --git a/src/util/util.c b/src/util/util.c index 91eab7210e..8b1f0dc5b8 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -3052,3 +3052,20 @@ bool virIsDevMapperDevice(const char *dev_name ATTRIBUTE_UNUSED) return false; } #endif + +bool +virValidateWWN(const char *wwn) { + int i; + + for (i = 0; wwn[i]; i++) + if (!c_isxdigit(wwn[i])) + break; + + if (i != 16 || wwn[i]) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Malformed wwn: %s")); + return false; + } + + return true; +} diff --git a/src/util/util.h b/src/util/util.h index a5d892dd4c..0c0efad150 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -277,4 +277,6 @@ int virBuildPathInternal(char **path, ...) ATTRIBUTE_SENTINEL; bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1); +bool virValidateWWN(const char *wwn); + #endif /* __VIR_UTIL_H__ */