Having seen that GNOME now launches apps under systemd scopes I’ve been looking at a way to get systemd to apply some cgroup resource and memory limits to my browser.
I want to apply a
CPUShare to all
app-gnome-firefox-*.scope instances per
But GNOME isn’t launching firefox with the instantiated unit format
app-gnome-firefox-@.scope so I don’t know how to make a systemd unit file that will apply automatically to all
I can manually apply the resource limits to an instance with
systemctl set-property --user app-gnome-firefox-92450.scope (for example) once the unit starts, but that’s a pain.
Is there any way to inject properties for transient scopes with pattern matching for names?
This isn’t really
gnome-shell specific; it applies just as well to a user terminal session that invokes a command with
systemd-run --user --scope.
Firefox is definitely launched under a systemd scope, and it gets its own cgroup:
$ systemctl --user status app-gnome-firefox-92450.scope
● app-gnome-firefox-92450.scope - Application launched by gnome-shell
Loaded: loaded (/run/user/1000/systemd/transient/app-gnome-firefox-92450.scope; transient)
Active: active (running) since Wed 2021-03-31 09:44:30 AWST; 32min ago
Tasks: 567 (limit: 38071)
CPU: 5min 39.138s
$ systemd-cgls --user-unit app-gnome-firefox-92450.scope
Unit app-gnome-firefox-92450.scope (/firstname.lastname@example.org/app-gnome-firefox-92450.scope):
$ ls -d /email@example.com/app-gnome-firefox-*
I can apply a
MemoryMax (cgroup v2 constraint
memory.max) to an already-running instance with
systemctl set-property and it takes effect:
$ systemctl set-property --user app-gnome-firefox-98883.scope MemoryMax=5G
$ systemctl show --user app-gnome-firefox-98883.scope |grep ^MemoryMax
$ cat /firstname.lastname@example.org/app-gnome-firefox-*/memory.max
It definitely takes effect – setting a low
100M causes the firefox scope to OOM, as seen in
journalctl --user -u app-gnome-firefox-98883.scope.
The trouble is that I can’t work out how to apply
systemd.resource-control rules automatically for new instances of the app automatically.
I’ve tried creating a
MemoryMax = 5G
but it appears to have no effect.
systemd-analyze verify chokes on it rather unhelpfully:
$ systemd-analyze verify --user .config/systemd/user/app-gnome-firefox-@.scope
Failed to load unit file /email@example.com: Invalid argument
If I use
systemctl set-property --user app-gnome-firefox-92450.scope on a running instance and
systemctl --user show app-gnome-firefox-92450.scope I see the drop-in files at:
Names containing the pid, so that can’t be matched easily:
and I’m kind of stumped. Advice would be greatly appreciated, hopefully not “gnome-shell is doing it wrong, patch it” advice. Some draft systemd docs suggest it’s using one of the accepted patterns.
The only workaround I see so far is to launch the firefox instance with
systemd-run --user --scope -u firefox.scope -p 'MemoryMax=5G' -p 'CPUQuota=80%' /usr/lib64/firefox/firefox
and let that be the control process. But it looks like this isolates the firefox control channel in some manner that prevents
firefox processes launched by other apps or the desktop session from then talking to the cgroup-scoped firefox, resulting in
Firefox is already running, but is not responding. To use Firefox, you must first close the existing Firefox process, restart your device, or use a different profile.
Edit: firefox remoting when launched manually via
systemd-run is fixed by setting
MOZ_DBUS_REMOTE in the environment both for my user session and as a
-E MOZ_DBUS_REMOTE=1 option to
systemd-run. It’s probably because I’m using Wayland.
Still a clumsy workaround – it should surely be possible to apply resource control rules to slices via