Merge pull request #476 from hqhq/hq_dont_fail_subsystem

don't fail when subsystem not mounted
This commit is contained in:
Victor Marmol 2015-05-11 09:29:59 -07:00
commit a37b2a4f15
6 changed files with 29 additions and 11 deletions

View File

@ -262,6 +262,11 @@ func (raw *data) join(subsystem string) (string, error) {
} }
func writeFile(dir, file, data string) error { func writeFile(dir, file, data string) error {
// Normally dir should not be empty, one case is that cgroup subsystem
// is not mounted, we will get empty dir, and we want it fail here.
if dir == "" {
return fmt.Errorf("no such directory for %s.", file)
}
return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
} }

View File

@ -17,7 +17,7 @@ func (s *CpuGroup) Apply(d *data) error {
// We always want to join the cpu group, to allow fair cpu scheduling // We always want to join the cpu group, to allow fair cpu scheduling
// on a container basis // on a container basis
dir, err := d.join("cpu") dir, err := d.join("cpu")
if err != nil { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }

View File

@ -16,7 +16,7 @@ type CpusetGroup struct {
func (s *CpusetGroup) Apply(d *data) error { func (s *CpusetGroup) Apply(d *data) error {
dir, err := d.path("cpuset") dir, err := d.path("cpuset")
if err != nil { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
@ -48,6 +48,11 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
} }
func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error {
// This might happen if we have no cpuset cgroup mounted.
// Just do nothing and don't fail.
if dir == "" {
return nil
}
if err := s.ensureParent(dir); err != nil { if err := s.ensureParent(dir); err != nil {
return err return err
} }

View File

@ -11,6 +11,8 @@ type DevicesGroup struct {
func (s *DevicesGroup) Apply(d *data) error { func (s *DevicesGroup) Apply(d *data) error {
dir, err := d.join("devices") dir, err := d.join("devices")
if err != nil { if err != nil {
// We will return error even it's `not found` error, devices
// cgroup is hard requirement for container's security.
return err return err
} }

View File

@ -16,8 +16,7 @@ type MemoryGroup struct {
func (s *MemoryGroup) Apply(d *data) error { func (s *MemoryGroup) Apply(d *data) error {
dir, err := d.join("memory") dir, err := d.join("memory")
// only return an error for memory if it was specified if err != nil && !cgroups.IsNotFound(err) {
if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) {
return err return err
} }
defer func() { defer func() {

View File

@ -256,6 +256,11 @@ func (m *Manager) GetPaths() map[string]string {
} }
func writeFile(dir, file, data string) error { func writeFile(dir, file, data string) error {
// Normally dir should not be empty, one case is that cgroup subsystem
// is not mounted, we will get empty dir, and we want it fail here.
if dir == "" {
return fmt.Errorf("no such directory for %s.", file)
}
return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
} }
@ -276,16 +281,16 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
func joinCpu(c *configs.Cgroup, pid int) error { func joinCpu(c *configs.Cgroup, pid int) error {
path, err := getSubsystemPath(c, "cpu") path, err := getSubsystemPath(c, "cpu")
if err != nil { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
if c.CpuQuota != 0 { if c.CpuQuota != 0 {
if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_quota_us"), []byte(strconv.FormatInt(c.CpuQuota, 10)), 0700); err != nil { if err = writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(c.CpuQuota, 10)); err != nil {
return err return err
} }
} }
if c.CpuPeriod != 0 { if c.CpuPeriod != 0 {
if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_period_us"), []byte(strconv.FormatInt(c.CpuPeriod, 10)), 0700); err != nil { if err = writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(c.CpuPeriod, 10)); err != nil {
return err return err
} }
} }
@ -293,7 +298,7 @@ func joinCpu(c *configs.Cgroup, pid int) error {
} }
func joinFreezer(c *configs.Cgroup, pid int) error { func joinFreezer(c *configs.Cgroup, pid int) error {
if _, err := join(c, "freezer", pid); err != nil { if _, err := join(c, "freezer", pid); err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
@ -393,6 +398,8 @@ func getUnitName(c *configs.Cgroup) string {
// This happens at least for v208 when any sibling unit is started. // This happens at least for v208 when any sibling unit is started.
func joinDevices(c *configs.Cgroup, pid int) error { func joinDevices(c *configs.Cgroup, pid int) error {
path, err := join(c, "devices", pid) path, err := join(c, "devices", pid)
// Even if it's `not found` error, we'll return err because devices cgroup
// is hard requirement for container security.
if err != nil { if err != nil {
return err return err
} }
@ -410,11 +417,11 @@ func joinMemory(c *configs.Cgroup, pid int) error {
} }
path, err := getSubsystemPath(c, "memory") path, err := getSubsystemPath(c, "memory")
if err != nil { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
return ioutil.WriteFile(filepath.Join(path, "memory.memsw.limit_in_bytes"), []byte(strconv.FormatInt(memorySwap, 10)), 0700) return writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10))
} }
// systemd does not atm set up the cpuset controller, so we must manually // systemd does not atm set up the cpuset controller, so we must manually
@ -422,7 +429,7 @@ func joinMemory(c *configs.Cgroup, pid int) error {
// level must have a full setup as the default for a new directory is "no cpus" // level must have a full setup as the default for a new directory is "no cpus"
func joinCpuset(c *configs.Cgroup, pid int) error { func joinCpuset(c *configs.Cgroup, pid int) error {
path, err := getSubsystemPath(c, "cpuset") path, err := getSubsystemPath(c, "cpuset")
if err != nil { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }