@@ -1401,6 +1401,82 @@ var _ = Describe("GCE PD CSI Driver", func() {
1401
1401
}()
1402
1402
})
1403
1403
1404
+ It ("Should block unstage if filesystem mounted" , func () {
1405
+ testContext := getRandomTestContext ()
1406
+
1407
+ p , z , _ := testContext .Instance .GetIdentity ()
1408
+ client := testContext .Client
1409
+ instance := testContext .Instance
1410
+
1411
+ // Create Disk
1412
+ volName , volID := createAndValidateUniqueZonalDisk (client , p , z , standardDiskType )
1413
+
1414
+ defer func () {
1415
+ // Delete Disk
1416
+ err := client .DeleteVolume (volID )
1417
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
1418
+
1419
+ // Validate Disk Deleted
1420
+ _ , err = computeService .Disks .Get (p , z , volName ).Do ()
1421
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
1422
+ }()
1423
+
1424
+ // Attach Disk
1425
+ err := client .ControllerPublishVolumeReadWrite (volID , instance .GetNodeID (), false /* forceAttach */ )
1426
+ Expect (err ).To (BeNil (), "ControllerPublishVolume failed with error for disk %v on node %v: %v" , volID , instance .GetNodeID (), err )
1427
+
1428
+ defer func () {
1429
+ // Detach Disk
1430
+ err = client .ControllerUnpublishVolume (volID , instance .GetNodeID ())
1431
+ if err != nil {
1432
+ klog .Errorf ("Failed to detach disk: %v" , err )
1433
+ }
1434
+ }()
1435
+
1436
+ // Stage Disk
1437
+ stageDir := filepath .Join ("/tmp/" , volName , "stage" )
1438
+ err = client .NodeStageExt4Volume (volID , stageDir )
1439
+ Expect (err ).To (BeNil (), "failed to stage volume: %v" , err )
1440
+
1441
+ // Create private bind mount
1442
+ boundMountStageDir := filepath .Join ("/tmp/bindmount" , volName , "bindmount" )
1443
+ boundMountStageMkdirOutput , err := instance .SSH ("mkdir" , "-p" , boundMountStageDir )
1444
+ Expect (err ).To (BeNil (), "mkdir failed on instance %v: output: %v: %v" , instance .GetNodeID (), boundMountStageMkdirOutput , err )
1445
+ bindMountOutput , err := instance .SSH ("mount" , "--rbind" , "--make-private" , stageDir , boundMountStageDir )
1446
+ Expect (err ).To (BeNil (), "Bind mount failed on instance %v: output: %v: %v" , instance .GetNodeID (), bindMountOutput , err )
1447
+
1448
+ privateBindMountRemoved := false
1449
+ unmountAndRmPrivateBindMount := func () {
1450
+ if ! privateBindMountRemoved {
1451
+ // Umount and delete private mount staging directory
1452
+ bindUmountOutput , err := instance .SSH ("umount" , boundMountStageDir )
1453
+ Expect (err ).To (BeNil (), "Bind mount failed on instance %v: output: %v: %v" , instance .GetNodeID (), bindUmountOutput , err )
1454
+ err = testutils .RmAll (instance , boundMountStageDir )
1455
+ Expect (err ).To (BeNil (), "Failed to rm mount stage dir %s: %v" , boundMountStageDir , err )
1456
+ }
1457
+ privateBindMountRemoved = true
1458
+ }
1459
+
1460
+ defer func () {
1461
+ unmountAndRmPrivateBindMount ()
1462
+ }()
1463
+
1464
+ // Unstage Disk
1465
+ err = client .NodeUnstageVolume (volID , stageDir )
1466
+ Expect (err ).ToNot (BeNil (), "Expected failure during unstage" )
1467
+ Expect (err ).To (MatchError (ContainSubstring (("is still in use" ))))
1468
+
1469
+ // Unmount private bind mount and try again
1470
+ unmountAndRmPrivateBindMount ()
1471
+
1472
+ // Unstage Disk
1473
+ err = client .NodeUnstageVolume (volID , stageDir )
1474
+ Expect (err ).To (BeNil (), "Failed to unstage volume: %v" , err )
1475
+ fp := filepath .Join ("/tmp/" , volName )
1476
+ err = testutils .RmAll (instance , fp )
1477
+ Expect (err ).To (BeNil (), "Failed to rm file path %s: %v" , fp , err )
1478
+ })
1479
+
1404
1480
type multiZoneTestConfig struct {
1405
1481
diskType string
1406
1482
readOnly bool
0 commit comments