@@ -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" )
@@ -202,7 +202,7 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
202202 // created from a PVC with a finalizer. This is to ensure that the PVC finalizer
203203 // can be removed even if a delete snapshot request is received before create
204204 // snapshot has completed.
205- if snapshot .ObjectMeta .DeletionTimestamp != nil && ! ctrl . isPVCwithFinalizerInUseByCurrentSnapshot ( snapshot ) {
205+ if snapshot .ObjectMeta .DeletionTimestamp != nil {
206206 return ctrl .processSnapshotWithDeletionTimestamp (snapshot )
207207 }
208208
@@ -234,27 +234,6 @@ func (ctrl *csiSnapshotCommonController) syncSnapshot(snapshot *crdv1.VolumeSnap
234234 return ctrl .syncReadySnapshot (snapshot )
235235}
236236
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-
258237// processSnapshotWithDeletionTimestamp processes finalizers and deletes the content when appropriate. It has the following steps:
259238// 1. Get the content which the to-be-deleted VolumeSnapshot points to and verifies bi-directional binding.
260239// 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 +837,7 @@ func (ctrl *csiSnapshotCommonController) ensurePVCFinalizer(snapshot *crdv1.Volu
858837}
859838
860839// removePVCFinalizer removes a Finalizer for VolumeSnapshot Source PVC.
861- func (ctrl * csiSnapshotCommonController ) removePVCFinalizer (pvc * v1.PersistentVolumeClaim , snapshot * crdv1. VolumeSnapshot ) error {
840+ func (ctrl * csiSnapshotCommonController ) removePVCFinalizer (pvc * v1.PersistentVolumeClaim ) error {
862841 // Get snapshot source which is a PVC
863842 // TODO(xyang): We get PVC from informer but it may be outdated
864843 // Should get it from API server directly before removing finalizer
@@ -874,8 +853,9 @@ func (ctrl *csiSnapshotCommonController) removePVCFinalizer(pvc *v1.PersistentVo
874853 return nil
875854}
876855
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 {
856+ // isPVCBeingUsed checks if a PVC is being used as a source to create a snapshot.
857+ // If skipCurrentSnapshot is true, skip checking if the current snapshot is using the PVC as source.
858+ func (ctrl * csiSnapshotCommonController ) isPVCBeingUsed (pvc * v1.PersistentVolumeClaim , snapshot * crdv1.VolumeSnapshot , skipCurrentSnapshot bool ) bool {
879859 klog .V (5 ).Infof ("Checking isPVCBeingUsed for snapshot [%s]" , utils .SnapshotKey (snapshot ))
880860
881861 // Going through snapshots in the cache (snapshotLister). If a snapshot's PVC source
@@ -886,6 +866,10 @@ func (ctrl *csiSnapshotCommonController) isPVCBeingUsed(pvc *v1.PersistentVolume
886866 return false
887867 }
888868 for _ , snap := range snapshots {
869+ // Skip the current snapshot
870+ if skipCurrentSnapshot && snap .Name == snapshot .Name {
871+ continue
872+ }
889873 // Skip pre-provisioned snapshot without a PVC source
890874 if snap .Spec .Source .PersistentVolumeClaimName == nil && snap .Spec .Source .VolumeSnapshotContentName != nil {
891875 klog .V (4 ).Infof ("Skipping static bound snapshot %s when checking PVC %s/%s" , snap .Name , pvc .Namespace , pvc .Name )
@@ -902,8 +886,9 @@ func (ctrl *csiSnapshotCommonController) isPVCBeingUsed(pvc *v1.PersistentVolume
902886}
903887
904888// 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 {
889+ // and removed it if needed. If skipCurrentSnapshot is true, skip checking if the current
890+ // snapshot is using the PVC as source.
891+ func (ctrl * csiSnapshotCommonController ) checkandRemovePVCFinalizer (snapshot * crdv1.VolumeSnapshot , skipCurrentSnapshot bool ) error {
907892 if snapshot .Spec .Source .PersistentVolumeClaimName == nil {
908893 // PVC finalizer is only needed for dynamic provisioning
909894 return nil
@@ -922,10 +907,10 @@ func (ctrl *csiSnapshotCommonController) checkandRemovePVCFinalizer(snapshot *cr
922907 if utils .ContainsString (pvc .ObjectMeta .Finalizers , utils .PVCFinalizer ) {
923908 // There is a Finalizer on PVC. Check if PVC is used
924909 // and remove finalizer if it's not used.
925- inUse := ctrl .isPVCBeingUsed (pvc , snapshot )
910+ inUse := ctrl .isPVCBeingUsed (pvc , snapshot , skipCurrentSnapshot )
926911 if ! inUse {
927912 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 )
913+ err = ctrl .removePVCFinalizer (pvc )
929914 if err != nil {
930915 klog .Errorf ("checkandRemovePVCFinalizer [%s]: removePVCFinalizer failed to remove finalizer %v" , snapshot .Name , err )
931916 return err
@@ -1325,6 +1310,16 @@ func (ctrl *csiSnapshotCommonController) removeSnapshotFinalizer(snapshot *crdv1
13251310 return nil
13261311 }
13271312
1313+ // If we are here, it means we are going to remove finalizers from the snapshot so that the snapshot can be deleted.
1314+ // We need to check if there is still PVC finalizer that needs to be removed before removing the snapshot finalizers.
1315+ // Once snapshot is deleted, there won't be any snapshot update event that can trigger the PVC finalizer removal.
1316+ if err := ctrl .checkandRemovePVCFinalizer (snapshot , true ); err != nil {
1317+ klog .Errorf ("removeSnapshotFinalizer: error check and remove PVC finalizer for snapshot [%s]: %v" , snapshot .Name , err )
1318+ // Log an event and keep the original error from checkandRemovePVCFinalizer
1319+ ctrl .eventRecorder .Event (snapshot , v1 .EventTypeWarning , "ErrorPVCFinalizer" , "Error check and remove PVC Finalizer for VolumeSnapshot" )
1320+ return newControllerUpdateError (snapshot .Name , err .Error ())
1321+ }
1322+
13281323 snapshotClone := snapshot .DeepCopy ()
13291324 if removeSourceFinalizer {
13301325 snapshotClone .ObjectMeta .Finalizers = utils .RemoveString (snapshotClone .ObjectMeta .Finalizers , utils .VolumeSnapshotAsSourceFinalizer )
0 commit comments