@@ -1341,6 +1341,82 @@ var _ = Describe("GCE PD CSI Driver", func() {
1341
1341
1342
1342
Expect (err ).To (BeNil (), "no error expected when passed valid compute url" )
1343
1343
})
1344
+
1345
+ It ("Should block unstage if filesystem mounted" , func () {
1346
+ testContext := getRandomTestContext ()
1347
+
1348
+ p , z , _ := testContext .Instance .GetIdentity ()
1349
+ client := testContext .Client
1350
+ instance := testContext .Instance
1351
+
1352
+ // Create Disk
1353
+ volName , volID := createAndValidateUniqueZonalDisk (client , p , z , standardDiskType )
1354
+
1355
+ defer func () {
1356
+ // Delete Disk
1357
+ err := client .DeleteVolume (volID )
1358
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
1359
+
1360
+ // Validate Disk Deleted
1361
+ _ , err = computeService .Disks .Get (p , z , volName ).Do ()
1362
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
1363
+ }()
1364
+
1365
+ // Attach Disk
1366
+ err := client .ControllerPublishVolume (volID , instance .GetNodeID (), false /* forceAttach */ )
1367
+ Expect (err ).To (BeNil (), "ControllerPublishVolume failed with error for disk %v on node %v: %v" , volID , instance .GetNodeID (), err )
1368
+
1369
+ defer func () {
1370
+ // Detach Disk
1371
+ err = client .ControllerUnpublishVolume (volID , instance .GetNodeID ())
1372
+ if err != nil {
1373
+ klog .Errorf ("Failed to detach disk: %v" , err )
1374
+ }
1375
+ }()
1376
+
1377
+ // Stage Disk
1378
+ stageDir := filepath .Join ("/tmp/" , volName , "stage" )
1379
+ err = client .NodeStageExt4Volume (volID , stageDir )
1380
+ Expect (err ).To (BeNil (), "failed to stage volume: %v" , err )
1381
+
1382
+ // Create private bind mount
1383
+ boundMountStageDir := filepath .Join ("/tmp/bindmount" , volName , "bindmount" )
1384
+ boundMountStageMkdirOutput , err := instance .SSH ("mkdir" , "-p" , boundMountStageDir )
1385
+ Expect (err ).To (BeNil (), "mkdir failed on instance %v: output: %v: %v" , instance .GetNodeID (), boundMountStageMkdirOutput , err )
1386
+ bindMountOutput , err := instance .SSH ("mount" , "--rbind" , "--make-private" , stageDir , boundMountStageDir )
1387
+ Expect (err ).To (BeNil (), "Bind mount failed on instance %v: output: %v: %v" , instance .GetNodeID (), bindMountOutput , err )
1388
+
1389
+ privateBindMountRemoved := false
1390
+ unmountAndRmPrivateBindMount := func () {
1391
+ if ! privateBindMountRemoved {
1392
+ // Umount and delete private mount staging directory
1393
+ bindUmountOutput , err := instance .SSH ("umount" , boundMountStageDir )
1394
+ Expect (err ).To (BeNil (), "Bind mount failed on instance %v: output: %v: %v" , instance .GetNodeID (), bindUmountOutput , err )
1395
+ err = testutils .RmAll (instance , boundMountStageDir )
1396
+ Expect (err ).To (BeNil (), "Failed to rm mount stage dir %s: %v" , boundMountStageDir , err )
1397
+ }
1398
+ privateBindMountRemoved = true
1399
+ }
1400
+
1401
+ defer func () {
1402
+ unmountAndRmPrivateBindMount ()
1403
+ }()
1404
+
1405
+ // Unstage Disk
1406
+ err = client .NodeUnstageVolume (volID , stageDir )
1407
+ Expect (err ).ToNot (BeNil (), "Expected failure during unstage" )
1408
+ Expect (err ).To (MatchError (ContainSubstring (("is still in use" ))))
1409
+
1410
+ // Unmount private bind mount and try again
1411
+ unmountAndRmPrivateBindMount ()
1412
+
1413
+ // Unstage Disk
1414
+ err = client .NodeUnstageVolume (volID , stageDir )
1415
+ Expect (err ).To (BeNil (), "Failed to unstage volume: %v" , err )
1416
+ fp := filepath .Join ("/tmp/" , volName )
1417
+ err = testutils .RmAll (instance , fp )
1418
+ Expect (err ).To (BeNil (), "Failed to rm file path %s: %v" , fp , err )
1419
+ })
1344
1420
})
1345
1421
1346
1422
func equalWithinEpsilon (a , b , epsiolon int64 ) bool {
0 commit comments