@@ -24,7 +24,7 @@ import (
24
24
"fmt"
25
25
"sync"
26
26
27
- "k8s.io/api/core/v1"
27
+ v1 "k8s.io/api/core/v1"
28
28
"k8s.io/apimachinery/pkg/types"
29
29
utilfeature "k8s.io/apiserver/pkg/util/feature"
30
30
"k8s.io/klog"
@@ -59,7 +59,7 @@ type ActualStateOfWorld interface {
59
59
// volume, reset the pod's remountRequired value.
60
60
// If a volume with the name volumeName does not exist in the list of
61
61
// attached volumes, an error is returned.
62
- AddPodToVolume (podName volumetypes. UniquePodName , podUID types. UID , volumeName v1. UniqueVolumeName , mounter volume. Mounter , blockVolumeMapper volume. BlockVolumeMapper , outerVolumeSpecName string , volumeGidValue string , volumeSpec * volume. Spec ) error
62
+ AddPodToVolume (operationexecutor. MarkVolumeOpts ) error
63
63
64
64
// MarkRemountRequired marks each volume that is successfully attached and
65
65
// mounted for the specified pod as requiring remount (if the plugin for the
@@ -68,13 +68,13 @@ type ActualStateOfWorld interface {
68
68
// pod update.
69
69
MarkRemountRequired (podName volumetypes.UniquePodName )
70
70
71
- // SetVolumeGloballyMounted sets the GloballyMounted value for the given
72
- // volume . When set to true this value indicates that the volume is mounted
73
- // to the underlying device at a global mount point. This global mount point
74
- // must unmounted prior to detach.
71
+ // SetDeviceMountState sets device mount state for the given volume. When deviceMountState is set to DeviceGloballyMounted
72
+ // then device is mounted at a global mount point . When it is set to DeviceMountUncertain then also it means volume
73
+ // MAY be globally mounted at a global mount point. In both cases - the volume must be unmounted from
74
+ // global mount point prior to detach.
75
75
// If a volume with the name volumeName does not exist in the list of
76
76
// attached volumes, an error is returned.
77
- SetVolumeGloballyMounted (volumeName v1.UniqueVolumeName , globallyMounted bool , devicePath , deviceMountPath string ) error
77
+ SetDeviceMountState (volumeName v1.UniqueVolumeName , deviceMountState operationexecutor. DeviceMountState , devicePath , deviceMountPath string ) error
78
78
79
79
// DeletePodFromVolume removes the given pod from the given volume in the
80
80
// cache indicating the volume has been successfully unmounted from the pod.
@@ -127,6 +127,10 @@ type ActualStateOfWorld interface {
127
127
// actual state of the world.
128
128
GetMountedVolumes () []MountedVolume
129
129
130
+ // GetAllMountedVolumes returns list of all possibly mounted volumes including
131
+ // those that are in VolumeMounted state and VolumeMountUncertain state.
132
+ GetAllMountedVolumes () []MountedVolume
133
+
130
134
// GetMountedVolumesForPod generates and returns a list of volumes that are
131
135
// successfully attached and mounted for the specified pod based on the
132
136
// current actual state of the world.
@@ -165,10 +169,15 @@ type MountedVolume struct {
165
169
type AttachedVolume struct {
166
170
operationexecutor.AttachedVolume
167
171
168
- // GloballyMounted indicates that the volume is mounted to the underlying
169
- // device at a global mount point. This global mount point must unmounted
170
- // prior to detach.
171
- GloballyMounted bool
172
+ // DeviceMountState indicates if device has been globally mounted or is not.
173
+ DeviceMountState operationexecutor.DeviceMountState
174
+ }
175
+
176
+ // DeviceMayBeMounted returns true if device is mounted in global path or is in
177
+ // uncertain state.
178
+ func (av AttachedVolume ) DeviceMayBeMounted () bool {
179
+ return av .DeviceMountState == operationexecutor .DeviceGloballyMounted ||
180
+ av .DeviceMountState == operationexecutor .DeviceMountUncertain
172
181
}
173
182
174
183
// NewActualStateOfWorld returns a new instance of ActualStateOfWorld.
@@ -245,10 +254,9 @@ type attachedVolume struct {
245
254
// this volume implements the volume.Attacher interface
246
255
pluginIsAttachable bool
247
256
248
- // globallyMounted indicates that the volume is mounted to the underlying
249
- // device at a global mount point. This global mount point must be unmounted
250
- // prior to detach.
251
- globallyMounted bool
257
+ // deviceMountState stores information that tells us if device is mounted
258
+ // globally or not
259
+ deviceMountState operationexecutor.DeviceMountState
252
260
253
261
// devicePath contains the path on the node where the volume is attached for
254
262
// attachable volumes
@@ -301,6 +309,11 @@ type mountedPod struct {
301
309
// fsResizeRequired indicates the underlying volume has been successfully
302
310
// mounted to this pod but its size has been expanded after that.
303
311
fsResizeRequired bool
312
+
313
+ // volumeMountStateForPod stores state of volume mount for the pod. if it is:
314
+ // - VolumeMounted: means volume for pod has been successfully mounted
315
+ // - VolumeMountUncertain: means volume for pod may not be mounted, but it must be unmounted
316
+ volumeMountStateForPod operationexecutor.VolumeMountState
304
317
}
305
318
306
319
func (asw * actualStateOfWorld ) MarkVolumeAsAttached (
@@ -318,24 +331,8 @@ func (asw *actualStateOfWorld) MarkVolumeAsDetached(
318
331
asw .DeleteVolume (volumeName )
319
332
}
320
333
321
- func (asw * actualStateOfWorld ) MarkVolumeAsMounted (
322
- podName volumetypes.UniquePodName ,
323
- podUID types.UID ,
324
- volumeName v1.UniqueVolumeName ,
325
- mounter volume.Mounter ,
326
- blockVolumeMapper volume.BlockVolumeMapper ,
327
- outerVolumeSpecName string ,
328
- volumeGidValue string ,
329
- volumeSpec * volume.Spec ) error {
330
- return asw .AddPodToVolume (
331
- podName ,
332
- podUID ,
333
- volumeName ,
334
- mounter ,
335
- blockVolumeMapper ,
336
- outerVolumeSpecName ,
337
- volumeGidValue ,
338
- volumeSpec )
334
+ func (asw * actualStateOfWorld ) MarkVolumeAsMounted (markVolumeOpts operationexecutor.MarkVolumeOpts ) error {
335
+ return asw .AddPodToVolume (markVolumeOpts )
339
336
}
340
337
341
338
func (asw * actualStateOfWorld ) AddVolumeToReportAsAttached (volumeName v1.UniqueVolumeName , nodeName types.NodeName ) {
@@ -354,12 +351,50 @@ func (asw *actualStateOfWorld) MarkVolumeAsUnmounted(
354
351
355
352
func (asw * actualStateOfWorld ) MarkDeviceAsMounted (
356
353
volumeName v1.UniqueVolumeName , devicePath , deviceMountPath string ) error {
357
- return asw .SetVolumeGloballyMounted (volumeName , true /* globallyMounted */ , devicePath , deviceMountPath )
354
+ return asw .SetDeviceMountState (volumeName , operationexecutor .DeviceGloballyMounted , devicePath , deviceMountPath )
355
+ }
356
+
357
+ func (asw * actualStateOfWorld ) MarkDeviceAsUncertain (
358
+ volumeName v1.UniqueVolumeName , devicePath , deviceMountPath string ) error {
359
+ return asw .SetDeviceMountState (volumeName , operationexecutor .DeviceMountUncertain , devicePath , deviceMountPath )
360
+ }
361
+
362
+ func (asw * actualStateOfWorld ) MarkVolumeMountAsUncertain (markVolumeOpts operationexecutor.MarkVolumeOpts ) error {
363
+ markVolumeOpts .VolumeMountState = operationexecutor .VolumeMountUncertain
364
+ return asw .AddPodToVolume (markVolumeOpts )
358
365
}
359
366
360
367
func (asw * actualStateOfWorld ) MarkDeviceAsUnmounted (
361
368
volumeName v1.UniqueVolumeName ) error {
362
- return asw .SetVolumeGloballyMounted (volumeName , false /* globallyMounted */ , "" , "" )
369
+ return asw .SetDeviceMountState (volumeName , operationexecutor .DeviceNotMounted , "" , "" )
370
+ }
371
+
372
+ func (asw * actualStateOfWorld ) GetDeviceMountState (volumeName v1.UniqueVolumeName ) operationexecutor.DeviceMountState {
373
+ asw .RLock ()
374
+ defer asw .RUnlock ()
375
+
376
+ volumeObj , volumeExists := asw .attachedVolumes [volumeName ]
377
+ if ! volumeExists {
378
+ return operationexecutor .DeviceNotMounted
379
+ }
380
+
381
+ return volumeObj .deviceMountState
382
+ }
383
+
384
+ func (asw * actualStateOfWorld ) GetVolumeMountState (volumeName v1.UniqueVolumeName , podName volumetypes.UniquePodName ) operationexecutor.VolumeMountState {
385
+ asw .RLock ()
386
+ defer asw .RUnlock ()
387
+
388
+ volumeObj , volumeExists := asw .attachedVolumes [volumeName ]
389
+ if ! volumeExists {
390
+ return operationexecutor .VolumeNotMounted
391
+ }
392
+
393
+ podObj , podExists := volumeObj .mountedPods [podName ]
394
+ if ! podExists {
395
+ return operationexecutor .VolumeNotMounted
396
+ }
397
+ return podObj .volumeMountStateForPod
363
398
}
364
399
365
400
// addVolume adds the given volume to the cache indicating the specified
@@ -405,7 +440,7 @@ func (asw *actualStateOfWorld) addVolume(
405
440
mountedPods : make (map [volumetypes.UniquePodName ]mountedPod ),
406
441
pluginName : volumePlugin .GetPluginName (),
407
442
pluginIsAttachable : pluginIsAttachable ,
408
- globallyMounted : false ,
443
+ deviceMountState : operationexecutor . DeviceNotMounted ,
409
444
devicePath : devicePath ,
410
445
}
411
446
} else {
@@ -420,15 +455,15 @@ func (asw *actualStateOfWorld) addVolume(
420
455
return nil
421
456
}
422
457
423
- func (asw * actualStateOfWorld ) AddPodToVolume (
424
- podName volumetypes. UniquePodName ,
425
- podUID types. UID ,
426
- volumeName v1. UniqueVolumeName ,
427
- mounter volume .Mounter ,
428
- blockVolumeMapper volume .BlockVolumeMapper ,
429
- outerVolumeSpecName string ,
430
- volumeGidValue string ,
431
- volumeSpec * volume. Spec ) error {
458
+ func (asw * actualStateOfWorld ) AddPodToVolume (markVolumeOpts operationexecutor. MarkVolumeOpts ) error {
459
+ podName := markVolumeOpts . PodName
460
+ podUID := markVolumeOpts . PodUID
461
+ volumeName := markVolumeOpts . VolumeName
462
+ mounter := markVolumeOpts .Mounter
463
+ blockVolumeMapper := markVolumeOpts .BlockVolumeMapper
464
+ outerVolumeSpecName := markVolumeOpts . OuterVolumeSpecName
465
+ volumeGidValue := markVolumeOpts . VolumeGidVolume
466
+ volumeSpec := markVolumeOpts . VolumeSpec
432
467
asw .Lock ()
433
468
defer asw .Unlock ()
434
469
@@ -442,20 +477,21 @@ func (asw *actualStateOfWorld) AddPodToVolume(
442
477
podObj , podExists := volumeObj .mountedPods [podName ]
443
478
if ! podExists {
444
479
podObj = mountedPod {
445
- podName : podName ,
446
- podUID : podUID ,
447
- mounter : mounter ,
448
- blockVolumeMapper : blockVolumeMapper ,
449
- outerVolumeSpecName : outerVolumeSpecName ,
450
- volumeGidValue : volumeGidValue ,
451
- volumeSpec : volumeSpec ,
480
+ podName : podName ,
481
+ podUID : podUID ,
482
+ mounter : mounter ,
483
+ blockVolumeMapper : blockVolumeMapper ,
484
+ outerVolumeSpecName : outerVolumeSpecName ,
485
+ volumeGidValue : volumeGidValue ,
486
+ volumeSpec : volumeSpec ,
487
+ volumeMountStateForPod : markVolumeOpts .VolumeMountState ,
452
488
}
453
489
}
454
490
455
491
// If pod exists, reset remountRequired value
456
492
podObj .remountRequired = false
493
+ podObj .volumeMountStateForPod = markVolumeOpts .VolumeMountState
457
494
asw .attachedVolumes [volumeName ].mountedPods [podName ] = podObj
458
-
459
495
return nil
460
496
}
461
497
@@ -554,8 +590,8 @@ func (asw *actualStateOfWorld) MarkFSResizeRequired(
554
590
}
555
591
}
556
592
557
- func (asw * actualStateOfWorld ) SetVolumeGloballyMounted (
558
- volumeName v1.UniqueVolumeName , globallyMounted bool , devicePath , deviceMountPath string ) error {
593
+ func (asw * actualStateOfWorld ) SetDeviceMountState (
594
+ volumeName v1.UniqueVolumeName , deviceMountState operationexecutor. DeviceMountState , devicePath , deviceMountPath string ) error {
559
595
asw .Lock ()
560
596
defer asw .Unlock ()
561
597
@@ -566,7 +602,7 @@ func (asw *actualStateOfWorld) SetVolumeGloballyMounted(
566
602
volumeName )
567
603
}
568
604
569
- volumeObj .globallyMounted = globallyMounted
605
+ volumeObj .deviceMountState = deviceMountState
570
606
volumeObj .deviceMountPath = deviceMountPath
571
607
if devicePath != "" {
572
608
volumeObj .devicePath = devicePath
@@ -628,6 +664,10 @@ func (asw *actualStateOfWorld) PodExistsInVolume(
628
664
629
665
podObj , podExists := volumeObj .mountedPods [podName ]
630
666
if podExists {
667
+ // if volume mount was uncertain we should keep trying to mount the volume
668
+ if podObj .volumeMountStateForPod == operationexecutor .VolumeMountUncertain {
669
+ return false , volumeObj .devicePath , nil
670
+ }
631
671
if podObj .remountRequired {
632
672
return true , volumeObj .devicePath , newRemountRequiredError (volumeObj .volumeName , podObj .podName )
633
673
}
@@ -668,9 +708,30 @@ func (asw *actualStateOfWorld) GetMountedVolumes() []MountedVolume {
668
708
mountedVolume := make ([]MountedVolume , 0 /* len */ , len (asw .attachedVolumes ) /* cap */ )
669
709
for _ , volumeObj := range asw .attachedVolumes {
670
710
for _ , podObj := range volumeObj .mountedPods {
671
- mountedVolume = append (
672
- mountedVolume ,
673
- getMountedVolume (& podObj , & volumeObj ))
711
+ if podObj .volumeMountStateForPod == operationexecutor .VolumeMounted {
712
+ mountedVolume = append (
713
+ mountedVolume ,
714
+ getMountedVolume (& podObj , & volumeObj ))
715
+ }
716
+ }
717
+ }
718
+ return mountedVolume
719
+ }
720
+
721
+ // GetAllMountedVolumes returns all volumes which could be locally mounted for a pod.
722
+ func (asw * actualStateOfWorld ) GetAllMountedVolumes () []MountedVolume {
723
+ asw .RLock ()
724
+ defer asw .RUnlock ()
725
+ mountedVolume := make ([]MountedVolume , 0 /* len */ , len (asw .attachedVolumes ) /* cap */ )
726
+ for _ , volumeObj := range asw .attachedVolumes {
727
+ for _ , podObj := range volumeObj .mountedPods {
728
+ if podObj .volumeMountStateForPod == operationexecutor .VolumeMounted ||
729
+ podObj .volumeMountStateForPod == operationexecutor .VolumeMountUncertain {
730
+ mountedVolume = append (
731
+ mountedVolume ,
732
+ getMountedVolume (& podObj , & volumeObj ))
733
+ }
734
+
674
735
}
675
736
}
676
737
@@ -683,10 +744,12 @@ func (asw *actualStateOfWorld) GetMountedVolumesForPod(
683
744
defer asw .RUnlock ()
684
745
mountedVolume := make ([]MountedVolume , 0 /* len */ , len (asw .attachedVolumes ) /* cap */ )
685
746
for _ , volumeObj := range asw .attachedVolumes {
686
- if podObj , podExists := volumeObj .mountedPods [podName ]; podExists {
687
- mountedVolume = append (
688
- mountedVolume ,
689
- getMountedVolume (& podObj , & volumeObj ))
747
+ for mountedPodName , podObj := range volumeObj .mountedPods {
748
+ if mountedPodName == podName && podObj .volumeMountStateForPod == operationexecutor .VolumeMounted {
749
+ mountedVolume = append (
750
+ mountedVolume ,
751
+ getMountedVolume (& podObj , & volumeObj ))
752
+ }
690
753
}
691
754
}
692
755
@@ -699,7 +762,7 @@ func (asw *actualStateOfWorld) GetGloballyMountedVolumes() []AttachedVolume {
699
762
globallyMountedVolumes := make (
700
763
[]AttachedVolume , 0 /* len */ , len (asw .attachedVolumes ) /* cap */ )
701
764
for _ , volumeObj := range asw .attachedVolumes {
702
- if volumeObj .globallyMounted {
765
+ if volumeObj .deviceMountState == operationexecutor . DeviceGloballyMounted {
703
766
globallyMountedVolumes = append (
704
767
globallyMountedVolumes ,
705
768
asw .newAttachedVolume (& volumeObj ))
@@ -749,7 +812,7 @@ func (asw *actualStateOfWorld) newAttachedVolume(
749
812
DevicePath : attachedVolume .devicePath ,
750
813
DeviceMountPath : attachedVolume .deviceMountPath ,
751
814
PluginName : attachedVolume .pluginName },
752
- GloballyMounted : attachedVolume .globallyMounted ,
815
+ DeviceMountState : attachedVolume .deviceMountState ,
753
816
}
754
817
}
755
818
0 commit comments