@@ -69,6 +69,21 @@ func getDefaultFsType() string {
6969 return defaultLinuxFsType
7070 }
7171}
72+ func (ns * GCENodeServer ) isVolumePathMounted (path string ) bool {
73+ notMnt , err := ns .Mounter .Interface .IsLikelyNotMountPoint (path )
74+ klog .V (4 ).Infof ("NodePublishVolume check volume path %s is mounted %t: error %v" , path , ! notMnt , err )
75+ if err == nil && ! notMnt {
76+ // TODO(#95): check if mount is compatible. Return OK if it is, or appropriate error.
77+ /*
78+ 1) Target Path MUST be the vol referenced by vol ID
79+ 2) TODO(#253): Check volume capability matches for ALREADY_EXISTS
80+ 3) Readonly MUST match
81+
82+ */
83+ return true
84+ }
85+ return false
86+ }
7287
7388func (ns * GCENodeServer ) NodePublishVolume (ctx context.Context , req * csi.NodePublishVolumeRequest ) (* csi.NodePublishVolumeResponse , error ) {
7489 // Validate Arguments
@@ -99,18 +114,7 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
99114 return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("VolumeCapability is invalid: %v" , err ))
100115 }
101116
102- notMnt , err := ns .Mounter .Interface .IsLikelyNotMountPoint (targetPath )
103- if err != nil && ! os .IsNotExist (err ) {
104- return nil , status .Error (codes .Internal , fmt .Sprintf ("cannot validate mount point: %s %v" , targetPath , err ))
105- }
106- if ! notMnt {
107- // TODO(#95): check if mount is compatible. Return OK if it is, or appropriate error.
108- /*
109- 1) Target Path MUST be the vol referenced by vol ID
110- 2) TODO(#253): Check volume capability matches for ALREADY_EXISTS
111- 3) Readonly MUST match
112-
113- */
117+ if ns .isVolumePathMounted (targetPath ) {
114118 klog .V (4 ).Infof ("NodePublishVolume succeeded on volume %v to %s, mount already exists." , volumeID , targetPath )
115119 return & csi.NodePublishVolumeResponse {}, nil
116120 }
@@ -122,6 +126,7 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
122126 if readOnly {
123127 options = append (options , "ro" )
124128 }
129+ var err error
125130
126131 if mnt := volumeCapability .GetMount (); mnt != nil {
127132 if mnt .FsType != "" {
@@ -169,12 +174,16 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
169174
170175 err = ns .Mounter .Interface .Mount (sourcePath , targetPath , fstype , options )
171176 if err != nil {
177+ klog .Errorf ("Mount of disk %s failed: %v" , targetPath , err )
172178 notMnt , mntErr := ns .Mounter .Interface .IsLikelyNotMountPoint (targetPath )
173179 if mntErr != nil {
174180 klog .Errorf ("IsLikelyNotMountPoint check failed: %v" , mntErr )
175181 return nil , status .Error (codes .Internal , fmt .Sprintf ("NodePublishVolume failed to check whether target path is a mount point: %v" , err ))
176182 }
177183 if ! notMnt {
184+ // TODO: check the logic here again. If mntErr == nil & notMnt == false, it means volume is actually mounted.
185+ // Why need to unmount?
186+ klog .Warningf ("Although volume mount failed, but IsLikelyNotMountPoint returns volume %s is mounted already at %s" , volumeID , targetPath )
178187 if mntErr = ns .Mounter .Interface .Unmount (targetPath ); mntErr != nil {
179188 klog .Errorf ("Failed to unmount: %v" , mntErr )
180189 return nil , status .Error (codes .Internal , fmt .Sprintf ("NodePublishVolume failed to unmount target path: %v" , err ))
@@ -190,8 +199,9 @@ func (ns *GCENodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePub
190199 return nil , status .Error (codes .Internal , fmt .Sprintf ("NodePublishVolume something is wrong with mounting: %v" , err ))
191200 }
192201 }
193- os .Remove (targetPath )
194- klog .Errorf ("Mount of disk %s failed: %v" , targetPath , err )
202+ if err := os .Remove (targetPath ); err != nil {
203+ klog .Errorf ("failed to remove targetPath %s: %v" , targetPath , err )
204+ }
195205 return nil , status .Error (codes .Internal , fmt .Sprintf ("NodePublishVolume mount of disk failed: %v" , err ))
196206 }
197207
@@ -280,22 +290,11 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
280290 klog .V (4 ).Infof ("Successfully found attached GCE PD %q at device path %s." , volumeKey .Name , devicePath )
281291
282292 // Part 2: Check if mount already exists at stagingTargetPath
283- notMnt , err := ns .Mounter .Interface .IsLikelyNotMountPoint (stagingTargetPath )
284- if err != nil && ! os .IsNotExist (err ) {
285- return nil , status .Error (codes .Internal , fmt .Sprintf ("cannot validate mount point: %s %v" , stagingTargetPath , err ))
286- }
287- if ! notMnt {
288- // TODO(#95): Check who is mounted here. No error if its us
289- /*
290- 1) Target Path MUST be the vol referenced by vol ID
291- 2) VolumeCapability MUST match
292- 3) Readonly MUST match
293-
294- */
295- klog .V (4 ).Infof ("NodeStageVolume succeeded on %v to %s, mount already exists." , volumeID , stagingTargetPath )
293+ if ns .isVolumePathMounted (stagingTargetPath ) {
294+ klog .V (4 ).Infof ("NodeStageVolume succeeded on volume %v to %s, mount already exists." , volumeID , stagingTargetPath )
296295 return & csi.NodeStageVolumeResponse {}, nil
297-
298296 }
297+
299298 if err := prepareStagePath (stagingTargetPath , ns .Mounter ); err != nil {
300299 return nil , status .Error (codes .Internal , fmt .Sprintf ("mkdir failed on disk %s (%v)" , stagingTargetPath , err ))
301300 }
0 commit comments