feat: add io limits controller for systemd youki-dev/youki #3235by gokulmaxi

When implementing a container runtime, you often need to interact with D-Bus. The most common example is cgroup operations. I tend to forget the details, so I'm writing this note for future reference.

$ man 5 org.freedesktop.systemd1
method
SetUnitProperties(in s name, in b runtime, in a(sv) properties)

You can modify unit properties at runtime using properties. cgroup resource limits (e.g., MemoryMax) can also be set through this interface.

Trying it out with busctl

  1. Create a test Unit

    /etc/systemd/system/memhog.service
    [Unit]
    Description=memhog demo service (for SetUnitProperties example)
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3 -c "import time; buf=bytearray(150*1024*1024); print('allocated', len(buf)); time.sleep(3600)"
    Restart=no
    
    [Install]
    WantedBy=multi-user.target

    Reload and start the service.

    $ sudo systemctl daemon-reload
    $ sudo systemctl start memhog.service
    $ sudo systemctl status memhog.service
    
  2. Get the Unit object path on D-Bus Retrieve the object path using GetUnit.

    $ busctl --system call \
    org.freedesktop.systemd1 /org/freedesktop/systemd1 \
    org.freedesktop.systemd1.Manager GetUnit \
    s "memhog.service"
    o "/org/freedesktop/systemd1/unit/memhog_2eservice"
    
  3. Check the type of MemoryMax using introspect

    Since SetUnitProperties takes a variant value, we need to know the type. Let's check it with introspect.

    $ busctl --system introspect \
    org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/memhog_2eservice \
    | grep MemoryMax
    .MemoryMax  property  t  18446744073709551615  -
    

    t is uint64

  4. Limit memory usage with D-Bus SetUnitProperties Finally, call SetUnitProperties

    $ sudo busctl --system call \
    org.freedesktop.systemd1 /org/freedesktop/systemd1 \
    org.freedesktop.systemd1.Manager SetUnitProperties \
    "sba(sv)" "memhog.service" true \
    1 \
    "MemoryMax" t 104857600
    

    Arguments:

    • true means runtime (until restart)
    • The leading 1 in a(sv) is the count of (sv) pairs
    • 104857600 = 100MiB
  5. Verify the setting (D-Bus / systemctl) Verify via D-Bus

    $ busctl --system get-property \
    org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/memhog_2eservice \
    org.freedesktop.systemd1.Service MemoryMax
    t 104857600
    

    Verify via systemctl

    $ systemctl show memhog.service -p MemoryMax
    MemoryMax=104857600
    
  6. Cleanup

    $ sudo systemctl stop memhog.service
    $ sudo rm /etc/systemd/system/memhog.service
    $ sudo systemctl daemon-reload