Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove kmem Initialization check while setting memory configuration #962

Merged
merged 1 commit into from
Aug 2, 2016

Conversation

dubstack
Copy link

@dubstack dubstack commented Jul 23, 2016

I suggest that we modify the logic for setting the kmem.limit_on_bytes to be more deterministic and
remove the kmemInitialized check.

If kernel memory is enabled we limit the cgroup during cgroup creation ie. in apply(). This will enable kernel memory accounting on the cgroup ( http://lxr.free-electrons.com/source/Documentation/cgroups/memory.txt?v=3.9#L284 ).
We limit the cgroup by writing some arbitrary limiting value(say 1) so that the kernel memory is accounted, and then we remove the limitation by writing -1.

Once accounting is enabled we should be able to set the kernel memory limit to configuration value in the Set method.

The only scenario in which this would fail is if someone straight out calls Set() on a cgroup which was not created by libcontainer, in which case, if there are already process attached to the cgroup setting kernel memory limit would return an Ebusy signal and we can error out.

cc @mrunalp @derekwaynecarr @cyphar @vishh @hqhq PTAL

@dubstack dubstack force-pushed the fix_kmem_limits branch 2 times, most recently from a5e95f8 to 1a323f1 Compare July 23, 2016 01:30
@mlaventure
Copy link
Contributor

Are we happy for it to fail if joining an existing cgroup with a limit already sets? On this PR, the error message is not very explicit from a user perspective as it will just be:

process_linux.go:258: applying cgroup configuration for process caused "failed to write 1 to memory.kmem.limit_in_bytes: write /sys/fs/cgroup/memory/xxx/memory.kmem.limit_in_bytes: device or resource busy"

I think adding a more explanatory message to the returned error on EBUSY may be a good idea.

WDYT?

@hqhq
Copy link
Contributor

hqhq commented Jul 25, 2016

Yeah, that's what I concerned in #841 (comment)

@dubstack
Copy link
Author

@mlaventure @hqhq Please have a look at my comment here: #841 (comment)

// We have to set kernel memory here, as we can't change it once
// processes have been attached to the cgroup.
if err := s.SetKernelMemory(path, d.config); err != nil {
// We have to limit the kernel memory here as it won't be accounted at all
Copy link
Author

Choose a reason for hiding this comment

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

We need to have a check here for determining if kmem is enabled on the system.
@hqhq @vishh Suggestions on how to check for the same?

Copy link
Contributor

Choose a reason for hiding this comment

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

Check if memory.kmem.limit_in_bytes file is there?

On Mon, Jul 25, 2016 at 11:46 AM, Buddha Prakash [email protected]
wrote:

In libcontainer/cgroups/fs/memory.go
#962 (comment):

@@ -34,9 +32,15 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
return err
}
}

  •   // We have to set kernel memory here, as we can't change it once
    
  •   // processes have been attached to the cgroup.
    
  •   if err := s.SetKernelMemory(path, d.config); err != nil {
    
  •   // We have to limit the kernel memory here as it won't be accounted at all
    

We need to have a check here for determining if kmem is enabled on the
system.
@hqhq https://github.com/hqhq @vishh https://github.com/vishh
Suggestions on how to check for the same?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/opencontainers/runc/pull/962/files/5106b565da1c9af39f279edb0235eb1da06d703d#r72121173,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGvIKEIF-LQ6vcR1xObXWdqCQ_kmAS4aks5qZQSdgaJpZM4JTOyV
.

hqhq added a commit to hqhq/runc that referenced this pull request Jul 26, 2016
@dubstack
Copy link
Author

Updated the patch to add a more specific error message when kernel memory limit write fails with an EBUSY.
@mlaventure @hqhq @cyphar @vishh PTAL.

@mlaventure
Copy link
Contributor

LGTM (IANAM).

return err

// Check if kernel memory is enabled
if _, err := os.Stat(filepath.Join(path, cgroupKernelMemoryLimit)); 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.

nit use cgroups.PathExists(...)

Copy link
Contributor

Choose a reason for hiding this comment

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

Why not move this check to SetKernelMemory(...) method?

Copy link
Author

Choose a reason for hiding this comment

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

The idea was we SetKernelMemory() only if kernel memory is enabled. So have the check and then call the method.

But having the check inside the method would be more cleaner. I will make that change.

@dubstack
Copy link
Author

@cyphar @hqhq @mrunalp @vishh Addressed all comments. PTAL. This is blocking work in Kubernetes. Can we get this quickly reviewed and merged?

if pathErr, ok := err.(*os.PathError); ok {
if errNo, ok := pathErr.Err.(syscall.Errno); ok {
if errNo == syscall.EBUSY {
return fmt.Errorf("Cannot set %s after tasks have joined this cgroup", cgroupKernelMemoryLimit)
Copy link
Contributor

Choose a reason for hiding this comment

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

EBUSY could also be returned if there are child cgroups, we need to change error message a bit to cover that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget to change the above comments.

Copy link
Contributor

Choose a reason for hiding this comment

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

And error messages start with lower case in runc.

Copy link
Author

Choose a reason for hiding this comment

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

Right! Thanks

@dubstack
Copy link
Author

@cyphar @hqhq @mrunalp @mlaventure I have updated the logic in systemd to be same as that of cgroup fs.

@mrunalp @derekwaynecarr Can you please have a look and maybe test it on a systemd system.

if pathErr, ok := err.(*os.PathError); ok {
if errNo, ok := pathErr.Err.(syscall.Errno); ok {
if errNo == syscall.EBUSY {
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroupe or it has chilren", cgroupKernelMemoryLimit)
Copy link
Contributor

Choose a reason for hiding this comment

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

s/cgroupe/cgroup
s/chilren/children

Copy link
Author

Choose a reason for hiding this comment

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

Thanks! I will make the change!

Signed-off-by: Buddha Prakash <[email protected]>
@dubstack
Copy link
Author

dubstack commented Aug 1, 2016

@cyphar @mrunalp @mlaventure friendly ping!

@vishh
Copy link
Contributor

vishh commented Aug 1, 2016

This LGTM. Thanks for the cleanup @dubstack !!

@opencontainers/runc-maintainers Can we get a quick review on this? This PR is important.

@mrunalp
Copy link
Contributor

mrunalp commented Aug 1, 2016

Testing this with systemd.

@mrunalp
Copy link
Contributor

mrunalp commented Aug 1, 2016

@hmeng-19 Could you test this PR on RHEL 7?

@haiyanmeng
Copy link
Contributor

@mrunalp , I tested this on RHEL7.
All the bats tests finished successfully.
All the unit tests except for TestInitJoinNetworkAndUser (as mentioned in #915) also finished successfully.

@mrunalp
Copy link
Contributor

mrunalp commented Aug 1, 2016

@hmeng-19 Thanks for testing.

@mrunalp
Copy link
Contributor

mrunalp commented Aug 1, 2016

LGTM

Approved with PullApprove

@haiyanmeng
Copy link
Contributor

@mrunalp , no problem.
To make it easy for others to test this PR, here is the testing command I used on RHEL7:

First, I created a basic config.json:

ocitools generate --tty --output=config.json \
--uidmappings=0:0:1024 --gidmappings=0:0:1024 \
--cgroups-path user.slice:hmeng:test2222 --mount-cgroups ro

Then add kernel memory limit into config.json:

        "memory": {
            "kernel": 50000000
        },

Finally, start the container and check the kernel memory limit:

runc --systemd-cgroup run 1234
runc run 1234

@hqhq
Copy link
Contributor

hqhq commented Aug 2, 2016

LGTM

Approved with PullApprove

@hqhq hqhq merged commit 50f0a2b into opencontainers:master Aug 2, 2016
hqhq added a commit to hqhq/runc that referenced this pull request Aug 2, 2016
Follow up: opencontainers#962

Signed-off-by: Qiang Huang <[email protected]>
@hqhq hqhq mentioned this pull request Aug 2, 2016
@hqhq
Copy link
Contributor

hqhq commented Aug 2, 2016

@dubstack Sorry for not being specific, we should do more cleanups for GetLongBit, I've opened a follow up PR #968 for not blocking this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants