fix data inconsistent when runc update in systemd driven cgroup v1
Signed-off-by: lifubang <lifubang@acmcoder.com>
This commit is contained in:
parent
7682a2b2a5
commit
1d4ccc8e0c
|
@ -63,6 +63,59 @@ var legacySubsystems = subsystemSet{
|
||||||
&fs.NameGroup{GroupName: "name=systemd"},
|
&fs.NameGroup{GroupName: "name=systemd"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func genV1ResourcesProperties(c *configs.Cgroup) ([]systemdDbus.Property, error) {
|
||||||
|
var properties []systemdDbus.Property
|
||||||
|
if c.Resources.Memory != 0 {
|
||||||
|
properties = append(properties,
|
||||||
|
newProp("MemoryLimit", uint64(c.Resources.Memory)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Resources.CpuShares != 0 {
|
||||||
|
properties = append(properties,
|
||||||
|
newProp("CPUShares", c.Resources.CpuShares))
|
||||||
|
}
|
||||||
|
|
||||||
|
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
|
||||||
|
if c.Resources.CpuQuota != 0 && c.Resources.CpuPeriod != 0 {
|
||||||
|
// corresponds to USEC_INFINITY in systemd
|
||||||
|
// if USEC_INFINITY is provided, CPUQuota is left unbound by systemd
|
||||||
|
// always setting a property value ensures we can apply a quota and remove it later
|
||||||
|
cpuQuotaPerSecUSec := uint64(math.MaxUint64)
|
||||||
|
if c.Resources.CpuQuota > 0 {
|
||||||
|
// systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
|
||||||
|
// (integer percentage of CPU) internally. This means that if a fractional percent of
|
||||||
|
// CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
|
||||||
|
// 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
|
||||||
|
cpuQuotaPerSecUSec = uint64(c.Resources.CpuQuota*1000000) / c.Resources.CpuPeriod
|
||||||
|
if cpuQuotaPerSecUSec%10000 != 0 {
|
||||||
|
cpuQuotaPerSecUSec = ((cpuQuotaPerSecUSec / 10000) + 1) * 10000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
properties = append(properties,
|
||||||
|
newProp("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Resources.BlkioWeight != 0 {
|
||||||
|
properties = append(properties,
|
||||||
|
newProp("BlockIOWeight", uint64(c.Resources.BlkioWeight)))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Resources.PidsLimit > 0 {
|
||||||
|
properties = append(properties,
|
||||||
|
newProp("TasksAccounting", true),
|
||||||
|
newProp("TasksMax", uint64(c.Resources.PidsLimit)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to set kernel memory here, as we can't change it once
|
||||||
|
// processes have been attached to the cgroup.
|
||||||
|
if c.Resources.KernelMemory != 0 {
|
||||||
|
if err := setKernelMemory(c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (m *LegacyManager) Apply(pid int) error {
|
func (m *LegacyManager) Apply(pid int) error {
|
||||||
var (
|
var (
|
||||||
c = m.Cgroups
|
c = m.Cgroups
|
||||||
|
@ -124,55 +177,11 @@ func (m *LegacyManager) Apply(pid int) error {
|
||||||
properties = append(properties,
|
properties = append(properties,
|
||||||
newProp("DefaultDependencies", false))
|
newProp("DefaultDependencies", false))
|
||||||
|
|
||||||
if c.Resources.Memory != 0 {
|
resourcesProperties, err := genV1ResourcesProperties(c)
|
||||||
properties = append(properties,
|
if err != nil {
|
||||||
newProp("MemoryLimit", uint64(c.Resources.Memory)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Resources.CpuShares != 0 {
|
|
||||||
properties = append(properties,
|
|
||||||
newProp("CPUShares", c.Resources.CpuShares))
|
|
||||||
}
|
|
||||||
|
|
||||||
// cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd.
|
|
||||||
if c.Resources.CpuQuota != 0 && c.Resources.CpuPeriod != 0 {
|
|
||||||
// corresponds to USEC_INFINITY in systemd
|
|
||||||
// if USEC_INFINITY is provided, CPUQuota is left unbound by systemd
|
|
||||||
// always setting a property value ensures we can apply a quota and remove it later
|
|
||||||
cpuQuotaPerSecUSec := uint64(math.MaxUint64)
|
|
||||||
if c.Resources.CpuQuota > 0 {
|
|
||||||
// systemd converts CPUQuotaPerSecUSec (microseconds per CPU second) to CPUQuota
|
|
||||||
// (integer percentage of CPU) internally. This means that if a fractional percent of
|
|
||||||
// CPU is indicated by Resources.CpuQuota, we need to round up to the nearest
|
|
||||||
// 10ms (1% of a second) such that child cgroups can set the cpu.cfs_quota_us they expect.
|
|
||||||
cpuQuotaPerSecUSec = uint64(c.Resources.CpuQuota*1000000) / c.Resources.CpuPeriod
|
|
||||||
if cpuQuotaPerSecUSec%10000 != 0 {
|
|
||||||
cpuQuotaPerSecUSec = ((cpuQuotaPerSecUSec / 10000) + 1) * 10000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
properties = append(properties,
|
|
||||||
newProp("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec))
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Resources.BlkioWeight != 0 {
|
|
||||||
properties = append(properties,
|
|
||||||
newProp("BlockIOWeight", uint64(c.Resources.BlkioWeight)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Resources.PidsLimit > 0 {
|
|
||||||
properties = append(properties,
|
|
||||||
newProp("TasksAccounting", true),
|
|
||||||
newProp("TasksMax", uint64(c.Resources.PidsLimit)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to set kernel memory here, as we can't change it once
|
|
||||||
// processes have been attached to the cgroup.
|
|
||||||
if c.Resources.KernelMemory != 0 {
|
|
||||||
if err := setKernelMemory(c); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
properties = append(properties, resourcesProperties...)
|
||||||
|
|
||||||
properties = append(properties, c.SystemdProps...)
|
properties = append(properties, c.SystemdProps...)
|
||||||
|
|
||||||
dbusConnection, err := getDbusConnection()
|
dbusConnection, err := getDbusConnection()
|
||||||
|
@ -376,6 +385,18 @@ func (m *LegacyManager) Set(container *configs.Config) error {
|
||||||
if m.Cgroups.Paths != nil {
|
if m.Cgroups.Paths != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
properties, err := genV1ResourcesProperties(container.Cgroups)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dbusConnection, err := getDbusConnection()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := dbusConnection.SetUnitProperties(getUnitName(container.Cgroups), true, properties...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, sys := range legacySubsystems {
|
for _, sys := range legacySubsystems {
|
||||||
// Get the subsystem path, but don't error out for not found cgroups.
|
// Get the subsystem path, but don't error out for not found cgroups.
|
||||||
path, err := getSubsystemPath(container.Cgroups, sys.Name())
|
path, err := getSubsystemPath(container.Cgroups, sys.Name())
|
||||||
|
|
Loading…
Reference in New Issue