From b88944f9e0f6eab202415441b20be326d4755e05 Mon Sep 17 00:00:00 2001 From: Ma Shimiao Date: Thu, 14 May 2015 09:09:14 +0800 Subject: [PATCH] cgroups: add support for net_cls Signed-off-by: Ma Shimiao --- cgroups/fs/apply_raw.go | 2 ++ cgroups/fs/net_cls.go | 40 ++++++++++++++++++++++++++++++++ cgroups/fs/net_cls_test.go | 36 ++++++++++++++++++++++++++++ cgroups/systemd/apply_systemd.go | 18 ++++++++++++-- configs/cgroup.go | 3 +++ 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 cgroups/fs/net_cls.go create mode 100644 cgroups/fs/net_cls_test.go diff --git a/cgroups/fs/apply_raw.go b/cgroups/fs/apply_raw.go index 99c78457..068ac783 100644 --- a/cgroups/fs/apply_raw.go +++ b/cgroups/fs/apply_raw.go @@ -22,6 +22,8 @@ var ( "cpuacct": &CpuacctGroup{}, "blkio": &BlkioGroup{}, "hugetlb": &HugetlbGroup{}, + "net_cls": &NetClsGroup{}, + "net_prio": &NetPrioGroup{}, "perf_event": &PerfEventGroup{}, "freezer": &FreezerGroup{}, } diff --git a/cgroups/fs/net_cls.go b/cgroups/fs/net_cls.go new file mode 100644 index 00000000..50ca647a --- /dev/null +++ b/cgroups/fs/net_cls.go @@ -0,0 +1,40 @@ +package fs + +import ( + "github.com/docker/libcontainer/cgroups" + "github.com/docker/libcontainer/configs" +) + +type NetClsGroup struct { +} + +func (s *NetClsGroup) Apply(d *data) error { + dir, err := d.join("net_cls") + if err != nil && !cgroups.IsNotFound(err) { + return err + } + + if err := s.Set(dir, d.c); err != nil { + return err + } + + return nil +} + +func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error { + if cgroup.NetClsClassid != "" { + if err := writeFile(path, "net_cls.classid", cgroup.NetClsClassid); err != nil { + return err + } + } + + return nil +} + +func (s *NetClsGroup) Remove(d *data) error { + return removePath(d.path("net_cls")) +} + +func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error { + return nil +} diff --git a/cgroups/fs/net_cls_test.go b/cgroups/fs/net_cls_test.go new file mode 100644 index 00000000..c24ee037 --- /dev/null +++ b/cgroups/fs/net_cls_test.go @@ -0,0 +1,36 @@ +package fs + +import ( + "testing" +) + +const ( + classidBefore = "0x100002" + classidAfter = "0x100001" +) + +func TestNetClsSetClassid(t *testing.T) { + helper := NewCgroupTestUtil("net_cls", t) + defer helper.cleanup() + + helper.writeFileContents(map[string]string{ + "net_cls.classid": classidBefore, + }) + + helper.CgroupData.c.NetClsClassid = classidAfter + netcls := &NetClsGroup{} + if err := netcls.Set(helper.CgroupPath, helper.CgroupData.c); err != nil { + t.Fatal(err) + } + + // As we are in mock environment, we can't get correct value of classid from + // net_cls.classid. + // So. we just judge if we successfully write classid into file + value, err := getCgroupParamString(helper.CgroupPath, "net_cls.classid") + if err != nil { + t.Fatalf("Failed to parse net_cls.classid - %s", err) + } + if value != classidAfter { + t.Fatal("Got the wrong value, set net_cls.classid failed.") + } +} diff --git a/cgroups/systemd/apply_systemd.go b/cgroups/systemd/apply_systemd.go index 27c11e18..77f75176 100644 --- a/cgroups/systemd/apply_systemd.go +++ b/cgroups/systemd/apply_systemd.go @@ -42,6 +42,7 @@ var subsystems = map[string]subsystem{ "perf_event": &fs.PerfEventGroup{}, "freezer": &fs.FreezerGroup{}, "net_prio": &fs.NetPrioGroup{}, + "net_cls": &fs.NetClsGroup{}, } const ( @@ -208,7 +209,7 @@ func (m *Manager) Apply(pid int) error { } - // we need to manually join the freezer, net_prio and cpuset cgroup in systemd + // we need to manually join the freezer, net_cls, net_prio and cpuset cgroup in systemd // because it does not currently support it via the dbus api. if err := joinFreezer(c, pid); err != nil { return err @@ -217,6 +218,9 @@ func (m *Manager) Apply(pid int) error { if err := joinNetPrio(c, pid); err != nil { return err } + if err := joinNetCls(c, pid); err != nil { + return err + } if err := joinCpuset(c, pid); err != nil { return err @@ -326,11 +330,21 @@ func joinNetPrio(c *configs.Cgroup, pid int) error { if err != nil && !cgroups.IsNotFound(err) { return err } - netPrio := subsystems["net_prio"] + return netPrio.Set(path, c) } +func joinNetCls(c *configs.Cgroup, pid int) error { + path, err := join(c, "net_cls", pid) + if err != nil && !cgroups.IsNotFound(err) { + return err + } + netcls := subsystems["net_cls"] + + return netcls.Set(path, c) +} + func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) if err != nil { diff --git a/configs/cgroup.go b/configs/cgroup.go index 8701de3f..dc35aac5 100644 --- a/configs/cgroup.go +++ b/configs/cgroup.go @@ -80,4 +80,7 @@ type Cgroup struct { // Set priority of network traffic for container NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"` + + // Set class identifier for container's network packets + NetClsClassid string `json:"net_cls_classid"` }