Skip to content

Conversation

@ErikJiang
Copy link
Contributor

@ErikJiang ErikJiang commented Aug 19, 2025

Refactored resource processing logic by extracting adjustMemoryResource and adjustCPUResource helper functions to eliminate code duplication.

  • Added adjustMemoryResource function for memory resource operations
  • Added adjustCPUResource function for CPU resource operations
  • Updated adjustResources and updateResources to use new helpers

@ErikJiang ErikJiang force-pushed the extract_helper_func branch 2 times, most recently from af3a7b2 to 3ba163e Compare August 19, 2025 05:54

func (r *result) adjustResources(resources *LinuxResources, plugin string) error {
if resources == nil {
func (r *result) processMemoryResource(mem *LinuxMemory, targetContainer, targetReply *LinuxMemory, id, plugin string) error {
Copy link
Contributor

@chrishenzie chrishenzie Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think I'm partial to the previous "adjust" method naming, which implies it's making adjustments to the result container and reply


func (r *result) adjustResources(resources *LinuxResources, plugin string) error {
if resources == nil {
func (r *result) processMemoryResource(mem *LinuxMemory, targetContainer, targetReply *LinuxMemory, id, plugin string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: mem is also the same type as the following two arguments. Should we remove this redundant LinuxMemory?

}
resources.Memory.UseHierarchy = Bool(v.GetValue())
}
if err := r.processMemoryResource(u.Linux.Resources.Memory, resources.Memory, &LinuxMemory{}, id, plugin); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without context, feeding in an empty struct that's unused here feels like an anti-pattern. What if we were to split up processMemoryResource() so that it only updates targetContainer, and then separately we can deep copy the results to reply? Thoughts on this approach?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review!
I've addressed your suggestions in the latest commit.
Please let me know if there are any further adjustments needed. 😊

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those proto.Clone()s are not a good idea (see my other, more detailed comments). Please revert to your original approach where you properly collected the requested changes only in the reply adjustment.

Comment on lines 746 to 751
reply.Memory = proto.Clone(container.Memory).(*LinuxMemory)

if err := r.adjustCPUResource(resources.Cpu, container.Cpu, id, plugin); err != nil {
return err
}
reply.Cpu = proto.Clone(container.Cpu).(*LinuxCPU)
Copy link
Member

@klihub klihub Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ErikJiang I think these blind deep copies are not a good idea. Please don't do these. They are altering behavior compared to the original implementation, even if that does not show currently up in the end result.

The original implementation deliberately collected only the requested changes in the reply adjustment. With these changes now if there is any change requested to any of the CPU or memory resources of a container which has non-empty resources, the reply will incorrectly claim that the plugin requested changing every single parameter with the unrequested ones being copies of the original ones. You can see this for yourself easily, if you change the tests so that we don't start with a container with empty resources, for instance using this commit:

commit 38c50ea6bc12092ee6b9fe8cf53c09ca6a96884c (HEAD)
Author: Krisztian Litkey <krisztian.litkey@intel.com>
Date:   Tue Sep 23 14:57:52 2025 +0300

    WiP: adaptation: demo altered semantics of collected resource adjustments.
    
    Signed-off-by: Krisztian Litkey <krisztian.litkey@intel.com>

diff --git a/pkg/adaptation/adaptation_suite_test.go b/pkg/adaptation/adaptation_suite_test.go
index 4a19c7a..e093ded 100644
--- a/pkg/adaptation/adaptation_suite_test.go
+++ b/pkg/adaptation/adaptation_suite_test.go
@@ -628,6 +628,19 @@ var _ = Describe("Plugin container creation adjustments", func() {
                                                        "argument",
                                                        "list",
                                                },
+                                               Linux: &api.LinuxContainer{
+                                                       Resources: &api.LinuxResources{
+                                                               Cpu: &api.LinuxCPU{
+                                                                       Shares: api.UInt64(111),
+                                                                       Quota:  api.Int64(222),
+                                                                       Period: api.UInt64(333),
+                                                               },
+                                                               Memory: &api.LinuxMemory{
+                                                                       Limit: api.Int64(11111),
+                                                                       Swap:  api.Int64(22222),
+                                                               },
+                                                       },
+                                               },
                                        }
                                )

make test (or alternatively ginkgo run ./pkg/adaptation) should now fail with this extra commit and the changes of this PR in place, while it passes without this PR.

I am pretty sure this is not intentional on your part. It is just a side effect of your latest changes (in response to a previous review comment) where you now proto.Clone()-deep-copy resources from the adjusted container in the request, instead of properly collecting them in the reply. Even if this would not have unintended side-effects on the final adjusted container itself now, it might have in the future if we change semantics, and it already might cause false positives now with custom validators and break stuff.

Please switch your PR back to your original approach where this aspect was not changed.

Copy link
Member

@klihub klihub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't alter the semantics of the collected adjustment. Your original implementation was correct in that sense and we should switch back to that or a functionally equivalent one.

@klihub
Copy link
Member

klihub commented Sep 23, 2025

@ErikJiang I filed #231 as minimal protection to prevent such unintentional changes to the semantics in the future.

@chrishenzie
Copy link
Contributor

chrishenzie commented Sep 23, 2025

@klihub @ErikJiang If we're going with the prior approach, can we leave a comment at the callsites briefly explaining why we're passing an empty reply?

@klihub
Copy link
Member

klihub commented Sep 23, 2025

@klihub @ErikJiang If we're going with the prior approach, can we leave a comment at the callsites briefly explaining why we're passing an empty reply?

I think instead of an empty reply, we could change the function so that if we pass in a nil instead, it's checked for and skipped, and we'd use a nil instead of a temporary variable which is otherwise unused. It'd seem much clearer that way to me.

Signed-off-by: bo.jiang <bo.jiang@daocloud.io>
@ErikJiang
Copy link
Contributor Author

@klihub @chrishenzie Thanks for the feedback. I've removed the proto.Clone() and reverted to selectively updating the reply to avoid the side effects you pointed out. The new commit is up for review.

Copy link
Contributor

@chrishenzie chrishenzie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Copy link
Member

@klihub klihub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ErikJiang LGTM. Thank you !

@klihub klihub merged commit 8a05f28 into containerd:main Sep 26, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants