From d8fc13791a5c3944ab5f4a1c02e88a12c8f2ed67 Mon Sep 17 00:00:00 2001 From: Jeremy Xu Date: Tue, 9 Jul 2019 23:29:02 +0800 Subject: [PATCH] Avoid RbdDiskManager's DetachDisk never execute again --- pkg/volume/rbd/attacher.go | 37 +++++++++++++++++++++++++++++-------- pkg/volume/rbd/rbd_test.go | 31 +++++++++++++++++++++++++++++++ pkg/volume/rbd/rbd_util.go | 18 ++++++++++++++++++ 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/pkg/volume/rbd/attacher.go b/pkg/volume/rbd/attacher.go index 8a05302a14bb..7dbb24b6685c 100644 --- a/pkg/volume/rbd/attacher.go +++ b/pkg/volume/rbd/attacher.go @@ -216,18 +216,39 @@ func (detacher *rbdDetacher) UnmountDevice(deviceMountPath string) error { return err } // Unmount the device from the device mount point. - klog.V(4).Infof("rbd: unmouting device mountpoint %s", deviceMountPath) - if err = detacher.mounter.Unmount(deviceMountPath); err != nil { + notMnt, err := detacher.mounter.IsLikelyNotMountPoint(deviceMountPath) + if err != nil { return err } - klog.V(3).Infof("rbd: successfully umount device mountpath %s", deviceMountPath) + if !notMnt { + klog.V(4).Infof("rbd: unmouting device mountpoint %s", deviceMountPath) + if err = detacher.mounter.Unmount(deviceMountPath); err != nil { + return err + } + klog.V(3).Infof("rbd: successfully umount device mountpath %s", deviceMountPath) + } - klog.V(4).Infof("rbd: detaching device %s", devicePath) - err = detacher.manager.DetachDisk(detacher.plugin, deviceMountPath, devicePath) - if err != nil { - return err + // Get devicePath from deviceMountPath if devicePath is empty + if devicePath == "" { + rbdImageInfo, err := getRbdImageInfo(deviceMountPath) + if err != nil { + return err + } + found := false + devicePath, found = getRbdDevFromImageAndPool(rbdImageInfo.pool, rbdImageInfo.name) + if !found { + klog.Warningf("rbd: can't found devicePath for %v. Device is already unmounted, Image %v, Pool %v", deviceMountPath, rbdImageInfo.pool, rbdImageInfo.name) + } + } + + if devicePath != "" { + klog.V(4).Infof("rbd: detaching device %s", devicePath) + err = detacher.manager.DetachDisk(detacher.plugin, deviceMountPath, devicePath) + if err != nil { + return err + } + klog.V(3).Infof("rbd: successfully detach device %s", devicePath) } - klog.V(3).Infof("rbd: successfully detach device %s", devicePath) err = os.Remove(deviceMountPath) if err != nil { return err diff --git a/pkg/volume/rbd/rbd_test.go b/pkg/volume/rbd/rbd_test.go index 4e133d1d551e..e792696def8d 100644 --- a/pkg/volume/rbd/rbd_test.go +++ b/pkg/volume/rbd/rbd_test.go @@ -707,3 +707,34 @@ func TestGetRbdImageSize(t *testing.T) { } } } + +func TestGetRbdImageInfo(t *testing.T) { + tmpDir, err := utiltesting.MkTmpdir("rbd_test") + if err != nil { + t.Fatalf("error creating temp dir: %v", err) + } + defer os.RemoveAll(tmpDir) + + for i, c := range []struct { + DeviceMountPath string + TargetRbdImageInfo *rbdImageInfo + }{ + { + DeviceMountPath: fmt.Sprintf("%s/plugins/kubernetes.io/rbd/rbd/pool1-image-image1", tmpDir), + TargetRbdImageInfo: &rbdImageInfo{pool: "pool1", name: "image1"}, + }, + { + DeviceMountPath: fmt.Sprintf("%s/plugins/kubernetes.io/rbd/mounts/pool2-image-image2", tmpDir), + TargetRbdImageInfo: &rbdImageInfo{pool: "pool2", name: "image2"}, + }, + } { + rbdImageInfo, err := getRbdImageInfo(c.DeviceMountPath) + if err != nil { + t.Errorf("Case %d: getRbdImageInfo failed: %v", i, err) + continue + } + if !reflect.DeepEqual(rbdImageInfo, c.TargetRbdImageInfo) { + t.Errorf("Case %d: unexpected RbdImageInfo, wanted %v, got %v", i, c.TargetRbdImageInfo, rbdImageInfo) + } + } +} diff --git a/pkg/volume/rbd/rbd_util.go b/pkg/volume/rbd/rbd_util.go index a83a0212fc46..a314821ef9b4 100644 --- a/pkg/volume/rbd/rbd_util.go +++ b/pkg/volume/rbd/rbd_util.go @@ -57,6 +57,12 @@ const ( rbdImageSizeUnitMiB = 1024 * 1024 ) +// A struct contains rbd image info. +type rbdImageInfo struct { + pool string + name string +} + func getDevFromImageAndPool(pool, image string) (string, bool) { device, found := getRbdDevFromImageAndPool(pool, image) if found { @@ -789,3 +795,15 @@ func (util *RBDUtil) rbdStatus(b *rbdMounter) (bool, string, error) { return false, output, nil } } + +// getRbdImageInfo try to get rbdImageInfo from deviceMountPath. +func getRbdImageInfo(deviceMountPath string) (*rbdImageInfo, error) { + deviceMountedPathSeps := strings.Split(filepath.Base(deviceMountPath), "-image-") + if len(deviceMountedPathSeps) != 2 { + return nil, fmt.Errorf("Can't found devicePath for %s ", deviceMountPath) + } + return &rbdImageInfo{ + pool: deviceMountedPathSeps[0], + name: deviceMountedPathSeps[1], + }, nil +}