Skip to content

Commit 40df9f8

Browse files
authored
Merge pull request kubernetes#82492 from gnufied/fix-uncertain-mounts
Fix uncertain mounts
2 parents e5f0648 + ca532c6 commit 40df9f8

25 files changed

+1392
-250
lines changed

pkg/kubelet/volumemanager/cache/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ go_test(
4040
"//pkg/volume:go_default_library",
4141
"//pkg/volume/testing:go_default_library",
4242
"//pkg/volume/util:go_default_library",
43+
"//pkg/volume/util/operationexecutor:go_default_library",
4344
"//pkg/volume/util/types:go_default_library",
4445
"//staging/src/k8s.io/api/core/v1:go_default_library",
4546
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

pkg/kubelet/volumemanager/cache/actual_state_of_world.go

Lines changed: 128 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"fmt"
2525
"sync"
2626

27-
"k8s.io/api/core/v1"
27+
v1 "k8s.io/api/core/v1"
2828
"k8s.io/apimachinery/pkg/types"
2929
utilfeature "k8s.io/apiserver/pkg/util/feature"
3030
"k8s.io/klog"
@@ -59,7 +59,7 @@ type ActualStateOfWorld interface {
5959
// volume, reset the pod's remountRequired value.
6060
// If a volume with the name volumeName does not exist in the list of
6161
// 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
6363

6464
// MarkRemountRequired marks each volume that is successfully attached and
6565
// mounted for the specified pod as requiring remount (if the plugin for the
@@ -68,13 +68,13 @@ type ActualStateOfWorld interface {
6868
// pod update.
6969
MarkRemountRequired(podName volumetypes.UniquePodName)
7070

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.
7575
// If a volume with the name volumeName does not exist in the list of
7676
// 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
7878

7979
// DeletePodFromVolume removes the given pod from the given volume in the
8080
// cache indicating the volume has been successfully unmounted from the pod.
@@ -127,6 +127,10 @@ type ActualStateOfWorld interface {
127127
// actual state of the world.
128128
GetMountedVolumes() []MountedVolume
129129

130+
// GetAllMountedVolumes returns list of all possibly mounted volumes including
131+
// those that are in VolumeMounted state and VolumeMountUncertain state.
132+
GetAllMountedVolumes() []MountedVolume
133+
130134
// GetMountedVolumesForPod generates and returns a list of volumes that are
131135
// successfully attached and mounted for the specified pod based on the
132136
// current actual state of the world.
@@ -165,10 +169,15 @@ type MountedVolume struct {
165169
type AttachedVolume struct {
166170
operationexecutor.AttachedVolume
167171

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
172181
}
173182

174183
// NewActualStateOfWorld returns a new instance of ActualStateOfWorld.
@@ -245,10 +254,9 @@ type attachedVolume struct {
245254
// this volume implements the volume.Attacher interface
246255
pluginIsAttachable bool
247256

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
252260

253261
// devicePath contains the path on the node where the volume is attached for
254262
// attachable volumes
@@ -301,6 +309,11 @@ type mountedPod struct {
301309
// fsResizeRequired indicates the underlying volume has been successfully
302310
// mounted to this pod but its size has been expanded after that.
303311
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
304317
}
305318

306319
func (asw *actualStateOfWorld) MarkVolumeAsAttached(
@@ -318,24 +331,8 @@ func (asw *actualStateOfWorld) MarkVolumeAsDetached(
318331
asw.DeleteVolume(volumeName)
319332
}
320333

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)
339336
}
340337

341338
func (asw *actualStateOfWorld) AddVolumeToReportAsAttached(volumeName v1.UniqueVolumeName, nodeName types.NodeName) {
@@ -354,12 +351,50 @@ func (asw *actualStateOfWorld) MarkVolumeAsUnmounted(
354351

355352
func (asw *actualStateOfWorld) MarkDeviceAsMounted(
356353
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)
358365
}
359366

360367
func (asw *actualStateOfWorld) MarkDeviceAsUnmounted(
361368
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
363398
}
364399

365400
// addVolume adds the given volume to the cache indicating the specified
@@ -405,7 +440,7 @@ func (asw *actualStateOfWorld) addVolume(
405440
mountedPods: make(map[volumetypes.UniquePodName]mountedPod),
406441
pluginName: volumePlugin.GetPluginName(),
407442
pluginIsAttachable: pluginIsAttachable,
408-
globallyMounted: false,
443+
deviceMountState: operationexecutor.DeviceNotMounted,
409444
devicePath: devicePath,
410445
}
411446
} else {
@@ -420,15 +455,15 @@ func (asw *actualStateOfWorld) addVolume(
420455
return nil
421456
}
422457

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
432467
asw.Lock()
433468
defer asw.Unlock()
434469

@@ -442,20 +477,21 @@ func (asw *actualStateOfWorld) AddPodToVolume(
442477
podObj, podExists := volumeObj.mountedPods[podName]
443478
if !podExists {
444479
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,
452488
}
453489
}
454490

455491
// If pod exists, reset remountRequired value
456492
podObj.remountRequired = false
493+
podObj.volumeMountStateForPod = markVolumeOpts.VolumeMountState
457494
asw.attachedVolumes[volumeName].mountedPods[podName] = podObj
458-
459495
return nil
460496
}
461497

@@ -554,8 +590,8 @@ func (asw *actualStateOfWorld) MarkFSResizeRequired(
554590
}
555591
}
556592

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 {
559595
asw.Lock()
560596
defer asw.Unlock()
561597

@@ -566,7 +602,7 @@ func (asw *actualStateOfWorld) SetVolumeGloballyMounted(
566602
volumeName)
567603
}
568604

569-
volumeObj.globallyMounted = globallyMounted
605+
volumeObj.deviceMountState = deviceMountState
570606
volumeObj.deviceMountPath = deviceMountPath
571607
if devicePath != "" {
572608
volumeObj.devicePath = devicePath
@@ -628,6 +664,10 @@ func (asw *actualStateOfWorld) PodExistsInVolume(
628664

629665
podObj, podExists := volumeObj.mountedPods[podName]
630666
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+
}
631671
if podObj.remountRequired {
632672
return true, volumeObj.devicePath, newRemountRequiredError(volumeObj.volumeName, podObj.podName)
633673
}
@@ -668,9 +708,30 @@ func (asw *actualStateOfWorld) GetMountedVolumes() []MountedVolume {
668708
mountedVolume := make([]MountedVolume, 0 /* len */, len(asw.attachedVolumes) /* cap */)
669709
for _, volumeObj := range asw.attachedVolumes {
670710
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+
674735
}
675736
}
676737

@@ -683,10 +744,12 @@ func (asw *actualStateOfWorld) GetMountedVolumesForPod(
683744
defer asw.RUnlock()
684745
mountedVolume := make([]MountedVolume, 0 /* len */, len(asw.attachedVolumes) /* cap */)
685746
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+
}
690753
}
691754
}
692755

@@ -699,7 +762,7 @@ func (asw *actualStateOfWorld) GetGloballyMountedVolumes() []AttachedVolume {
699762
globallyMountedVolumes := make(
700763
[]AttachedVolume, 0 /* len */, len(asw.attachedVolumes) /* cap */)
701764
for _, volumeObj := range asw.attachedVolumes {
702-
if volumeObj.globallyMounted {
765+
if volumeObj.deviceMountState == operationexecutor.DeviceGloballyMounted {
703766
globallyMountedVolumes = append(
704767
globallyMountedVolumes,
705768
asw.newAttachedVolume(&volumeObj))
@@ -749,7 +812,7 @@ func (asw *actualStateOfWorld) newAttachedVolume(
749812
DevicePath: attachedVolume.devicePath,
750813
DeviceMountPath: attachedVolume.deviceMountPath,
751814
PluginName: attachedVolume.pluginName},
752-
GloballyMounted: attachedVolume.globallyMounted,
815+
DeviceMountState: attachedVolume.deviceMountState,
753816
}
754817
}
755818

0 commit comments

Comments
 (0)