diff --git a/cgroups/fs/net_prio.go b/cgroups/fs/net_prio.go new file mode 100644 index 00000000..62882f9f --- /dev/null +++ b/cgroups/fs/net_prio.go @@ -0,0 +1,40 @@ +package fs + +import ( + "github.com/docker/libcontainer/cgroups" + "github.com/docker/libcontainer/configs" +) + +type NetPrioGroup struct { +} + +func (s *NetPrioGroup) Apply(d *data) error { + dir, err := d.join("net_prio") + if err != nil && !cgroups.IsNotFound(err) { + return err + } + + if err := s.Set(dir, d.c); err != nil { + return err + } + + return nil +} + +func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error { + for _, prioMap := range cgroup.NetPrioIfpriomap { + if err := writeFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil { + return err + } + } + + return nil +} + +func (s *NetPrioGroup) Remove(d *data) error { + return removePath(d.path("net_prio")) +} + +func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error { + return nil +} diff --git a/cgroups/fs/net_prio_test.go b/cgroups/fs/net_prio_test.go new file mode 100644 index 00000000..878775a5 --- /dev/null +++ b/cgroups/fs/net_prio_test.go @@ -0,0 +1,36 @@ +package fs + +import ( + "strings" + "testing" + + "github.com/docker/libcontainer/configs" +) + +var ( + prioMap = []*configs.IfPrioMap{ + { + Interface: "test", + Priority: 5, + }, + } +) + +func TestNetPrioSetIfPrio(t *testing.T) { + helper := NewCgroupTestUtil("net_prio", t) + defer helper.cleanup() + + helper.CgroupData.c.NetPrioIfpriomap = prioMap + netPrio := &NetPrioGroup{} + if err := netPrio.Set(helper.CgroupPath, helper.CgroupData.c); err != nil { + t.Fatal(err) + } + + value, err := getCgroupParamString(helper.CgroupPath, "net_prio.ifpriomap") + if err != nil { + t.Fatalf("Failed to parse net_prio.ifpriomap - %s", err) + } + if !strings.Contains(value, "test 5") { + t.Fatal("Got the wrong value, set net_prio.ifpriomap failed.") + } +} diff --git a/cgroups/systemd/apply_systemd.go b/cgroups/systemd/apply_systemd.go index 8737e69f..27c11e18 100644 --- a/cgroups/systemd/apply_systemd.go +++ b/cgroups/systemd/apply_systemd.go @@ -41,6 +41,7 @@ var subsystems = map[string]subsystem{ "hugetlb": &fs.HugetlbGroup{}, "perf_event": &fs.PerfEventGroup{}, "freezer": &fs.FreezerGroup{}, + "net_prio": &fs.NetPrioGroup{}, } const ( @@ -207,12 +208,16 @@ func (m *Manager) Apply(pid int) error { } - // we need to manually join the freezer and cpuset cgroup in systemd + // we need to manually join the freezer, 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 } + if err := joinNetPrio(c, pid); err != nil { + return err + } + if err := joinCpuset(c, pid); err != nil { return err } @@ -316,6 +321,16 @@ func joinFreezer(c *configs.Cgroup, pid int) error { return nil } +func joinNetPrio(c *configs.Cgroup, pid int) error { + path, err := join(c, "net_prio", pid) + if err != nil && !cgroups.IsNotFound(err) { + return err + } + + netPrio := subsystems["net_prio"] + return netPrio.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 5c546a4b..8701de3f 100644 --- a/configs/cgroup.go +++ b/configs/cgroup.go @@ -77,4 +77,7 @@ type Cgroup struct { // Whether to disable OOM Killer OomKillDisable bool `json:"oom_kill_disable"` + + // Set priority of network traffic for container + NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"` } diff --git a/configs/interface_priority_map.go b/configs/interface_priority_map.go new file mode 100644 index 00000000..9a0395ea --- /dev/null +++ b/configs/interface_priority_map.go @@ -0,0 +1,14 @@ +package configs + +import ( + "fmt" +) + +type IfPrioMap struct { + Interface string `json:"interface"` + Priority int64 `json:"priority"` +} + +func (i *IfPrioMap) CgroupString() string { + return fmt.Sprintf("%s %d", i.Interface, i.Priority) +}