@@ -172,8 +172,11 @@ func (ctrl *resizeController) updatePVC(oldObj, newObj interface{}) {
172
172
return
173
173
}
174
174
175
- newSize := newPVC .Spec .Resources .Requests [v1 .ResourceStorage ]
176
- oldSize := oldPVC .Spec .Resources .Requests [v1 .ResourceStorage ]
175
+ newReq := newPVC .Spec .Resources .Requests [v1 .ResourceStorage ]
176
+ oldReq := oldPVC .Spec .Resources .Requests [v1 .ResourceStorage ]
177
+
178
+ newCap := newPVC .Status .Capacity [v1 .ResourceStorage ]
179
+ oldCap := oldPVC .Status .Capacity [v1 .ResourceStorage ]
177
180
178
181
newResizerName := newPVC .Annotations [util .VolumeResizerKey ]
179
182
oldResizerName := oldPVC .Annotations [util .VolumeResizerKey ]
@@ -192,23 +195,27 @@ func (ctrl *resizeController) updatePVC(oldObj, newObj interface{}) {
192
195
// know how to support resizing of a "un-annotated" in-tree PVC. When in-tree resizer does add the annotation, a second
193
196
// update even will be received and we add the pvc to workqueue. If annotation matches the registered driver name in
194
197
// csi_resizer object, we proceeds with expansion internally or we discard the PVC.
195
- // 2 . An already expanded in-tree PVC:
198
+ // 3 . An already expanded in-tree PVC:
196
199
// An in-tree PVC is resized with in-tree resizer. And later, CSI migration is turned on and resizer name is updated from
197
200
// in-tree resizer name to CSI driver name.
198
- if newSize .Cmp (oldSize ) > 0 || newResizerName != oldResizerName {
201
+ if newReq .Cmp (oldReq ) > 0 || newResizerName != oldResizerName {
199
202
ctrl .addPVC (newObj )
200
203
} else {
201
204
// PVC's size not changed, so this Update event maybe caused by:
202
205
//
203
206
// 1. Administrators or users introduce other changes(such as add labels, modify annotations, etc.)
204
207
// unrelated to volume resize.
205
208
// 2. Informer resynced the PVC and send this Update event without any changes.
209
+ // 3. PV's filesystem has recently been resized and requires removal of its resize annotation
206
210
//
207
- // If it is case 1, we can just discard this event. If case 2, we need to put it into the queue to
211
+ // If it is case 1, we can just discard this event. If case 2 or 3 , we need to put it into the queue to
208
212
// perform a resync operation.
209
213
if newPVC .ResourceVersion == oldPVC .ResourceVersion {
210
214
// This is case 2.
211
215
ctrl .addPVC (newObj )
216
+ } else if newCap .Cmp (oldCap ) > 0 {
217
+ // This is case 3
218
+ ctrl .addPVC (newObj )
212
219
}
213
220
}
214
221
}
@@ -300,16 +307,10 @@ func (ctrl *resizeController) syncPVC(key string) error {
300
307
return fmt .Errorf ("expected PVC got: %v" , pvcObject )
301
308
}
302
309
303
- if ! ctrl .pvcNeedResize (pvc ) {
304
- klog .V (4 ).Infof ("No need to resize PVC %q" , util .PVCKey (pvc ))
305
- return nil
306
- }
307
-
308
310
volumeObj , exists , err := ctrl .volumes .GetByKey (pvc .Spec .VolumeName )
309
311
if err != nil {
310
312
return fmt .Errorf ("Get PV %q of pvc %q failed: %v" , pvc .Spec .VolumeName , util .PVCKey (pvc ), err )
311
313
}
312
-
313
314
if ! exists {
314
315
klog .Warningf ("PV %q bound to PVC %s not found" , pvc .Spec .VolumeName , util .PVCKey (pvc ))
315
316
return nil
@@ -320,6 +321,16 @@ func (ctrl *resizeController) syncPVC(key string) error {
320
321
return fmt .Errorf ("expected volume but got %+v" , volumeObj )
321
322
}
322
323
324
+ if ctrl .isFsResizeComplete (pvc , pv ) && metav1 .HasAnnotation (pv .ObjectMeta , util .AnnPreResizeCapacity ) {
325
+ if err := ctrl .deletePreResizeCapAnnotation (pv ); err != nil {
326
+ return fmt .Errorf ("Failed removing annotation %s from pv %q: %v" , util .AnnPreResizeCapacity , pv .Name , err )
327
+ }
328
+ }
329
+
330
+ if ! ctrl .pvcNeedResize (pvc ) {
331
+ klog .V (4 ).Infof ("No need to resize PVC %q" , util .PVCKey (pvc ))
332
+ return nil
333
+ }
323
334
if ! ctrl .pvNeedResize (pvc , pv ) {
324
335
klog .V (4 ).Infof ("No need to resize PV %q" , pv .Name )
325
336
return nil
@@ -376,6 +387,13 @@ func (ctrl *resizeController) pvNeedResize(pvc *v1.PersistentVolumeClaim, pv *v1
376
387
return true
377
388
}
378
389
390
+ // isFsResizeComplete returns true if pvc.Status.Capacity >= pv.Spec.Capacity
391
+ func (ctrl * resizeController ) isFsResizeComplete (pvc * v1.PersistentVolumeClaim , pv * v1.PersistentVolume ) bool {
392
+ klog .V (4 ).Infof ("pv %q capacity = %v, pvc %s capacity = %v" , pv .Name , pv .Spec .Capacity [v1 .ResourceStorage ], util .PVCKey (pvc ), pvc .Status .Capacity [v1 .ResourceStorage ])
393
+ pvcCap , pvCap := pvc .Status .Capacity [v1 .ResourceStorage ], pv .Spec .Capacity [v1 .ResourceStorage ]
394
+ return pvcCap .Cmp (pvCap ) >= 0
395
+ }
396
+
379
397
// resizePVC will:
380
398
// 1. Mark pvc as resizing.
381
399
// 2. Resize the volume and the pv object.
@@ -446,7 +464,7 @@ func (ctrl *resizeController) resizeVolume(
446
464
}
447
465
klog .V (4 ).Infof ("Resize volume succeeded for volume %q, start to update PV's capacity" , pv .Name )
448
466
449
- err = ctrl .updatePVCapacity (pv , newSize )
467
+ err = ctrl .updatePVCapacity (pv , pvc . Status . Capacity [ v1 . ResourceStorage ], newSize , fsResizeRequired )
450
468
if err != nil {
451
469
return newSize , fsResizeRequired , err
452
470
}
@@ -533,11 +551,34 @@ func (ctrl *resizeController) patchClaim(oldPVC, newPVC *v1.PersistentVolumeClai
533
551
return updatedClaim , nil
534
552
}
535
553
536
- func (ctrl * resizeController ) updatePVCapacity (pv * v1.PersistentVolume , newCapacity resource.Quantity ) error {
554
+ func (ctrl * resizeController ) deletePreResizeCapAnnotation (pv * v1.PersistentVolume ) error {
555
+ // if the pv does not have a resize annotation skip the entire process
556
+ if ! metav1 .HasAnnotation (pv .ObjectMeta , util .AnnPreResizeCapacity ) {
557
+ return nil
558
+ }
559
+ pvClone := pv .DeepCopy ()
560
+ delete (pvClone .ObjectMeta .Annotations , util .AnnPreResizeCapacity )
561
+
562
+ _ , err := ctrl .patchPersistentVolume (pv , pvClone )
563
+ return err
564
+ }
565
+
566
+ func (ctrl * resizeController ) updatePVCapacity (pv * v1.PersistentVolume , oldCapacity , newCapacity resource.Quantity , fsResizeRequired bool ) error {
537
567
klog .V (4 ).Infof ("Resize volume succeeded for volume %q, start to update PV's capacity" , pv .Name )
538
568
newPV := pv .DeepCopy ()
539
569
newPV .Spec .Capacity [v1 .ResourceStorage ] = newCapacity
540
570
571
+ if fsResizeRequired {
572
+ // if the pv already has a resize annotation skip
573
+ if metav1 .HasAnnotation (pv .ObjectMeta , util .AnnPreResizeCapacity ) {
574
+ return nil
575
+ }
576
+ if newPV .ObjectMeta .Annotations == nil {
577
+ newPV .ObjectMeta .Annotations = make (map [string ]string )
578
+ }
579
+ newPV .ObjectMeta .Annotations [util .AnnPreResizeCapacity ] = (& oldCapacity ).String ()
580
+ }
581
+
541
582
_ , err := ctrl .patchPersistentVolume (pv , newPV )
542
583
if err != nil {
543
584
return fmt .Errorf ("updating capacity of PV %q to %s failed: %v" , pv .Name , newCapacity .String (), err )
0 commit comments