Merge pull request #49416 from mtanino/issue/49392

Automatic merge from submit-queue (batch tested with PRs 49870, 49416, 49872, 49892, 49908)

FC volume plugin: remove block device at DetachDisk

**What this PR does / why we need it**:

After a volume is unmounted from pod and worker node, and then PV and PVC are deleted, cluster admin or external-provisioner might delete the disk from storage, therefore block device on the node should be cleaned up beforehand.

The photon volume plugin already has same functionality.

**Which issue this PR fixes**: fixes #49392

**Special notes for your reviewer**:

/assign @rootfs  
/cc @jsafrane @saad-ali 

**Release note**:

```
NONE
```
pull/6/head
Kubernetes Submit Queue 2017-08-01 19:52:59 -07:00 committed by GitHub
commit 2672f1cd1d
3 changed files with 43 additions and 5 deletions

View File

@ -142,7 +142,24 @@ func (detacher *fcDetacher) Detach(deviceMountPath string, nodeName types.NodeNa
}
func (detacher *fcDetacher) UnmountDevice(deviceMountPath string) error {
return volumeutil.UnmountPath(deviceMountPath, detacher.mounter)
// Specify device name for DetachDisk later
devName, _, err := mount.GetDeviceNameFromMount(detacher.mounter, deviceMountPath)
if err != nil {
glog.Errorf("fc: failed to get device from mnt: %s\nError: %v", deviceMountPath, err)
return err
}
// Unmount for deviceMountPath(=globalPDPath)
err = volumeutil.UnmountPath(deviceMountPath, detacher.mounter)
if err != nil {
return fmt.Errorf("fc: failed to unmount: %s\nError: %v", deviceMountPath, err)
}
unMounter := volumeSpecToUnmounter(detacher.mounter)
err = detacher.manager.DetachDisk(*unMounter, devName)
if err != nil {
return fmt.Errorf("fc: failed to detach disk: %s\nError: %v", devName, err)
}
glog.V(4).Infof("fc: successfully detached disk: %s", devName)
return nil
}
func volumeSpecToMounter(spec *volume.Spec, host volume.VolumeHost) (*fcDiskMounter, error) {
@ -168,3 +185,12 @@ func volumeSpecToMounter(spec *volume.Spec, host volume.VolumeHost) (*fcDiskMoun
mounter: &mount.SafeFormatAndMount{Interface: host.GetMounter(), Runner: exec.New()},
}, nil
}
func volumeSpecToUnmounter(mounter mount.Interface) *fcDiskUnmounter {
return &fcDiskUnmounter{
fcDisk: &fcDisk{
io: &osIOHandler{},
},
mounter: mounter,
}
}

View File

@ -30,7 +30,7 @@ type diskManager interface {
// Attaches the disk to the kubelet's host machine.
AttachDisk(b fcDiskMounter) (string, error)
// Detaches the disk from the kubelet's host machine.
DetachDisk(disk fcDiskUnmounter, mntPath string) error
DetachDisk(disk fcDiskUnmounter, devName string) error
}
// utility to mount a disk based filesystem

View File

@ -89,6 +89,14 @@ func findDisk(wwn, lun string, io ioHandler) (string, string) {
return "", ""
}
// Removes a scsi device based upon /dev/sdX name
func removeFromScsiSubsystem(deviceName string, io ioHandler) {
fileName := "/sys/block/" + deviceName + "/device/delete"
glog.V(4).Infof("fc: remove device from scsi-subsystem: path: %s", fileName)
data := []byte("1")
io.WriteFile(fileName, data, 0666)
}
// rescan scsi bus
func scsiHostRescan(io ioHandler) {
scsi_path := "/sys/class/scsi_host/"
@ -177,9 +185,13 @@ func (util *FCUtil) AttachDisk(b fcDiskMounter) (string, error) {
return devicePath, err
}
func (util *FCUtil) DetachDisk(c fcDiskUnmounter, mntPath string) error {
if err := c.mounter.Unmount(mntPath); err != nil {
return fmt.Errorf("fc detach disk: failed to unmount: %s\nError: %v", mntPath, err)
func (util *FCUtil) DetachDisk(c fcDiskUnmounter, devName string) error {
// Remove scsi device from the node.
if !strings.HasPrefix(devName, "/dev/") {
return fmt.Errorf("fc detach disk: invalid device name: %s", devName)
}
arr := strings.Split(devName, "/")
dev := arr[len(arr)-1]
removeFromScsiSubsystem(dev, c.io)
return nil
}