@@ -191,6 +191,8 @@ type Operator struct {
191191 // featurechangestopper controller will detect when cluster feature gate config changes and shutdown the CVO.
192192 enabledFeatureGates featuregates.CvoGateChecker
193193
194+ // featureGatesMutex protects access to enabledManifestFeatureGates
195+ featureGatesMutex sync.RWMutex
194196 enabledManifestFeatureGates sets.Set [string ]
195197
196198 clusterProfile string
@@ -1115,6 +1117,9 @@ func (optr *Operator) featureGateEventHandler() cache.ResourceEventHandler {
11151117
11161118// initializeFeatureGates initializes the cluster feature gates from the current FeatureGate object
11171119func (optr * Operator ) initializeFeatureGates () {
1120+ optr .featureGatesMutex .Lock ()
1121+ defer optr .featureGatesMutex .Unlock ()
1122+
11181123 optr .enabledManifestFeatureGates = sets.Set [string ]{}
11191124
11201125 // Try to load initial state from the cluster FeatureGate object
@@ -1135,6 +1140,9 @@ func (optr *Operator) updateEnabledFeatureGates(obj interface{}) {
11351140
11361141 newGates := optr .extractEnabledGates (featureGate )
11371142
1143+ optr .featureGatesMutex .Lock ()
1144+ defer optr .featureGatesMutex .Unlock ()
1145+
11381146 // Check if gates actually changed to avoid unnecessary work
11391147 if ! optr .enabledManifestFeatureGates .Equal (newGates ) {
11401148 klog .V (2 ).Infof ("Cluster feature gates changed from %v to %v" ,
@@ -1145,6 +1153,9 @@ func (optr *Operator) updateEnabledFeatureGates(obj interface{}) {
11451153
11461154// getEnabledFeatureGates returns a copy of the current cluster feature gates for safe consumption
11471155func (optr * Operator ) getEnabledFeatureGates () sets.Set [string ] {
1156+ optr .featureGatesMutex .RLock ()
1157+ defer optr .featureGatesMutex .RUnlock ()
1158+
11481159 // Return a copy to prevent external modification
11491160 result := sets.Set [string ]{}
11501161 for gate := range optr .enabledManifestFeatureGates {
0 commit comments