fix path error in systemd when stopped#2338
Conversation
|
|
kolyshkin
left a comment
There was a problem hiding this comment.
I'd rather check if path exists in callers, whenever deemed necessary (or ignore ENOENT in some cases)
0e410f7 to
157518f
Compare
Force pushed. |
f90a6ec to
cd9408b
Compare
|
travis-ci green now! |
| } | ||
| } | ||
|
|
||
| pids, err = c.cgroupManager.GetAllPids() |
There was a problem hiding this comment.
wouldn't this already be able to have a check for os.IsNotExist(err) ? (Also wondering if c.cgroupManager.GetAllPids() should ignore os.IsNotExist(err) by default (if the path doesn't exist, just return an empty list of pids ?
There was a problem hiding this comment.
wouldn't this already be able to have a check for
os.IsNotExist(err)?
Yes, but in fs cgroup driver, there is no error when the container is in stopped state. And I think we should not ignore IsNotExist error when it is not in stopped state or it has joined a new pid namespace without path is not in a private pid namespace.
(Also wondering if
c.cgroupManager.GetAllPids()should ignoreos.IsNotExist(err)by default (if the path doesn't exist, just return an empty list of pids ?
I think we should not ignore IsNotExist error when it is not in stopped state or it has joined a new pid namespace without path is not in a private pid namespace
146afb1 to
9e6d835
Compare
|
@lifubang this needs a rebase |
d946961 to
b565295
Compare
libcontainer/container_linux_test.go
Outdated
| pid := 1 | ||
| stat, err := system.Stat(pid) | ||
| if err != nil { | ||
| t.Fatalf("can't state pid %d", pid) |
There was a problem hiding this comment.
nit: s/state/stat/
nit: include the actual error as well
| cgroupManager: &mockCgroupManager{ | ||
| allPids: []int{1, 2, 3}, | ||
| paths: map[string]string{ | ||
| "device": "/proc/self/cgroups", |
There was a problem hiding this comment.
this looks kind of weird.
There was a problem hiding this comment.
It's a mock data, I don't have any idea to improve it.
libcontainer/cgroups/fs/apply_raw.go
Outdated
|
|
||
| func (m *manager) Exists() bool { | ||
| paths := m.GetPaths() | ||
| return cgroups.PathExists(paths["devices"]) |
There was a problem hiding this comment.
I think you can just do
return cgroups.PathExists(m.Path("devices"))
libcontainer/cgroups/systemd/v1.go
Outdated
| } | ||
|
|
||
| func (m *legacyManager) Exists() bool { | ||
| path, err := getSubsystemPath(m.cgroups, "devices") |
There was a problem hiding this comment.
getSubsystemPath is super expensive, it parses the whole /proc/self/mountinfo.
I think you should be using m.Path("devices") here.
|
@lifubang PTAL at Kir's comments. Also, can we have an integration test? |
When we use cgroup with systemd driver, the cgroup path will be auto removed by systemd when all processes exited. So we should check cgroup path exists when we access the cgroup path, for example in `kill/ps`, or else we will got an error. Signed-off-by: lifubang <lifubang@acmcoder.com>
finished now, PTAL. |
tests/integration/ps.bats
Outdated
|
|
||
| @test "ps after the container stopped" { | ||
| # ps is not supported, it requires cgroups | ||
| requires root |
There was a problem hiding this comment.
should suppprt rootless cgroup
|
CI failing |
Signed-off-by: lifubang <lifubang@acmcoder.com>
| func (m *mockCgroupManager) Exists() bool { | ||
| paths := m.GetPaths() | ||
| if paths != nil { | ||
| _, err := os.Lstat(paths["devices"]) |
There was a problem hiding this comment.
While it is technically OK to use m.GetPaths() here, and it's a mock code so it doesn't really matter, I'd still like to have m.Path("devices") used here, because since commit 714c91e we're not supposed to use GetPaths() for anything other than state save/restore.
| } | ||
|
|
||
| func (m *manager) Exists() bool { | ||
| return cgroups.PathExists(m.paths["devices"]) |
There was a problem hiding this comment.
It probably doesn't matter in practice, but we're not supposed to access a map without holding a lock. This is why I have suggested using m.Path("devices") earlier -- it takes a lock before accessing m.paths.
Alternatively, you can leave this code as is but add taking a lock (same as Path()).
| } | ||
|
|
||
| func (m *legacyManager) Exists() bool { | ||
| return cgroups.PathExists(m.paths["devices"]) |
kolyshkin
left a comment
There was a problem hiding this comment.
couple of nits about using Path() vs GetPaths() and locking when accessing the m.paths map in v1 code.
|
@lifubang could you update the PR? |
|
@kolyshkin @mrunalp |
|
I am fine with that. |
|
@kolyshkin WDYT? |
fix #2337
Because when the container is in stopped state, the cgroup path has been deleted by systemd driver.
Signed-off-by: lifubang lifubang@acmcoder.com