@@ -370,6 +370,20 @@ func (dn *NodeReconciler) checkSystemdStatus() (*hosttypes.SriovResult, bool, er
370370// 7. Updating the lastAppliedGeneration to the current generation.
371371func (dn * NodeReconciler ) apply (ctx context.Context , desiredNodeState * sriovnetworkv1.SriovNetworkNodeState , reqReboot bool , sriovResult * hosttypes.SriovResult ) (ctrl.Result , error ) {
372372 reqLogger := log .FromContext (ctx ).WithName ("Apply" )
373+
374+ // Restart the device plugin *before* applying configuration if the
375+ // BlockDevicePluginUntilConfiguredFeatureGate feature is enabled.
376+ // With this gate enabled, the device plugin will remain blocked until it is
377+ // explicitly unblocked after configuration (see waitForDevicePluginPodAndTryUnblock).
378+ // If the feature gate is not enabled, preserve legacy behavior by
379+ // restarting the device plugin *after* configuration is applied.
380+ if vars .FeatureGate .IsEnabled (consts .BlockDevicePluginUntilConfiguredFeatureGate ) {
381+ if err := dn .restartDevicePluginPod (ctx ); err != nil {
382+ reqLogger .Error (err , "failed to restart device plugin on the node" )
383+ return ctrl.Result {}, err
384+ }
385+ }
386+
373387 // apply the additional plugins after we are done with drain if needed
374388 for _ , p := range dn .additionalPlugins {
375389 err := p .Apply ()
@@ -395,15 +409,18 @@ func (dn *NodeReconciler) apply(ctx context.Context, desiredNodeState *sriovnetw
395409 return ctrl.Result {}, dn .rebootNode ()
396410 }
397411
398- if err := dn .restartDevicePluginPod (ctx ); err != nil {
399- reqLogger .Error (err , "failed to restart device plugin on the node" )
400- return ctrl.Result {}, err
401- }
402412 if vars .FeatureGate .IsEnabled (consts .BlockDevicePluginUntilConfiguredFeatureGate ) {
403413 if err := dn .waitForDevicePluginPodAndTryUnblock (ctx , desiredNodeState ); err != nil {
404414 reqLogger .Error (err , "failed to wait for device plugin pod to start and try to unblock it" )
405415 return ctrl.Result {}, err
406416 }
417+ } else {
418+ // if the feature gate is not enabled we preserver the old behavior
419+ // and restart device plugin after configuration is applied
420+ if err := dn .restartDevicePluginPod (ctx ); err != nil {
421+ reqLogger .Error (err , "failed to restart device plugin on the node" )
422+ return ctrl.Result {}, err
423+ }
407424 }
408425
409426 err := dn .annotate (ctx , desiredNodeState , consts .DrainIdle )
@@ -452,7 +469,7 @@ func (dn *NodeReconciler) tryUnblockDevicePlugin(ctx context.Context,
452469 for _ , pod := range devicePluginPods {
453470 if err := utils .RemoveAnnotationFromObject (ctx , & pod ,
454471 consts .DevicePluginWaitConfigAnnotation , dn .client ); err != nil {
455- return fmt .Errorf ("failed to remove wait-for-config annotation from pod: %w" , err )
472+ return fmt .Errorf ("failed to remove %s annotation from pod: %w" , consts . DevicePluginWaitConfigAnnotation , err )
456473 }
457474 }
458475 return nil
@@ -577,18 +594,19 @@ func (dn *NodeReconciler) handleDrain(ctx context.Context, desiredNodeState *sri
577594
578595// getDevicePluginPods returns the device plugin pods running on this node
579596func (dn * NodeReconciler ) getDevicePluginPodsForNode (ctx context.Context ) ([]corev1.Pod , error ) {
597+ funcLog := log .Log .WithName ("getDevicePluginPodsForNode" )
580598 pods := & corev1.PodList {}
581599 err := dn .client .List (ctx , pods , & client.ListOptions {
582600 Namespace : vars .Namespace , Raw : & metav1.ListOptions {
583601 LabelSelector : "app=sriov-device-plugin" ,
584602 FieldSelector : "spec.nodeName=" + vars .NodeName ,
585603 }})
586604 if err != nil {
587- log . Log . Error (err , "getDevicePluginPodsForNode(): failed to list device plugin pods" )
605+ funcLog . Error (err , "failed to list device plugin pods" )
588606 return []corev1.Pod {}, err
589607 }
590608 if len (pods .Items ) == 0 {
591- log . Log . Info ("getDevicePluginPodsForNode(): no device plugin pods found" )
609+ funcLog . Info ("no device plugin pods found" )
592610 return []corev1.Pod {}, nil
593611 }
594612 return pods .Items , nil
@@ -649,18 +667,18 @@ func (dn *NodeReconciler) restartDevicePluginPod(ctx context.Context) error {
649667// for the periodic check. We expect to have at least one device plugin pod for the node.
650668func (dn * NodeReconciler ) waitForDevicePluginPodAndTryUnblock (ctx context.Context , desiredNodeState * sriovnetworkv1.SriovNetworkNodeState ) error {
651669 funcLog := log .Log .WithName ("waitForDevicePluginPodAndTryUnblock" )
652- funcLog .Info ("waiting for device plugin to set wait-for-config annotation" )
670+ funcLog .Info ("waiting for device plugin to set wait-for-config annotation" , "annotation" , consts . DevicePluginWaitConfigAnnotation )
653671 var devicePluginPods []corev1.Pod
654672 err := wait .PollUntilContextTimeout (ctx , time .Second , 2 * time .Minute , true ,
655673 func (ctx context.Context ) (bool , error ) {
656674 var err error
657675 devicePluginPods , err = dn .getDevicePluginPodsForNode (ctx )
658676 if err != nil {
659- log . Log . Error (err , "waitForDevicePluginPodAndUnblock(): failed to get device plugin pod while waiting for a new pod to start" )
677+ funcLog . Error (err , "failed to get device plugin pod while waiting for a new pod to start" )
660678 return false , err
661679 }
662680 if len (devicePluginPods ) == 0 {
663- log . Log . V (2 ).Info ("waitForDevicePluginPodAndUnblock(): no device plugin pods found while waiting for a new pod to start" )
681+ funcLog . V (2 ).Info ("no device plugin pods found while waiting for a new pod to start" )
664682 return false , nil
665683 }
666684 for _ , pod := range devicePluginPods {
@@ -669,12 +687,12 @@ func (dn *NodeReconciler) waitForDevicePluginPodAndTryUnblock(ctx context.Contex
669687 // may also match our selector. Since unmanaged pods won't have this annotation,
670688 // we only require one pod (the managed one) to have it.
671689 if utils .ObjectHasAnnotationKey (& pod , consts .DevicePluginWaitConfigAnnotation ) {
672- log . Log . Info ("waitForDevicePluginPodAndUnblock(): wait-for-config annotation found on pod" ,
690+ funcLog . Info ("wait-for-config annotation found on pod" ,
673691 "pod" , pod .Name )
674692 return true , nil
675693 }
676694 }
677- log . Log . V (2 ).Info ("waitForDevicePluginPodAndUnblock(): waiting for new device plugin pod to have wait-for-config annotation" )
695+ funcLog . V (2 ).Info ("waiting for new device plugin pod to have wait-for-config annotation" )
678696 return false , nil
679697 })
680698 if err != nil {
@@ -683,8 +701,8 @@ func (dn *NodeReconciler) waitForDevicePluginPodAndTryUnblock(ctx context.Contex
683701 }
684702 // If annotation is not found within the timeout, log a warning and proceed.
685703 // The device plugin pod will be unblocked by the periodic check logic in tryUnblockDevicePlugin.
686- log . Log . Info ("waitForDevicePluginPodAndUnblock(): WARNING: device plugin pod with " +
687- "wait-for-config annotation not found within timeout" )
704+ funcLog . Info ("WARNING: device plugin pod with wait-for-config annotation not found within timeout" )
705+ return nil
688706 }
689707 if len (devicePluginPods ) > 0 {
690708 // try to unblock all device plugin pods we retrieved with the latest loop iteration
0 commit comments