pam_cgfs(8)
π pam_cgfs(8) β the girlies' guide to cgroup management for unprivileged LXC containers
Okay so bestie, buckle up, because this is pam_cgfs(8) and it's genuinely one of the most underrated little modules out there. It's a PAM module, it's iconic, and it's about to make your unprivileged containers behave. π«Ά
β¨ NAME β¨
pam_cgfs β cgroup management for unprivileged LXC containers. That's the whole vibe. No cap.
π SYNOPSIS π
pam_cgfs.so {-c kernel_controller,name=named_controller}
That's it. That's the whole thing. One option, but she serves. π
πΈ DESCRIPTION πΈ
So, storytime. LXC has been out here supporting fully unprivileged containers since LXC 1.0, and lowkey these are the safest containers you can run. They're run by normal, non-root users, and the way that works is user namespaces β you map a whole range of UIDs and GIDs on the host to a different (and unprivileged!) range of UIDs and GIDs inside the container. Which means: uid 0 (root) inside the container is actually mapped to some unprivileged user id outside of it (something like 1000000), and it only has rights over resources that it actually owns itself. No sneaky host takeover, no drama. π₯
Now, cgroup management of fully unprivileged containers is all about restricting what those containers can use β like limiting the CPU usage of a container, or the number of processes it's allowed to spawn, or the memory it's allowed to consume. And it's clear (like, obvious) that fully unprivileged containers are run by normal users, so there's a real need to limit and manage resource consumption among all the containers. But unprivileged cgroup management is not easy with most init systems. So pam_cgfs.so came into existence. Main character energy, honestly. π
Here's the technical tea, bestie β write it down:
- The
pam_cgfs.somodule can handle pure cgroupfs v1 (/sys/fs/cgroup/$controller) and mixed mounts, where some controllers are mounted in a standard cgroupfs v1 hierarchy (/sys/fs/cgroup/$controller) and others in a cgroupfs v2 hierarchy (/sys/fs/cgroup/unified). - Writeable cgroups are either created for all controllers, or β if you specify them β for only the controllers listed as arguments on the command line.
- > Pure cgroup v2 mount is NOT covered by the
pam_cgfs.somodule. Sorry babe. π
The cgroup created is user/$user/n, and that's for the *n*th session under that cgroup kernel controller hierarchy. Numbered sessions, so organized. π
Systemd systems get special treatment, both for cgroupfs v1 and cgroupfs v2. For both of them, the module checks whether systemd already placed the user in a cgroup it created β user.slice/user-$uid/session-n.scope β by checking whether $uid == login uid. If so, the login user chowns the session-n.scope. Otherwise, a cgroup is created as outlined above (user/$user/n) and chowned to the login uid. And if the init system has already placed the login user inside a session-specific group, pam_cgfs.so is smart enough to detect it and just re-use that cgroup. She's perceptive like that. π§
In essence: pam_cgfs.so takes care of placing unprivileged (non-root) users into writable cgroups at login, and cleaning up those cgroup hierarchies on logout, so they're free to delegate resources to containers as needed β resources that have been provided to them. In and out, tidy, periodt. π
π OPTIONS π
-ccontroller-list β takes a string argument that sets the list of kernel controllers and named controllers, delimited by commas in-between,. Named controllers need to be specified in the formname=$namedcontroller. You can useallto enable all cgroup resource controller hierarchies. β οΈ But heads up: specifyingalland other controllers explicitly returnsPAM_SESSION_ERR. That's a hard no. π«
π¦ MODULE TYPES PROVIDED π¦
Only the session module type is provided β and needed. That's it. One type. She's focused. β¨
β RETURN VALUES β
PAM_SUCCESSβ writeable cgroups have been created for the user. Slay! πPAM_SESSION_ERRβ failed to create writable cgroups for the user. π
π FILES π
/etc/pam.d/common-session{,-noninteractive}β the default configuration is added at the end of these files.
π EXAMPLE π
session optional pam_cgfs.so -c freezer,memory,named=systemd
# default configuration
# user writable cgroups are created under freezer, memory and named cgroup systemd hierarchies.
# /sys/fs/cgroup/$controller/user/$user/n for freezer,memory.
# /sys/fs/cgroup/systemd/user.slice/user-$uid/session-n.scope for systemd.
session optional pam_cgfs.so -c all
# user writable cgroups are created under all cgroup controllers.
session optional pam_cgfs.so -c all,memory,freezer
# invalid argument and returns PAM_SESSION_ERR
See that last one? That's the all-plus-extras trap we warned you about. Do not do it. π
π SEE ALSO π
lxc-cgroup(1), cgroups(7), user_namespaces(7), namespaces(7), pam(8)
Okay that's the whole page, bestie β go forth and let your unprivileged containers have exactly the resources they deserve and not one crumb more. This was pam_cgfs(8), dated 2026-05-01, and honestly? Iconic of her. π
β¨ππ«Ά
π¦ where this page comes from
- alpine 3.24: lxc-doc 7.0.0-r0 Β· LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms