fabric_name is one of many fc_host attributes in Linux that is optional and left to the low-level driver to decide if it is implemented. The zfcp device driver does not provide a fabric name for an fcp host. This patch removes the requirement for a fabric name by making it optional. Signed-off-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxxxxxxx> --- docs/formatnode.html.in | 2 +- docs/news.xml | 12 +++++++++ docs/schemas/nodedev.rng | 8 +++--- src/libvirt_private.syms | 1 + src/node_device/node_device_linux_sysfs.c | 6 ++--- src/util/virutil.c | 23 ++++++++++++++++ src/util/virutil.h | 5 ++++ tests/fchostdata/fc_host/host6/node_name | 1 + tests/fchostdata/fc_host/host6/port_name | 1 + tests/fchostdata/fc_host/host6/port_state | 1 + tests/fchosttest.c | 44 ++++++++++++++++++++++++++++--- 11 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 tests/fchostdata/fc_host/host6/node_name create mode 100644 tests/fchostdata/fc_host/host6/port_name create mode 100644 tests/fchostdata/fc_host/host6/port_state diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in index e7b1140..f8d0e12 100644 --- a/docs/formatnode.html.in +++ b/docs/formatnode.html.in @@ -254,7 +254,7 @@ number of vport in use. <code>max_vports</code> shows the maximum vports the HBA supports. "fc_host" implies following sub-elements: <code>wwnn</code>, <code>wwpn</code>, and - <code>fabric_wwn</code>. + optionally <code>fabric_wwn</code>. </dd> </dl> </dd> diff --git a/docs/news.xml b/docs/news.xml index 50c3b3e..a645953 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -144,6 +144,18 @@ <section title="Bug fixes"> <change> <summary> + nodedev: Fabric name must not be required for fc_host capability + </summary> + <description> + fabric_name is one of many fc_host attributes in Linux that is + optional and left to the low-level driver to decide if it is + implemented. For example the zfcp device driver does not provide a + fabric name for an fcp host. The requirement for the existence of + a fabric name has been removed by making it optional. + </description> + </change> + <change> + <summary> qemu: Correct GetBlockInfo values </summary> <description> diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng index 9c98402..b100a6e 100644 --- a/docs/schemas/nodedev.rng +++ b/docs/schemas/nodedev.rng @@ -367,9 +367,11 @@ <ref name='wwn'/> </element> - <element name='fabric_wwn'> - <ref name='wwn'/> - </element> + <optional> + <element name='fabric_wwn'> + <ref name='wwn'/> + </element> + </optional> </define> <define name='capsvports'> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 70ed87b..43f460f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2717,6 +2717,7 @@ virParseOwnershipIds; virParseVersionString; virPipeReadUntilEOF; virReadFCHost; +virReadFCHostOption; virReadSCSIUniqueId; virScaleInteger; virSetBlocking; diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index be99c41..1bb5b74 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -72,10 +72,10 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d) VIR_FREE(d->scsi_host.wwnn); VIR_STEAL_PTR(d->scsi_host.wwnn, tmp); - if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, "fabric_name"))) { - VIR_WARN("Failed to read fabric WWN for host%d", + if (!(tmp = virReadFCHostOption(NULL, d->scsi_host.host, + "fabric_name", false))) { + VIR_INFO("Optional fabric WWN for host%d not available", d->scsi_host.host); - goto cleanup; } VIR_FREE(d->scsi_host.fabric_wwn); VIR_STEAL_PTR(d->scsi_host.fabric_wwn, tmp); diff --git a/src/util/virutil.c b/src/util/virutil.c index aeaa7f9..5bfbf37 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -2019,6 +2019,26 @@ virReadFCHost(const char *sysfs_prefix, int host, const char *entry) { + return virReadFCHostOption(sysfs_prefix, host, entry, true); +} + +/* virReadFCHostOption: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @host: Host number, E.g. 5 of "fc_host/host5" + * @entry: Name of the sysfs entry to read + * @required: If true reports error when entry not found else no error + * + * Read the value of sysfs "fc_host" entry. + * + * Returns result as a string on success, caller must free @result after + * Otherwise returns NULL. + */ +char * +virReadFCHostOption(const char *sysfs_prefix, + int host, + const char *entry, + bool required) +{ char *sysfs_path = NULL; char *p = NULL; char *buf = NULL; @@ -2029,6 +2049,9 @@ virReadFCHost(const char *sysfs_prefix, host, entry) < 0) goto cleanup; + if (!required && !virFileExists(sysfs_path)) + goto cleanup; + if (virFileReadAll(sysfs_path, 1024, &buf) < 0) goto cleanup; diff --git a/src/util/virutil.h b/src/util/virutil.h index 3fbd7b0..db86052 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -186,6 +186,11 @@ char *virReadFCHost(const char *sysfs_prefix, int host, const char *entry) ATTRIBUTE_NONNULL(3); +char *virReadFCHostOption(const char *sysfs_prefix, + int host, + const char *entry, + bool required) + ATTRIBUTE_NONNULL(3); bool virIsCapableFCHost(const char *sysfs_prefix, int host); bool virIsCapableVport(const char *sysfs_prefix, int host); diff --git a/tests/fchostdata/fc_host/host6/node_name b/tests/fchostdata/fc_host/host6/node_name new file mode 100644 index 0000000..73a91bd --- /dev/null +++ b/tests/fchostdata/fc_host/host6/node_name @@ -0,0 +1 @@ +0x2002001b32a9da4e diff --git a/tests/fchostdata/fc_host/host6/port_name b/tests/fchostdata/fc_host/host6/port_name new file mode 100644 index 0000000..f25abeb --- /dev/null +++ b/tests/fchostdata/fc_host/host6/port_name @@ -0,0 +1 @@ +0x2102001b32a9da4e diff --git a/tests/fchostdata/fc_host/host6/port_state b/tests/fchostdata/fc_host/host6/port_state new file mode 100644 index 0000000..b73dd46 --- /dev/null +++ b/tests/fchostdata/fc_host/host6/port_state @@ -0,0 +1 @@ +Online diff --git a/tests/fchosttest.c b/tests/fchosttest.c index a08a2e8..01c20df 100644 --- a/tests/fchosttest.c +++ b/tests/fchosttest.c @@ -29,13 +29,16 @@ static char *fchost_prefix; #define TEST_FC_HOST_PREFIX fchost_prefix #define TEST_FC_HOST_NUM 5 +#define TEST_FC_HOST_NUM_NO_FAB 6 /* Test virIsCapableFCHost */ static int test1(const void *data ATTRIBUTE_UNUSED) { if (virIsCapableFCHost(TEST_FC_HOST_PREFIX, - TEST_FC_HOST_NUM)) + TEST_FC_HOST_NUM) && + virIsCapableFCHost(TEST_FC_HOST_PREFIX, + TEST_FC_HOST_NUM_NO_FAB)) return 0; return -1; @@ -76,8 +79,8 @@ test3(const void *data ATTRIBUTE_UNUSED) "port_name"))) goto cleanup; - if (!(fabric_wwn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "fabric_name"))) + if (!(fabric_wwn = virReadFCHostOption(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "fabric_name", false))) goto cleanup; if (!(max_vports = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, @@ -148,6 +151,39 @@ test5(const void *data ATTRIBUTE_UNUSED) return ret; } +/* Test virReadFCHost fabric name optional */ +static int +test6(const void *data ATTRIBUTE_UNUSED) +{ + const char *expect_wwnn = "2002001b32a9da4e"; + const char *expect_wwpn = "2102001b32a9da4e"; + char *wwnn = NULL; + char *wwpn = NULL; + int ret = -1; + + if (!(wwnn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, + "node_name"))) + return -1; + + if (!(wwpn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, + "port_name"))) + goto cleanup; + + if (virReadFCHostOption(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, + "fabric_name", false)) + goto cleanup; + + if (STRNEQ(expect_wwnn, wwnn) || + STRNEQ(expect_wwpn, wwpn)) + goto cleanup; + + ret = 0; + cleanup: + VIR_FREE(wwnn); + VIR_FREE(wwpn); + return ret; +} + static int mymain(void) { @@ -169,6 +205,8 @@ mymain(void) ret = -1; if (virTestRun("test5", test5, NULL) < 0) ret = -1; + if (virTestRun("test6", test6, NULL) < 0) + ret = -1; cleanup: VIR_FREE(fchost_prefix); -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list