Merge pull request #39928 from humblec/iscsi-multipath-backuptp

Automatic merge from submit-queue

Add mulitpath support to iscsi plugin

#issue https://github.com/kubernetes/kubernetes/issues/39345
Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
Kubernetes Submit Queue
2017-02-13 12:18:55 -08:00
committed by GitHub
25 changed files with 1063 additions and 800 deletions

View File

@@ -104,14 +104,18 @@ func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UI
lun := strconv.Itoa(int(iscsi.Lun))
portal := portalMounter(iscsi.TargetPortal)
var bkportal []string
bkportal = append(bkportal, portal)
for _, tp := range iscsi.Portals {
bkportal = append(bkportal, portalMounter(string(tp)))
}
iface := iscsi.ISCSIInterface
return &iscsiDiskMounter{
iscsiDisk: &iscsiDisk{
podUID: podUID,
volName: spec.Name(),
portal: portal,
portals: bkportal,
iqn: iscsi.IQN,
lun: lun,
iface: iface,
@@ -162,7 +166,7 @@ func (plugin *iscsiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*v
type iscsiDisk struct {
volName string
podUID types.UID
portal string
portals []string
iqn string
lun string
iface string

View File

@@ -98,13 +98,13 @@ func makePDNameInternal(host volume.VolumeHost, portal string, iqn string, lun s
type ISCSIUtil struct{}
func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string {
return makePDNameInternal(iscsi.plugin.host, iscsi.portal, iscsi.iqn, iscsi.lun)
return makePDNameInternal(iscsi.plugin.host, iscsi.portals[0], iscsi.iqn, iscsi.lun)
}
func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
var devicePath string
var devicePaths []string
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))
@@ -112,34 +112,50 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
}
iscsiTransport = extractTransportname(string(out))
bkpPortal := b.portals
for _, tp := range bkpPortal {
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", tp, "iscsi", b.iqn, "lun", b.lun}, "-")
} else {
devicePath = strings.Join([]string{"/dev/disk/by-path/pci", "*", "ip", tp, "iscsi", b.iqn, "lun", b.lun}, "-")
}
exist := waitForPathToExist(devicePath, 1, iscsiTransport)
if exist == false {
// discover iscsi target
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", tp, "-I", b.iface})
if err != nil {
glog.Errorf("iscsi: failed to sendtargets to portal %s error: %s", tp, string(out))
continue
}
// login to iscsi target
out, err = b.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", tp, "-T", b.iqn, "-I", b.iface, "--login"})
if err != nil {
glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err)
continue
}
exist = waitForPathToExist(devicePath, 10, iscsiTransport)
if !exist {
glog.Errorf("Could not attach disk: Timeout after 10s")
} else {
devicePaths = append(devicePaths, devicePath)
}
} else {
glog.V(4).Infof("iscsi: devicepath (%s) exists", devicePath)
devicePaths = append(devicePaths, devicePath)
}
}
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, iscsiTransport)
if exist == false {
// discover iscsi target
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", b.portal, "-I", b.iface})
if err != nil {
glog.Errorf("iscsi: failed to sendtargets to portal %s error: %s", b.portal, string(out))
return err
}
// login to iscsi target
out, err = b.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", b.portal, "-T", b.iqn, "-I", b.iface, "--login"})
if err != nil {
glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err)
return err
}
exist = waitForPathToExist(devicePath, 10, iscsiTransport)
if !exist {
return errors.New("Could not attach disk: Timeout after 10s")
}
if len(devicePaths) == 0 {
glog.Errorf("iscsi: failed to get any path for iscsi disk")
return errors.New("failed to get any path for iscsi disk")
}
//Make sure we use a valid devicepath to find mpio device.
devicePath = devicePaths[0]
// mount it
globalPDPath := b.manager.MakeGlobalPDName(*b.iscsiDisk)
notMnt, err := b.mounter.IsLikelyNotMountPoint(globalPDPath)
@@ -153,9 +169,17 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
return err
}
// check if the dev is using mpio and if so mount it via the dm-XX device
if mappedDevicePath := b.deviceUtil.FindMultipathDeviceForDevice(devicePath); mappedDevicePath != "" {
devicePath = mappedDevicePath
for _, path := range devicePaths {
// There shouldnt be any empty device paths. However adding this check
// for safer side to avoid the possibility of an empty entry.
if path == "" {
continue
}
// check if the dev is using mpio and if so mount it via the dm-XX device
if mappedDevicePath := b.deviceUtil.FindMultipathDeviceForDevice(path); mappedDevicePath != "" {
devicePath = mappedDevicePath
break
}
}
err = b.mounter.FormatAndMount(devicePath, globalPDPath, b.fsType, nil)
if err != nil {