Check iscsi iface file for transport name
This commit is contained in:
		| @@ -22,6 +22,7 @@ import ( | |||||||
| 	"os" | 	"os" | ||||||
| 	"path" | 	"path" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
|  | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -35,15 +36,15 @@ import ( | |||||||
| type StatFunc func(string) (os.FileInfo, error) | type StatFunc func(string) (os.FileInfo, error) | ||||||
| type GlobFunc func(string) ([]string, 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 | 	// 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++ { | 	for i := 0; i < maxRetries; i++ { | ||||||
| 		var err error | 		var err error | ||||||
| 		if deviceInterface == "default" { | 		if deviceTransport == "tcp" { | ||||||
| 			_, err = osStat(devicePath) | 			_, err = osStat(devicePath) | ||||||
| 		} else { | 		} else { | ||||||
| 			fpath, _ := filepathGlob(devicePath) | 			fpath, _ := filepathGlob(devicePath) | ||||||
| @@ -99,12 +100,25 @@ func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string { | |||||||
|  |  | ||||||
| func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error { | func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error { | ||||||
| 	var devicePath string | 	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}, "-") | 		devicePath = strings.Join([]string{"/dev/disk/by-path/ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-") | ||||||
| 	} else { | 	} else { | ||||||
| 		devicePath = strings.Join([]string{"/dev/disk/by-path/pci", "*", "ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-") | 		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 { | 	if exist == false { | ||||||
| 		// discover iscsi target | 		// discover iscsi target | ||||||
| 		out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", b.portal, "-I", b.iface}) | 		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) | 			glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		exist = waitForPathToExist(devicePath, 10, b.iface) | 		exist = waitForPathToExist(devicePath, 10, iscsiTransport) | ||||||
| 		if !exist { | 		if !exist { | ||||||
| 			return errors.New("Could not attach disk: Timeout after 10s") | 			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 | 	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) { | func extractDeviceAndPrefix(mntPath string) (string, string, error) { | ||||||
| 	ind := strings.LastIndex(mntPath, "/") | 	ind := strings.LastIndex(mntPath, "/") | ||||||
| 	if ind < 0 { | 	if ind < 0 { | ||||||
|   | |||||||
| @@ -86,11 +86,50 @@ func fakeFilepathGlob(devicePath string) (globs []string, err error) { | |||||||
| 	return []string{devicePath}, nil | 	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) { | 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", | 	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"} | 		"/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 { | 	if exist == false { | ||||||
| 		t.Errorf("waitForPathToExist: could not find path %s", devicePath[0]) | 		t.Errorf("waitForPathToExist: could not find path %s", devicePath[0]) | ||||||
| 	} | 	} | ||||||
| @@ -103,7 +142,7 @@ func TestWaitForPathToExist(t *testing.T) { | |||||||
| 	if exist == false { | 	if exist == false { | ||||||
| 		t.Errorf("waitForPathToExist: could not find path %s", devicePath[1]) | 		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 { | 	if exist != false { | ||||||
| 		t.Errorf("waitForPathToExist: wrong code path called for %s", devicePath[1]) | 		t.Errorf("waitForPathToExist: wrong code path called for %s", devicePath[1]) | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anish Bhatt
					Anish Bhatt