Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check iscsi iface file for transport name #29532

Merged
merged 1 commit into from
Jul 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 38 additions & 7 deletions pkg/volume/iscsi/iscsi_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strings"
"time"

Expand All @@ -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)
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add the above log info to err so we know where the problem comes from in kubectl output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rootfs kinda confused how to do this. The rest of the function just prints out with glog.Errorf and returns just the error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let's make a separate PR to reformat these 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})
Expand All @@ -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")
}
Expand Down Expand Up @@ -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 == "<empty>" {
iscsiTransport = "tcp"
}
return iscsiTransport
}

func extractDeviceAndPrefix(mntPath string) (string, string, error) {
ind := strings.LastIndex(mntPath, "/")
if ind < 0 {
Expand Down
43 changes: 41 additions & 2 deletions pkg/volume/iscsi/iscsi_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <empty>\n" +
"# END RECORD",
"# BEGIN RECORD 2.0-873\n" +
"iface.iscsi_ifacename = default\n" +
"iface.transport_name = cxgb4i\n" +
"iface.initiatorname = <empty>\n" +
"# END RECORD",
"# BEGIN RECORD 2.0-873\n" +
"iface.iscsi_ifacename = default\n" +
"iface.transport_name = <empty>\n" +
"iface.initiatorname = <empty>\n" +
"# END RECORD",
"# BEGIN RECORD 2.0-873\n" +
"iface.iscsi_ifacename = default\n" +
"iface.initiatorname = <empty>\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])
}
Expand All @@ -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])
}
Expand Down