@@ -94,8 +94,6 @@ const (
94
94
RundSocketDir = "/host/etc/kubernetes/volumes/rund/"
95
95
// VolumeDirRemove volume dir remove
96
96
VolumeDirRemove = "/host/etc/kubernetes/volumes/disk/remove"
97
- // InputOutputErr tag
98
- InputOutputErr = "input/output error"
99
97
// CreateDiskARN ARN parameter of the CreateDisk interface
100
98
CreateDiskARN = "alibabacloud.com/createdisk-arn"
101
99
// PVC annotation key of KMS key ID, override the storage class parameter kmsKeyId
@@ -692,9 +690,20 @@ func addDiskXattr(diskID string) (err error) {
692
690
return unix .Setxattr (device , DiskXattrName , []byte (diskID ), 0 )
693
691
}
694
692
695
- // target format: /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pv-disk-1e7001e0-c54a-11e9-8f89-00163e0e78a0/globalmount
693
+ func ensureUnmounted (mounter k8smount.Interface , target string ) error {
694
+ notmounted , err := mounter .IsLikelyNotMountPoint (target )
695
+ if err != nil {
696
+ return fmt .Errorf ("failed to check if %s is not a mount point after unmount: %w" , target , err )
697
+ }
698
+ if ! notmounted {
699
+ return fmt .Errorf ("path %s is still mounted after unmount" , target )
700
+ }
701
+ return nil
702
+ }
703
+
696
704
func (ns * nodeServer ) NodeUnstageVolume (ctx context.Context , req * csi.NodeUnstageVolumeRequest ) (* csi.NodeUnstageVolumeResponse , error ) {
697
- klog .Infof ("NodeUnstageVolume:: Starting to Unmount volume, volumeId: %s, target: %v" , req .VolumeId , req .StagingTargetPath )
705
+ logger := klog .FromContext (ctx )
706
+ logger .Info ("Starting to Unmount volume" , "target" , req .StagingTargetPath )
698
707
699
708
if ! ns .locks .TryAcquire (req .VolumeId ) {
700
709
return nil , status .Errorf (codes .Aborted , "There is already an operation for %s" , req .VolumeId )
@@ -703,66 +712,35 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
703
712
704
713
// check block device mountpoint
705
714
targetPath := req .GetStagingTargetPath ()
706
- tmpPath := filepath .Join (req .GetStagingTargetPath (), req .VolumeId )
707
- if IsFileExisting (tmpPath ) {
708
- fileInfo , err := os .Lstat (tmpPath )
709
- if err != nil {
710
- if strings .Contains (strings .ToLower (err .Error ()), InputOutputErr ) {
711
- if err = isPathAvailable (targetPath ); err != nil {
712
- if err = ns .k8smounter .Unmount (targetPath ); err != nil {
713
- klog .Errorf ("NodeUnstageVolume: umount target %s(input/output error) with error: %v" , targetPath , err )
714
- return nil , status .Errorf (codes .InvalidArgument , "NodeUnstageVolume umount target %s with error: %v" , targetPath , err )
715
- }
716
- klog .Warningf ("NodeUnstageVolume: target path %s show input/output error: %v, umount it." , targetPath , err )
717
- }
718
- } else {
719
- klog .Errorf ("NodeUnstageVolume: lstat mountpoint: %s with error: %s" , tmpPath , err .Error ())
720
- return nil , status .Error (codes .InvalidArgument , "NodeUnstageVolume: stat mountpoint error: " + err .Error ())
721
- }
722
- } else {
723
- if (fileInfo .Mode () & os .ModeDevice ) != 0 {
724
- klog .Infof ("NodeUnstageVolume: mountpoint %s, is block device" , tmpPath )
715
+ err := unix .Unmount (targetPath , 0 )
716
+ if err != nil {
717
+ switch {
718
+ case errors .Is (err , unix .ENOENT ):
719
+ logger .Info ("targetPath not exist, continue to detach" )
720
+ case errors .Is (err , unix .EINVAL ):
721
+ // Maybe unmounted, lets check
722
+ if errCheck := ensureUnmounted (ns .k8smounter , targetPath ); errCheck != nil {
723
+ return nil , status .Errorf (codes .Internal , "failed to unmount %s: %v. %v" , targetPath , err , errCheck )
725
724
}
726
- // if mountpoint not a block device, maybe something wrong happened in VolumeStageVolume.
727
- // when pod deleted, the volume should be detached
728
- targetPath = tmpPath
729
- }
730
- }
731
725
732
- // Step 1: check folder exists and umount
733
- msgLog := ""
734
- if IsFileExisting (targetPath ) {
735
- notmounted , err := ns .k8smounter .IsLikelyNotMountPoint (targetPath )
736
- if err != nil {
737
- klog .Errorf ("NodeUnstageVolume: VolumeId: %s, check mountPoint: %s error: %v" , req .VolumeId , targetPath , err )
738
- return nil , status .Error (codes .Internal , err .Error ())
739
- }
740
- if ! notmounted {
741
- err = ns .k8smounter .Unmount (targetPath )
742
- if err != nil {
743
- klog .Errorf ("NodeUnstageVolume: VolumeId: %s, umount path: %s failed with: %v" , req .VolumeId , targetPath , err )
744
- return nil , status .Error (codes .Internal , err .Error ())
745
- }
746
- notmounted , err = ns .k8smounter .IsLikelyNotMountPoint (targetPath )
726
+ // really umounted, check volumeDevice
727
+ // Note: we remove the blockPath, but not targetPath, because the former is created by us, while the latter is created by CO.
728
+ blockPath := filepath .Join (targetPath , req .VolumeId )
729
+ logger .Info ("targetPath may not be a mountpoint, checking volumeDevice" )
730
+ err := utils .CleanupSimpleMount (blockPath )
747
731
if err != nil {
748
- return nil , status .Errorf (codes .Internal , "failed to check if %s is not a mount point after umount : %v" , targetPath , err )
732
+ return nil , status .Errorf (codes .Internal , "failed to cleanup volumeDevice path %s : %v" , blockPath , err )
749
733
}
750
- if ! notmounted {
751
- klog .Errorf ("NodeUnstageVolume: TargetPath mounted yet, volumeId: %s, Target: %s" , req .VolumeId , targetPath )
752
- return nil , status .Error (codes .Internal , "NodeUnstageVolume: TargetPath mounted yet with target" + targetPath )
753
- }
754
- } else {
755
- msgLog = fmt .Sprintf ("NodeUnstageVolume: VolumeId: %s, mountpoint: %s not mounted, skipping and continue to detach" , req .VolumeId , targetPath )
734
+ default :
735
+ return nil , status .Errorf (codes .Internal , "failed to unmount %s: %v" , targetPath , err )
756
736
}
757
737
} else {
758
- msgLog = fmt .Sprintf ("NodeUnstageVolume: VolumeId: %s, Path %s doesn't exist, continue to detach" , req .VolumeId , targetPath )
759
- }
760
-
761
- if msgLog == "" {
762
- klog .Infof ("NodeUnstageVolume: Unmount TargetPath successful, target %v, volumeId: %s" , targetPath , req .VolumeId )
763
- } else {
764
- klog .Info (msgLog )
738
+ err := ensureUnmounted (ns .k8smounter , targetPath )
739
+ if err != nil {
740
+ return nil , status .Error (codes .Internal , err .Error ())
741
+ }
765
742
}
743
+ logger .V (2 ).Info ("targetPath cleaned up" )
766
744
767
745
if IsVFNode () {
768
746
if err := unbindBdfDisk (req .VolumeId ); err != nil {
@@ -781,7 +759,7 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
781
759
}
782
760
}
783
761
784
- err : = addDiskXattr (req .VolumeId )
762
+ err = addDiskXattr (req .VolumeId )
785
763
if err != nil {
786
764
klog .Errorf ("NodeUnstageVolume: addDiskXattr %s failed: %v" , req .VolumeId , err )
787
765
}
0 commit comments