@@ -1401,6 +1401,82 @@ var _ = Describe("GCE PD CSI Driver", func() {
14011401 }()
14021402 })
14031403
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+
14041480 type multiZoneTestConfig struct {
14051481 diskType string
14061482 readOnly bool
0 commit comments