./Crashloop.sh

Bitwise OR and Samir can set requests and limits now via cgroups!

/logo.pngYoucef GuichiJuly 27, 2025

My Own Docker Samir (WIP)

Bitwise OR and Samir can set requests and limits now via cgroups!

Bitwise OR Refresher

Remember learning bitwise OR at university but never quite understanding its practical use? Bitwise OR works with integer values by comparing their bits position by position.

Rule: If either bit is 1, the result is 1 at that position; otherwise, the result is 0.

Example: 001 010 =011 So, bitwise OR between 001 and 010 equals 011.

Kernel Feature Flags with Bitwise OR

Suppose we have the following features, each represented in 8 bits:

  • feature1 = 00000001 = 1
  • feature2 = 00000010 = 2
  • feature3 = 00000100 = 4

If you want to enable feature1 and feature3, you don't pass them as a list. Instead, the kernel uses bitwise OR:

 00000001
 00000100
=00000101 = 5

The kernel enables features based on which bits are set to 1. So, 00000101 enables the first and third features.

In Go, bitwise OR is represented by |. For example:

CreateNamespaces(unix.CLONE_NEWUTS | unix.CLONE_NEWPID | unix.CLONE_NEWNS)

Resource Requests and Limits with Cgroups

I have implemented resource requests and limits for both CPU and memory.

To create a new cgroup, place it in the cgroup filesystem:
/sys/fs/cgroup/your-group
This will automatically populate new files.

Memory Resources

  • Requests: Write bytes to /sys/fs/cgroup/your-group/memory.low
  • Limits: Write bytes to /sys/fs/cgroup/your-group/memory.max

CPU Resources

  • Requests: Write to /sys/fs/cgroup/your-group/cpu.weight
  • Limits: Write to /sys/fs/cgroup/your-group/cpu.max

cpu.max Format

cpu.max expects the format: quota period.
For example, if you specify CPU as 500m (half a core), the kernel understands it in time, not cores.

Formula:
quota = (millicores / 1000) * period

The default period is 100000 microseconds.

For 500m:

  • quota = (500 / 1000) * 100000 = 50000 microseconds

So, write to /sys/fs/cgroup/your-group/cpu.max: 50000 100000 This means every 100000 microseconds, your process can use the CPU for 50000 microseconds.

You can find the implementation code in my infra-for-fun-with-golang/container repository on GitHub.