@@ -45,8 +45,8 @@ func (c *criService) UpdateContainerResources(ctx context.Context, r *runtime.Up
4545 // Update resources in status update transaction, so that:
4646 // 1) There won't be race condition with container start.
4747 // 2) There won't be concurrent resource update to the same container.
48- if err := container .Status .Update (func (status containerstore.Status ) (containerstore.Status , error ) {
49- return status , c .updateContainerResources (ctx , container , r , status )
48+ if err := container .Status .UpdateSync (func (status containerstore.Status ) (containerstore.Status , error ) {
49+ return c .updateContainerResources (ctx , container , r , status )
5050 }); err != nil {
5151 return nil , fmt .Errorf ("failed to update resources: %w" , err )
5252 }
@@ -56,11 +56,13 @@ func (c *criService) UpdateContainerResources(ctx context.Context, r *runtime.Up
5656func (c * criService ) updateContainerResources (ctx context.Context ,
5757 cntr containerstore.Container ,
5858 r * runtime.UpdateContainerResourcesRequest ,
59- status containerstore.Status ) (retErr error ) {
59+ status containerstore.Status ) (newStatus containerstore.Status , retErr error ) {
60+
61+ newStatus = status
6062 id := cntr .ID
6163 // Do not update the container when there is a removal in progress.
6264 if status .Removing {
63- return fmt .Errorf ("container %q is in removing state" , id )
65+ return newStatus , fmt .Errorf ("container %q is in removing state" , id )
6466 }
6567
6668 // Update container spec. If the container is not started yet, updating
@@ -69,15 +71,15 @@ func (c *criService) updateContainerResources(ctx context.Context,
6971 // the spec will become our source of truth for resource limits.
7072 oldSpec , err := cntr .Container .Spec (ctx )
7173 if err != nil {
72- return fmt .Errorf ("failed to get container spec: %w" , err )
74+ return newStatus , fmt .Errorf ("failed to get container spec: %w" , err )
7375 }
7476 newSpec , err := updateOCIResource (ctx , oldSpec , r , c .config )
7577 if err != nil {
76- return fmt .Errorf ("failed to update resource in spec: %w" , err )
78+ return newStatus , fmt .Errorf ("failed to update resource in spec: %w" , err )
7779 }
7880
7981 if err := updateContainerSpec (ctx , cntr .Container , newSpec ); err != nil {
80- return err
82+ return newStatus , err
8183 }
8284 defer func () {
8385 if retErr != nil {
@@ -87,32 +89,35 @@ func (c *criService) updateContainerResources(ctx context.Context,
8789 if err := updateContainerSpec (deferCtx , cntr .Container , oldSpec ); err != nil {
8890 log .G (ctx ).WithError (err ).Errorf ("Failed to update spec %+v for container %q" , oldSpec , id )
8991 }
92+ } else {
93+ // Update container status only when the spec is updated
94+ newStatus = copyResourcesToStatus (newSpec , status )
9095 }
9196 }()
9297
9398 // If container is not running, only update spec is enough, new resource
9499 // limit will be applied when container start.
95100 if status .State () != runtime .ContainerState_CONTAINER_RUNNING {
96- return nil
101+ return newStatus , nil
97102 }
98103
99104 task , err := cntr .Container .Task (ctx , nil )
100105 if err != nil {
101106 if errdefs .IsNotFound (err ) {
102107 // Task exited already.
103- return nil
108+ return newStatus , nil
104109 }
105- return fmt .Errorf ("failed to get task: %w" , err )
110+ return newStatus , fmt .Errorf ("failed to get task: %w" , err )
106111 }
107112 // newSpec.Linux / newSpec.Windows won't be nil
108113 if err := task .Update (ctx , containerd .WithResources (getResources (newSpec ))); err != nil {
109114 if errdefs .IsNotFound (err ) {
110115 // Task exited already.
111- return nil
116+ return newStatus , nil
112117 }
113- return fmt .Errorf ("failed to update resources: %w" , err )
118+ return newStatus , fmt .Errorf ("failed to update resources: %w" , err )
114119 }
115- return nil
120+ return newStatus , nil
116121}
117122
118123// updateContainerSpec updates container spec.
0 commit comments