From 531a961a96efef2be1640f240d6039ff6e7908b1 Mon Sep 17 00:00:00 2001 From: Anish Bhatt Date: Sun, 24 Jul 2016 21:18:38 -0700 Subject: [PATCH] Check iscsi iface file for transport name --- pkg/volume/iscsi/iscsi_util.go | 45 ++++++++++++++++++++++++----- pkg/volume/iscsi/iscsi_util_test.go | 43 +++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/pkg/volume/iscsi/iscsi_util.go b/pkg/volume/iscsi/iscsi_util.go index bdeec6c0df1..dd35a8280f3 100644 --- a/pkg/volume/iscsi/iscsi_util.go +++ b/pkg/volume/iscsi/iscsi_util.go @@ -22,6 +22,7 @@ import ( "os" "path" "path/filepath" + "regexp" "strings" "time" @@ -35,15 +36,15 @@ import ( type StatFunc func(string) (os.FileInfo, error) type GlobFunc func(string) ([]string, error) -func waitForPathToExist(devicePath string, maxRetries int, deviceInterface string) bool { +func waitForPathToExist(devicePath string, maxRetries int, deviceTransport string) bool { // This makes unit testing a lot easier - return waitForPathToExistInternal(devicePath, maxRetries, deviceInterface, os.Stat, filepath.Glob) + return waitForPathToExistInternal(devicePath, maxRetries, deviceTransport, os.Stat, filepath.Glob) } -func waitForPathToExistInternal(devicePath string, maxRetries int, deviceInterface string, osStat StatFunc, filepathGlob GlobFunc) bool { +func waitForPathToExistInternal(devicePath string, maxRetries int, deviceTransport string, osStat StatFunc, filepathGlob GlobFunc) bool { for i := 0; i < maxRetries; i++ { var err error - if deviceInterface == "default" { + if deviceTransport == "tcp" { _, err = osStat(devicePath) } else { fpath, _ := filepathGlob(devicePath) @@ -99,12 +100,25 @@ func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string { func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error { var devicePath string - if b.iface == "default" { + var iscsiTransport string + + out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "iface", "-I", b.iface, "-o", "show"}) + if err != nil { + glog.Errorf("iscsi: could not read iface %s error: %s", b.iface, string(out)) + return err + } + + iscsiTransport = extractTransportname(string(out)) + + if iscsiTransport == "" { + glog.Errorf("iscsi: could not find transport name in iface %s", b.iface) + return errors.New(fmt.Sprintf("Could not parse iface file for %s", b.iface)) + } else if iscsiTransport == "tcp" { devicePath = strings.Join([]string{"/dev/disk/by-path/ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-") } else { devicePath = strings.Join([]string{"/dev/disk/by-path/pci", "*", "ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-") } - exist := waitForPathToExist(devicePath, 1, b.iface) + exist := waitForPathToExist(devicePath, 1, iscsiTransport) if exist == false { // discover iscsi target out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", b.portal, "-I", b.iface}) @@ -118,7 +132,7 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error { glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err) return err } - exist = waitForPathToExist(devicePath, 10, b.iface) + exist = waitForPathToExist(devicePath, 10, iscsiTransport) if !exist { return errors.New("Could not attach disk: Timeout after 10s") } @@ -184,6 +198,23 @@ func (util *ISCSIUtil) DetachDisk(c iscsiDiskUnmounter, mntPath string) error { return nil } +func extractTransportname(ifaceOutput string) (iscsiTransport string) { + re := regexp.MustCompile(`iface.transport_name = (.*)\n`) + + rex_output := re.FindStringSubmatch(ifaceOutput) + if rex_output != nil { + iscsiTransport = rex_output[1] + } else { + return "" + } + + // While iface.transport_name is a required parameter, handle it being unspecified anyways + if iscsiTransport == "" { + iscsiTransport = "tcp" + } + return iscsiTransport +} + func extractDeviceAndPrefix(mntPath string) (string, string, error) { ind := strings.LastIndex(mntPath, "/") if ind < 0 { diff --git a/pkg/volume/iscsi/iscsi_util_test.go b/pkg/volume/iscsi/iscsi_util_test.go index 70309474316..fb32ac7d99f 100644 --- a/pkg/volume/iscsi/iscsi_util_test.go +++ b/pkg/volume/iscsi/iscsi_util_test.go @@ -86,11 +86,50 @@ func fakeFilepathGlob(devicePath string) (globs []string, err error) { return []string{devicePath}, nil } +func TestextractTransportname(t *testing.T) { + fakeIscsiadmOutput := []string{ + "# BEGIN RECORD 2.0-873\n" + + "iface.iscsi_ifacename = default\n" + + "iface.transport_name = tcp\n" + + "iface.initiatorname = \n" + + "# END RECORD", + "# BEGIN RECORD 2.0-873\n" + + "iface.iscsi_ifacename = default\n" + + "iface.transport_name = cxgb4i\n" + + "iface.initiatorname = \n" + + "# END RECORD", + "# BEGIN RECORD 2.0-873\n" + + "iface.iscsi_ifacename = default\n" + + "iface.transport_name = \n" + + "iface.initiatorname = \n" + + "# END RECORD", + "# BEGIN RECORD 2.0-873\n" + + "iface.iscsi_ifacename = default\n" + + "iface.initiatorname = \n" + + "# END RECORD"} + transportName := extractTransportname(fakeIscsiadmOutput[0]) + if transportName != "tcp" { + t.Errorf("extractTransportname: Could not extract correct iface.transport_name 'tcp', got %s", transportName) + } + transportName = extractTransportname(fakeIscsiadmOutput[1]) + if transportName != "cxgb4i" { + t.Errorf("extractTransportname: Could not extract correct iface.transport_name 'cxgb4i', got %s", transportName) + } + transportName = extractTransportname(fakeIscsiadmOutput[2]) + if transportName != "tcp" { + t.Errorf("extractTransportname: Could not extract correct iface.transport_name 'tcp', got %s", transportName) + } + transportName = extractTransportname(fakeIscsiadmOutput[3]) + if transportName != "" { + t.Errorf("extractTransportname: Could not extract correct iface.transport_name '', got %s", transportName) + } +} + func TestWaitForPathToExist(t *testing.T) { devicePath := []string{"/dev/disk/by-path/ip-127.0.0.1:3260-iqn.2014-12.com.example:test.tgt00-lun-0", "/dev/disk/by-path/pci-0000:00:00.0-ip-127.0.0.1:3260-iqn.2014-12.com.example:test.tgt00-lun-0"} - exist := waitForPathToExistInternal(devicePath[0], 1, "default", fakeOsStat, filepath.Glob) + exist := waitForPathToExistInternal(devicePath[0], 1, "tcp", fakeOsStat, filepath.Glob) if exist == false { t.Errorf("waitForPathToExist: could not find path %s", devicePath[0]) } @@ -103,7 +142,7 @@ func TestWaitForPathToExist(t *testing.T) { if exist == false { t.Errorf("waitForPathToExist: could not find path %s", devicePath[1]) } - exist = waitForPathToExistInternal(devicePath[1], 1, "default", os.Stat, fakeFilepathGlob) + exist = waitForPathToExistInternal(devicePath[1], 1, "tcp", os.Stat, fakeFilepathGlob) if exist != false { t.Errorf("waitForPathToExist: wrong code path called for %s", devicePath[1]) }