Change:
open-iscsi software initiators are currently broken for non- interfaces due to the fact that the devicePath (in ) is assumed to use the prefixing scheme for all interfaces not named . This causes waitForPathToExist to timeout after 10 seconds since the device path that it is waiting for is not the - prefixed path that is created, resulting in host logging such as: or K8S event logs such as: open-iscsi support for hardware transports was in the following commit: In this commit, software iSCSI support was assumed to be done through only the use of the default interface. According to the documentation at (Section 5.1.1) both software and offload/hardware interfaces are intended to be configured using named interface specifications and is only a backwards-compatibility vehicle. Configuration of cannot be done via the use of as this approach is specifically forbidden in the documentation: Leaving this here to help others associate various failure modes with this issue and possible resolution: In my case I am just learning and this is my first iSCSI deployment. My initial error was that I was receiving an message at discovery-time even though I had used to define a name. This approach failed because I didn't realize that iscsid needed to be bounced before it would pick up changes to that file. I had defined a custom specification and was using that to accomplish the task of setting my initiator name. I was able to unwind this mess and return to the use of once I read the code and understood what it was attempting to do.
i'm marking this as a feature request against the iscsi volume driver. RFE: support iscsi interfaces named something besides 'default'.
In theory the fix should be easy, just move the path check from iface name to transport_name. I will take a look asap, unfortunately I am travelling till monday
Sorry about the previous comment, I was logged in to the wrong account. In theory the fix should be easy, just move the path check from iface name to transport_name. I will take a look asap, unfortunately I am travelling till monday. can you share your iface file ? It will help me validate
I no longer have the file precisely as it was. However, I did have some version of what I had used committed into my VCS. While not 100% sure this is what I was using while encountering the failure it does looks to be about what I'd expect:

Discussion:
"os" "path" "path/filepath" <ins> "regexp" </ins> "strings" "time"

type StatFunc func(string) (os.FileInfo, error) type GlobFunc func(string) ([]string, error) <del> func waitForPathToExist(devicePath string, maxRetries int, deviceInterface string) bool { </del> <ins> func waitForPathToExist(devicePath string, maxRetries int, deviceTransport string) bool { </ins> // This makes unit testing a lot easier <del> return waitForPathToExistInternal(devicePath, maxRetries, deviceInterface, os.Stat, filepath.Glob) </del> <ins> return waitForPathToExistInternal(devicePath, maxRetries, deviceTransport, os.Stat, filepath.Glob) </ins> } <del> func waitForPathToExistInternal(devicePath string, maxRetries int, deviceInterface string, osStat StatFunc, filepathGlob GlobFunc) bool { </del> <ins> func waitForPathToExistInternal(devicePath string, maxRetries int, deviceTransport string, osStat StatFunc, filepathGlob GlobFunc) bool { </ins> for i := 0; i < maxRetries; i++ { var err error <del> if deviceInterface == "default" { </del> <ins> if deviceTransport == "tcp" { </ins> _, err = osStat(devicePath) } else { fpath, _ := filepathGlob(devicePath)

func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error { var devicePath string <del> if b.iface == "default" { </del> <ins> 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" { </ins> 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}, "-") } <del> exist := waitForPathToExist(devicePath, 1, b.iface) </del> <ins> exist := waitForPathToExist(devicePath, 1, iscsiTransport) </ins> if exist == false { // discover iscsi target out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", b.portal, "-I", b.iface})

glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err) return err } <del> exist = waitForPathToExist(devicePath, 10, b.iface) </del> <ins> exist = waitForPathToExist(devicePath, 10, iscsiTransport) </ins> if !exist { return errors.New("Could not attach disk: Timeout after 10s") }

return nil } <ins> 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 } </ins> func extractDeviceAndPrefix(mntPath string) (string, string, error) { ind := strings.LastIndex(mntPath, "/") if ind < 0 {

return []string{devicePath}, nil } <ins> func TestextractTransportname(t *testing.T) { fakeIscsiadmOutput := []string{ "# BEGIN RECORD 2.0-873n" + "iface.iscsi_ifacename = defaultn" + "iface.transport_name = tcpn" + "iface.initiatorname = <empty>n" + "# END RECORD", "# BEGIN RECORD 2.0-873n" + "iface.iscsi_ifacename = defaultn" + "iface.transport_name = cxgb4in" + "iface.initiatorname = <empty>n" + "# END RECORD", "# BEGIN RECORD 2.0-873n" + "iface.iscsi_ifacename = defaultn" + "iface.transport_name = <empty>n" + "iface.initiatorname = <empty>n" + "# END RECORD", "# BEGIN RECORD 2.0-873n" + "iface.iscsi_ifacename = defaultn" + "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) } } </ins> 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"} <del> exist := waitForPathToExistInternal(devicePath[0], 1, "default", fakeOsStat, filepath.Glob) </del> <ins> exist := waitForPathToExistInternal(devicePath[0], 1, "tcp", fakeOsStat, filepath.Glob) </ins> if exist == false { t.Errorf("waitForPathToExist: could not find path %s", devicePath[0]) }

if exist == false { t.Errorf("waitForPathToExist: could not find path %s", devicePath[1]) } <del> exist = waitForPathToExistInternal(devicePath[1], 1, "default", os.Stat, fakeFilepathGlob) </del> <ins> exist = waitForPathToExistInternal(devicePath[1], 1, "tcp", os.Stat, fakeFilepathGlob) </ins> if exist != false { t.Errorf("waitForPathToExist: wrong code path called for %s", devicePath[1]) }