mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #29532 from anish/iscsi_iface
Automatic merge from submit-queue Check iscsi iface file for transport name When checking for tcp vs hardware transports, check actual iscsi iface file to see if we are using tcp as a transport, rather than relying on just the transport name of 'default'. This fixes the open-iscsi software iscsi initiator for non-default interfaces. fixes #27131
This commit is contained in:
commit
15c0c2c901
@ -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])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user