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

Proposal: just signal all processes inside the container #2037

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcontainer/cgroups/cgroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Manager interface {
GetStats() (*Stats, error)

// Toggles the freezer cgroup according with specified state
Freeze(state configs.FreezerState) error
Freeze(state configs.FreezerState, justContainer bool) error

// Destroys the cgroup set
Destroy() error
Expand Down
58 changes: 38 additions & 20 deletions libcontainer/cgroups/fs/apply_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ type subsystem interface {
}

type Manager struct {
mu sync.Mutex
Cgroups *configs.Cgroup
Rootless bool // ignore permission-related errors
Paths map[string]string
mu sync.Mutex
Cgroups *configs.Cgroup
Rootless bool // ignore permission-related errors
Paths map[string]string
ContainerId string
}

// The absolute path to the root of the cgroup hierarchies.
Expand Down Expand Up @@ -96,10 +97,11 @@ func getCgroupRoot() (string, error) {
}

type cgroupData struct {
root string
innerPath string
config *configs.Cgroup
pid int
root string
innerPath string
config *configs.Cgroup
pid int
ContainerId string
}

// isIgnorableError returns whether err is a permission error (in the loose
Expand Down Expand Up @@ -138,7 +140,7 @@ func (m *Manager) Apply(pid int) (err error) {

var c = m.Cgroups

d, err := getCgroupData(m.Cgroups, pid)
d, err := getCgroupData(m.Cgroups, pid, m.ContainerId)
if err != nil {
return err
}
Expand Down Expand Up @@ -172,6 +174,9 @@ func (m *Manager) Apply(pid int) (err error) {
return err
}
m.Paths[sys.Name()] = p
if sys.Name() == "freezer" && m.ContainerId != "" {
m.Paths["freezer_parent"] = filepath.Join(p, "..")
}

if err := sys.Apply(d); err != nil {
// In the case of rootless (including euid=0 in userns), where an explicit cgroup path hasn't
Expand Down Expand Up @@ -261,9 +266,12 @@ func (m *Manager) Set(container *configs.Config) error {

// Freeze toggles the container's freezer cgroup depending on the state
// provided
func (m *Manager) Freeze(state configs.FreezerState) error {
func (m *Manager) Freeze(state configs.FreezerState, justContainer bool) error {
paths := m.GetPaths()
dir := paths["freezer"]
if !justContainer {
dir = filepath.Join(dir, "../")
}
prevState := m.Cgroups.Resources.Freezer
m.Cgroups.Resources.Freezer = state
freezer, err := subsystems.Get("freezer")
Expand All @@ -280,15 +288,19 @@ func (m *Manager) Freeze(state configs.FreezerState) error {

func (m *Manager) GetPids() ([]int, error) {
paths := m.GetPaths()
return cgroups.GetPids(paths["devices"])
return cgroups.GetPids(paths["freezer"])
}

func (m *Manager) GetAllPids() ([]int, error) {
paths := m.GetPaths()
return cgroups.GetAllPids(paths["devices"])
path := paths["freezer"]
if m.ContainerId != "" {
path = filepath.Join(path, "..")
}
return cgroups.GetAllPids(path)
}

func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
func getCgroupData(c *configs.Cgroup, pid int, ContainerId string) (*cgroupData, error) {
root, err := getCgroupRoot()
if err != nil {
return nil, err
Expand All @@ -309,10 +321,11 @@ func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
}

return &cgroupData{
root: root,
innerPath: innerPath,
config: c,
pid: pid,
root: root,
innerPath: innerPath,
config: c,
pid: pid,
ContainerId: ContainerId,
}, nil
}

Expand All @@ -323,10 +336,15 @@ func (raw *cgroupData) path(subsystem string) (string, error) {
return "", err
}

innerPath := raw.innerPath
if subsystem == "freezer" && raw.ContainerId != "" {
innerPath = filepath.Join(innerPath, raw.ContainerId)
}

// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
if filepath.IsAbs(raw.innerPath) {
if filepath.IsAbs(innerPath) {
// Sometimes subsystems can be mounted together as 'cpu,cpuacct'.
return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil
return filepath.Join(raw.root, filepath.Base(mnt), innerPath), nil
}

// Use GetOwnCgroupPath instead of GetInitCgroupPath, because the creating
Expand All @@ -337,7 +355,7 @@ func (raw *cgroupData) path(subsystem string) (string, error) {
return "", err
}

return filepath.Join(parentPath, raw.innerPath), nil
return filepath.Join(parentPath, innerPath), nil
}

func (raw *cgroupData) join(subsystem string) (string, error) {
Expand Down
39 changes: 28 additions & 11 deletions libcontainer/cgroups/systemd/apply_systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import (
)

type Manager struct {
mu sync.Mutex
Cgroups *configs.Cgroup
Paths map[string]string
mu sync.Mutex
Cgroups *configs.Cgroup
Paths map[string]string
ContainerId string
}

type subsystem interface {
Expand Down Expand Up @@ -293,7 +294,7 @@ func (m *Manager) Apply(pid int) error {
return err
}

if err := joinCgroups(c, pid); err != nil {
if err := joinCgroups(c, pid, m.ContainerId); err != nil {
return err
}

Expand All @@ -307,7 +308,12 @@ func (m *Manager) Apply(pid int) error {
}
return err
}
paths[s.Name()] = subsystemPath
if s.Name() == "freezer" && m.ContainerId != "" {
paths[s.Name()] = filepath.Join(subsystemPath, m.ContainerId)
paths["freezer_parent"] = subsystemPath
} else {
paths[s.Name()] = subsystemPath
}
}
m.Paths = paths
return nil
Expand All @@ -334,11 +340,14 @@ func (m *Manager) GetPaths() map[string]string {
return paths
}

func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
func join(c *configs.Cgroup, subsystem string, pid int, ContainerId string) (string, error) {
path, err := getSubsystemPath(c, subsystem)
if err != nil {
return "", err
}
if subsystem == "freezer" && ContainerId != "" {
path = filepath.Join(path, ContainerId)
}
if err := os.MkdirAll(path, 0755); err != nil {
return "", err
}
Expand All @@ -348,7 +357,7 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
return path, nil
}

func joinCgroups(c *configs.Cgroup, pid int) error {
func joinCgroups(c *configs.Cgroup, pid int, ContainerId string) error {
for _, sys := range subsystems {
name := sys.Name()
switch name {
Expand All @@ -364,7 +373,7 @@ func joinCgroups(c *configs.Cgroup, pid int) error {
return err
}
default:
_, err := join(c, name, pid)
_, err := join(c, name, pid, ContainerId)
if err != nil {
// Even if it's `not found` error, we'll return err
// because devices cgroup is hard requirement for
Expand Down Expand Up @@ -444,11 +453,16 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
}

func (m *Manager) Freeze(state configs.FreezerState) error {
func (m *Manager) Freeze(state configs.FreezerState, justContainer bool) error {
path, err := getSubsystemPath(m.Cgroups, "freezer")
if err != nil {
return err
}
if !justContainer {
if m.ContainerId != "" {
path = filepath.Join(path, "..")
}
}
prevState := m.Cgroups.Resources.Freezer
m.Cgroups.Resources.Freezer = state
freezer, err := subsystems.Get("freezer")
Expand All @@ -464,18 +478,21 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
}

func (m *Manager) GetPids() ([]int, error) {
path, err := getSubsystemPath(m.Cgroups, "devices")
path, err := getSubsystemPath(m.Cgroups, "freezer")
if err != nil {
return nil, err
}
return cgroups.GetPids(path)
}

func (m *Manager) GetAllPids() ([]int, error) {
path, err := getSubsystemPath(m.Cgroups, "devices")
path, err := getSubsystemPath(m.Cgroups, "freezer")
if err != nil {
return nil, err
}
if m.ContainerId != "" {
path = filepath.Join(path, "..")
}
return cgroups.GetAllPids(path)
}

Expand Down
2 changes: 2 additions & 0 deletions libcontainer/configs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ type Syscall struct {

// Config defines configuration options for executing a process inside a contained environment.
type Config struct {
ContainerId string `json:"container_id"`

// NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs
// This is a common option when the container is running in ramdisk
NoPivotRoot bool `json:"no_pivot_root"`
Expand Down
5 changes: 4 additions & 1 deletion libcontainer/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ func (s Status) String() string {
// BaseState represents the platform agnostic pieces relating to a
// running container's state
type BaseState struct {
// ID is the container ID.
// ID is the container Name.
ID string `json:"id"`

// ID is the container UUID.
UUID string `json:"uuid"`

// InitProcessPid is the init process id in the parent namespace.
InitProcessPid int `json:"init_process_pid"`

Expand Down
13 changes: 10 additions & 3 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const stdioFdCount = 3

type linuxContainer struct {
id string
uuid string
root string
config *configs.Config
cgroupManager cgroups.Manager
Expand Down Expand Up @@ -136,11 +137,16 @@ type Container interface {
NotifyMemoryPressure(level PressureLevel) (<-chan struct{}, error)
}

// ID returns the container's unique ID
// ID returns the container's unique Name
func (c *linuxContainer) ID() string {
return c.id
}

// ID returns the container's unique ID
func (c *linuxContainer) UUID() string {
return c.uuid
}

// Config returns the container's configuration
func (c *linuxContainer) Config() configs.Config {
return *c.config
Expand Down Expand Up @@ -598,7 +604,7 @@ func (c *linuxContainer) Pause() error {
}
switch status {
case Running, Created:
if err := c.cgroupManager.Freeze(configs.Frozen); err != nil {
if err := c.cgroupManager.Freeze(configs.Frozen, false); err != nil {
return err
}
return c.state.transition(&pausedState{
Expand All @@ -618,7 +624,7 @@ func (c *linuxContainer) Resume() error {
if status != Paused {
return newGenericError(fmt.Errorf("container not paused"), ContainerNotPaused)
}
if err := c.cgroupManager.Freeze(configs.Thawed); err != nil {
if err := c.cgroupManager.Freeze(configs.Thawed, false); err != nil {
return err
}
return c.state.transition(&runningState{
Expand Down Expand Up @@ -1827,6 +1833,7 @@ func (c *linuxContainer) currentState() (*State, error) {
state := &State{
BaseState: BaseState{
ID: c.ID(),
UUID: c.UUID(),
Config: *c.config,
InitProcessPid: pid,
InitProcessStartTime: startTime,
Expand Down
Loading