@@ -182,7 +182,7 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
182182	klog .V (5 ).Infof ("syncSnapshot [%s]: check if we should remove finalizer on snapshot PVC source and remove it if we can" , utils .SnapshotKey (snapshot ))
183183
184184	// Check if we should remove finalizer on PVC and remove it if we can. 
185- 	if  err  :=  ctrl .checkandRemovePVCFinalizer (snapshot ); err  !=  nil  {
185+ 	if  err  :=  ctrl .checkandRemovePVCFinalizer (snapshot ,  false ); err  !=  nil  {
186186		klog .Errorf ("error check and remove PVC finalizer for snapshot [%s]: %v" , snapshot .Name , err )
187187		// Log an event and keep the original error from checkandRemovePVCFinalizer 
188188		ctrl .eventRecorder .Event (snapshot , v1 .EventTypeWarning , "ErrorPVCFinalizer" , "Error check and remove PVC Finalizer for VolumeSnapshot" )
@@ -198,11 +198,8 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
198198		return  err 
199199	}
200200
201- 	// Proceed with snapshot deletion only if snapshot is not in the middled of being 
202- 	// created from a PVC with a finalizer. This is to ensure that the PVC finalizer 
203- 	// can be removed even if a delete snapshot request is received before create 
204- 	// snapshot has completed. 
205- 	if  snapshot .ObjectMeta .DeletionTimestamp  !=  nil  &&  ! ctrl .isPVCwithFinalizerInUseByCurrentSnapshot (snapshot ) {
201+ 	// Proceed with snapshot deletion and remove finalizers when needed 
202+ 	if  snapshot .ObjectMeta .DeletionTimestamp  !=  nil  {
206203		return  ctrl .processSnapshotWithDeletionTimestamp (snapshot )
207204	}
208205
@@ -234,27 +231,6 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
234231	return  ctrl .syncReadySnapshot (snapshot )
235232}
236233
237- // Check if PVC has a finalizer and if it is being used by the current snapshot as source. 
238- func  (ctrl  * csiSnapshotCommonController ) isPVCwithFinalizerInUseByCurrentSnapshot (snapshot  * crdv1.VolumeSnapshot ) bool  {
239- 	// Get snapshot source which is a PVC 
240- 	pvc , err  :=  ctrl .getClaimFromVolumeSnapshot (snapshot )
241- 	if  err  !=  nil  {
242- 		klog .Infof ("cannot get claim from snapshot [%s]: [%v] Claim may be deleted already." , snapshot .Name , err )
243- 		return  false 
244- 	}
245- 
246- 	// Check if there is a Finalizer on PVC. If not, return false 
247- 	if  ! utils .ContainsString (pvc .ObjectMeta .Finalizers , utils .PVCFinalizer ) {
248- 		return  false 
249- 	}
250- 
251- 	if  ! utils .IsSnapshotReady (snapshot ) {
252- 		klog .V (2 ).Infof ("PVC %s/%s is being used by snapshot %s/%s as source" , pvc .Namespace , pvc .Name , snapshot .Namespace , snapshot .Name )
253- 		return  true 
254- 	}
255- 	return  false 
256- }
257- 
258234// processSnapshotWithDeletionTimestamp processes finalizers and deletes the content when appropriate. It has the following steps: 
259235// 1. Get the content which the to-be-deleted VolumeSnapshot points to and verifies bi-directional binding. 
260236// 2. Call checkandRemoveSnapshotFinalizersAndCheckandDeleteContent() with information obtained from step 1. This function name is very long but the name suggests what it does. It determines whether to remove finalizers on snapshot and whether to delete content. 
@@ -858,7 +834,7 @@ func (ctrl *csiSnapshotCommonController) ensurePVCFinalizer(snapshot *crdv1.Volu
858834}
859835
860836// removePVCFinalizer removes a Finalizer for VolumeSnapshot Source PVC. 
861- func  (ctrl  * csiSnapshotCommonController ) removePVCFinalizer (pvc  * v1.PersistentVolumeClaim ,  snapshot   * crdv1. VolumeSnapshot ) error  {
837+ func  (ctrl  * csiSnapshotCommonController ) removePVCFinalizer (pvc  * v1.PersistentVolumeClaim ) error  {
862838	// Get snapshot source which is a PVC 
863839	// TODO(xyang): We get PVC from informer but it may be outdated 
864840	// Should get it from API server directly before removing finalizer 
@@ -874,8 +850,9 @@ func (ctrl *csiSnapshotCommonController) removePVCFinalizer(pvc *v1.PersistentVo
874850	return  nil 
875851}
876852
877- // isPVCBeingUsed checks if a PVC is being used as a source to create a snapshot 
878- func  (ctrl  * csiSnapshotCommonController ) isPVCBeingUsed (pvc  * v1.PersistentVolumeClaim , snapshot  * crdv1.VolumeSnapshot ) bool  {
853+ // isPVCBeingUsed checks if a PVC is being used as a source to create a snapshot. 
854+ // If skipCurrentSnapshot is true, skip checking if the current snapshot is using the PVC as source. 
855+ func  (ctrl  * csiSnapshotCommonController ) isPVCBeingUsed (pvc  * v1.PersistentVolumeClaim , snapshot  * crdv1.VolumeSnapshot , skipCurrentSnapshot  bool ) bool  {
879856	klog .V (5 ).Infof ("Checking isPVCBeingUsed for snapshot [%s]" , utils .SnapshotKey (snapshot ))
880857
881858	// Going through snapshots in the cache (snapshotLister). If a snapshot's PVC source 
@@ -886,6 +863,10 @@ func (ctrl *csiSnapshotCommonController) isPVCBeingUsed(pvc *v1.PersistentVolume
886863		return  false 
887864	}
888865	for  _ , snap  :=  range  snapshots  {
866+ 		// Skip the current snapshot 
867+ 		if  skipCurrentSnapshot  &&  snap .Name  ==  snapshot .Name  {
868+ 			continue 
869+ 		}
889870		// Skip pre-provisioned snapshot without a PVC source 
890871		if  snap .Spec .Source .PersistentVolumeClaimName  ==  nil  &&  snap .Spec .Source .VolumeSnapshotContentName  !=  nil  {
891872			klog .V (4 ).Infof ("Skipping static bound snapshot %s when checking PVC %s/%s" , snap .Name , pvc .Namespace , pvc .Name )
@@ -902,8 +883,9 @@ func (ctrl *csiSnapshotCommonController) isPVCBeingUsed(pvc *v1.PersistentVolume
902883}
903884
904885// checkandRemovePVCFinalizer checks if the snapshot source finalizer should be removed 
905- // and removed it if needed. 
906- func  (ctrl  * csiSnapshotCommonController ) checkandRemovePVCFinalizer (snapshot  * crdv1.VolumeSnapshot ) error  {
886+ // and removed it if needed. If skipCurrentSnapshot is true, skip checking if the current 
887+ // snapshot is using the PVC as source. 
888+ func  (ctrl  * csiSnapshotCommonController ) checkandRemovePVCFinalizer (snapshot  * crdv1.VolumeSnapshot , skipCurrentSnapshot  bool ) error  {
907889	if  snapshot .Spec .Source .PersistentVolumeClaimName  ==  nil  {
908890		// PVC finalizer is only needed for dynamic provisioning 
909891		return  nil 
@@ -922,10 +904,10 @@ func (ctrl *csiSnapshotCommonController) checkandRemovePVCFinalizer(snapshot *cr
922904	if  utils .ContainsString (pvc .ObjectMeta .Finalizers , utils .PVCFinalizer ) {
923905		// There is a Finalizer on PVC. Check if PVC is used 
924906		// and remove finalizer if it's not used. 
925- 		inUse  :=  ctrl .isPVCBeingUsed (pvc , snapshot )
907+ 		inUse  :=  ctrl .isPVCBeingUsed (pvc , snapshot ,  skipCurrentSnapshot )
926908		if  ! inUse  {
927909			klog .Infof ("checkandRemovePVCFinalizer[%s]: Remove Finalizer for PVC %s as it is not used by snapshots in creation" , snapshot .Name , pvc .Name )
928- 			err  =  ctrl .removePVCFinalizer (pvc ,  snapshot )
910+ 			err  =  ctrl .removePVCFinalizer (pvc )
929911			if  err  !=  nil  {
930912				klog .Errorf ("checkandRemovePVCFinalizer [%s]: removePVCFinalizer failed to remove finalizer %v" , snapshot .Name , err )
931913				return  err 
@@ -1325,6 +1307,23 @@ func (ctrl *csiSnapshotCommonController) removeSnapshotFinalizer(snapshot *crdv1
13251307		return  nil 
13261308	}
13271309
1310+ 	// NOTE(xyang): We have to make sure PVC finalizer is deleted before 
1311+ 	// the VolumeSnapshot API object is deleted. Once the VolumeSnapshot 
1312+ 	// API object is deleted, there won't be any VolumeSnapshot update 
1313+ 	// event that can trigger the PVC finalizer removal any more. 
1314+ 	// We also can't remove PVC finalizer too early. PVC finalizer should 
1315+ 	// not be removed if a VolumeSnapshot API object is still using it. 
1316+ 	// If we are here, it means we are going to remove finalizers from the 
1317+ 	// VolumeSnapshot API object so that the VolumeSnapshot API object can 
1318+ 	// be deleted. This means we no longer need to keep the PVC finalizer 
1319+ 	// for this particular snapshot. 
1320+ 	if  err  :=  ctrl .checkandRemovePVCFinalizer (snapshot , true ); err  !=  nil  {
1321+ 		klog .Errorf ("removeSnapshotFinalizer: error check and remove PVC finalizer for snapshot [%s]: %v" , snapshot .Name , err )
1322+ 		// Log an event and keep the original error from checkandRemovePVCFinalizer 
1323+ 		ctrl .eventRecorder .Event (snapshot , v1 .EventTypeWarning , "ErrorPVCFinalizer" , "Error check and remove PVC Finalizer for VolumeSnapshot" )
1324+ 		return  newControllerUpdateError (snapshot .Name , err .Error ())
1325+ 	}
1326+ 
13281327	snapshotClone  :=  snapshot .DeepCopy ()
13291328	if  removeSourceFinalizer  {
13301329		snapshotClone .ObjectMeta .Finalizers  =  utils .RemoveString (snapshotClone .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer )
0 commit comments