diff --git a/remote/mounter/block_device_utils/mpath.go b/remote/mounter/block_device_utils/mpath.go index 381cd514..fb982a9b 100644 --- a/remote/mounter/block_device_utils/mpath.go +++ b/remote/mounter/block_device_utils/mpath.go @@ -111,6 +111,8 @@ func (b *blockDeviceUtils) mpathDevFullPath(dev string) string { func (b *blockDeviceUtils) DiscoverBySgInq(mpathOutput string, volumeWwn string) (string, error) { defer b.logger.Trace(logs.DEBUG)() + mpathOutput = utils.ExcludeNoTargetPortGroupMessagesFromMultipathOutput(mpathOutput, b.logger) + scanner := bufio.NewScanner(strings.NewReader(mpathOutput)) // regex to find all dm-X line from IBM vendor. // Note: searching "IBM" in the line also focus the search on IBM devices only and also eliminate the need to run sg_inq on faulty devices. diff --git a/utils/mpath.go b/utils/mpath.go index f1b32c12..4bf78c23 100644 --- a/utils/mpath.go +++ b/utils/mpath.go @@ -2,12 +2,16 @@ package utils import ( "bufio" + "fmt" "regexp" "strings" + + "github.com/IBM/ubiquity/utils/logs" ) const multipathCmd = "multipath" const MultipathTimeout = 10 * 1000 +const WarningNoTargetPortGroup = "couldn't get target port group" /* GetMultipathOutputAndDeviceMapperAndDevice analysises the output of command "multipath -ll", @@ -85,3 +89,26 @@ func GetMultipathOutputAndDeviceMapperAndDevice(volumeWwn string, exec Executor) } return outputBytes, devMapper, deviceNames, nil } + +func excludeWarningMessageLines(inputData string, warningPattern *regexp.Regexp, logger logs.Logger) string { + scanner := bufio.NewScanner(strings.NewReader(inputData)) + res := "" + for scanner.Scan() { + line := scanner.Text() + if warningPattern.MatchString(line) { + logger.Debug(fmt.Sprintf(`Found warning message line "%s", exclude it.`, line)) + continue + } + if res == "" { + res = line + } else { + res = res + "\n" + line + } + } + return res +} + +func ExcludeNoTargetPortGroupMessagesFromMultipathOutput(mpathOutput string, logger logs.Logger) string { + regex, _ := regexp.Compile(WarningNoTargetPortGroup) + return excludeWarningMessageLines(mpathOutput, regex, logger) +} diff --git a/utils/mpath_test.go b/utils/mpath_test.go index caa47f27..0572ef3b 100644 --- a/utils/mpath_test.go +++ b/utils/mpath_test.go @@ -6,6 +6,7 @@ import ( "github.com/IBM/ubiquity/fakes" "github.com/IBM/ubiquity/utils" + "github.com/IBM/ubiquity/utils/logs" ) const ( @@ -18,7 +19,7 @@ const ( fakeProfile = "gold" ) -var fakeWwn = "6005076306ffd69d0000000000001004" +var fakeWwn = "6005076306FFD69d0000000000001004" var fakeMultipathOutput = ` mpathg (36005076306ffd69d0000000000001004) dm-14 IBM ,2107900 @@ -35,7 +36,7 @@ size=2.0G features='1 queue_if_no_path' hwhandler='0' wp=rw ` + "`- 29:0:7:0 sdd 8:48 active ready running\n" var fakeMultipathOutputWithMultiplePathGroups = ` -mpathc (6005076306ffd69d0000000000001004) dm-4 IBM ,2145 +mpathc (36005076306ffd69d0000000000001004) dm-4 IBM ,2145 size=1.0G features='0' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=50 status=active | '- 43:0:0:3 sda 8:112 active ready running @@ -50,7 +51,7 @@ size=1.0G features='1 queue_if_no_path' hwhandler='0' wp=rw ` var fakeMultipathOutputWithDifferentSpaces = ` -mpathj (6005076306ffd69d0000000000001004) dm-27 IBM ,2107900 +mpathj (36005076306ffd69d0000000000001004) dm-27 IBM ,2107900 size=1.0G features='0' hwhandler='0' wp=rw '-+- policy='service-time 0' prio=1 status=active |- 33:0:12:1 sdcp 69:208 active ready running @@ -61,7 +62,37 @@ size=1.0G features='0' hwhandler='0' wp=rw '- 34:0:9:1 sdcq 69:224 active ready running ` -var _ = Describe("scbe_mounter_test", func() { +var fakeMultipathOutputWithWarnings = ` +Apr 04 16:38:06 | sde: couldn't get target port group +Apr 04 16:38:06 | sdd: couldn't get target port group +mpathj (36005076306ffd69d0000000000001004) dm-17 IBM ,2145 +size=1.0G features='1 queue_if_no_path' hwhandler='0' wp=rw +|-+- policy='service-time 0' prio=0 status=enabled +| '- 39:0:0:1 sde 8:64 failed faulty running +'-+- policy='service-time 0' prio=0 status=enabled + '- 40:0:0:1 sdd 8:48 failed faulty running +mpathi (3600507680c8701159800000000001af3) dm-14 IBM ,2145 +size=20G features='1 queue_if_no_path' hwhandler='0' wp=rw +|-+- policy='service-time 0' prio=50 status=active +| '- 40:0:0:0 sdb 8:16 active ready running +'-+- policy='service-time 0' prio=10 status=enabled + '- 39:0:0:0 sdc 8:32 active ready running +` + +var fakeMultipathOutputWithWarningsExcluded = `mpathj (36005076306ffd69d0000000000001004) dm-17 IBM ,2145 +size=1.0G features='1 queue_if_no_path' hwhandler='0' wp=rw +|-+- policy='service-time 0' prio=0 status=enabled +| '- 39:0:0:1 sde 8:64 failed faulty running +'-+- policy='service-time 0' prio=0 status=enabled + '- 40:0:0:1 sdd 8:48 failed faulty running +mpathi (3600507680c8701159800000000001af3) dm-14 IBM ,2145 +size=20G features='1 queue_if_no_path' hwhandler='0' wp=rw +|-+- policy='service-time 0' prio=50 status=active +| '- 40:0:0:0 sdb 8:16 active ready running +'-+- policy='service-time 0' prio=10 status=enabled + '- 39:0:0:0 sdc 8:32 active ready running` + +var _ = Describe("multipath_utils_test", func() { var ( fakeExec *fakes.FakeExecutor ) @@ -95,5 +126,22 @@ var _ = Describe("scbe_mounter_test", func() { Expect(devMapper).To(Equal("mpathj")) Expect(devNames).To(Equal([]string{"sdcp", "sdcn", "sdco", "sdcr", "sdcs", "sdcq"})) }) + + It("should get device names from multipath output with warning header", func() { + fakeExec.ExecuteWithTimeoutReturns([]byte(fakeMultipathOutputWithWarnings), nil) + _, devMapper, devNames, err := utils.GetMultipathOutputAndDeviceMapperAndDevice(fakeWwn, fakeExec) + Ω(err).ShouldNot(HaveOccurred()) + Expect(devMapper).To(Equal("mpathj")) + Expect(devNames).To(Equal([]string{"sde", "sdd"})) + }) + }) + + Context("ExcludeNoTargetPortGroupMessagesFromMultipathOutput", func() { + + It("should exclude the warning messages from multipath output", func() { + logger := logs.GetLogger() + out := utils.ExcludeNoTargetPortGroupMessagesFromMultipathOutput(fakeMultipathOutputWithWarnings, logger) + Expect(out).To(Equal(fakeMultipathOutputWithWarningsExcluded)) + }) }) })