mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 13:45:06 +00:00
Fix for Premature iSCSI logout #39202.
This commit is contained in:
52
pkg/volume/iscsi/iscsi_util.go
Normal file → Executable file
52
pkg/volume/iscsi/iscsi_util.go
Normal file → Executable file
@@ -90,21 +90,22 @@ func getDevicePrefixRefCount(mounter mount.Interface, deviceNamePrefix string) (
|
|||||||
return refCount, nil
|
return refCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a directory like /var/lib/kubelet/plugins/kubernetes.io/iscsi/portal-some_iqn-lun-lun_id
|
// make a directory like /var/lib/kubelet/plugins/kubernetes.io/iscsi/iface_name/portal-some_iqn-lun-lun_id
|
||||||
func makePDNameInternal(host volume.VolumeHost, portal string, iqn string, lun string) string {
|
func makePDNameInternal(host volume.VolumeHost, portal string, iqn string, lun string, iface string) string {
|
||||||
return path.Join(host.GetPluginDir(iscsiPluginName), portal+"-"+iqn+"-lun-"+lun)
|
return path.Join(host.GetPluginDir(iscsiPluginName), iface, portal+"-"+iqn+"-lun-"+lun)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ISCSIUtil struct{}
|
type ISCSIUtil struct{}
|
||||||
|
|
||||||
func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string {
|
func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string {
|
||||||
return makePDNameInternal(iscsi.plugin.host, iscsi.portals[0], iscsi.iqn, iscsi.lun)
|
return makePDNameInternal(iscsi.plugin.host, iscsi.portals[0], iscsi.iqn, iscsi.lun, iscsi.iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
||||||
var devicePath string
|
var devicePath string
|
||||||
var devicePaths []string
|
var devicePaths []string
|
||||||
var iscsiTransport string
|
var iscsiTransport string
|
||||||
|
|
||||||
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "iface", "-I", b.iface, "-o", "show"})
|
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "iface", "-I", b.iface, "-o", "show"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("iscsi: could not read iface %s error: %s", b.iface, string(out))
|
glog.Errorf("iscsi: could not read iface %s error: %s", b.iface, string(out))
|
||||||
@@ -112,8 +113,16 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
iscsiTransport = extractTransportname(string(out))
|
iscsiTransport = extractTransportname(string(out))
|
||||||
|
|
||||||
bkpPortal := b.portals
|
bkpPortal := b.portals
|
||||||
for _, tp := range bkpPortal {
|
for _, tp := range bkpPortal {
|
||||||
|
// Rescan sessions to discover newly mapped LUNs. Do not specify the interface when rescanning
|
||||||
|
// to avoid establishing additional sessions to the same target.
|
||||||
|
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", tp, "-T", b.iqn, "-R"})
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("iscsi: failed to rescan session with error: %s (%v)", string(out), err)
|
||||||
|
}
|
||||||
|
|
||||||
if iscsiTransport == "" {
|
if iscsiTransport == "" {
|
||||||
glog.Errorf("iscsi: could not find transport name in iface %s", b.iface)
|
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))
|
return errors.New(fmt.Sprintf("Could not parse iface file for %s", b.iface))
|
||||||
@@ -209,14 +218,20 @@ func (util *ISCSIUtil) DetachDisk(c iscsiDiskUnmounter, mntPath string) error {
|
|||||||
refCount, err := getDevicePrefixRefCount(c.mounter, prefix)
|
refCount, err := getDevicePrefixRefCount(c.mounter, prefix)
|
||||||
|
|
||||||
if err == nil && refCount == 0 {
|
if err == nil && refCount == 0 {
|
||||||
// this portal/iqn are no longer referenced, log out
|
// this portal/iqn/iface are no longer referenced, log out
|
||||||
|
// extract iface from mount path
|
||||||
|
iface, err := extractIface(mntPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// extract portal and iqn from device path
|
// extract portal and iqn from device path
|
||||||
portal, iqn, err := extractPortalAndIqn(device)
|
portal, iqn, err := extractPortalAndIqn(device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
glog.Infof("iscsi: log out target %s iqn %s", portal, iqn)
|
glog.Infof("iscsi: log out target %s iqn %s iface %s", portal, iqn, iface)
|
||||||
out, err := c.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", portal, "-T", iqn, "--logout"})
|
// logout may fail as no session may exist for the portal/IQN on the specified interface
|
||||||
|
out, err := c.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", portal, "-T", iqn, "-I", iface, "--logout"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("iscsi: failed to detach disk Error: %s", string(out))
|
glog.Errorf("iscsi: failed to detach disk Error: %s", string(out))
|
||||||
}
|
}
|
||||||
@@ -248,15 +263,32 @@ func extractDeviceAndPrefix(mntPath string) (string, string, error) {
|
|||||||
return "", "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
return "", "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
||||||
}
|
}
|
||||||
device := mntPath[(ind + 1):]
|
device := mntPath[(ind + 1):]
|
||||||
// strip -lun- from device path
|
// strip -lun- from mount path
|
||||||
ind = strings.LastIndex(device, "-lun-")
|
ind = strings.LastIndex(mntPath, "-lun-")
|
||||||
if ind < 0 {
|
if ind < 0 {
|
||||||
return "", "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
return "", "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
||||||
}
|
}
|
||||||
prefix := device[:ind]
|
prefix := mntPath[:ind]
|
||||||
return device, prefix, nil
|
return device, prefix, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractIface(mntPath string) (string, error) {
|
||||||
|
ind := strings.LastIndex(mntPath, "/")
|
||||||
|
if ind < 0 {
|
||||||
|
return "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
baseMntPath := mntPath[:ind]
|
||||||
|
ind = strings.LastIndex(baseMntPath, "/")
|
||||||
|
if ind < 0 {
|
||||||
|
return "", fmt.Errorf("iscsi detach disk: malformatted mnt path: %s", mntPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
iface := baseMntPath[(ind + 1):]
|
||||||
|
|
||||||
|
return iface, nil
|
||||||
|
}
|
||||||
|
|
||||||
func extractPortalAndIqn(device string) (string, string, error) {
|
func extractPortalAndIqn(device string) (string, string, error) {
|
||||||
ind1 := strings.Index(device, "-")
|
ind1 := strings.Index(device, "-")
|
||||||
if ind1 < 0 {
|
if ind1 < 0 {
|
||||||
|
Reference in New Issue
Block a user