Check iscsi iface file for transport name
This commit is contained in:
		| @@ -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 == "<empty>" { | ||||
| 		iscsiTransport = "tcp" | ||||
| 	} | ||||
| 	return iscsiTransport | ||||
| } | ||||
|  | ||||
| func extractDeviceAndPrefix(mntPath string) (string, string, error) { | ||||
| 	ind := strings.LastIndex(mntPath, "/") | ||||
| 	if ind < 0 { | ||||
|   | ||||
| @@ -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]) | ||||
| 	} | ||||
| @@ -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]) | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Anish Bhatt
					Anish Bhatt