ORG.FREEDESKTOP.SYSTEMD1(5)

โœจ NAME โœจ

org.freedesktop.systemd1 โ€” the D-Bus interface of systemd ๐Ÿ’…

Bestie, this is the manual page for org.freedesktop.systemd1(5), and it's giving main character energy for systemd's D-Bus APIs. ๐Ÿซถ


๐ŸŒธ INTRODUCTION ๐ŸŒธ

okay so first things first: systemd(1) and its auxiliary daemons expose a number of APIs over D-Bus. This page only describes the various APIs exposed by the system and service manager itself. It does not cover the auxiliary daemons. periodt. ๐Ÿ’…

The service manager exposes a number of objects on the bus: one Manager object as a central entry point for clients along with individual objects for each unit and for each queued job. The unit objects implement a generic Unit interface as well as a type-specific interface. For example, service units implement both org.freedesktop.systemd1.Unit and org.freedesktop.systemd1.Service. The manager object can list unit and job objects or directly convert a unit name or job identifier to a bus path of the corresponding D-Bus object. no cap, it's literally that flexible. โœจ

Properties exposing time values are usually encoded in microseconds (ฮผs) on the bus, even if their corresponding settings in the unit files are in seconds. so like, watch out for that little unit conversion moment bestie, it's lowkey important. ๐Ÿ˜ญ

PID 1 uses polkit[1] to allow access to privileged operations for unprivileged processes. Some operations (such as shutdown/reboot/suspend) are also available through the D-Bus API of logind, see org.freedesktop.login1(5). iconic behavior, honestly. ๐Ÿ‘‘


๐Ÿ‘‘ THE MANAGER OBJECT ๐Ÿ‘‘

The main entry point object is available on the fixed /org/freedesktop/systemd1 object path:

okay so here's the whole entire D-Bus interface block for the Manager object โ€” every method, every signal, exactly how it lands when you point a bus at it. no filtering, no skipping, we're reading the whole menu together bestie ๐Ÿซถ

           node /org/freedesktop/systemd1 {
             interface org.freedesktop.systemd1.Manager {
               methods:
                 GetUnit(in  s name,
                         out o unit);
                 GetUnitByPID(in  u pid,
                              out o unit);
                 GetUnitByInvocationID(in  ay invocation_id,
                                       out o unit);
                 GetUnitByControlGroup(in  s cgroup,
                                       out o unit);
                 GetUnitByPIDFD(in  h pidfd,
                                out o unit,
                                out s unit_id,
                                out ay invocation_id);
                 LoadUnit(in  s name,
                          out o unit);
                 StartUnit(in  s name,
                           in  s mode,
                           out o job);
                 StartUnitWithFlags(in  s name,
                                    in  s mode,
                                    in  t flags,
                                    out o job);
                 StartUnitReplace(in  s old_unit,
                                  in  s new_unit,
                                  in  s mode,
                                  out o job);
                 StopUnit(in  s name,
                          in  s mode,
                          out o job);
                 ReloadUnit(in  s name,
                            in  s mode,
                            out o job);
                 RestartUnit(in  s name,
                             in  s mode,
                             out o job);
                 TryRestartUnit(in  s name,
                                in  s mode,
                                out o job);
                 ReloadOrRestartUnit(in  s name,
                                     in  s mode,
                                     out o job);
                 ReloadOrTryRestartUnit(in  s name,
                                        in  s mode,
                                        out o job);
                 EnqueueUnitJob(in  s name,
                                in  s job_type,
                                in  s job_mode,
                                out u job_id,
                                out o job_path,
                                out s unit_id,
                                out o unit_path,
                                out s job_type,
                                out a(uosos) affected_jobs);
                 EnqueueUnitJobMany(in  as units,
                                    in  s job_type,
                                    in  s job_mode,
                                    in  t flags,
                                    out a(uosos) jobs);
                 KillUnit(in  s name,
                          in  s whom,
                          in  i signal);
                 KillUnitSubgroup(in  s name,
                                  in  s whom,
                                  in  s subgroup,
                                  in  i signal);
                 QueueSignalUnit(in  s name,
                                 in  s whom,
                                 in  i signal,
                                 in  i value);
                 CleanUnit(in  s name,
                           in  as mask);
                 FreezeUnit(in  s name);
                 ThawUnit(in  s name);
                 ResetFailedUnit(in  s name);
                 SetUnitProperties(in  s name,
                                   in  b runtime,
                                   in  a(sv) properties);
                 BindMountUnit(in  s name,
                               in  s source,
                               in  s destination,
                               in  b read_only,
                               in  b mkdir);
                 MountImageUnit(in  s name,
                                in  s source,
                                in  s destination,
                                in  b read_only,
                                in  b mkdir,
                                in  a(ss) options);
                 RefUnit(in  s name);
                 UnrefUnit(in  s name);
                 StartTransientUnit(in  s name,
                                    in  s mode,
                                    in  a(sv) properties,
                                    in  a(sa(sv)) aux,
                                    out o job);
                 GetUnitProcesses(in  s name,
                                  out a(sus) processes);
                 AttachProcessesToUnit(in  s unit_name,
                                       in  s subcgroup,
                                       in  au pids);
                 RemoveSubgroupFromUnit(in  s unit_name,
                                        in  s subcgroup,
                                        in  t flags);
                 AbandonScope(in  s name);
                 GetJob(in  u id,
                        out o job);
                 GetJobAfter(in  u id,
                             out a(usssoo) jobs);
                 GetJobBefore(in  u id,
                              out a(usssoo) jobs);
                 CancelJob(in  u id);
                 ClearJobs();
                 ResetFailed();
                 SetShowStatus(in  s mode);
                 ListUnits(out a(ssssssouso) units);
                 ListUnitsFiltered(in  as states,
                                   out a(ssssssouso) units);
                 ListUnitsByPatterns(in  as states,
                                     in  as patterns,
                                     out a(ssssssouso) units);
                 ListUnitsByNames(in  as names,
                                  out a(ssssssouso) units);
                 ListJobs(out a(usssoo) jobs);
                 Subscribe();
                 Unsubscribe();
                 Dump(out s output);
                 DumpUnitsMatchingPatterns(in  as patterns,
                                           out s output);
                 DumpByFileDescriptor(out h fd);
                 DumpUnitsMatchingPatternsByFileDescriptor(in  as patterns,
                                                           out h fd);
                 Reload();
                 @org.freedesktop.DBus.Method.NoReply("true")
                 Reexecute();
                 @org.freedesktop.systemd1.Privileged("true")
                 Exit();
                 @org.freedesktop.systemd1.Privileged("true")
                 Reboot();
                 @org.freedesktop.systemd1.Privileged("true")
                 SoftReboot(in  s new_root);
                 @org.freedesktop.systemd1.Privileged("true")
                 PowerOff();
                 @org.freedesktop.systemd1.Privileged("true")
                 Halt();
                 @org.freedesktop.systemd1.Privileged("true")
                 KExec();
                 @org.freedesktop.systemd1.Privileged("true")
                 SwitchRoot(in  s new_root,
                            in  s init);
                 SetEnvironment(in  as assignments);
                 UnsetEnvironment(in  as names);
                 UnsetAndSetEnvironment(in  as names,
                                        in  as assignments);
                 EnqueueMarkedJobs(out ao jobs);
                 ListUnitFiles(out a(ss) unit_files);
                 ListUnitFilesByPatterns(in  as states,
                                         in  as patterns,
                                         out a(ss) unit_files);
                 GetUnitFileState(in  s file,
                                  out s state);
                 EnableUnitFiles(in  as files,
                                 in  b runtime,
                                 in  b force,
                                 out b carries_install_info,
                                 out a(sss) changes);
                 DisableUnitFiles(in  as files,
                                  in  b runtime,
                                  out a(sss) changes);
                 EnableUnitFilesWithFlags(in  as files,
                                          in  t flags,
                                          out b carries_install_info,
                                          out a(sss) changes);
                 DisableUnitFilesWithFlags(in  as files,
                                           in  t flags,
                                           out a(sss) changes);
                 DisableUnitFilesWithFlagsAndInstallInfo(in  as files,
                                                         in  t flags,
                                                         out b carries_install_info,
                                                         out a(sss) changes);
                 ReenableUnitFiles(in  as files,
                                   in  b runtime,
                                   in  b force,
                                   out b carries_install_info,
                                   out a(sss) changes);
                 LinkUnitFiles(in  as files,
                               in  b runtime,
                               in  b force,
                               out a(sss) changes);
                 PresetUnitFiles(in  as files,
                                 in  b runtime,
                                 in  b force,
                                 out b carries_install_info,
                                 out a(sss) changes);
                 PresetUnitFilesWithMode(in  as files,
                                         in  s mode,
                                         in  b runtime,
                                         in  b force,
                                         out b carries_install_info,
                                         out a(sss) changes);
                 MaskUnitFiles(in  as files,
                               in  b runtime,
                               in  b force,
                               out a(sss) changes);
                 UnmaskUnitFiles(in  as files,
                                 in  b runtime,
                                 out a(sss) changes);
                 RevertUnitFiles(in  as files,
                                 out a(sss) changes);
                 SetDefaultTarget(in  s name,
                                  in  b force,
                                  out a(sss) changes);
                 GetDefaultTarget(out s name);
                 PresetAllUnitFiles(in  s mode,
                                    in  b runtime,
                                    in  b force,
                                    out a(sss) changes);
                 AddDependencyUnitFiles(in  as files,
                                        in  s target,
                                        in  s type,
                                        in  b runtime,
                                        in  b force,
                                        out a(sss) changes);
                 GetUnitFileLinks(in  s name,
                                  in  b runtime,
                                  out as links);
                 SetExitCode(in  y number);
                 LookupDynamicUserByName(in  s name,
                                         out u uid);
                 LookupDynamicUserByUID(in  u uid,
                                        out s name);
                 GetDynamicUsers(out a(us) users);
                 DumpUnitFileDescriptorStore(in  s name,
                                             out a(suuutuusu) entries);
               signals:
                 UnitNew(s id,
                         o unit);
                 UnitRemoved(s id,
                             o unit);
                 JobNew(u id,
                        o job,
                        s unit);
                 JobRemoved(u id,
                            o job,
                            s unit,
                            s result);

๐Ÿ’… methods:

okay first vibe check: this is a LOT of methods. like a lot lot. and every single one is written as Name(in <type> <arg>, ..., out <type> <arg>) so you always clock what goes in and what comes back out. the type letters (s, o, u, b, t, i, y, h, ay, as, au, ao, a(sv), a(sa(sv)), and the stacked-tuple ones like a(ssssssouso)) are doing SO much heavy lifting in there, so read them carefully before you call anything, bestie ๐Ÿซถ

  • the unit lookup crew โ€” GetUnit, GetUnitByPID, GetUnitByInvocationID, GetUnitByControlGroup, GetUnitByPIDFD, LoadUnit. all of them hand you back an object path (out o unit)โ€ฆ except GetUnitByPIDFD, which is extra and gives you three things: out o unit, out s unit_id, out ay invocation_id. not me being obsessed with a triple return ๐Ÿ’…
  • the job starters โ€” StartUnit, StartUnitWithFlags, StartUnitReplace, StopUnit, ReloadUnit, RestartUnit, TryRestartUnit, ReloadOrRestartUnit, ReloadOrTryRestartUnit. every single one takes in s name + in s mode and gives you out o job. StartUnitWithFlags is the one that also takes in t flags, and StartUnitReplace swaps in in s old_unit + in s new_unit instead of a single name. she's different, she's versatile โœจ
  • enqueue era โ€” EnqueueUnitJob takes in s name, in s job_type, in s job_mode and returns out u job_id, out o job_path, out s unit_id, out o unit_path, out s job_type, plus out a(uosos) affected_jobs (thorough queen). then EnqueueUnitJobMany takes in as units, in s job_type, in s job_mode, in t flags and returns out a(uosos) jobs.
  • the kill/signal trio โ€” KillUnit (in s name, in s whom, in i signal), KillUnitSubgroup (same but with an extra in s subgroup), and QueueSignalUnit (same but with an extra in i value). ๐ŸŽ€
  • unit housekeeping โ€” CleanUnit (in as mask), FreezeUnit, ThawUnit, ResetFailedUnit, SetUnitProperties (in b runtime + in a(sv) properties), BindMountUnit (in s source, in s destination, in b read_only, in b mkdir), MountImageUnit (that exact same shape plus in a(ss) options), RefUnit, UnrefUnit.
  • transient + process stuff โ€” StartTransientUnit (in s name, in s mode, in a(sv) properties, in a(sa(sv)) aux, out o job โ€” that nested a(sa(sv)) is a whole vibe ngl), GetUnitProcesses (in s name, out a(sus) processes), AttachProcessesToUnit (in s unit_name, in s subcgroup, in au pids), RemoveSubgroupFromUnit (in s unit_name, in s subcgroup, in t flags), AbandonScope (in s name).
  • jobs o'clock โ€” GetJob (in u id โ†’ out o job), GetJobAfter and GetJobBefore (both in u id โ†’ out a(usssoo) jobs), CancelJob (in u id), ClearJobs, ResetFailed, and SetShowStatus (in s mode).
  • listing era โ€” ListUnits, ListUnitsFiltered (in as states), ListUnitsByPatterns (in as states, in as patterns), ListUnitsByNames (in as names) โ€” every one of them returns out a(ssssssouso) units, which is a stacked signature, ok? and then ListJobs with out a(usssoo) jobs. ๐Ÿฆ‹
  • bus chit-chat โ€” Subscribe, Unsubscribe, Dump (out s output), DumpUnitsMatchingPatterns (in as patterns โ†’ out s output), DumpByFileDescriptor (out h fd), DumpUnitsMatchingPatternsByFileDescriptor (in as patterns โ†’ out h fd).
  • big moves โ€” Reload, Reexecute, Exit, Reboot, SoftReboot (in s new_root), PowerOff, Halt, KExec, SwitchRoot (in s new_root, in s init). and listen: Reexecute is sitting under @org.freedesktop.DBus.Method.NoReply("true") โ€” no reply comes back, that's literally the point of the annotation. meanwhile Exit, Reboot, SoftReboot, PowerOff, Halt, KExec and SwitchRoot all carry @org.freedesktop.systemd1.Privileged("true") above them. main character energy only ๐Ÿ‘‘
  • environment โ€” SetEnvironment (in as assignments), UnsetEnvironment (in as names), UnsetAndSetEnvironment (in as names, in as assignments), and EnqueueMarkedJobs (out ao jobs).
  • unit file central โ€” ListUnitFiles (out a(ss) unit_files), ListUnitFilesByPatterns (in as states, in as patterns โ†’ out a(ss) unit_files), GetUnitFileState (in s file โ†’ out s state), EnableUnitFiles (in as files, in b runtime, in b force โ†’ out b carries_install_info + out a(sss) changes), DisableUnitFiles (in as files, in b runtime โ†’ out a(sss) changes), EnableUnitFilesWithFlags (in as files, in t flags โ†’ out b carries_install_info + out a(sss) changes), DisableUnitFilesWithFlags (in as files, in t flags โ†’ out a(sss) changes), DisableUnitFilesWithFlagsAndInstallInfo (that same shape but with out b carries_install_info back in the outs), ReenableUnitFiles (in as files, in b runtime, in b force โ†’ out b carries_install_info + out a(sss) changes), LinkUnitFiles (in as files, in b runtime, in b force โ†’ out a(sss) changes), PresetUnitFiles (in as files, in b runtime, in b force โ†’ out b carries_install_info + out a(sss) changes), PresetUnitFilesWithMode (that plus an in s mode at the front), MaskUnitFiles (in as files, in b runtime, in b force โ†’ out a(sss) changes), UnmaskUnitFiles (in as files, in b runtime โ†’ out a(sss) changes), and RevertUnitFiles (in as files โ†’ out a(sss) changes). yes, they're all extremely similar and yes, the runtime/force pair is doing a lot of repeating. iykyk ๐ŸŒธ
  • targets + deps โ€” SetDefaultTarget (in s name, in b force โ†’ out a(sss) changes), GetDefaultTarget (out s name), PresetAllUnitFiles (in s mode, in b runtime, in b force โ†’ out a(sss) changes), AddDependencyUnitFiles (in as files, in s target, in s type, in b runtime, in b force โ†’ out a(sss) changes), GetUnitFileLinks (in s name, in b runtime โ†’ out as links).
  • the stragglers โ€” SetExitCode (in y number), LookupDynamicUserByName (in s name โ†’ out u uid), LookupDynamicUserByUID (in u uid โ†’ out s name), GetDynamicUsers (out a(us) users), and DumpUnitFileDescriptorStore (in s name โ†’ out a(suuutuusu) entries). that last signature. that's it, that's the whole thought. ๐Ÿ˜ญ

๐Ÿ“ฃ signals:

four of them, four signatures, all spelled out exactly as they arrive โ€” no edits, no trimming:

  • UnitNew(s id, o unit) โ€” takes s id and o unit.
  • UnitRemoved(s id, o unit) โ€” takes s id and o unit.
  • JobNew(u id, o job, s unit) โ€” takes u id, o job, s unit.
  • JobRemoved(u id, o job, s unit, s result) โ€” takes u id, o job, s unit, and an extra s result. ๐Ÿซถ

and yeah, that's the entire method roster and the signal squad, all sitting right there inside interface org.freedesktop.systemd1.Manager { under node /org/freedesktop/systemd1 { โ€” no cap, nothing skipped, every single in, every single out, every annotation accounted for ๐Ÿ’–

...and it keeps going, because of course it does. Here's the rest of the signal block, plus the moment this whole thing pivots into the property zone:

StartupFinished(t firmware,
                t loader,
                t kernel,
                t initrd,
                t userspace,
                t total);
UnitFilesChanged();
Reloading(b active);
properties:

Okay so StartupFinished() rolls up to you with six separate t-typed numbers โ€” firmware, loader, kernel, initrd, userspace, and total โ€” so if you're the kind of person who wants the whole boot timeline in one shot instead of doom-scrolling a million individual timestamp properties, this is the signal for you. Then UnitFilesChanged() with no arguments at all (it's just vibing, zero params), and Reloading(b active) handing you a single b-typed active. And then, boom, properties: โ€” we're in the property section now, bestie, and it's a long one. Buckle up. ๐ŸŽ€


โœจ Properties โœจ

๐Ÿฆ‹ The "who even am I" block

Identity crisis, but make it const. Every one of these is a read-only string and every one carries @org.freedesktop.DBus.Property.EmitsChangedSignal("const"):

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Version = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Features = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Virtualization = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ConfidentialVirtualization = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Architecture = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Tainted = '...';

That "const" annotation is the way the interface says "this one does not emit a changed signal" โ€” so don't sit there waiting for a notification that is never, ever coming. ๐Ÿซถ Six strings, all <pink>readonly</pink>, all s, all with the exact same annotation line in front of them.

โฐ The timestamp cinematic universe

This is the part where I need you to stay with me, because it is a lot of t-typed properties and they all have "const" on them:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t FirmwareTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t FirmwareTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LoaderTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LoaderTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t KernelTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t KernelTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UserspaceTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UserspaceTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t FinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t FinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t ShutdownStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t ShutdownStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t ShutdownFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t ShutdownFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownLateStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownLateStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownLateFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t PreviousShutdownLateFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t SecurityStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t SecurityStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t SecurityFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t SecurityFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t GeneratorsStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t GeneratorsStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t GeneratorsFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t GeneratorsFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t UnitsLoadTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDSecurityFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDGeneratorsStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDGeneratorsStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDGeneratorsFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDGeneratorsFinishTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDUnitsLoadStartTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDUnitsLoadStartTimestampMonotonic = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDUnitsLoadFinishTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t InitRDUnitsLoadFinishTimestampMonotonic = ...;

Notice the pattern, bestie, because it's genuinely the whole trick: every single one of these has a ...Monotonic twin right after it. Firmware, Loader, Kernel, InitRD, Userspace, Finish, ShutdownStart, ShutdownFinish, then a whole flashback arc of PreviousShutdownStart, PreviousShutdownFinish, PreviousShutdownLateStart, PreviousShutdownLateFinish, then Security, Generators, UnitsLoadStart, UnitsLoadFinish, UnitsLoad, and then the InitRD remix of InitRDSecurity, InitRDGenerators, InitRDUnitsLoadStart, InitRDUnitsLoadFinish โ€” all of them readonly t ... = ...; with the "const" annotation glued on top. Fifty-four lines of pure timestamp realness. No notes. ๐Ÿ’…

๐ŸŽš๏ธ The two you can actually write to

Okay so unlike everything above, these two are <hotpink>readwrite</hotpink> โ€” and both are marked @org.freedesktop.systemd1.Privileged("true") with EmitsChangedSignal("false"):

@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s LogLevel = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s LogTarget = '...';

Two s-typed strings, LogLevel and LogTarget. They're readwrite, so yeah you can set them, but Privileged("true") is sitting right there telling you this is a privileged operation โ€” so don't act surprised when unprivileged you gets told no. ๐Ÿ™ˆ

๐Ÿ”ข The counters (and one array, and one double, and one list)

@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly u NNames = ...;
readonly u NFailedUnits = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly u NJobs = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly u NInstalledJobs = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly u NFailedJobs = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly at TransactionsWithOrderingCycle = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly d Progress = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly as Environment = ['...', ...];

Read that carefully because it's sneaky: NNames has the "false" annotation above it, and then NFailedUnits does not โ€” it's the one bare line in this little cluster, no annotation of its own. Keep it that way, don't "fix" it, it's literally the source. Everything else here is "false" + readonly.

Type check while we're here: u for NNames, NFailedUnits, NJobs, NInstalledJobs, NFailedJobs; at for TransactionsWithOrderingCycle; d for Progress; as for Environment. Four different type letters in one neighbourhood, we love range. ๐ŸŒˆ

๐Ÿ•ต๏ธ The assorted-facts corner

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ConfirmSpawn = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly b ShowStatus = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as UnitPath = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s DefaultStandardOutput = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s DefaultStandardError = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s WatchdogDevice = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t WatchdogLastPingTimestamp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly t WatchdogLastPingTimestampMonotonic = ...;

Watch the annotations here, because they alternate and it's so easy to glaze over: ConfirmSpawn is "const", ShowStatus is "false", UnitPath is "const", DefaultStandardOutput is "const", DefaultStandardError is "const", WatchdogDevice is "const", then both WatchdogLastPingTimestamp and its ...Monotonic twin drop back to "false". Types: b, b, as, s, s, s, t, t. All <purple>readonly</purple>, every last one. โญ

๐Ÿ• The watchdog control panel

Now the fun part โ€” six properties that are readwrite and Privileged("true"), all with EmitsChangedSignal("false"):

@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite t RuntimeWatchdogUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite t RuntimeWatchdogPreUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite s RuntimeWatchdogPreGovernor = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite t RebootWatchdogUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite t KExecWatchdogUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@org.freedesktop.systemd1.Privileged("true")
readwrite b ServiceWatchdogs = ...;

Two ts (RuntimeWatchdogUSec, RuntimeWatchdogPreUSec), then the one s in the group (RuntimeWatchdogPreGovernor โ€” the only string here, main character behaviour honestly), then two more ts (RebootWatchdogUSec, KExecWatchdogUSec), and it finishes on a b (ServiceWatchdogs). Six for six on readwrite + Privileged("true") + EmitsChangedSignal("false"). ๐Ÿ‘‘

๐Ÿ  Last two, and they're "false"

@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s ControlGroup = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s SystemState = '...';

Two plain readonly strings, both "false", and that closes out the property list. Whew. ๐Ÿ˜ฎโ€๐Ÿ’จ


And yeah โ€” the manager object still has more to show you, so don't go anywhere. ๐Ÿ’–

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly y ExitCode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultTimerAccuracyUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultTimeoutStartUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultTimeoutStopUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t DefaultTimeoutAbortUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultDeviceTimeoutUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultRestartUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultStartLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u DefaultStartLimitBurst = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t EventLoopRateLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u EventLoopRateLimitBurst = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultIOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultIPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultMemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultTasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitCPU = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitCPUSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitFSIZE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitFSIZESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitDATA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitDATASoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitSTACK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitSTACKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitCORE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitCORESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRSS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRSSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNOFILE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNOFILESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitAS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitASSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNPROC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNPROCSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitMEMLOCK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitMEMLOCKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitLOCKS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitLOCKSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitSIGPENDING = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitSIGPENDINGSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitMSGQUEUE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitMSGQUEUESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNICE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitNICESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRTPRIO = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRTPRIOSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRTTIME = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DefaultLimitRTTIMESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t DefaultTasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t DefaultMemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DefaultMemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t DefaultCPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DefaultCPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t DefaultIOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DefaultIOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimerSlackNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s DefaultOOMPolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i DefaultOOMScoreAdjust = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultRestrictSUIDSGID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s CtrlAltDelBurstAction = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u SoftRebootsCount = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u KExecCount = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ReloadCount = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DefaultMemoryZSwapWriteback = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
           };

okay so that whole wall right there? that's the rest of the manager's properties ๐Ÿ’– bestie it's giving deep lore, and the very last three lines โ€” org.freedesktop.DBus.Peer, org.freedesktop.DBus.Introspectable, org.freedesktop.DBus.Properties โ€” are just the standard D-Bus housekeeping interfaces every object has, and that final }; closes the whole org.freedesktop.systemd1.Manager interface block. slay, we survived the property list ๐Ÿซถ


๐Ÿ’… Methods ๐Ÿ’…

okay so before we even start โ€” there's a lil quirk here that lowkey trips everybody up, so let's get it out of the way:

Note that many of the methods exist twice: once on the Manager object and once on the respective unit objects. This is to optimize access times so that methods that belong to unit objects do not have to be called with a resolved unit path, but can be called with only the unit id, too.

fr fr โ€” same method, two doors, pick whichever's faster for you ๐Ÿšชโœจ


  • GetUnit() โ€” your โœจlookup bestieโœจ. You hand it a unit name, it hands you back the unit object path. That's it. But heads up: if a unit hasn't been loaded yet by that name, this method fails. No unit, no path, no mercy ๐Ÿ’€
  • GetUnitByPID() โ€” same energy but for processes. You give it a UNIX PID and it returns the object path of the unit that PID belongs to. The catch? That PID has to refer to an existing system process, so no asking about ghosts ๐Ÿ‘ป
  • GetUnitByPIDFD() โ€” the glow-up version of the above ๐Ÿ˜Œ instead of a PID you query with a Linux PIDFD (see: pidfd_open(2)), which is safer because UNIX PIDs can get recycled โ€” like, that PID you knew could get reused by a whole different process and then you'd be asking about a stranger ๐Ÿ˜ญ This one returns the unit id and the invocation id, together with the unit object path. three for the price of one, we love to see it ๐Ÿ’…
  • LoadUnit() โ€” basically GetUnit()'s overachieving sibling. It does the same thing but will load the unit from disk if possible. no vibes left behind ๐Ÿฆ‹
  • StartUnit() โ€” the main character ๐ŸŒŸ It enqueues a start job, and possibly some depending jobs too. Two args: the unit you wanna activate, and a mode string. And that mode has to be exactly one of these five, no improvising:
    • "replace" โ€” starts the unit and its dependencies, and it may replace already-queued jobs that conflict with it. out with the old ๐Ÿ’…
    • "fail" โ€” starts the unit and its dependencies, but fails if that would change an already queued job. it's giving "i don't do edits" ๐Ÿ™…
    • "isolate" โ€” starts the unit in question and terminates all units that are not dependencies of it. dramatic. iconic. very "you're either with me or you're gone" ๐Ÿ’€
    • "ignore-dependencies" โ€” starts a unit but ignores all its dependencies. bold.
    • "ignore-requirements" โ€” starts a unit but only ignores the requirement dependencies.
Not recommended to make use of the latter two options. fr fr, just don't ๐Ÿ™ˆ

And on a successful reply, this method returns the newly created job object that got enqueued for asynchronous activation. So if you actually care about whether the start worked? you can't just vibe and assume ๐Ÿ˜ญ you have to track the outcome of that job.

The โœจrace-freeโœจ way to do it: first subscribe to the JobRemoved() signal, then call StartUnit(), then use the returned job object to filter out all the unrelated JobRemoved() signals until the one you want shows up โ€” that one carries the result of the start operation. no cap, order matters here, do it in that order or you're gonna have a bad time ๐Ÿ’–

  • StartUnitReplace() โ€” StartUnit() again, but it takes a job that's queued for one unit and replaces it with a job for another unit. swap szn ๐Ÿ”
  • StartUnitWithFlags() โ€” StartUnit() but you can also pass an extra flags parameter. And bestie, listen: it does not support any flags for now, it's just reserved for future extensions. so don't get excited, there's nothing in there yet, it's a cute empty box ๐ŸŽ
  • StopUnit() โ€” StartUnit()'s opposite-number ๐Ÿ’” it stops the specified unit instead of starting it. oh andโ€”
Note that the "isolate" mode is invalid for this method. don't try it, it will not go well ๐Ÿ™ˆ

and that's the methods so far โ€” yes there's more coming, don't you dare close the tab yet ๐ŸŽ€

ReloadUnit(), RestartUnit(), TryRestartUnit(), ReloadOrRestartUnit(), and ReloadOrTryRestartUnit() are your little glow-up squad for restarting and/or reloading a unit. ๐Ÿ’… They take basically the same args as StartUnit(). Reloading only happens if the unit's already running โ€” otherwise it just fails, no cap. And if you restart a service that isn't running? It gets started, unless you went with the "Try" flavor, in which case a not-running service is left completely alone by the restart. The "ReloadOrRestart" flavors are the flexible besties: they try a reload if the unit can do it, and fall back to a full restart otherwise. ๐ŸŽ€

EnqueueUnitJob() is giving the same energy as all those StartUnit()/StopUnit()/RestartUnit() methods up above, but it's the unified interface that works on one single unit. The job_type argument picks the job type, and it's one of "start", "stop", "reload", "restart", "try-restart", "reload-or-restart" or "reload-or-try-restart". The job_mode argument matches the mode argument of StartUnit(). On reply, the method hands you back:

  • the enqueued anchor job's numeric id and object path,
  • the affected unit's id and object path,
  • the job type that was actually queued (after type collapsing โ€” so like, "reload-or-restart" becomes "restart" or "reload"), and
  • an array of additional jobs that got enqueued as part of the same transaction, just to satisfy dependencies. ๐Ÿฆ‹

EnqueueUnitJobMany() is the same vibe as EnqueueUnitJob(), but it handles multiple units at once. All the requested units go into a single transaction, which is honestly necessary to properly honour After=/Before= ordering between units passed in the same call โ€” no matter what order they're in in the array, periodt. The job_type argument applies to each listed unit, including the magic values "reload-or-restart" and "reload-or-try-restart", which get resolved per unit (units that support reloading get a reload job, everyone else gets a restart). The flags argument doesn't support any flags for now and must be passed as "0" โ€” it's reserved for future extensions, so don't come for it. On reply, you get an array of tuples describing the anchor job enqueued for each requested unit:

  • the numeric job id,
  • the job object path,
  • the unit id,
  • the unit object path, and
  • the job type that was actually queued.
heads up bestie โ€” the order of tuples in the reply is unspecified and may not match the order of your input array. ๐Ÿ™ˆ

EnqueueMarkedJobs() creates reload/restart jobs for units that have been appropriately marked โ€” see the Markers property above. It's equivalent to calling TryRestartUnit() or ReloadOrTryRestartUnit() for the marked units. โœจ

BindMountUnit() lets you bind mount new files or directories into a running service's mount namespace. If the kernel supports it, any prior mount on the selected target gets replaced by the new mount. If not supported, the prior mount just gets over-mounted instead โ€” but it stays pinned and inaccessible. ๐Ÿ˜ญ

MountImageUnit() does the same thing but for mounting new images into a running service's mount namespace. Same deal: if the kernel's got your back, the prior mount on the selected target is replaced. If not, the prior mount is over-mounted but stays pinned and inaccessible. ๐ŸŒธ

KillUnit() is how you kill (i.e. send a signal to) all the processes of a unit. It takes the unit name, an enum who, and a UNIX signal number to send. The who enum is one of "main", "control", "cgroup" or "all":

  • "main" โ€” only the main process of the unit gets killed.
  • "control" โ€” only the control process of the unit gets killed.
  • "cgroup" โ€” only the processes in the control group of the unit get killed, which might or might not include the main and control processes too.
  • "all" โ€” literally everything dies: the main process, the control process, and those in the control group. ๐Ÿ’€

A "control" process is, for example, a process configured via ExecStop= that gets spawned in parallel to the main daemon process to shut it down. The value can be suffixed by -fail, in which case the operation will fail if no matching process was found (otherwise it returns successfully while executing absolutely no operation, iconic).

KillUnitSubgroup() is just like KillUnit() but takes an additional path argument that selects a sub-control group of the unit's control group. Only processes in that subgroup get killed. The path may be specified with or without a leading "/" โ€” either way it's taken relative to the unit's control group. If the subgroup path is specified as an empty string or as "/", it has the same effect as KillUnit(). If it's anything else, the whom parameter must be set to either "cgroup" or "cgroup-fail". ๐ŸŒˆ

QueueSignalUnit() is similar to KillUnit() but it may be used to enqueue a POSIX Realtime Signal (i.e. SIGRTMIN+... and SIGRTMAX-...) to the selected process(es). It takes the same parameters as KillUnit() with one extra argument: an integer that gets passed in the sival_int value accompanying the queued signal. See sigqueue(3) for details. ๐Ÿซถ

GetJob() returns the job object path for a specific job, identified by its id.

CancelJob() cancels a specific job identified by its numeric ID. This operation is also available as the Cancel() method of Job objects (see below), and it exists primarily to reduce the necessary round trips to execute this operation. Note that this won't have any effect on jobs whose execution has already begun. ๐Ÿ˜Œ

ClearJobs() flushes the job queue, removing all jobs that are still queued. Note that this does not have any effect on jobs whose execution has already begun โ€” it only flushes jobs that are queued and haven't yet started executing.

ResetFailedUnit() resets the "failed" state of a specific unit. Fresh start energy. โœจ

SetShowStatus() configures the display of status messages during bootup and shutdown. The mode parameter can be set to any value that's valid for the systemd.show_status kernel parameter. For more info about systemd.show_status, see systemd(1). The mode parameter can also be set to an empty string โ€” when mode is an empty string, SetShowStatus() resets ShowStatus back to its original value. You can use SetShowStatus() to create a service that does something like this:

  1. Send a D-Bus message that will turn off status messages.
  2. Block until a reply to that message is received.
  3. Print multiple lines without being interrupted by status messages.
  4. Send a D-Bus message that will reset ShowStatus back to its original value.

ResetFailed() resets the "failed" state of all units. Clean slate, we love to see it. ๐ŸŽ€

ListUnits() returns an array of all currently loaded units. Note that units may be known by multiple names at the same time, so there might be more unit names loaded than actual units behind them. The array consists of structures with the following elements:

  • The primary unit name as string
  • The human-readable description string
  • The load state (i.e. whether the unit file has been loaded successfully)
  • The active state (i.e. whether the unit is currently started or not)
  • The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not)
  • A unit that is being followed in its state by this unit, if there is any, otherwise the empty string.
  • The unit object path
  • If there is a job queued for the job unit, the numeric job id, 0 otherwise
  • The job type as string
  • The job object path

ListJobs() returns an array with all currently queued jobs. Returns an array consisting of structures with the following elements:

  • The numeric job id
  • The primary unit name for this job
  • The job type as string
  • The job state as string
  • The job object path
  • The unit object path

Subscribe() enables most bus signals to be sent out. Clients that are interested in signals need to call this method. Signals are only sent out if at least one client invoked this method. Note that this behavior applies to all the signals that the object in /org/freedesktop/systemd1 may emit โ€” including the D-Bus standard org.freedesktop.DBus.Properties.PropertiesChanged signal and others that don't belong to the org.freedesktop.systemd1 interface. ๐Ÿฆ‹

Unsubscribe() reverts the signal subscription that Subscribe() implements. It's not necessary to invoke Unsubscribe(), since clients are tracked โ€” signals stop being sent out as soon as all clients that previously asked for Subscribe() either closed their connection to the bus or invoked Unsubscribe(). ๐Ÿ’œ

Dump() returns a text dump of the internal service manager state. This is a privileged, low-level debugging interface only. The returned string is supposed to be readable exclusively by developers, and not programmatically. There's no interface stability guaranteed on the returned string โ€” new fields may be added any time, old fields removed, and the general structure may be rearranged drastically between releases. This is exposed by systemd-analyze(1)'s dump command. Similarly, DumpUnitsMatchingPatterns() returns the internal state of units whose names match the glob expressions specified in the patterns argument. The DumpByFileDescriptor()/DumpUnitsMatchingPatternsByFileDescriptor() methods are identical to Dump()/DumpUnitsMatchingPatterns(), but return data serialized into a file descriptor (the client should read the text data from it until hitting EOF). Given the size limits on D-Bus messages and the possibly large size of the returned strings, DumpByFileDescriptor()/DumpUnitsMatchingPatternsByFileDescriptor() are usually the preferred interface, since it ensures the data can be passed reliably from the service manager to the client. Note though that they cannot work when communicating with the service manager remotely, as file descriptors are strictly local to a system. All the Dump*() methods are rate limited for unprivileged users. ๐Ÿ˜ค

Reload() may be invoked to reload all unit files. ๐ŸŒธ

Reexecute() may be invoked to reexecute the main manager process. It will serialize its state, reexecute, and deserialize the state again. This is useful for upgrades and is a more comprehensive version of Reload(). ๐Ÿ”ฅ

Exit() may be invoked to ask the manager to exit. This is not available for the system manager and is useful only for user session managers. ๐Ÿ‘‘

Reboot(), PowerOff(), Halt(), KExec() and SoftReboot() are the "okay we're DONE here" buttons โ€” they ask for an immediate reboot, power down, halt, kexec-based reboot, or soft reboot of the system. Bestie, listen: this does not shut down any services. It just immediately transitions into the later shutdown operation. ๐Ÿ’€ These functions are normally only called as the very last step of shutdown, so pls do not call them directly, okay? If you actually wanna shut the machine down, the better move is to invoke Reboot(), RebootWithFlags() or PowerOff() on the systemd-logind manager object โ€” check org.freedesktop.login1(5) for the deets. ๐Ÿซถ

SoftReboot() takes an argument for the path of the root file system to activate for the next boot cycle. If you pass an empty string, the /run/nextroot/ path gets used โ€” but only if it exists. ๐Ÿ‘‘


SwitchRoot() is for transitioning to a new root directory. It's meant for use in the initrd, and also for going from the host system into a shutdown initrd. It takes two arguments: the new root directory (which you have to specify) and an init binary path (which you can leave empty โ€” in that case it gets automatically searched for). The state of the system manager gets serialized before the transition, and after it, the manager binary on the main system is invoked and replaces the old PID 1. Then all that state gets deserialized. โœจ

SetEnvironment() lets you alter the environment block that's passed to every spawned process. It takes a string array of environment variable assignments, and any previously set env vars get overridden. simple as that. ๐Ÿ’…

UnsetEnvironment() does the opposite โ€” it unsets env vars. It takes a string array of environment variable names. Every variable you list gets unset (if it was set before) and is no longer passed to spawned processes. If a variable wasn't set in the first place, this method just... has no effect. It won't fail on you though. no drama. ๐Ÿ™ˆ

UnsetAndSetEnvironment() is literally UnsetEnvironment() + SetEnvironment() combined, the way that it takes two lists. First list = variables to unset. Second list = assignments to set. And if a variable shows up in both lists? It's set when the method returns โ€” so the set list overrides the unset list. periodt. ๐Ÿ”ฅ

ListUnitFiles() returns an array of unit names plus their enablement status. Quick vibe check on the difference: ListUnit() returns units currently loaded into memory, while ListUnitFiles() returns unit files found on disk. And ngl, while most units are read directly from a unit file with the same name, some units aren't backed by files at all, and some files (templates) can't be loaded directly as units โ€” they have to be instantiated instead. ๐Ÿฆ‹

GetUnitFileState() returns the current enablement status of one specific unit file.

EnableUnitFiles() enables one or more units in the system (by creating symlinks to them in /etc/ or /run/). It takes a list of unit files to enable โ€” either just file names, or full absolute paths if the unit files live outside the usual unit search paths โ€” plus two booleans:

  • the first controls whether the unit is enabled for runtime only (true, /run/) or persistently (false, /etc/)
  • the second controls whether symlinks pointing to other units shall be replaced if necessary

This method returns one boolean and an array of the changes made. The boolean signals whether the unit files contained any enablement information (i.e. an [Install] section). The changes array consists of structures with three strings: the type of the change (one of "symlink" or "unlink"), the file name of the symlink, and the destination of the symlink. Heads up: most of the calls below return a changes list in this same format. ๐Ÿ‘‘

Similarly, DisableUnitFiles() disables one or more units in the system โ€” i.e. it removes all symlinks to them in /etc/ and /run/.


The EnableUnitFilesWithFlags() and DisableUnitFilesWithFlags() calls take options as flags instead of booleans, so things stay extendable. Here's how they're defined:

#define SD_SYSTEMD_UNIT_RUNTIME  (UINT64_C(1) << 0)
#define SD_SYSTEMD_UNIT_FORCE    (UINT64_C(1) << 1)
#define SD_SYSTEMD_UNIT_PORTABLE (UINT64_C(1) << 2)
  • SD_SYSTEMD_UNIT_RUNTIME โ€” enable or disable the unit for runtime only
  • SD_SYSTEMD_UNIT_FORCE โ€” controls whether symlinks pointing to other units shall be replaced if necessary
  • SD_SYSTEMD_UNIT_PORTABLE โ€” adds or removes the symlinks in /etc/systemd/system.attached and /run/systemd/system.attached

DisableUnitFilesWithFlagsAndInstallInfo() is similar to DisableUnitFilesWithFlags() and takes the same arguments โ€” but it also returns a boolean indicating whether the unit files contain any enablement information, just like EnableUnitFiles(). The changes made are still returned in an array. ๐Ÿ’–

Similarly, ReenableUnitFiles() applies the changes to one or more units that would result from disabling and enabling the unit quickly one after the other, in an atomic fashion. This is useful for applying updated [Install] information contained in unit files. โœจ

Similarly, LinkUnitFiles() links unit files (ones located outside of the usual unit search paths) into the unit search path.

Similarly, PresetUnitFiles() enables/disables one or more unit files according to the preset policy. See systemd.preset(5) for more info. ๐ŸŒธ

Similarly, MaskUnitFiles() masks unit files, and UnmaskUnitFiles() unmasks them again. the cycle of life fr fr. ๐ŸŒˆ

SetDefaultTarget() changes the default.target link. See bootup(7) for more.

GetDefaultTarget() retrieves the name of the unit to which default.target is aliased.

SetUnitProperties() can modify certain unit properties at runtime. Not all properties can be changed at runtime, but a lot of resource management settings can (primarily those listed in systemd.resource-control(5)). The changes apply instantly and get stored on disk for future boots โ€” unless runtime is true, in which case the settings only apply until the next reboot. name is the name of the unit to modify. properties are the settings to set, encoded as an array of property name and value pairs. Note that this is not a dictionary! And also note: when setting array properties with this method, it usually results in appending to the pre-configured array. To reset configured arrays, set the property to an empty array first, then append to it. iykyk. ๐Ÿ’…

StartTransientUnit() creates and starts a transient unit โ€” one that gets released as soon as it's not running or referenced anymore, or the system is rebooted. name is the unit name including its suffix, and it must be unique. mode is the same as in StartUnit(). properties contains properties of the unit, specified like in SetUnitProperties(). aux is currently unused and should be passed as an empty array. See the New Control Group Interface[2] for more info on how to use this for resource control purposes. ๐ŸŽ€

DumpUnitFileDescriptorStore() returns an array with information about the file descriptors currently in the file descriptor store of the specified unit. This call is equivalent to DumpFileDescriptorStore() on the org.freedesktop.systemd1.Service. For further details, see below. ๐Ÿ‘€

CleanUnit() deletes the configuration, state, logs, cache and runtime data directories, and clears out the file descriptor store for the unit โ€” as specified in the mask parameters. The possible values are "configuration", "state", "logs", "cache", "runtime", "fdstore", and "all". ๐Ÿงนโœจ

RemoveSubgroupFromUnit() removes a subcgroup belonging to a unit's cgroup. It takes three arguments: the unit name (if empty, defaults to the caller's unit), a cgroup path (which must start with a slash /), taken relative to the unit's cgroup, and a flags argument (which must be zero for now). This is primarily useful for unprivileged service managers to ask the system service manager to remove subcgroups it manages โ€” in case one was delegated to other UIDs. ๐Ÿ‘‘


๐Ÿ’ซ Signals ๐Ÿ’ซ

okay so, quick note bestie: most signals are sent out only after Subscribe() has been invoked by at least one client. Make sure you invoke this method when you're subscribing to these signals! ๐Ÿ™ˆ

UnitNew() and UnitRemoved() get sent out each time a new unit is loaded or unloaded. This has little to do with whether a unit is available on disk or not โ€” it simply reflects the units currently loaded into memory. These signals take two parameters: the primary unit name and the object path. ๐Ÿฆ‹

JobNew() and JobRemoved() get sent out each time a new job is queued or dequeued. Both signals take the numeric job ID, the bus path, and the primary unit name for this job as arguments. JobRemoved() also includes a result string, which is one of:

  • "done" โ€” successful execution of a job
  • "canceled" โ€” the job was canceled (via CancelJob() above) before it finished execution. Note that this does not necessarily mean the job operation is actually cancelled too โ€” see above.
  • "timeout" โ€” the job timeout was reached
  • "failed" โ€” the job failed
  • "dependency" โ€” a job this job depended on failed, and the job hence was removed as well
  • "skipped" โ€” a job was skipped because it did not apply to the unit's current state

StartupFinished() is sent out when startup finishes. It carries six microsecond timespan values, each indicating how much boot time was spent in the firmware (if known), in the boot loader (if known), in the kernel initialization phase, in the initrd (if known), in userspace, and in total. These values may also be calculated from the FirmwareTimestampMonotonic, LoaderTimestampMonotonic, InitRDTimestampMonotonic, UserspaceTimestampMonotonic, and FinishTimestampMonotonic properties (see below). โฑ๏ธ

UnitFilesChanged() is sent out each time the list of enabled or masked unit files on disk has changed.

Reloading() is sent out immediately before a daemon reload is done (with the boolean parameter set to True) and after a daemon reload is completed (with the boolean parameter set to False). UIs can use this to optimize UI updates. ๐Ÿ’…


๐ŸŒŸ Properties ๐ŸŒŸ

Most properties simply reflect the respective options in /etc/systemd/system.conf and the kernel command line. cute, right?

The others:

Version encodes the version string of the running systemd instance. Note that the version string is purely informational. It should not be parsed, and one may not assume the version to be formatted in any particular way. We take the liberty to change the versioning scheme at any time, and it is not part of the public API. ๐Ÿ’€

Features encodes the features that have been enabled and disabled for this build. Enabled options are prefixed with +, disabled options with -.

  • "unmerged-usr" โ€” /bin, /sbin and /lib* are not symlinks to their counterparts under /usr/. ๐Ÿ’€ bestie if you wanna know more about this whole saga, go consult The Case for the /usr Merge[3].

Added in version 252.

  • "unmerged-bin" โ€” /usr/sbin is not a symlink to /usr/bin/. ๐Ÿ˜ญ

Added in version 256.

  • "var-run-bad" โ€” either /run/ doesn't exist, or /var/run is not a symlink pointing at /run/. ๐Ÿ™ˆ

Added in version 252.

  • "cgroupsv1" โ€” the system is running on the deprecated cgroup v1 hierarchy. yes this is a callout, no it's not a vibe.

Added in version 252.

  • "local-hwclock" โ€” the local hardware clock (RTC) is configured to be in local time instead of UTC. โฐ

Added in version 252.

  • "support-ended" โ€” the system is running past the end of support that the vendor declared. Go read the description of SUPPORT_END= in os-release(5) for the tea. ๐Ÿซ 

Added in version 252.

  • "old-kernel" โ€” the system is running a kernel version that is older than the minimum supported by this version of systemd. โœจ

Added in version 252.

  • "overflowuid-not-65534", "overflowgid-not-65534" โ€” the kernel overflow UID or GID has a value that is not 65534. ๐Ÿ‘€

Added in version 252.

  • "short-uid-range", "short-gid-range" โ€” the UID or GID range assigned to the running systemd instance covers less than 0...65534. ๐Ÿ’…

Added in version 252.


FirmwareTimestamp, FirmwareTimestampMonotonic, LoaderTimestamp, LoaderTimestampMonotonic, KernelTimestamp, KernelTimestampMonotonic, InitRDTimestamp, InitRDTimestampMonotonic, UserspaceTimestamp, UserspaceTimestampMonotonic, FinishTimestamp, FinishTimestampMonotonic, ShutdownStartTimestamp and ShutdownStartTimestampMonotonic encode CLOCK_REALTIME and CLOCK_MONOTONIC microsecond timestamps, taken when:

  • the firmware first began execution,
  • the boot loader first began execution,
  • the kernel first began execution,
  • the initrd first began execution,
  • the main systemd instance began execution,
  • all queued startup jobs finished execution,
  • and finally, when a shutdown operation first began execution. ๐ŸŽ€

These values are so useful for figuring out boot-time performance, fr fr. Just note that because monotonic time starts with kernel startup, the KernelTimestampMonotonic timestamp will always be 0, and FirmwareTimestampMonotonic and LoaderTimestampMonotonic are meant to be read as negative values. Also, not all fields are always available โ€” it depends on the firmware, boot loader or initrd implementation being used. In those cases the respective pairs of timestamps are both 0, which is the polite way of saying "no data available bestie". ๐Ÿ˜ญ

ShutdownFinishTimestamp and ShutdownFinishTimestampMonotonic encode CLOCK_REALTIME and CLOCK_MONOTONIC microsecond timestamps taken when all units have finished stopping during shutdown, i.e. when shutdown.target is reached. Together with ShutdownStartTimestamp (which is taken when unit stopping begins) they bracket the time spent stopping units. ๐Ÿฆ‹

PreviousShutdownStartTimestamp, PreviousShutdownFinishTimestamp, PreviousShutdownLateStartTimestamp, PreviousShutdownLateFinishTimestamp and their Monotonic counterparts encode CLOCK_REALTIME and CLOCK_MONOTONIC microsecond timestamps describing the shutdown of the previous boot, restored from the Live Update Orchestrator (LUO) payload after a kexec-based live update. PreviousShutdownStartTimestamp and PreviousShutdownFinishTimestamp bracket the unit-stopping phase of that previous boot, while PreviousShutdownLateStartTimestamp and PreviousShutdownLateFinishTimestamp are taken by systemd-shutdown itself โ€” when it began execution, and when it was about to kexec() into the current kernel, respectively. Unlike the current cycle's ShutdownStartTimestamp and ShutdownFinishTimestamp (which describe an in-progress shutdown of the running system), these always refer to a previous, already-completed boot, similar to the firmware, boot loader and kernel timestamps. They're populated only after a kexec-based live update, and they're useful for determining shutdown and live-update performance; otherwise they are all 0. ๐Ÿ‘‘

UnitsLoadTimestamp and UnitsLoadTimestampMonotonic encode CLOCK_REALTIME and CLOCK_MONOTONIC microseconds timestamps (as described above). The timestamps are taken every time when the manager starts loading unit files. โญ

Similarly, the SecurityStartTimestamp, GeneratorsStartTimestamp and LoadUnitTimestamp (as well as their monotonic and stop counterparts) expose performance data for uploading the security policies to the kernel (such as the SELinux, IMA, or SMACK policies), for running the generator tools, and for loading the unit files. ๐Ÿ’–

NNames encodes how many unit names are currently known. This only includes names of units that are currently loaded, and it can be more than the amount of actually loaded units, since units may have more than one name. ๐Ÿคฏ

NJobs encodes how many jobs are currently queued. ๐Ÿ“‹

NInstalledJobs encodes how many jobs have ever been queued in total. ๐Ÿ”ข

NFailedJobs encodes how many jobs have ever failed in total. ๐Ÿ˜ฌ

TransactionsWithOrderingCycle encodes IDs of transactions that encountered an ordering cycle. ๐Ÿ”„

Progress encodes boot progress as a floating point value between 0.0 and 1.0. This value begins at 0.0 at early-boot and ends at 1.0 when boot is finished, and it's based on the number of executed and queued jobs. After startup, this field is always 1.0, indicating a finished boot. ๐ŸŒˆ

Environment encodes the environment block passed to all executed services. It may be altered with bus calls such as SetEnvironment() (see above). ๐ŸŒธ

ShowStatus encodes systemd's current policy for displaying status messages during bootup and shutdown. Its value can be any valid value for the systemd.show_status kernel parameter (see systemd(1)). It may be altered using SetShowStatus() (see above). ๐Ÿ‘‘

UnitPath encodes the currently active unit file search path. It's an array of file system paths encoded as strings. ๐Ÿ—‚๏ธ

SoftRebootsCount encodes how many soft-reboots were successfully completed since the last full boot. Starts at "0". ๐Ÿ”

KExecCount encodes how many kexec-based live updates were successfully completed since the last full boot. Starts at "0". The counter is preserved across the kexec through the Live Update Orchestrator (LUO), and is hence "0" when the kernel does not provide LUO support. ๐Ÿš€

ReloadCount encodes the number of successfully completed configuration reloads of the manager. The counter is reset to "0" on daemon-reexec and on the initial boot. โ™ป๏ธ

Virtualization contains a short ID string describing the virtualization technology the system runs in. On bare-metal hardware this is the empty string. Otherwise it contains an identifier such as "kvm", "vmware" and so on. For a full list of IDs see systemd-detect-virt(1). Note that only the innermost virtualization technology is exported here. This detects both full-machine virtualizations (VMs) and shared-kernel virtualization (containers). ๐Ÿ–ฅ๏ธ

ConfidentialVirtualization contains a short ID string describing the confidential virtualization technology the system runs in. On bare-metal hardware this is the empty string. Otherwise it contains an identifier such as "sev", "sev-es", "sev-snp", "tdx" and so on. For a full list of IDs see systemd-detect-virt(1) . ๐Ÿ”

Architecture contains a short ID string describing the architecture the systemd instance is running on. This follows the same vocabulary as ConditionArchitectures=. ๐Ÿง 

ControlGroup contains the root control group path of this system manager. Note that the root path is encoded as the empty string here (not as "/"!), so that it can be appended to /sys/fs/cgroup/systemd easily. This value will be set to the empty string for the host instance and some other string for container instances. ๐Ÿซถ

AccessSELinuxContext contains the SELinux context that is used to control access to the unit. It's read from the unit file when it is loaded, and cached until the service manager is reloaded. This property contains an empty string if SELinux is not used, or if no label could be read (for example because the unit is not backed by a file on disk). ๐Ÿท๏ธ

SystemState contains the current state of the system manager. The possible values are:

  • "initializing" โ€” the system is booting, and basic.target has not been reached yet. ๐ŸŒฑ
  • "starting" โ€” the system is booting, and basic.target has been reached. โœจ
  • "running" โ€” the system has finished booting, and no units are in the failed state. ๐ŸŽ‰
  • "degraded" โ€” the system has finished booting, but some units are in the failed state. ๐Ÿ˜ญ
  • "maintenance" โ€” the system has finished booting, but it has been put in rescue or maintenance mode. ๐Ÿ› ๏ธ
  • "stopping" โ€” the system is shutting down. ๐Ÿ’ค

๐Ÿ’– Security ๐Ÿ’–

Read access is generally granted to all clients. ๐Ÿซถ Additionally, for unprivileged clients, some operations are allowed through the polkit privilege system. Here's the whole vibe check, bestie:

  • Operations which modify unit state โ€” StartUnit(), StopUnit(), KillUnit(), KillUnitSubgroup(), QueueSignalUnit(), RestartUnit() and similar, plus SetUnitProperties() โ€” require org.freedesktop.systemd1.manage-units. ๐Ÿ”ฅ
  • Operations which modify unit file enablement state โ€” EnableUnitFiles(), DisableUnitFiles(), EnableUnitFilesWithFlags(), DisableUnitFilesWithFlags(), ReenableUnitFiles(), LinkUnitFiles(), PresetUnitFiles(), MaskUnitFiles(), and similar โ€” require org.freedesktop.systemd1.manage-unit-files. ๐Ÿ“
  • Operations which modify the exported environment โ€” SetEnvironment(), UnsetEnvironment(), UnsetAndSetEnvironment() โ€” require org.freedesktop.systemd1.set-environment. ๐ŸŒ
  • Reload() and Reexecute() require org.freedesktop.systemd1.reload-daemon. ๐Ÿ”„
  • Operations which dump internal state require org.freedesktop.systemd1.bypass-dump-ratelimit to avoid rate limits. ๐Ÿšฆ
ngl if you're hitting the polkit wall and wondering why your call got denied โ€” it's probably one of these. iykyk ๐Ÿ’…

๐Ÿฆ‹ UNIT OBJECTS ๐Ÿฆ‹

okay so now we get to the actual units, bestie. like every single unit on your system gets its own little D-Bus node, and here's what one of them looks like. the example systemd ships is avahi_2ddaemon_2eservice, which is avahi-daemon.service with the escaping applied (- becomes _2d, . becomes _2e โ€” that's just how D-Bus path names roll, iykyk ๐Ÿ’…).

so the node path is:

node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
  interface org.freedesktop.systemd1.Unit {
    methods:
      Start(in  s mode,
            out o job);
      Stop(in  s mode,
           out o job);
      Reload(in  s mode,
             out o job);
      Restart(in  s mode,
              out o job);
      TryRestart(in  s mode,
                 out o job);
      ReloadOrRestart(in  s mode,
                      out o job);
      ReloadOrTryRestart(in  s mode,
                         out o job);
      EnqueueJob(in  s job_type,
                 in  s job_mode,
                 out u job_id,
                 out o job_path,
                 out s unit_id,
                 out o unit_path,
                 out s job_type,
                 out a(uosos) affected_jobs);
      Kill(in  s whom,
           in  i signal);
      KillSubgroup(in  s subgroup,
                   in  i signal);
      QueueSignal(in  s whom,
                  in  i signal,
                  in  i value);
      ResetFailed();
      SetProperties(in  b runtime,
                    in  a(sv) properties);
      Ref();
      Unref();
      Clean(in  as mask);
      Freeze();
      Thaw();
    properties:
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Id = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Names = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s Following = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Requires = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Requisite = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Wants = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as BindsTo = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as PartOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Upholds = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as RequiredBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as RequisiteOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as WantedBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as BoundBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as UpheldBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as ConsistsOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Conflicts = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as ConflictedBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Before = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as After = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as OnSuccess = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as OnSuccessOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as OnFailure = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as OnFailureOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Triggers = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as TriggeredBy = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as PropagatesReloadTo = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as ReloadPropagatedFrom = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as PropagatesStopTo = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as StopPropagatedFrom = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as JoinsNamespaceOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as SliceOf = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as RequiresMountsFor = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as WantsMountsFor = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Documentation = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Description = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s AccessSELinuxContext = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s LoadState = '...';
      readonly s ActiveState = '...';
      readonly s FreezerState = '...';
      readonly s SubState = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s FragmentPath = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SourcePath = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as DropInPaths = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s UnitFileState = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s UnitFilePreset = '...';
      readonly t StateChangeTimestamp = ...;
      readonly t StateChangeTimestampMonotonic = ...;
      readonly t InactiveExitTimestamp = ...;
      readonly t InactiveExitTimestampMonotonic = ...;
      readonly t ActiveEnterTimestamp = ...;
      readonly t ActiveEnterTimestampMonotonic = ...;
      readonly t ActiveExitTimestamp = ...;
      readonly t ActiveExitTimestampMonotonic = ...;
      readonly t InactiveEnterTimestamp = ...;
      readonly t InactiveEnterTimestampMonotonic = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanStart = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanStop = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanReload = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanIsolate = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as CanClean = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanFreeze = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b CanLiveMount = ...;
      readonly (uo) Job = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b StopWhenUnneeded = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b RefuseManualStart = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b RefuseManualStop = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b AllowIsolate = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b DefaultDependencies = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b SurviveFinalKillSignal = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s OnSuccessJobMode = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s OnFailureJobMode = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b IgnoreOnIsolate = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b NeedDaemonReload = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as Markers = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t JobTimeoutUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t JobRunningTimeoutUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s JobTimeoutAction = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s JobTimeoutRebootArgument = '...';
      readonly b ConditionResult = ...;
      readonly b AssertResult = ...;
      readonly t ConditionTimestamp = ...;
      readonly t ConditionTimestampMonotonic = ...;
      readonly t AssertTimestamp = ...;
      readonly t AssertTimestampMonotonic = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sbbsi) Conditions = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sbbsi) Asserts = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly (ss) LoadError = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Transient = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Perpetual = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t StartLimitIntervalUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u StartLimitBurst = ...;

๐Ÿซถ the methods, real quick

so the org.freedesktop.systemd1.Unit interface hands you these, in this exact order:

  • Start(in s mode, out o job)
  • Stop(in s mode, out o job)
  • Reload(in s mode, out o job)
  • Restart(in s mode, out o job)
  • TryRestart(in s mode, out o job)
  • ReloadOrRestart(in s mode, out o job)
  • ReloadOrTryRestart(in s mode, out o job)
  • EnqueueJob(in s job_type, in s job_mode, out u job_id, out o job_path, out s unit_id, out o unit_path, out s job_type, out a(uosos) affected_jobs)
  • Kill(in s whom, in i signal)
  • KillSubgroup(in s subgroup, in i signal)
  • QueueSignal(in s whom, in i signal, in i value)
  • ResetFailed()
  • SetProperties(in b runtime, in a(sv) properties)
  • Ref()
  • Unref()
  • Clean(in as mask)
  • Freeze()
  • Thaw()

notice basically every state-changing one returns an o (object path) called job โ€” that's your job object, your receipt, your little tracker for "yeah bestie, that's in flight". โœจ and EnqueueJob is the extra one that hands you the whole situation: job_id, job_path, unit_id, unit_path, job_type, plus affected_jobs as an array of (uosos) tuples. that's a whole meal. ๐Ÿ“

๐Ÿ’œ the properties, all of them

there's like, a lot, so let's vibe through the categories โ€” every single name stays exactly as-is, no cap:

  • identity + naming: Id, Names, Following, Description, AccessSELinuxContext, Documentation
  • the dependency web (the way that everything connects to everything ๐Ÿ˜ญ): Requires, Requisite, Wants, BindsTo, PartOf, Upholds, RequiredBy, RequisiteOf, WantedBy, BoundBy, UpheldBy, ConsistsOf, Conflicts, ConflictedBy, Before, After, OnSuccess, OnSuccessOf, OnFailure, OnFailureOf, Triggers, TriggeredBy, PropagatesReloadTo, ReloadPropagatedFrom, PropagatesStopTo, StopPropagatedFrom, JoinsNamespaceOf, SliceOf, RequiresMountsFor, WantsMountsFor
  • where it lives on disk: FragmentPath, SourcePath, DropInPaths, UnitFileState, UnitFilePreset
  • what state it's in rn: LoadState, ActiveState, FreezerState, SubState, Job
  • when stuff happened (monotonic twin for each, always): StateChangeTimestamp, StateChangeTimestampMonotonic, InactiveExitTimestamp, InactiveExitTimestampMonotonic, ActiveEnterTimestamp, ActiveEnterTimestampMonotonic, ActiveExitTimestamp, ActiveExitTimestampMonotonic, InactiveEnterTimestamp, InactiveEnterTimestampMonotonic
  • permissions / capabilities flags: CanStart, CanStop, CanReload, CanIsolate, CanClean, CanFreeze, CanLiveMount, StopWhenUnneeded, RefuseManualStart, RefuseManualStop, AllowIsolate, DefaultDependencies, SurviveFinalKillSignal, IgnoreOnIsolate, OnSuccessJobMode, OnFailureJobMode
  • timeouts + start limiting: JobTimeoutUSec, JobRunningTimeoutUSec, JobTimeoutAction, JobTimeoutRebootArgument, StartLimitIntervalUSec, StartLimitBurst
  • conditions & asserts (the "should I even run tho" club): ConditionResult, AssertResult, ConditionTimestamp, ConditionTimestampMonotonic, AssertTimestamp, AssertTimestampMonotonic, Conditions, Asserts
  • misc slay: NeedDaemonReload, Markers, LoadError, Transient, Perpetual
heads up bestie โ€” the @org.freedesktop.DBus.Property.EmitsChangedSignal(...) line above each property is literally the vibe check on whether D-Bus pings you when it changes. "const" = never changes, "false" = changes but no signal, "invalidates" = it'll tell you the whole thing is stale. those annotations are in the code block verbatim, don't skip 'em. ๐ŸŽ€

also notice Conditions is typed a(sbbsi) and Asserts is typed a(sbbsi) too, and Job is a (uo) tuple โ€” u for the id, o for the path. iconic. ๐Ÿ‘‘

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StartLimitAction = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s FailureAction = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FailureActionExitStatus = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s SuccessAction = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SuccessActionExitStatus = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RebootArgument = '...';
                 readonly ay InvocationID = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s CollectMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as Refs = ['...', ...];
                 readonly a(ss) ActivationDetails = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b DebugInvocation = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
           };

Methods ๐Ÿ’…

okay bestie, so Start(), Stop(), Reload(), Restart(), TryRestart(), ReloadOrRestart(), ReloadOrTryRestart(), Kill(), KillSubgroup(), QueueSignal(), ResetFailed(), and SetProperties() do the exact same operation as the respective methods on the Manager object (scroll up, bestie). But these ones operate on the unit object itself, so they don't take a unit name parameter. Invoking the methods directly on the Manager object is a whole vibe because it means you don't need a GetUnit() call to get the unit object for a specific unit name. Calling them on the Manager is therefore a round trip optimization. periodt. ๐Ÿ’…

Properties ๐ŸŽ€

  • Id โ€” contains the primary name of the unit. main character identifier, honestly.
  • Names โ€” contains all names of the unit, including the primary name that is also exposed in Id. so it's giving full government name plus nicknames.
  • Following โ€” either contains the empty string or contains the name of another unit that this unit follows in state. This is used for some device units which reflect the unit state machine of another unit, and which other unit this is might possibly change. lowkey mysterious.
  • Requires, RequiresOverridable, Requisite, RequisiteOverridable, Wants, BindsTo, RequiredBy, RequiredByOverridable, WantedBy, BoundBy, Conflicts, ConflictedBy, Before, After, OnFailure, Triggers, TriggeredBy, PropagatesReloadTo, and RequiresMountsFor โ€” contain arrays which encode the dependencies and their inverse dependencies (where this applies) as configured in the unit file or determined automatically. the friend group drama, but for units.
  • Description โ€” contains the human-readable description string for the unit. cute little summary.
  • SourcePath โ€” contains the path to a configuration file this unit is automatically generated from in case it is not a native unit (in which case it contains the empty string). For example, all mount units generated from /etc/fstab have this field set to /etc/fstab. so it's like the origin story.
  • Documentation โ€” contains a string array with URLs of documentation for this unit. links to the lore.
  • LoadState โ€” contains a state value that reflects whether the configuration file of this unit has been loaded. The following states are currently defined: "loaded", "error", and "masked". "loaded" indicates that the configuration was successfully loaded. "error" indicates that the configuration failed to load. The LoadError field (see below) contains information about the cause of this failure. "masked" indicates that the unit is currently masked out (i.e. symlinked to /dev/null or empty). Note that the LoadState is fully orthogonal to the ActiveState (see below) as units without valid loaded configuration might be active (because configuration might have been reloaded at a time where a unit was already active). no cap, they're independent.
  • ActiveState โ€” contains a state value that reflects whether the unit is currently active or not. The following states are currently defined:

Table 1. Unit ACTIVE states

  • active โ€” Started, bound, plugged in, ..., depending on the unit type.
  • inactive โ€” Stopped, unbound, unplugged, ..., depending on the unit type.
  • failed โ€” Similar to inactive, but the unit failed in some way (process returned error code on exit, crashed, an operation timed out, or after too many restarts).
  • activating โ€” Changing from inactive to active.
  • deactivating โ€” Changing from active to inactive.
  • maintenance โ€” Unit is inactive and a maintenance operation is in progress.
  • reloading โ€” Unit is active and it is reloading its configuration.
  • refreshing โ€” Unit is active and a new mount is being activated in its namespace.
  • SubState โ€” encodes states of the same state machine that ActiveState covers, but knows more fine-grained states that are unit-type-specific. Where ActiveState only covers eight high-level states, SubState covers possibly many more low-level unit-type-specific states that are mapped to the eight high-level states. Note that multiple low-level states might map to the same high-level state, but not vice versa. Not all high-level states have low-level counterparts on all unit types. At this point the low-level states are not documented here, and are more likely to be extended later on than the common high-level states explained above. so it's the director's cut.
  • FragmentPath โ€” contains the unit file path this unit was read from, if there is one (if not, it contains the empty string). where it lives.
  • UnitFileState โ€” encodes the install state of the unit file of FragmentPath. It currently knows the following states: "enabled", "enabled-runtime", "linked", "linked-runtime", "masked", "masked-runtime", "static", "disabled", and "invalid". "enabled" indicates that a unit file is permanently enabled. "enable-runtime" indicates the unit file is only temporarily enabled and will no longer be enabled after a reboot (that means, it is enabled via /run/ symlinks, rather than /etc/). "linked" indicates that a unit is linked into /etc/ permanently. "linked-runtime" indicates that a unit is linked into /run/ temporarily (until the next reboot). "masked" indicates that the unit file is masked permanently. "masked-runtime" indicates that it is masked in /run/ temporarily (until the next reboot). "static" indicates that the unit is statically enabled, i.e. always enabled and does not need to be enabled explicitly. "invalid" indicates that it could not be determined whether the unit file is enabled. (yes, the list says "enabled-runtime" and the description says "enable-runtime" โ€” we don't make the rules, we just report them ๐Ÿ’€)
  • InactiveExitTimestamp, InactiveExitTimestampMonotonic, ActiveEnterTimestamp, ActiveEnterTimestampMonotonic, ActiveExitTimestamp, ActiveExitTimestampMonotonic, InactiveEnterTimestamp, and InactiveEnterTimestampMonotonic โ€” contain CLOCK_REALTIME and CLOCK_MONOTONIC 64-bit microsecond timestamps of the last time a unit left the inactive state, entered the active state, exited the active state, or entered an inactive state. These are the points in time where the unit transitioned "inactive"/"failed" โ†’ "activating", "activating" โ†’ "active", "active" โ†’ "deactivating", and finally "deactivating" โ†’ "inactive"/"failed". The fields are 0 in case such a transition has not yet been recorded on this boot. timestamp receipts.
  • CanStart, CanStop, and CanReload โ€” encode as booleans whether the unit supports the start, stop or reload operations. Even if a unit supports such an operation, the client might not have the necessary privileges to execute them. so capability โ‰  permission, bestie.
  • CanIsolate โ€” encodes as a boolean whether the unit may be started in isolation mode.
  • Job โ€” encodes the job ID and job object path of the job currently scheduled or executed for this unit, if there is any. If no job is scheduled or executed, the job id field will be 0. no job, no id.
  • StopWhenUnneeded, RefuseManualStart, RefuseManualStop, AllowIsolate, DefaultDependencies, OnFailureIsolate, IgnoreOnIsolate, IgnoreOnSnapshot โ€” map directly to the corresponding configuration booleans in the unit file. straight up copy-paste from config.
  • NeedDaemonReload โ€” is a boolean that indicates whether the configuration file this unit is loaded from (i.e. FragmentPath or SourcePath) has changed since the configuration was read and hence whether a configuration reload is recommended. so if this is true, maybe go reload, bestie.
  • Markers โ€” an array of string flags, settable with SetUnitProperties(), that's basically your unit waving a lil hand going "hey bestie i need a reload / restart ๐Ÿฅบ". The currently known values are "needs-restart", "needs-stop", "needs-start" and "needs-reload". Package scripts can use the first three to mark units for a later restart, start, or stop when a new version of the package gets installed or yeeted out. Configuration management scripts can use the fourth to mark units for a later reload when the config gets tweaked. Those flags are not set by the manager itself โ€” the manager only ever unsets them, and only when it's appropriate, i.e. when the unit is stopped, restarted, or reloaded. When markers are set, they get normalized according to these precedence rules, which are modeled after the job type merging logic. And when new markers are applied incrementally (with the "+" prefix), conflicting existing markers get cleared before the new ones merge in:
  • "needs-reload" loses against literally everything else. If any of "needs-restart", "needs-start", or "needs-stop" is set, "needs-reload" gets cleared. ๐Ÿ’€
  • "needs-stop" wins against "needs-restart" and "needs-reload", clearing both of them.
  • "needs-start" wins against "needs-stop", clearing it.
  • "needs-restart" wins against "needs-start". If both are set, "needs-start" gets cleared.

So for example, if a unit currently has "needs-stop" set and a new "+needs-start" marker gets applied, the existing "needs-stop" is cleared and only "needs-start" remains. Conversely, applying "+needs-stop" to any existing marker will clear all other markers โ€” because "needs-stop" takes precedence over "needs-restart" and "needs-reload", and the new marker clears conflicting existing ones. It's giving "there can only be one" ๐Ÿ‘‘.

  • JobTimeoutUSec โ€” maps directly to the corresponding configuration setting in the unit file. no cap, no middleman โœจ
  • ConditionTimestamp and ConditionTimestampMonotonic โ€” hold the CLOCK_REALTIME/CLOCK_MONOTONIC microsecond timestamps of the last time the configured conditions of the unit were checked, or 0 if they've literally never been checked. Conditions get checked when a unit is requested to start.
  • ConditionResult โ€” the condition result from the last time the configured conditions of this unit were checked.
  • Conditions โ€” all the configured conditions of the unit. For each condition, five fields are given: the condition type (e.g. ConditionPathExists), whether the condition is a trigger condition, whether the condition is reversed, the right hand side of the condition (e.g. the path in the case of ConditionPathExists), and the status. The status can be 0, in which case the condition hasn't been checked yet; a positive value, in which case the condition passed; or a negative value, in which case the condition is not met. Currently only 0, +1, and -1 are used, but additional values may show up in the future โ€” they'll keep the whole zero/positive/negative meaning though, so don't panic ๐Ÿซถ.
  • LoadError โ€” a pair of strings. If the unit failed to load (as encoded in LoadState, see above), this will include a D-Bus error pair: the error ID plus an explanatory human-readable string of what happened. If it loaded successfully, it's a pair of empty strings. no drama ๐Ÿ’…
  • Transient โ€” a boolean that tells you whether the unit was created as a transient unit (i.e. via StartTransientUnit() on the manager object).
  • ActivationDetails โ€” a list of string pairs, key and value, describing the event that caused the unit to be activated, if any. The key describes the information (e.g.: trigger_unit, with value foo.service). This is only filled in if the unit was triggered by a Path or Timer unit, and it's only provided in a best-effort fashion: it's not guaranteed to be set, and it's not guaranteed to be the only trigger. The only thing guaranteed is that it's a valid trigger that caused the activation job to be enqueued and complete successfully. The key value pairs correspond (in lowercase) to the environment variables described in the "Environment Variables Set or Propagated by the Service Manager" section in systemd.exec(5). Heads up bestie: new key value pairs may be added at any time in future versions โ€” but existing entries will not be removed, promise ๐Ÿคž.
  • DebugInvocation โ€” a boolean that flips to true when the unit is restarted with the log level set to debug due to an earlier failure, and flips back to false when either the unit successfully starts or the restart rate limit is reached. See the "RestartMode=" section in systemd.service(5) for more details. she's dramatic but she's consistent ๐Ÿ’…
  • OOMKills โ€” holds a different value depending on whether OOMPolicy=kill is enabled for the unit or not. If it's enabled, the property contains the number of times the kernel OOM killer killed all the processes in the unit's cgroup and its descendant cgroups. If it's disabled, the property contains the number of processes the kernel OOM killer has killed in the unit's cgroup and its descendant cgroups. And when the corresponding cgroups haven't been realized, it reports 18446744073709551615 (2^64 - 1) โ€” yeah, that's the big scary number, that's on purpose ๐Ÿ˜ญ.
  • ManagedOOMKills โ€” the number of times systemd-oomd killed all the processes in the unit's cgroup and its descendant cgroups. When the corresponding cgroups haven't been realized yet, it reports 18446744073709551615 (2^64 - 1). same energy, different killer ๐Ÿฉธ

๐Ÿ”’ Security ๐Ÿ”’

Same deal as the methods on the Manager object: read-only access is allowed for everyone. All operations are allowed for clients when the org.freedesktop.systemd1.manage-units privilege is granted by polkit. iykyk ๐ŸŽ€


๐ŸŒˆ SERVICE UNIT OBJECTS ๐ŸŒˆ

All service unit objects implement the org.freedesktop.systemd1.Service interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). two interfaces, one unit, main character energy fr fr ๐Ÿ’–

okay bestie, we're deep in the introspection dump now โ€” this is the raw XML that systemd hands you when you ask the bus "so what does this thing even look like?", and we're looking at one specific node. Say hi to:

           node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
             interface org.freedesktop.systemd1.Service {
               methods:
                 BindMount(in  s source,
                           in  s destination,
                           in  b read_only,
                           in  b mkdir);
                 MountImage(in  s source,
                            in  s destination,
                            in  b read_only,
                            in  b mkdir,
                            in  a(ss) options);
                 DumpFileDescriptorStore(out a(suuutuusu) entries);
                 GetProcesses(out a(sus) processes);
                 AttachProcesses(in  s subcgroup,
                                 in  au pids);
                 RemoveSubgroup(in  s subcgroup,
                                in  t flags);
               properties:

no cap, that node name is the escaped/mangled one โ€” avahi_2ddaemon_2eservice, you know the drill, that's just the unit name wearing a disguise so it can live in a bus path. ๐Ÿ™ˆ And look at those six methods: BindMount(), MountImage(), DumpFileDescriptorStore(), GetProcesses(), AttachProcesses(), RemoveSubgroup(). Six little entry points and every one of them keeps its argument types exactly as written โ€” in s, in b, in a(ss), out a(suuutuusu), out a(sus), in au, in t. Do not come for the signatures, they are perfect as-is. ๐Ÿ’…

then the property parade starts, and the first thing you clock is the annotation sitting on top of basically everything:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Type = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ExitType = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Restart = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RestartMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PIDFile = '...';
                 readonly s NotifyAccess = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestartUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u RestartSteps = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestartMaxDelayUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestartRandomizedDelayUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t RestartUSecNext = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutStartUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutStopUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TimeoutAbortUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s TimeoutStartFailureMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s TimeoutStopFailureMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RuntimeMaxUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RuntimeRandomizedExtraUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t WatchdogUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t WatchdogTimestamp = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t WatchdogTimestampMonotonic = ...;

not me counting the t-typed microsecond properties like it's a hobby. ๐Ÿ˜ญ The way that NotifyAccess is sitting there all alone with no annotation above it โ€” yeah bestie, it's giving "I get to be different", iconic behaviour, we love a main character property. โœจ

And the vibe check on the annotations themselves: some get stamped "const", some get stamped "false", and which one you get is literally the โœจtellโœจ โ€” just look at the pairs. RestartUSec is const, but its next-door neighbour RestartUSecNext is false. TimeoutStartUSec and TimeoutStopUSec are const, TimeoutAbortUSec is false. WatchdogUSec, WatchdogTimestamp and WatchdogTimestampMonotonic are all false, all three, no crumbs. ๐Ÿฆ‹

moving on, the booleans and the little status crew arrive:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RootDirectoryStartOnly = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RemainAfterExit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b GuessMainPID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (aiai) RestartPreventExitStatus = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (aiai) RestartForceExitStatus = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (aiai) SuccessExitStatus = ...;
                 readonly u MainPID = ...;
                 readonly u ControlPID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BusName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u FileDescriptorStoreMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u NFileDescriptorStore = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s FileDescriptorStorePreserve = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as LUOSession = ['...', ...];
                 readonly s StatusText = '...';
                 readonly i StatusErrno = ...;
                 readonly s StatusBusError = '...';
                 readonly s StatusVarlinkError = '...';
                 readonly s Result = '...';
                 readonly s ReloadResult = '...';
                 readonly s CleanResult = '...';
                 readonly s LiveMountResult = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s USBFunctionDescriptors = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s USBFunctionStrings = '...';
                 readonly u UID = ...;
                 readonly u GID = ...;
                 readonly u NRestarts = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s OOMPolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) OpenFile = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExtraFileDescriptorNames = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i ReloadSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as RefreshOnReload = ['...', ...];

the un-annotated girlies are back: NotifyAccess had company now โ€” MainPID, ControlPID, StatusText, StatusErrno, StatusBusError, StatusVarlinkError, Result, ReloadResult, CleanResult, LiveMountResult, UID, GID, NRestarts. All just vibing with no EmitsChangedSignal at all. we respect the quiet ones ๐Ÿซถ

Also note the shapes, because they are not all the same and I will not let you pretend they are: (aiai) for RestartPreventExitStatus, RestartForceExitStatus and SuccessExitStatus. as for LUOSession, ExtraFileDescriptorNames and RefreshOnReload โ€” those show up as ['...', ...]. a(sst) for OpenFile which shows as [...]. i for ReloadSignal, s for the string-y ones, u for MainPID, ControlPID, FileDescriptorStoreMax, NFileDescriptorStore, UID, GID and NRestarts, b for the three booleans. exact types, always. ๐ŸŽ€

then the timestamps and the exit bookkeeping, aka the "what even happened" department:

                 readonly t ExecMainStartTimestamp = ...;
                 readonly t ExecMainStartTimestampMonotonic = ...;
                 readonly t ExecMainExitTimestamp = ...;
                 readonly t ExecMainExitTimestampMonotonic = ...;
                 readonly t ExecMainHandoffTimestamp = ...;
                 readonly t ExecMainHandoffTimestampMonotonic = ...;
                 readonly u ExecMainPID = ...;
                 readonly i ExecMainCode = ...;
                 readonly i ExecMainStatus = ...;

start, exit, handoff โ€” each one twice, once plain and once monotonic, because of course. ๐Ÿ’€ And then ExecMainPID (u), ExecMainCode (i), ExecMainStatus (i). no annotation on any of them. they're just out here reporting. ๐Ÿ‘‘

and now the big one, the Exec* families, and heads up because every single one of these carries EmitsChangedSignal("invalidates") โ€” not const, not false, invalidates:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecCondition = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecConditionEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecStartPre = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecStartPreEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecStart = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecStartEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecStartPost = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecStartPostEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecReload = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecReloadEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecReloadPost = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecReloadPostEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecStop = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecStopEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecStopPost = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasasttttuii) ExecStopPostEx = [...];

the way that it's every command slot twice โ€” the plain flavour a(sasbttttuii) and the Ex flavour a(sasasttttuii) โ€” for Condition, StartPre, Start, StartPost, Reload, ReloadPost, Stop, StopPost. Sixteen properties. sixteen. ๐ŸŒˆ iykyk. and yes, ExecReloadPost and ExecReloadPostEx are really in there, they're not a typo, don't @ me. ๐Ÿงš

and then we slide into the runtime/cgroup stats, all of them stamped "false":

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s Slice = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ControlGroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ControlGroupId = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryAvailable = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUUsageNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveTasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

all the memory โ€” MemoryCurrent, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, MemoryZSwapCurrent, MemoryAvailable, EffectiveMemoryMax, EffectiveMemoryHigh. the way that ZSwap really said "I'm here too bestie". ๐Ÿ˜ญ then CPU: CPUUsageNSec, plus the two ay byte-array ones EffectiveCPUs and EffectiveMemoryNodes showing as [...]. then task counts TasksCurrent and EffectiveTasksMax. then the network four: IPIngressBytes, IPIngressPackets, IPEgressBytes, IPEgressPackets. all t, all "false", all eating. ๐Ÿ”ฅ

and bestie look at the very last line โ€” there's an @org.freedesktop.DBus.Property.EmitsChangedSignal("false") just sitting there with no property under it. that's not a bug in my typing, that's genuinely where this chunk stops. ๐Ÿ˜ญ cliffhanger. the annotation is dangling, waiting for its property, and honestly? same energy. the Service interface has more to say and we are so not done here. ๐Ÿฆ‹

okay so the property list just keeps going and honestly? respect the commitment. ๐Ÿ’… we're still deep in the Unit interface, so let's keep scrolling through the interface definition together โ€” same energy, same annotations, no skipping.

                 readonly t IOReadBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t OOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b Delegate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DelegateControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DelegateSubgroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupCPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPerSecUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPeriodUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUSetPartition = '...';

see how every single one of these carries that @org.freedesktop.DBus.Property.EmitsChangedSignal("false") annotation? yeah. it's the whole vibe of this stretch โ€” and notice how the Startup* twins keep showing up next to their non-Startup besties like matching outfits. ๐ŸŽ€ the symmetry? obsessed.


now the I/O and memory control block, and bestie, it is long. a(st) all over the place, a(st) my beloved. ๐Ÿฆ‹

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupIOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceWeight = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceLatencyTargetUSec = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMin = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryZSwapWriteback = ...;

MemoryMin โ†’ MemoryLow โ†’ MemoryHigh โ†’ MemoryMax?? it's giving a whole little ladder of intensity and i for one am here for it. ๐Ÿ™ˆ


devices, tasks, and the networking block โ€” this is where the a(iayu) girlies live. ๐Ÿ’…โœจ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DevicePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) DeviceAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b TasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPIngressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPEgressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DisableControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMSwap = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMMemoryPressure = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ManagedOOMMemoryPressureLimit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMMemoryPressureDurationUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMPreference = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as OOMRules = ['...', ...];

IPAddressAllow and IPAddressDeny sitting right next to each other, both typed a(iayu)... it's giving "we're a matched set and we know it". ๐Ÿ˜ญ also OOMKills and ManagedOOMKills from earlier said hi, they're all part of the same OOM saga, iykyk.


BPF, socket binds, network interfaces, and then the pressure watch trio. this chunk has range. ๐ŸŒˆ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;

okay but the MemoryPressureWatch / CPUPressureWatch / IOPressureWatch triple with their matching *ThresholdUSec partners?? iconic naming, no notes. ๐Ÿ’š


and NOW. the annotation changes. ๐Ÿ‘€ every property so far was "false", but from here on out it's "const", starting with the environment block and then an absolute wall of resource limits. buckle up bestie, this is the finale of the part. ๐Ÿ”ฅ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as Environment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sb) EnvironmentFiles = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as PassEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as UnsetEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u UMask = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPU = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPUSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATASoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitAS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitASSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROCSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

the Limit* + Limit*Soft pairs marching down the screen, all readonly t, all "const"... the way that it just keeps pairing up is so satisfying to my little gremlin brain. ๐Ÿงš and notice โ€” LimitMEMLOCK gets its annotation line and then we're cut off mid-list, because bestie, the limits list is NOT done. ๐Ÿซถ it literally keeps going.

heads up: this is exactly where the listing continues โ€” don't close the fence in your head, the next chunk picks up right after that trailing annotation. no cap. ๐Ÿ’–

okay bestie we are still in the property declarations and they just keep going, and honestly? iconic behaviour. every single one of these is readonly and carries that same @org.freedesktop.DBus.Property.EmitsChangedSignal("const") badge, so they're all in the same club. no skips, no shortcuts, here's the whole gang:

                 readonly t LimitMEMLOCKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDING = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDINGSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIO = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIOSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIME = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIMESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s WorkingDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImage = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) RootImageOptions = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHash = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHashSignature = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashSignaturePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootVerity = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RootEphemeral = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootMStack = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExtensionDirectories = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sba(ss)) ExtensionImages = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssba(ss)) MountImages = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i OOMScoreAdjust = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t CoredumpFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i Nice = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingClass = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay CPUAffinity = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUAffinityFromNUMA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i NUMAPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay NUMAMask = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimerSlackNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUSchedulingResetOnFork = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NonBlocking = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay StandardInputData = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardError = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardErrorFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s TTYPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYReset = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVHangup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVTDisallocate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYRows = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYColumns = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s SyslogIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SyslogLevelPrefix = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogLevel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogFacility = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i LogLevelMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LogRateLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogRateLimitBurst = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly aay LogExtraFields = [[...], ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(bs) LogFilterPatterns = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s LogNamespace = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SecureBits = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t CapabilityBoundingSet = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t AmbientCapabilities = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s User = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Group = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DynamicUser = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SetLoginEnvironment = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RemoveIPC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(say) SetCredential = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(say) SetCredentialEncrypted = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) LoadCredential = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) LoadCredentialEncrypted = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ImportCredential = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) ImportCredentialEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as SupplementaryGroups = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PAMName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ReadWritePaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ReadOnlyPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as InaccessiblePaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExecPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as NoExecPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExecSearchPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t MountFlags = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateTmp = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateTmpEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateDevices = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectClock = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectKernelTunables = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

so like, vibe check on what you just scrolled through ๐Ÿ’… these are all just the D-Bus mirror of the unit file settings, sorted into lil fams so your brain can breathe:

  • the resource-limit girlies โ€” LimitMEMLOCKSoft, LimitLOCKS, LimitLOCKSSoft, LimitSIGPENDING, LimitSIGPENDINGSoft, LimitMSGQUEUE, LimitMSGQUEUESoft, LimitNICE, LimitNICESoft, LimitRTPRIO, LimitRTPRIOSoft, LimitRTTIME, LimitRTTIMESoft
  • the filesystem / root / image besties โ€” WorkingDirectory, RootDirectory, RootImage, RootImageOptions, RootHash, RootHashPath, RootHashSignature, RootHashSignaturePath, RootVerity, RootEphemeral, RootMStack, ExtensionDirectories, ExtensionImages, MountImages
  • scheduling, OOM & NUMA era โ€” OOMScoreAdjust, CoredumpFilter, Nice, IOSchedulingClass, IOSchedulingPriority, CPUSchedulingPolicy, CPUSchedulingPriority, CPUAffinity, CPUAffinityFromNUMA, NUMAPolicy, NUMAMask, TimerSlackNSec, CPUSchedulingResetOnFork, NonBlocking
  • stdio & tty mains โ€” StandardInput, StandardInputFileDescriptorName, StandardInputData, StandardOutput, StandardOutputFileDescriptorName, StandardError, StandardErrorFileDescriptorName, TTYPath, TTYReset, TTYVHangup, TTYVTDisallocate, TTYRows, TTYColumns
  • logging (aka the receipts) ๐Ÿ“ โ€” SyslogPriority, SyslogIdentifier, SyslogLevelPrefix, SyslogLevel, SyslogFacility, LogLevelMax, LogRateLimitIntervalUSec, LogRateLimitBurst, LogExtraFields, LogFilterPatterns, LogNamespace
  • identity, creds & capabilities ๐ŸŽ€ โ€” SecureBits, CapabilityBoundingSet, AmbientCapabilities, User, Group, DynamicUser, SetLoginEnvironment, RemoveIPC, SetCredential, SetCredentialEncrypted, LoadCredential, LoadCredentialEncrypted, ImportCredential, ImportCredentialEx, SupplementaryGroups, PAMName
  • the sandbox / protection squad ๐Ÿ›ก๏ธ โ€” ReadWritePaths, ReadOnlyPaths, InaccessiblePaths, ExecPaths, NoExecPaths, ExecSearchPath, MountFlags, PrivateTmp, PrivateTmpEx, PrivateDevices, ProtectClock, ProtectKernelTunables

notice how the types are doing their own thing too โ€” t is the unsigned 64-bit one, i signed 32-bit, u unsigned 32-bit, q unsigned 16-bit, b boolean, s string, as array of strings, ay array of bytes, and then the spicy compound ones like a(ss), a(say), a(bs), a(sba(ss)), a(ssba(ss)) and aay for when a single value just wasn't enough โœจ copy them exactly if you're hand-rolling a call, bestie, because D-Bus will absolutely humble you if the signature is off by one character ๐Ÿ˜ญ

and fr fr, every one of these bad boys says EmitsChangedSignal("const"), so like the ones before it, it's the "this doesn't change after the unit's loaded" energy. no cap.

we are SO not done though, there's more coming ๐Ÿ‘‘

okay so bestie, we are still inside the big D-Bus property dump for the service unit โ€” and like, every single one of these is readonly, so they're set once and then they simply do not take feedback ๐Ÿ’…. Think permanent personality traits, not moods.

ngl the annotation for ProtectKernelModules got cut in half by the page break โ€” it lives at the very end of the last part. Same energy, promise. โœจ
                 readonly b ProtectKernelModules = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectKernelLogs = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectControlGroups = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectControlGroupsEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateNetwork = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateUsers = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateUsersEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateMounts = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateIPC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivatePIDs = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectHome = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectSystem = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SameProcessGroup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SELinuxContext = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) AppArmorProfile = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SmackProcessLabel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b IgnoreSIGPIPE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NoNewPrivileges = ...;

sandbox girlies rise up ๐ŸŽ€ โ€” that whole block is the containment clique: Protect*, Private*, and the MAC-label trio (SELinuxContext, AppArmorProfile, SmackProcessLabel) all chillin' with their (bs) struct shapes. And yeah, the -Ex variants are there too, being extra. slay.


next up, the syscall crew ๐Ÿงš โ€” filter, log, arch, error number, all of it, plus the personality situation:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as SystemCallArchitectures = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SystemCallErrorNumber = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallLog = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Personality = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LockPersonality = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictAddressFamilies = ...;

like, SystemCallArchitectures is the only as in that bunch โ€” everybody else is doing a struct or a plain scalar. not me noticing the little type differences ๐Ÿ‘€


then it's the directory-creation saga ๐Ÿ“ which is honestly so long it deserves its own little era. runtime, state, cache, logs, config โ€” each one gets a symlink array, a mode, and the state/cache/logs ones ALSO get an accounting flag and a quota struct:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) RuntimeDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RuntimeDirectoryPreserve = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u RuntimeDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as RuntimeDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) StateDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u StateDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b StateDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) StateDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as StateDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) CacheDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u CacheDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CacheDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) CacheDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as CacheDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) LogsDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogsDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LogsDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) LogsDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as LogsDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u ConfigurationDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ConfigurationDirectory = ['...', ...];

the way that ConfigurationDirectory is the only one without a Symlink, a Preserve, an Accounting, or a Quota... it's giving minimal effort and honestly, respect ๐Ÿซถ


and then, the hardening finale ๐Ÿ”ฅ โ€” cleanup timeouts, memory guards, namespace restrictions, the whole mount situation, keyrings, proc, hostname, BPF delegation, KSM, THP, and all the namespace paths:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutCleanUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryDenyWriteExecute = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictRealtime = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictSUIDSGID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestrictNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DelegateNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictFileSystems = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssbt) BindPaths = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssbt) BindReadOnlyPaths = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) TemporaryFileSystem = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MountAPIVFS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b BindLogSockets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KeyringMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectProc = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProcSubset = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectHostname = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (ss) ProtectHostnameEx = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateBPF = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateCommands = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateMaps = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegatePrograms = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateAttachments = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryKSM = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MemoryTHP = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UserNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s NetworkNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s IPCNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MountImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ExtensionImagePolicy = '...';

RestrictNamespaces and DelegateNamespaces are both t (that's the unsigned-64-bit one, iykyk) โ€” they're the bitmask besties ๐Ÿ’œ. And BindPaths/BindReadOnlyPaths share the exact same a(ssbt) shape, which is chef's kiss consistency.


๐Ÿšจ okay pause. these next three are the rebels of the whole list, because their annotation is "false" instead of "const":

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) StateDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) CacheDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) LogsDirectoryQuotaUsage = ...;

not them being the only ones breaking the "const" streak ๐Ÿ˜ญ the *Usage properties are lowkey the main characters here, fr fr.


and finally the kill/restart block ๐Ÿ’€ โ€” because every process needs a way out, and systemd is gonna pick it for you:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KillMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i KillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i RestartKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FinalKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGKILL = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGHUP = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i WatchdogSignal = ...;
             };

all the signal ones are i (signed 32-bit ints, since signals are just lil numbers โœจ) and then we hit the closing brace โ€” the property era is officially over, bestie.


and look at the little encore after it ๐ŸŽ€ โ€” four more interfaces get name-dropped, three of them being the D-Bus basics every object has to carry:

             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

org.freedesktop.DBus.Peer, org.freedesktop.DBus.Introspectable, org.freedesktop.DBus.Properties โ€” the trio that literally every object on the bus has to have, no exceptions, no cap. And then org.freedesktop.systemd1.Unit slides in at the end because, yeah, a service is a unit, the inheritance is giving iconic ๐Ÿ‘‘.

and that }; with all the extra indentation? that's the whole org.freedesktop.systemd1.Service interface shutting its door. periodt. but bestie we are NOT done โ€” there's more coming ๐Ÿ’–

โœจ Methods โœจ

  • BindMount() and MountImage() โ€” bestie, these do the exact same thing as the methods with the same names on the Manager object (scroll up, they're right there ๐Ÿ’…). The plot twist? These ones live on the service object itself, so they don't take a unit name parameter at all. Now, calling them on the Manager object instead has one lil perk: you skip the whole GetUnit() call just to grab the unit object for a specific unit name. So yeah, going through the Manager is basically a round trip optimization โ€” fewer laps around the bus, yk? ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ
  • DumpFileDescriptorStore() โ€” returns an array stuffed with info about all the file descriptors currently chilling in the service's file descriptor store. Each entry is giving:
    • the file descriptor name (that's the FDNAME= field),
    • the file descriptor inode type and access mode as an integer (a mode_t value, so flags like S_IFREG, S_IRUSR, โ€ฆ),
    • the major and minor numbers of the device number of the file system backing the inode of the file descriptor,
    • the inode number,
    • the major and minor numbers of the device number if this refers to a character or block device node,
    • a file system path pointing to the inode,
    • and the file descriptor flags (you know, O_RDWR, O_RDONLY, โ€ฆ).

๐Ÿ’… Properties ๐Ÿ’…

Okay so most properties on the Service interface map directly to the corresponding settings in service unit files. No notes, no drama, 1:1, periodt. So for the sake of brevity, here's the list of all the exceptions only ๐Ÿ‘‘:

  • TimeoutStartUSec, TimeoutStopUSec and TimeoutAbortUSec โ€” these hold the start, stop and abort timeouts, in microseconds. And ngl, peep the slight naming difference compared to the matching unit file settings (see systemd.service(5)): these bus properties strictly use microseconds (hence the ...USec suffix) while the unit file settings default to a time unit of seconds (hence ...Sec), unless a different unit is explicitly specified. Why tho? Because internally the service manager deals in microsecond units only, and the bus properties are a relatively low-level (binary) concept exposing exactly that. The unit file settings, on the other hand, are relatively high-level (string-based) concepts, so they support more user-friendly time specifications that default to second time units but allow other units too, if you specify them. Iconic layering tbh ๐ŸŒˆ
  • WatchdogTimestamp and WatchdogTimestampMonotonic โ€” these contain CLOCK_REALTIME/CLOCK_MONOTONIC microsecond timestamps of the last watchdog ping received from the service, or 0 if none was ever received. No ping, no timestamp, that simple ๐Ÿ’€
  • ExecStartPre, ExecStart, ExecStartPost, ExecReload, ExecReloadPost, ExecStop, and ExecStopPost โ€” arrays of structures, and each struct contains:
    • the binary path to execute;
    • an array with all arguments to pass to the executed command, starting with argument 0;
    • a boolean whether it should be considered a failure if the process exits uncleanly;
    • two pairs of CLOCK_REALTIME/CLOCK_MONOTONIC microsecond timestamps for when the process began and finished running the last time, or 0 if it never ran or never finished running;
    • the PID of the process, or 0 if it has not run yet;
    • the exit code and status of the last run.

So this field maps more or less to the corresponding setting in the service unit file, but it's been augmented with runtime data. Glow up โœจ

  • LimitCPU (and related properties) โ€” map more or less directly to the corresponding settings in the service unit files, except that if they are not set their value is 18446744073709551615 (i.e. -1). Yeah that's a real number bestie, it's fine, breathe ๐Ÿซถ
  • Capabilities โ€” contains the configured capabilities, as formatted with cap_to_text(3).
  • SecureBits, CapabilityBoundingSet, MountFlags โ€” also correspond to the configured settings of the unit files, but instead of being formatted as strings, they are encoded as the actual binary flags they are. Raw. Unfiltered. We love that ๐Ÿ’…
  • ExecMainStartTimestamp, ExecMainStartTimestampMonotonic, ExecMainExitTimestamp, ExecMainExitTimestampMonotonic, ExecMainHandoffTimestamp, ExecMainHandoffTimestampMonotonic, ExecMainPID, ExecMainCode, ExecMainStatus โ€” all the tea about the main process of the service, as far as it is known. The ExecMainStartTimestamp timestamps record when the main process of the service is created. The ExecMainExitTimestamp timestamps record when the main process exit has been detected by the service manager. The ExecMainHandoffTimestamp timestamps record when the service binary is about to be executed by systemd-executor (and bestie, this timestamp gets recorded regardless of whether the immediately following execve() system call succeeds or fails โ€” no cap). This is often the same runtime information that's also maintained for ExecStart=. However, it deviates for services with Type=forking as well as services that use MAINPID= sd_notify() messages, because in that case the main process of the service is not forked off by the service manager directly. These fields either contain information of the last run of the process or of the current running process. Either way, receipts ๐Ÿ“
  • MainPID and ControlPID โ€” the main and control PID of the service. The main PID is the current main PID of the service, and it's 0 when the service currently has no main PID. The control PID is the PID of the current start/stop/reload process running, and it's 0 if no such process is currently running. So that means ExecMainPID and MainPID differ in that the latter immediately reflects whether a main process is currently running, while the former possibly contains information collected from the last run even if the process is no longer around. One is live, one is a memory ๐Ÿ’ญ
  • StatusText, StatusErrno, StatusBusError, and StatusVarlinkError โ€” these contain the status text, the error number, and the D-Bus/Varlink error name passed to the service manager via sd_notify(3), respectively. Services can use them to inform the service manager about their internal state. Like a lil mood update in the group chat ๐Ÿ“ฒ
  • Result โ€” encodes the execution result of the last run of the service. It's genuinely useful for figuring out why a service failed if it's in the "failed" state (peep ActiveState above ๐Ÿ‘€). The following values are currently known:
    • "success" โ€” set if the unit did not fail. We love a clean run โœจ
    • "resources" โ€” not enough resources were available to fork off and execute the service processes.
    • "timeout" โ€” a timeout occurred while executing a service operation.
    • "exit-code" โ€” a service process exited with an unclean exit code.
    • "signal" โ€” a service process exited with an uncaught signal.
    • "core-dump" โ€” a service process exited uncleanly and dumped core.
    • "watchdog" โ€” a service did not send out watchdog ping messages often enough. Rude of it, honestly.
    • "start-limit-hit" โ€” a service has been started too frequently in a specific time frame (as configured in StartLimitInterval, StartLimitBurst).
    • "oom-kill" โ€” a service was terminated due to an out-of-memory (OOM) situation. ๐Ÿ˜ญ
  • ControlGroup โ€” indicates the control group path the processes of this service unit are placed in. Their lil neighborhood ๐Ÿก
  • The following properties map 1:1 to corresponding settings in the unit file: RootDirectory RootImage RootImageOptions RootVerity RootHash RootHashSignature MountImages ExtensionImages ExtensionDirectories RootMStack โ€” see systemd.exec(5) for their meaning.
  • MemoryAvailable โ€” takes into account the unit's and parents' "MemoryMax" or "MemoryHigh" or physically available RAM versus the given level's memory consumption, and takes the minimum. โš ๏ธ Beware: other units below the tightest parent slice may consume the memory quicker and less than the reported value would remain for your own allocation. It works better in conjunction with MemoryAccounting=yes on the involved units. Fr fr, don't trust it blindly ๐Ÿ™ˆ
  • DelegateSubgroup โ€” contains the cgroup subgroup to place invoked unit processes in. As configured by the option of the same name in unit files. This is set to the empty string when it does not apply or no subgroup has been configured.
  • RuntimeDirectorySymlink, StateDirectorySymlink, CacheDirectorySymlink and LogsDirectorySymlink โ€” respectively implement the destination parameter of the unit files settings RuntimeDirectory, StateDirectory, CacheDirectory and LogsDirectory, which will create a symlink of the given name to the respective directory. The messages take a flags parameter that make the directory read only:
#define SD_EXEC_DIRECTORY_READ_ONLY            (UINT64_C(1) << 0)
  • ExtraFileDescriptorNames โ€” contains file descriptor names passed to the service via the ExtraFileDescriptors property in the StartTransientUnit() method. See sd_listen_fds(3) for more details on how to retrieve these file descriptors. And unlike the ExtraFileDescriptors input property, ExtraFileDescriptorNames only contains names and not the file descriptors. Names only, bestie, the fds stay home ๐Ÿ’…
  • ManagedOOMMemoryPressureDurationUSec โ€” implements the destination parameter of the unit file setting ManagedOOMMemoryPressureDurationSec= listed in systemd.resource-control(5). Note the time unit is expressed in "ฮผs".
  • ProtectControlGroupsEx โ€” implements the destination parameter of the unit file setting ProtectControlGroups= listed in systemd.exec(5). Unlike the boolean ProtectControlGroups, ProtectControlGroupsEx is a string type.
  • PrivatePIDs โ€” implements the destination parameter of the unit file setting PrivatePIDs= listed in systemd.exec(5). Note PrivatePIDs is a string type to allow adding more values in the future. Future-proof queen ๐Ÿ‘‘
  • ProtectHostnameEx โ€” implements the destination parameter of the unit file setting ProtectHostname= listed in systemd.exec(5). Unlike the boolean ProtectHostname, ProtectHostnameEx is a pair of strings: the first one is a boolean string or the special value "private", and the second one is an optional private hostname that will be set in a new UTS namespace for the unit. Two strings, one namespace, so much lore ๐ŸŒธ

โœจ SOCKET UNIT OBJECTS โœจ

bestie. okay. sit down. hydrate. because this is the socket unit era and it is a lot of properties. ๐Ÿ’…

A socket unit exposes itself on the bus at a node path that looks like this, where the unit name gets escaped (- becomes _2d, . becomes _2e), so avahi-daemon.socket shows up as avahi_2ddaemon_2esocket:

node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
  interface org.freedesktop.systemd1.Socket {
    methods:
      GetProcesses(out a(sus) processes);
      AttachProcesses(in  s subcgroup,
                      in  au pids);
      RemoveSubgroup(in  s subcgroup,
                     in  t flags);
    properties:
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s BindIPv6Only = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u Backlog = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t TimeoutUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s BindToDevice = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SocketUser = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SocketGroup = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u SocketMode = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u DirectoryMode = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Accept = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b FlushPending = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Writable = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b KeepAlive = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t KeepAliveTimeUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t KeepAliveIntervalUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u KeepAliveProbes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t DeferAcceptUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b NoDelay = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly i Priority = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t ReceiveBuffer = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t SendBuffer = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly i IPTOS = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly i IPTTL = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t PipeSize = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b FreeBind = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Transparent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b Broadcast = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b PassCredentials = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b PassPIDFD = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b PassSecurity = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b PassPacketInfo = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b AcceptFileDescriptors = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Timestamping = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b RemoveOnStop = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly a(ss) Listen = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly as Symlinks = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly a(ss) XAttrEntryPoint = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly a(ss) XAttrListen = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly a(ss) XAttrAccept = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly i Mark = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u MaxConnections = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u MaxConnectionsPerSource = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly x MessageQueueMaxMessages = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly x MessageQueueMessageSize = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s TCPCongestion = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b ReusePort = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SmackLabel = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SmackLabelIPIn = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s SmackLabelIPOut = '...';
      readonly u ControlPID = ...;
      readonly s Result = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly u NConnections = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly u NAccepted = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly u NRefused = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s FileDescriptorName = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly i SocketProtocol = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t TriggerLimitIntervalUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u TriggerLimitBurst = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t PollLimitIntervalUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u PollLimitBurst = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s DeferTrigger = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t DeferTriggerMaxUSec = ...;
      readonly u UID = ...;
      readonly u GID = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b PassFileDescriptorsToExec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecStartPre = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecStartPost = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecStopPre = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecStopPost = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s Slice = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s ControlGroup = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t ControlGroupId = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryPeak = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemorySwapCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemorySwapPeak = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryZSwapCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryAvailable = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveMemoryMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveMemoryHigh = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t CPUUsageNSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay EffectiveCPUs = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay EffectiveMemoryNodes = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t TasksCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveTasksMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPIngressBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPIngressPackets = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPEgressBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPEgressPackets = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOReadBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOReadOperations = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOWriteBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOWriteOperations = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t OOMKills = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

Okay so yes, that's the vibe. ๐ŸŒธ Now let's actually walk it because there is SO much here.


๐Ÿซถ Methods

  • GetProcesses โ€” takes no inputs and hands you back a(sus) processes. Cute little tuple situation, iykyk.
  • AttachProcesses โ€” you give it s subcgroup and au pids, and that's it. No return value, it just does the thing.
  • RemoveSubgroup โ€” you give it s subcgroup and t flags. Also no return value. Bye girl ๐Ÿ’…

๐Ÿ’– Properties

Heads up bestie: almost every single one of these is @org.freedesktop.DBus.Property.EmitsChangedSignal("const"), which means they're set in stone once the unit loads and the signal doesn't fire for them. A few are "false" (they change, but no signal announcement, so you gotta go look yourself), a few are "invalidates", and a couple have no annotation at all. I'm flagging each one so you never get caught slipping. โœจ

๐ŸŒˆ The const crew

  • BindIPv6Only โ€” s, "const"
  • Backlog โ€” u, "const"
  • TimeoutUSec โ€” t, "const"
  • BindToDevice โ€” s, "const"
  • SocketUser โ€” s, "const"
  • SocketGroup โ€” s, "const"
  • SocketMode โ€” u, "const"
  • DirectoryMode โ€” u, "const"
  • Accept โ€” b, "const"
  • FlushPending โ€” b, "const"
  • Writable โ€” b, "const"
  • KeepAlive โ€” b, "const"
  • KeepAliveTimeUSec โ€” t, "const"
  • KeepAliveIntervalUSec โ€” t, "const"
  • KeepAliveProbes โ€” u, "const"
  • DeferAcceptUSec โ€” t, "const"
  • NoDelay โ€” b, "const"
  • Priority โ€” i, "const"
  • ReceiveBuffer โ€” t, "const"
  • SendBuffer โ€” t, "const"
  • IPTOS โ€” i, "const"
  • IPTTL โ€” i, "const"
  • PipeSize โ€” t, "const"
  • FreeBind โ€” b, "const"
  • Transparent โ€” b, "const"
  • Broadcast โ€” b, "const"
  • PassCredentials โ€” b, "const"
  • PassPIDFD โ€” b, "const"
  • PassSecurity โ€” b, "const"
  • PassPacketInfo โ€” b, "const"
  • AcceptFileDescriptors โ€” b, "const"
  • Timestamping โ€” s, "const"
  • RemoveOnStop โ€” b, "const"
  • Listen โ€” a(ss), "const", shows up as a list of pairs like [...]
  • Symlinks โ€” as, "const", that's a list of strings, looks like ['...', ...]
  • XAttrEntryPoint โ€” a(ss), "const", [...]
  • XAttrListen โ€” a(ss), "const", [...]
  • XAttrAccept โ€” a(ss), "const", [...]
  • Mark โ€” i, "const"
  • MaxConnections โ€” u, "const"
  • MaxConnectionsPerSource โ€” u, "const"
  • MessageQueueMaxMessages โ€” x, "const"
  • MessageQueueMessageSize โ€” x, "const"
  • TCPCongestion โ€” s, "const"
  • ReusePort โ€” b, "const"
  • SmackLabel โ€” s, "const"
  • SmackLabelIPIn โ€” s, "const"
  • SmackLabelIPOut โ€” s, "const"
  • SocketProtocol โ€” i, "const"
  • TriggerLimitIntervalUSec โ€” t, "const"
  • TriggerLimitBurst โ€” u, "const"
  • PollLimitIntervalUSec โ€” t, "const"
  • PollLimitBurst โ€” u, "const"
  • DeferTrigger โ€” s, "const"
  • DeferTriggerMaxUSec โ€” t, "const"
  • PassFileDescriptorsToExec โ€” b, "const"

๐ŸŒธ The no-annotation girlies

These ones just say readonly and nothing else, no signal gossip attached:

  • ControlPID โ€” u
  • Result โ€” s
  • UID โ€” u
  • GID โ€” u

๐Ÿฆ‹ The "false" squad (no change signal, go look yourself)

  • NConnections โ€” u, "false"
  • NAccepted โ€” u, "false"
  • NRefused โ€” u, "false"
  • FileDescriptorName โ€” s, "false"
  • Slice โ€” s, "false"
  • ControlGroup โ€” s, "false"
  • ControlGroupId โ€” t, "false"
  • MemoryCurrent โ€” t, "false"
  • MemoryPeak โ€” t, "false"
  • MemorySwapCurrent โ€” t, "false"
  • MemorySwapPeak โ€” t, "false"
  • MemoryZSwapCurrent โ€” t, "false"
  • MemoryAvailable โ€” t, "false"
  • EffectiveMemoryMax โ€” t, "false"
  • EffectiveMemoryHigh โ€” t, "false"
  • CPUUsageNSec โ€” t, "false"
  • EffectiveCPUs โ€” ay, "false", [...]
  • EffectiveMemoryNodes โ€” ay, "false", [...]
  • TasksCurrent โ€” t, "false"
  • EffectiveTasksMax โ€” t, "false"
  • IPIngressBytes โ€” t, "false"
  • IPIngressPackets โ€” t, "false"
  • IPEgressBytes โ€” t, "false"
  • IPEgressPackets โ€” t, "false"
  • IOReadBytes โ€” t, "false"
  • IOReadOperations โ€” t, "false"
  • IOWriteBytes โ€” t, "false"
  • IOWriteOperations โ€” t, "false"
  • OOMKills โ€” t, "false"

๐ŸŽ€ The "invalidates" ones

These four are a(sasbttttuii), they show up as [...], and they invalidate instead of doing a cute little change ping:

  • ExecStartPre โ€” a(sasbttttuii), "invalidates"
  • ExecStartPost โ€” a(sasbttttuii), "invalidates"
  • ExecStopPre โ€” a(sasbttttuii), "invalidates"
  • ExecStopPost โ€” a(sasbttttuii), "invalidates"

And then the code block just. ends. mid-property, dangling on an annotation with nothing after it. Not me getting left on read by the manpage ๐Ÿ’€ Keep reading bestie, there's more coming.

...and the list just keeps going, bestie. We're still deep in the resource-control properties, so buckle up ๐ŸŽ€

                 readonly t ManagedOOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b Delegate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DelegateControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DelegateSubgroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupCPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPerSecUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPeriodUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUSetPartition = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupIOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceWeight = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceLatencyTargetUSec = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMin = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryZSwapWriteback = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DevicePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) DeviceAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b TasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPIngressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPEgressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DisableControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMSwap = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMMemoryPressure = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ManagedOOMMemoryPressureLimit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMMemoryPressureDurationUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMPreference = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as OOMRules = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;

okay so that whole chunk is giving "no signal" energy โ€” every single one of them is tagged @org.freedesktop.DBus.Property.EmitsChangedSignal("false"), which is D-Bus's way of saying don't expect me to ping you when this changes. They're still readonly, they still exist, they just don't announce themselves. lowkey mysterious of them ๐Ÿ’…

Then the annotations switch up. Meet the const crew โœจ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as Environment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sb) EnvironmentFiles = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as PassEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as UnsetEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u UMask = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPU = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPUSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATASoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitAS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitASSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROCSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDING = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDINGSoft = ...;

so like. the environment stuff โ€” Environment, EnvironmentFiles, PassEnvironment, UnsetEnvironment โ€” and the UMask plus that whole iconic Limitโ€ฆ family (every one of them paired with its โ€ฆSoft sibling, no cap, they come in twos ๐Ÿซถ) are all annotated "const". Same readonly treatment, different annotation. periodt.

and yes, we're still not done, bestie โ€” more properties are coming in the next bit ๐Ÿ’–

okay so we are still deep in the property wall bestie, and this whole stretch is just @org.freedesktop.DBus.Property.EmitsChangedSignal("const") over and over โ€” it's giving very much "same energy, different property name" ๐Ÿ’… every single one of these is tagged const, and we do not skip a single one. first up, the resource-limit girlies ๐ŸŽ€

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitMSGQUEUE = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitMSGQUEUESoft = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitNICE = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitNICESoft = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitRTPRIO = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitRTPRIOSoft = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitRTTIME = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LimitRTTIMESoft = ...;

see how they all come in little pairs? โœจ the plain one and the ...Soft one, like a matched set, obsessed. and every one of them is a t, okay, noted, moving on ๐Ÿซถ

then we get the directory-and-root section, which is lowkey the longest glow-up in this whole chunk โ€” working dirs, root dirs, root images, hashes, verity, and then the extension/mount image trio at the end ๐ŸŒธ

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s WorkingDirectory = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootDirectory = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootImage = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) RootImageOptions = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly ay RootHash = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootHashPath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly ay RootHashSignature = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootHashSignaturePath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootVerity = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RootEphemeral = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RootMStack = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ExtensionDirectories = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(sba(ss)) ExtensionImages = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ssba(ss)) MountImages = [...];

like look at a(sba(ss)) and a(ssba(ss)) โ€” those signatures are doing the MOST and honestly? iconic. ๐Ÿฆ‹

next: scheduling and priorities, aka the "who gets the CPU and who waits" chapter. OOM scores, coredump filters, nice, io scheduling, cpu scheduling, affinity, NUMA, timer slack, and the two little booleans at the bottom ๐ŸŽ€

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i OOMScoreAdjust = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t CoredumpFilter = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i Nice = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i IOSchedulingClass = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i IOSchedulingPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i CPUSchedulingPolicy = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i CPUSchedulingPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly ay CPUAffinity = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CPUAffinityFromNUMA = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i NUMAPolicy = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly ay NUMAMask = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t TimerSlackNSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CPUSchedulingResetOnFork = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b NonBlocking = ...;

then the stdio / TTY / logging era ๐Ÿ’– we've got standard input, output and error (each with its own FileDescriptorName, cute), the TTY properties including TTYRows and TTYColumns which are typed q, and then the whole syslog + log cluster at the bottom, finishing on LogNamespace. not me getting emotional over LogExtraFields being a aay ๐Ÿฅน

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardInput = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardInputFileDescriptorName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly ay StandardInputData = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardOutput = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardOutputFileDescriptorName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardError = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s StandardErrorFileDescriptorName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s TTYPath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYReset = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVHangup = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b TTYVTDisallocate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly q TTYRows = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly q TTYColumns = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogPriority = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s SyslogIdentifier = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b SyslogLevelPrefix = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogLevel = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SyslogFacility = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i LogLevelMax = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t LogRateLimitIntervalUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u LogRateLimitBurst = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly aay LogExtraFields = [[...], ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(bs) LogFilterPatterns = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s LogNamespace = '...';

and now we roll into the user / credentials / sandbox zone, which is where the real main character energy lives ๐Ÿ‘‘ secure bits, capability bounding sets, ambient capabilities, user, group, dynamic user, login environment, IPC removal, then the entire credential saga (SetCredential, SetCredentialEncrypted, LoadCredential, LoadCredentialEncrypted, ImportCredential, ImportCredentialEx โ€” bestie they really said "one credential option is not enough"), supplementary groups, PAM name, and the whole path-permission parade ๐Ÿฆ‹

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SecureBits = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t CapabilityBoundingSet = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t AmbientCapabilities = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s User = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Group = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b DynamicUser = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b SetLoginEnvironment = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(say) SetCredential = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(say) SetCredentialEncrypted = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) LoadCredential = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) LoadCredentialEncrypted = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ImportCredential = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) ImportCredentialEx = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ReadWritePaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ReadOnlyPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as InaccessiblePaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ExecPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as NoExecPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ExecSearchPath = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t MountFlags = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateTmp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PrivateTmpEx = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateDevices = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectClock = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelTunables = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelModules = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelLogs = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectControlGroups = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectControlGroupsEx = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateNetwork = ...;

okay and the Protect* booleans all stacked up at the end like a little row of shields? ๐Ÿ›ก๏ธ adorable, protective, exactly the vibe. and we end this part right on PrivateNetwork, which is honestly the perfect cliffhanger, because bestie there is still SO much more of this property list to go โ€” so don't go anywhere ๐Ÿ’œ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateUsers = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateUsersEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateMounts = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateIPC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivatePIDs = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectHome = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectSystem = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SameProcessGroup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SELinuxContext = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) AppArmorProfile = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SmackProcessLabel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b IgnoreSIGPIPE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NoNewPrivileges = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as SystemCallArchitectures = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SystemCallErrorNumber = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallLog = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Personality = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LockPersonality = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictAddressFamilies = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) RuntimeDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RuntimeDirectoryPreserve = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u RuntimeDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as RuntimeDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) StateDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u StateDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b StateDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) StateDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as StateDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) CacheDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u CacheDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CacheDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) CacheDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as CacheDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) LogsDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogsDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LogsDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) LogsDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as LogsDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u ConfigurationDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ConfigurationDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutCleanUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryDenyWriteExecute = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictRealtime = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictSUIDSGID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestrictNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DelegateNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictFileSystems = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssbt) BindPaths = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssbt) BindReadOnlyPaths = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) TemporaryFileSystem = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MountAPIVFS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b BindLogSockets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KeyringMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectProc = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProcSubset = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectHostname = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (ss) ProtectHostnameEx = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateBPF = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateCommands = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateMaps = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegatePrograms = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateAttachments = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryKSM = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MemoryTHP = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UserNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s NetworkNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s IPCNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MountImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ExtensionImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) StateDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) CacheDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) LogsDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KillMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i KillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i RestartKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FinalKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGKILL = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGHUP = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i WatchdogSignal = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

okay so that's the rest of the execution-context property wall ๐Ÿ’… bestie, and yes, the closing braces are exactly like that โ€” the Service interface ends with };, and then the other interfaces (org.freedesktop.DBus.Peer, org.freedesktop.DBus.Introspectable, org.freedesktop.DBus.Properties, and org.freedesktop.systemd1.Unit) each get their own little { ... }; cameo inside the same object, and the whole object closes out with };. the way that's just nesting all the way down... iconic, honestly ๐ŸŒธ


the PollLimitIntervalUSec and PollLimitBurst properties configure the polling limit for the socket unit ๐ŸŽ€

  • PollLimitIntervalUSec expects a time in ยตs
  • PollLimitBurst expects an unsigned integer
and if either one of them is set to zero, the limiting feature is turned off ๐Ÿ’€ no cap, zero means off, not "zero of a thing".

โœจ Properties โœจ

ngl, most of these properties are just a 1:1 glow-up of the settings you already know from socket unit files ๐Ÿฆ‹ like, you write it in the unit file, it shows up here, they're the same facts in a cuter outfit.

also โ€” and this is the part people forget โ€” socket units can include ExecStartPre (and similar) fields, and those fields contain info about processes to execute ๐Ÿซถ so socket units also share most of the fields related to the execution context that Service objects expose. see above for all of that โฌ†๏ธ (it's a lot, I know, but we got through it together).

and on top of all of those properties, there are the following:

cue the next part, bestie ๐Ÿงš

NAccepted is the lil counter of every connection this socket has ever accepted, like all-time, no take-backs ๐Ÿ’–. But bestie, heads up: this only counts for sockets where Accept is set to "yes", aka the ones where systemd is the one doing the accepting. If systemd isn't the acceptor, this number is just vibing at zero, not relevant to you โœจ.

NConnections is the currently open connections on this socket โ€” like, right now, the live ones ๐Ÿซถ. Same deal as above: it only applies to socket units with Accept set to "yes". No accept, no count, periodt.

Result is the tea on why a socket unit failed if it's sitting in the "failed" state (peep ActiveState above ๐Ÿ‘†). The values are:

  • "success"
  • "resources"
  • "timeout"
  • "exit-code"
  • "signal"
  • "core-dump"

โ€ฆand these mean exactly what they mean for the matching field on service units (see above, iykyk). AND there's one extra: "service-failed-permanent" means the service of this socket failed continuously โ€” like it just kept failing, no cap ๐Ÿ˜ญ.

FlushPending says whether to flush the socket right before it enters the listening state. Lowkey important: this setting only applies to sockets with Accept= set to "no". So if you're in accept-yes land, this does nothing for you, sorry bestie ๐Ÿ™ˆ.

XAttrEntryPoint, XAttrListen and XAttrAccept each hold a list of extended attributes (as "NAME"/"VALUE" pairs) to slap onto socket inodes ๐Ÿ’…. Here's the breakdown:

  • XAttrEntryPoint applies to the file-system inode an AF_UNIX socket is bound to.
  • XAttrListen applies to the listening socket.
  • XAttrAccept applies to connection sockets accepted off the listening socket.

For all the deets, go read the XAttrEntryPoint=, XAttrListen= and XAttrAccept= settings in systemd.socket(5) ๐Ÿ“–.


๐ŸŽฏ TARGET UNIT OBJECTS ๐ŸŽฏ

node /org/freedesktop/systemd1/unit/basic_2etarget {
  interface org.freedesktop.systemd1.Target {
  };
  interface org.freedesktop.DBus.Peer { ... };
  interface org.freedesktop.DBus.Introspectable { ... };
  interface org.freedesktop.DBus.Properties { ... };
  interface org.freedesktop.systemd1.Unit { ... };
};

Target units have neither type-specific methods nor properties โ€” they're the chill minimalist icon of the unit world, just vibes, nothing else โœจ.


๐Ÿ’ป DEVICE UNIT OBJECTS ๐Ÿ’ป

Every device unit object implements the org.freedesktop.systemd1.Device interface (described right here, bestie) plus the generic org.freedesktop.systemd1.Unit interface (see above ๐Ÿ‘†).

node /org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice {
  interface org.freedesktop.systemd1.Device {
    properties:
      readonly s SysFSPath = '...';
  };
  interface org.freedesktop.DBus.Peer { ... };
  interface org.freedesktop.DBus.Introspectable { ... };
  interface org.freedesktop.DBus.Properties { ... };
  interface org.freedesktop.systemd1.Unit { ... };
};

โœจ Properties โœจ

Device units are keeping it cute and only expose one single type-specific property ๐ŸŽ€:

  • SysFSPath โ€” holds the sysfs path of the kernel device this object corresponds to ๐Ÿ”ฅ.

๐ŸŒˆ MOUNT UNIT OBJECTS ๐ŸŒˆ

Every mount unit object implements the org.freedesktop.systemd1.Mount interface (described right here, bestie) plus the generic org.freedesktop.systemd1.Unit interface (see above ๐Ÿ‘†).

okay so here's the actual shape of a mount unit on the bus, bestie. Every property, every annotation, every method โ€” laid out exactly like the introspection hands it over. ๐Ÿ‘‘

node /org/freedesktop/systemd1/unit/home_2emount {
  interface org.freedesktop.systemd1.Mount {
    methods:
      GetProcesses(out a(sus) processes);
      AttachProcesses(in  s subcgroup,
                      in  au pids);
      RemoveSubgroup(in  s subcgroup,
                     in  t flags);
    properties:
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly s Where = '...';
      readonly s What = '...';
      readonly s Options = '...';
      readonly s Type = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly t TimeoutUSec = ...;
      readonly u ControlPID = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly u DirectoryMode = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b SloppyOptions = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b LazyUnmount = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b ForceUnmount = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
      readonly b ReadWriteOnly = ...;
      readonly s Result = '...';
      readonly s ReloadResult = '...';
      readonly s CleanResult = '...';
      readonly u UID = ...;
      readonly u GID = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecMount = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecUnmount = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
      readonly a(sasbttttuii) ExecRemount = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s Slice = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s ControlGroup = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t ControlGroupId = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryPeak = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemorySwapCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemorySwapPeak = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryZSwapCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryAvailable = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveMemoryMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveMemoryHigh = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t CPUUsageNSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay EffectiveCPUs = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay EffectiveMemoryNodes = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t TasksCurrent = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t EffectiveTasksMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPIngressBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPIngressPackets = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPEgressBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IPEgressPackets = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOReadBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOReadOperations = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOWriteBytes = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOWriteOperations = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t OOMKills = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t ManagedOOMKills = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b Delegate = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as DelegateControllers = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s DelegateSubgroup = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t CPUWeight = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupCPUWeight = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t CPUQuotaPerSecUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t CPUQuotaPeriodUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay AllowedCPUs = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay StartupAllowedCPUs = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay AllowedMemoryNodes = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly ay StartupAllowedMemoryNodes = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s CPUSetPartition = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b IOAccounting = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t IOWeight = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupIOWeight = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IODeviceWeight = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IOReadBandwidthMax = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IOWriteBandwidthMax = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IOReadIOPSMax = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IOWriteIOPSMax = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(st) IODeviceLatencyTargetUSec = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b MemoryAccounting = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryMin = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryLow = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupMemoryLow = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryHigh = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupMemoryHigh = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupMemoryMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemorySwapMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupMemorySwapMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t MemoryZSwapMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t StartupMemoryZSwapMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b MemoryZSwapWriteback = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s DevicePolicy = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(ss) DeviceAllow = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b TasksAccounting = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t TasksMax = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly b IPAccounting = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(iayu) IPAddressAllow = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly a(iayu) IPAddressDeny = [...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as IPIngressFilterPath = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as IPEgressFilterPath = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as DisableControllers = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s ManagedOOMSwap = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s ManagedOOMMemoryPressure = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly u ManagedOOMMemoryPressureLimit = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly t ManagedOOMMemoryPressureDurationUSec = ...;
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly s ManagedOOMPreference = '...';
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
      readonly as OOMRules = ['...', ...];
      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

<h3>๐ŸŒธ the little bits at the top ๐ŸŒธ</h3>

The mount unit inherits a few methods from the unit interface, and they're right there at the top of the listing:

  • GetProcesses(out a(sus) processes) โ€” hands you back the processes as a(sus).
  • AttachProcesses(in s subcgroup, in au pids) โ€” takes a subcgroup and a list of pids.
  • RemoveSubgroup(in s subcgroup, in t flags) โ€” takes a subcgroup and flags.

so tidy, so demure, so mindful ๐Ÿ’…


<h3>๐Ÿฆ‹ the mount-specific properties ๐Ÿฆ‹</h3>

These are the ones that make it a mount and not just any old unit:

  • Where, What, Options, Type โ€” all plain s strings, and Where is marked const.
  • TimeoutUSec (t, const) and ControlPID (u).
  • DirectoryMode (u, const).
  • SloppyOptions, LazyUnmount, ForceUnmount, ReadWriteOnly โ€” all b, all const.
  • Result, ReloadResult, CleanResult โ€” three separate s strings, one per flavour of outcome.
  • UID and GID โ€” both u.
  • ExecMount, ExecUnmount, ExecRemount โ€” the big ones, each a(sasbttttuii), and each tagged @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates").

<h3>โญ and then... the long haul โญ</h3>

After that it's every single resource-control and accounting property you could possibly want, all of them tagged @org.freedesktop.DBus.Property.EmitsChangedSignal("false"), all readonly, and all just vibing in a very long column. We're talking Slice, ControlGroup, ControlGroupId, the whole memory family (MemoryCurrent, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, MemoryZSwapCurrent, MemoryAvailable, EffectiveMemoryMax, EffectiveMemoryHigh), the CPU gang (CPUUsageNSec, EffectiveCPUs, EffectiveMemoryNodes, CPUWeight, StartupCPUWeight, CPUQuotaPerSecUSec, CPUQuotaPeriodUSec, AllowedCPUs, StartupAllowedCPUs, AllowedMemoryNodes, StartupAllowedMemoryNodes, CPUSetPartition), the task counters (TasksCurrent, EffectiveTasksMax), the network counters (IPIngressBytes, IPIngressPackets, IPEgressBytes, IPEgressPackets), the IO counters and knobs (IOReadBytes, IOReadOperations, IOWriteBytes, IOWriteOperations, IOAccounting, IOWeight, StartupIOWeight, IODeviceWeight, IOReadBandwidthMax, IOWriteBandwidthMax, IOReadIOPSMax, IOWriteIOPSMax, IODeviceLatencyTargetUSec), the OOM drama (OOMKills, ManagedOOMKills, ManagedOOMSwap, ManagedOOMMemoryPressure, ManagedOOMMemoryPressureLimit, ManagedOOMMemoryPressureDurationUSec, ManagedOOMPreference, OOMRules), the delegation set (Delegate, DelegateControllers, DelegateSubgroup), the memory limits with all their Startup* twins (MemoryMin, MemoryLow, StartupMemoryLow, MemoryHigh, StartupMemoryHigh, MemoryMax, StartupMemoryMax, MemorySwapMax, StartupMemorySwapMax, MemoryZSwapMax, StartupMemoryZSwapMax, MemoryZSwapWriteback), the device policy (DevicePolicy, DeviceAllow), the task accounting (TasksAccounting, TasksMax), the IP accounting (IPAccounting, IPAddressAllow, IPAddressDeny, IPIngressFilterPath, IPEgressFilterPath), and DisableControllers.

it's giving "I contain multitudes" and honestly? iconic.

And right at the very end the listing cuts off mid-annotation โ€” one lonely @org.freedesktop.DBus.Property.EmitsChangedSignal("false") sitting there with its property still on the way. ๐Ÿซถ Hold that thought, bestie, because the next bit picks it right up.


okay so we are STILL deep in the property list and bestie it does not stop, it just keeps going, and every single line is load-bearing so we're reading all of them ๐Ÿ’–

first up, the batch that's tagged EmitsChangedSignal("false") โ€” the introspection data itself is out here saying "don't hold your breath for a changed signal on these":

                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;

notice the little throuple situation with MemoryPressureWatch, CPUPressureWatch and IOPressureWatch โ€” three strings, each with its own t (that's a uint64, bestie, big number energy) threshold companion measured in microseconds. and RestrictNetworkInterfaces is the only one up there rocking a (bas) signature, while SocketBindAllow and SocketBindDeny are twins with a(iiqq). iconic. โœจ

then the vibe shifts HARD, because everything from here down is tagged EmitsChangedSignal("const") instead. the environment-and-limits block, let's go:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as Environment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sb) EnvironmentFiles = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as PassEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as UnsetEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u UMask = ...;

Environment, PassEnvironment and UnsetEnvironment are all as โ€” arrays of strings, three of them, all about the environment, all const. and EnvironmentFiles is a(sb), a little array-of-struct action. UMask is a lone u (uint32) holding it down by itself. ๐Ÿซถ

and NOW, the main event, the reason your eyes are about to glaze over: THE LIMITS. every one of them a t, every one of them const, and every single one of them comes with a ...Soft sibling. all twenty of them. no cap, we're listing every last one:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPU = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPUSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATASoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitAS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitASSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROCSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDING = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDINGSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIO = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIOSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIME = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIMESoft = ...;

look at that. LimitCPU/LimitCPUSoft, LimitFSIZE/LimitFSIZESoft, LimitDATA/LimitDATASoft, LimitSTACK/LimitSTACKSoft, LimitCORE/LimitCORESoft, LimitRSS/LimitRSSSoft, LimitNOFILE/LimitNOFILESoft, LimitAS/LimitASSoft, LimitNPROC/LimitNPROCSoft, LimitMEMLOCK/LimitMEMLOCKSoft, LimitLOCKS/LimitLOCKSSoft, LimitSIGPENDING/LimitSIGPENDINGSoft, LimitMSGQUEUE/LimitMSGQUEUESoft, LimitNICE/LimitNICESoft, LimitRTPRIO/LimitRTPRIOSoft, LimitRTTIME/LimitRTTIMESoft. seventeen pairs, thirty-four properties, all t, all const, all with the identical annotation line above them like they're in uniform. ate and left no crumbs. ๐Ÿ’…


okay, breathe. ๐Ÿงš now we get into the filesystem-rooting-and-images section, and the type signatures get SPICY:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s WorkingDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImage = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) RootImageOptions = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHash = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHashSignature = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashSignaturePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootVerity = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RootEphemeral = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootMStack = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExtensionDirectories = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sba(ss)) ExtensionImages = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssba(ss)) MountImages = [...];

so we've got strings galore (WorkingDirectory, RootDirectory, RootImage, RootHashPath, RootHashSignaturePath, RootVerity, RootMStack), two ay byte arrays (RootHash and RootHashSignature โ€” raw bytes, no strings attached, literally), one b boolean (RootEphemeral), one as (ExtensionDirectories), and then the two absolute UNITS: ExtensionImages with a(sba(ss)) and MountImages with a(ssba(ss)). look at those nested signatures. a(ssba(ss)). that's four things inside a struct inside an array. she's doing a lot and she's doing it well. ๐Ÿ‘‘

and we roll straight on into the scheduling / resource-flavouring block, still all const, still not slowing down:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i OOMScoreAdjust = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t CoredumpFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i Nice = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingClass = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay CPUAffinity = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUAffinityFromNUMA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i NUMAPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay NUMAMask = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimerSlackNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUSchedulingResetOnFork = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NonBlocking = ...;

OOMScoreAdjust, Nice, IOSchedulingClass, IOSchedulingPriority, CPUSchedulingPolicy, CPUSchedulingPriority, NUMAPolicy โ€” all i, all signed 32-bit ints. CPUAffinity and NUMAMask are ay. CPUAffinityFromNUMA, CPUSchedulingResetOnFork and NonBlocking are b. and CoredumpFilter and TimerSlackNSec are the only ts in this bunch, keeping the pattern alive. ๐ŸŒˆ

and the last stretch for this part โ€” standard I/O, TTY, and syslog. the plumbing. the "where does the output even go" department:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay StandardInputData = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardError = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardErrorFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s TTYPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYReset = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVHangup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVTDisallocate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYRows = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYColumns = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s SyslogIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SyslogLevelPrefix = ...;

the trio pattern is so clean here: StandardInput + StandardInputFileDescriptorName, StandardOutput + StandardOutputFileDescriptorName, StandardError + StandardErrorFileDescriptorName โ€” and only the input one gets a bonus ay in the form of StandardInputData. the TTY gang: TTYPath is s, TTYReset / TTYVHangup / TTYVTDisallocate are b, and then TTYRows and TTYColumns show up as q โ€” that's uint16, the smallest of the integer types here, which honestly makes sense for a row count, lowkey adorable. ๐Ÿ“

and then SyslogPriority (i), SyslogIdentifier (s), and SyslogLevelPrefix (b) walk us right up to the edge of this partโ€ฆ and we are not done, bestie. there's more list after this. obviously there's more list. there's always more list. ๐Ÿ’€

...and the property pile keeps going, bestie ๐Ÿ’– we are still in Service unit properties, and this stretch is the stretch โ€” logging knobs, credentials, sandboxing, directories, syscall filters, all of it. Every single one of these carries the exact same @org.freedesktop.DBus.Property.EmitsChangedSignal("const") annotation, over and over, like a little stamp. Not me being obsessed with how consistent it is ๐Ÿ˜ญ

First up, the logging girlies:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogLevel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogFacility = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i LogLevelMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LogRateLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogRateLimitBurst = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly aay LogExtraFields = [[...], ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(bs) LogFilterPatterns = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s LogNamespace = '...';

Then we get into identity and credentials โ€” who the service runs as, which caps it gets, and every flavour of credential the thing can carry. Look at SetCredential, SetCredentialEncrypted, LoadCredential, LoadCredentialEncrypted, ImportCredential, ImportCredentialEx โ€” six whole credential options, she's thorough ๐Ÿ’…

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SecureBits = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t CapabilityBoundingSet = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t AmbientCapabilities = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s User = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Group = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DynamicUser = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SetLoginEnvironment = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RemoveIPC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(say) SetCredential = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(say) SetCredentialEncrypted = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) LoadCredential = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) LoadCredentialEncrypted = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ImportCredential = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) ImportCredentialEx = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as SupplementaryGroups = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PAMName = '...';

Paths next!! ๐Ÿฆ‹ read-write, read-only, inaccessible, exec, no-exec, and the search path. Six of them, all as (arrays of strings), all lined up like little soldiers:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ReadWritePaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ReadOnlyPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as InaccessiblePaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExecPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as NoExecPaths = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExecSearchPath = ['...', ...];

And now the big sandbox section โ€” this is the main character energy part of the whole page, fr fr. Mount flags, private tmp, private devices, protecting the clock, kernel tunables, kernel modules, kernel logs, control groups, network, users, mounts, IPC, PIDs, home, system. Notice the Ex variants โ€” PrivateTmpEx, ProtectControlGroupsEx, PrivateUsersEx โ€” she's got layers ๐Ÿ˜Œ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t MountFlags = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateTmp = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateTmpEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateDevices = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectClock = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectKernelTunables = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectKernelModules = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectKernelLogs = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectControlGroups = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectControlGroupsEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateNetwork = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateUsers = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateUsersEx = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateMounts = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b PrivateIPC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivatePIDs = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectHome = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ProtectSystem = '...';

Then some terminal + security-label things, plus IgnoreSIGPIPE and NoNewPrivileges. The security ones are all (bs) โ€” a boolean and a string hanging out together ๐Ÿซถ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SameProcessGroup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UtmpMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SELinuxContext = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) AppArmorProfile = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bs) SmackProcessLabel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b IgnoreSIGPIPE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NoNewPrivileges = ...;

Syscall + personality + address families. SystemCallFilter and SystemCallLog are both (bas) โ€” boolean, array of strings, string. Restrict those address families, bestie, we don't know them like that ๐Ÿ”ฅ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as SystemCallArchitectures = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SystemCallErrorNumber = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) SystemCallLog = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Personality = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LockPersonality = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictAddressFamilies = ...;

Okay and now the directories block โ€” this one is long, and honestly iconic. Runtime, State, Cache, Logs, Configuration. Each one has its own symlink property (a(sst)), its own mode, its own accounting boolean, and its own quota (tus), then the plain as list. Runtime gets a RuntimeDirectoryPreserve string instead of an accounting flag, because she's special ๐Ÿ’…

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) RuntimeDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RuntimeDirectoryPreserve = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u RuntimeDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as RuntimeDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) StateDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u StateDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b StateDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) StateDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as StateDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) CacheDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u CacheDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CacheDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) CacheDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as CacheDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sst) LogsDirectorySymlink = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogsDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b LogsDirectoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (tus) LogsDirectoryQuota = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as LogsDirectory = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u ConfigurationDirectoryMode = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ConfigurationDirectory = ['...', ...];
Lowkey note: ConfigurationDirectory gets a mode and a list but no symlink, no accounting and no quota. That's just how it's written here, bestie โ€” don't @ me, I'm only telling you what the page says ๐Ÿ™ˆ

And to close out this chunk: a cleanup timeout plus the final run of restriction toggles. RestrictFileSystems is (bas), same shape as the syscall filters above, and DelegateNamespaces and RestrictNamespaces are both t.

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutCleanUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryDenyWriteExecute = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictRealtime = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RestrictSUIDSGID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RestrictNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t DelegateNamespaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (bas) RestrictFileSystems = ...;

Okay phew ๐Ÿ˜ญ that was a whole cardio session of properties. Every last one of them is readonly, every last one is @org.freedesktop.DBus.Property.EmitsChangedSignal("const"), and every last one is still sitting inside the Service unit object. There's more coming, so don't go anywhere ๐ŸŒธ

okay so the mount unit's property dump just keeps going, bestie, and here's the rest of it ๐Ÿ’… every one of these is @org.freedesktop.DBus.Property.EmitsChangedSignal("const") unless it says otherwise:

                 readonly a(ssbt) BindPaths = [...];
                 readonly a(ssbt) BindReadOnlyPaths = [...];
                 readonly a(ss) TemporaryFileSystem = [...];
                 readonly b MountAPIVFS = ...;
                 readonly b BindLogSockets = ...;
                 readonly s KeyringMode = '...';
                 readonly s ProtectProc = '...';
                 readonly s ProcSubset = '...';
                 readonly b ProtectHostname = ...;
                 readonly (ss) ProtectHostnameEx = ...;
                 readonly s PrivateBPF = '...';
                 readonly s BPFDelegateCommands = '...';
                 readonly s BPFDelegateMaps = '...';
                 readonly s BPFDelegatePrograms = '...';
                 readonly s BPFDelegateAttachments = '...';
                 readonly b MemoryKSM = ...;
                 readonly s MemoryTHP = '...';
                 readonly s UserNamespacePath = '...';
                 readonly s NetworkNamespacePath = '...';
                 readonly s IPCNamespacePath = '...';
                 readonly s RootImagePolicy = '...';
                 readonly s MountImagePolicy = '...';
                 readonly s ExtensionImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) StateDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) CacheDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) LogsDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KillMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i KillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i RestartKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FinalKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGKILL = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGHUP = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i WatchdogSignal = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

and THAT'S the whole mount node, slayed โœจ


๐ŸŒธ Properties ๐ŸŒธ

most of these properties are literally just the matching settings from the mount unit files, mapped straight over ๐Ÿซถ but here's the lil twist: since mount units actually run the /usr/bin/mount command, their bus objects carry implicit ExecMount fields (and similar ones, iykyk) that hold info about the processes to execute. they also share most of the execution-context fields that Service objects expose โ€” scroll up for those, bestie ๐Ÿ’–

and on top of all that, here's the extra stuff:

  • ControlPID โ€” the PID of the /usr/bin/mount or /usr/bin/umount command that's currently running, if one is. no process going? then it's just 0 ๐Ÿ’€
  • Result โ€” spills the tea on why a mount unit failed, if it failed. it can be "success", "resources", "timeout", "exit-code", "signal", or "core-dump", and those mean exactly the same thing as the matching values on the corresponding field of service unit objects (see above ๐Ÿ‘†).

๐Ÿฆ‹ AUTOMOUNT UNIT OBJECTS ๐Ÿฆ‹

every automount unit object implements the org.freedesktop.systemd1.Automount interface (described here) plus the generic org.freedesktop.systemd1.Unit interface (see above). the whole package, no crumbs ๐Ÿ‘‘

           node /org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount {
             interface org.freedesktop.systemd1.Automount {
               properties:
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Where = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ExtraOptions = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u DirectoryMode = ...;
                 readonly s Result = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutIdleUSec = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

๐ŸŒˆ Properties ๐ŸŒˆ

most of the properties map directly onto the matching settings in the automount unit files. simple as that โœจ

Result only knows the values "success" and "resources" at this time, and they mean the same thing as the matching values on the corresponding field of the Service object.


โฐ TIMER UNIT OBJECTS โฐ

every timer unit object implements the org.freedesktop.systemd1.Timer interface (described here) and the generic org.freedesktop.systemd1.Unit interface (see above). okay so the timer is lowkey the main character here, no cap ๐Ÿ•๐Ÿ’…

           node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
             interface org.freedesktop.systemd1.Timer {
               properties:
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Unit = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(stt) TimersMonotonic = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sst) TimersCalendar = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b OnClockChange = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b OnTimezoneChange = ...;
                 readonly t NextElapseUSecRealtime = ...;
                 readonly t NextElapseUSecMonotonic = ...;
                 readonly t LastTriggerUSec = ...;
                 readonly t LastTriggerUSecMonotonic = ...;
                 readonly s Result = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t AccuracyUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RandomizedDelayUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RandomizedOffsetUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b FixedRandomDelay = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b Persistent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b WakeSystem = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RemainAfterElapse = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b DeferReactivation = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

โœจ Properties โœจ

  • Unit โ€” holds the name of the unit that gets activated when the timer elapses. that's the whole point, periodt ๐Ÿ’…
  • TimersMonotonic โ€” an array of structs holding info about all the monotonic timers on this timer unit. each struct has: a string naming the timer base โ€” one of "OnActiveUSec", "OnBootUSec", "OnStartupUSec", "OnUnitActiveUSec", or "OnUnitInactiveUSec", which line up with the settings of the same names in the timer unit files; the microsecond offset from that timer base in monotonic time; and the next elapsation point on the CLOCK_MONOTONIC clock, relative to its epoch ๐Ÿ•ฐ๏ธ
  • TimersCalendar โ€” an array of structs holding info about all the realtime/calendar timers on this timer unit. each struct has: a string naming the timer base, which for now may only be "OnCalendar"; the calendar specification string; and the next elapsation point on the CLOCK_REALTIME clock, relative to its epoch ๐Ÿ“…
  • NextElapseUSecRealtime โ€” the next elapsation point on the CLOCK_REALTIME clock, in microseconds since the epoch. or 0 if this timer event doesn't include at least one calendar event ๐Ÿ™ˆ
  • NextElapseUSecMonotonic โ€” same energy, but for the CLOCK_MONOTONIC clock: the next elapsation point in microseconds since the epoch, or 0 if this timer event doesn't include at least one monotonic event.
  • Result โ€” knows the values "success" and "resources", with the same meanings as the matching values of the corresponding property on the service interface.

๐Ÿ”„ SWAP UNIT OBJECTS ๐Ÿ”„

every swap unit object implements the org.freedesktop.systemd1.Swap interface (described here) in addition to the generic org.freedesktop.systemd1.Unit interface (see above). two interfaces, one icon ๐Ÿ’…

...and here we go, straight into the properties block, bestie. Buckle up, this is the part where systemd shows you everything it knows about your swap unit's cgroup. ๐Ÿ’…

           node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
             interface org.freedesktop.systemd1.Swap {
               methods:
                 GetProcesses(out a(sus) processes);
                 AttachProcesses(in  s subcgroup,
                                 in  au pids);
                 RemoveSubgroup(in  s subcgroup,
                                in  t flags);
               properties:
                 readonly s What = '...';
                 readonly i Priority = ...;
                 readonly s Options = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutUSec = ...;
                 readonly u ControlPID = ...;
                 readonly s Result = '...';
                 readonly u UID = ...;
                 readonly u GID = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecActivate = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("invalidates")
                 readonly a(sasbttttuii) ExecDeactivate = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s Slice = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ControlGroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ControlGroupId = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryAvailable = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUUsageNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveTasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t OOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b Delegate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DelegateControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DelegateSubgroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupCPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPerSecUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPeriodUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUSetPartition = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupIOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceWeight = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceLatencyTargetUSec = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMin = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryZSwapWriteback = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DevicePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) DeviceAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b TasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPIngressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPEgressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DisableControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMSwap = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMMemoryPressure = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ManagedOOMMemoryPressureLimit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMMemoryPressureDurationUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMPreference = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as OOMRules = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")

okay so let's actually read this thing, because it's giving โœจ lore drop โœจ.

๐Ÿฆ‹ the swap node itself

  • node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap โ€” this is the D-Bus object that is your swap unit, hanging off the manager. It's an interface org.freedesktop.systemd1.Swap living inside it. Very "I have my own address on the bus" of it. ๐Ÿ‘‘

๐Ÿ’… the methods

  • GetProcesses(out a(sus) processes); โ€” hand over the processes, shaped as a(sus).
  • AttachProcesses(in s subcgroup, in au pids); โ€” takes a subcgroup string and an array of pids (au) and attaches them. Note the cute lil double-space after in โ€” that's alignment, bestie, respect the craft.
  • RemoveSubgroup(in s subcgroup, in t flags); โ€” takes a subcgroup and flags (a t, i.e. the 64-bit unsigned type) and removes it.

๐ŸŽ€ the properties, in the order they showed up

First the ones without an EmitsChangedSignal annotation, just raw readonly energy:

  • What (s) โ€” '...'
  • Priority (i) โ€” ...
  • Options (s) โ€” '...'
  • TimeoutUSec (t) โ€” and this one is tagged @org.freedesktop.DBus.Property.EmitsChangedSignal("const"). Only one here with const, so obviously it thinks it's special. ๐Ÿ˜Œ
  • ControlPID (u) โ€” ...
  • Result (s) โ€” '...'
  • UID (u) โ€” ...
  • GID (u) โ€” ...
  • ExecActivate (a(sasbttttuii)) โ€” [...], tagged invalidates.
  • ExecDeactivate (a(sasbttttuii)) โ€” [...], also tagged invalidates. Those two are the only invalidates girlies in this whole block, everyone else got "false". ๐Ÿซถ

And then โ€” every. single. remaining. property. tagged @org.freedesktop.DBus.Property.EmitsChangedSignal("false"). No skips. No shortcuts. Here's the full roll call:

  • Slice (s) '...'
  • ControlGroup (s) '...'
  • ControlGroupId (t) ...
  • MemoryCurrent (t) ...
  • MemoryPeak (t) ...
  • MemorySwapCurrent (t) ...
  • MemorySwapPeak (t) ...
  • MemoryZSwapCurrent (t) ...
  • MemoryAvailable (t) ...
  • EffectiveMemoryMax (t) ...
  • EffectiveMemoryHigh (t) ...
  • CPUUsageNSec (t) ...
  • EffectiveCPUs (ay) [...]
  • EffectiveMemoryNodes (ay) [...]
  • TasksCurrent (t) ...
  • EffectiveTasksMax (t) ...
  • IPIngressBytes (t) ...
  • IPIngressPackets (t) ...
  • IPEgressBytes (t) ...
  • IPEgressPackets (t) ...
  • IOReadBytes (t) ...
  • IOReadOperations (t) ...
  • IOWriteBytes (t) ...
  • IOWriteOperations (t) ...
  • OOMKills (t) ...
  • ManagedOOMKills (t) ...
  • Delegate (b) ...
  • DelegateControllers (as) ['...', ...]
  • DelegateSubgroup (s) '...'
  • CPUWeight (t) ...
  • StartupCPUWeight (t) ...
  • CPUQuotaPerSecUSec (t) ...
  • CPUQuotaPeriodUSec (t) ...
  • AllowedCPUs (ay) [...]
  • StartupAllowedCPUs (ay) [...]
  • AllowedMemoryNodes (ay) [...]
  • StartupAllowedMemoryNodes (ay) [...]
  • CPUSetPartition (s) '...'
  • IOAccounting (b) ...
  • IOWeight (t) ...
  • StartupIOWeight (t) ...
  • IODeviceWeight (a(st)) [...]
  • IOReadBandwidthMax (a(st)) [...]
  • IOWriteBandwidthMax (a(st)) [...]
  • IOReadIOPSMax (a(st)) [...]
  • IOWriteIOPSMax (a(st)) [...]
  • IODeviceLatencyTargetUSec (a(st)) [...]
  • MemoryAccounting (b) ...
  • MemoryMin (t) ...
  • MemoryLow (t) ...
  • StartupMemoryLow (t) ...
  • MemoryHigh (t) ...
  • StartupMemoryHigh (t) ...
  • MemoryMax (t) ...
  • StartupMemoryMax (t) ...
  • MemorySwapMax (t) ...
  • StartupMemorySwapMax (t) ...
  • MemoryZSwapMax (t) ...
  • StartupMemoryZSwapMax (t) ...
  • MemoryZSwapWriteback (b) ...
  • DevicePolicy (s) '...'
  • DeviceAllow (a(ss)) [...]
  • TasksAccounting (b) ...
  • TasksMax (t) ...
  • IPAccounting (b) ...
  • IPAddressAllow (a(iayu)) [...]
  • IPAddressDeny (a(iayu)) [...]
  • IPIngressFilterPath (as) ['...', ...]
  • IPEgressFilterPath (as) ['...', ...]
  • DisableControllers (as) ['...', ...]
  • ManagedOOMSwap (s) '...'
  • ManagedOOMMemoryPressure (s) '...'
  • ManagedOOMMemoryPressureLimit (u) ...
  • ManagedOOMMemoryPressureDurationUSec (t) ...
  • ManagedOOMPreference (s) '...'
  • OOMRules (as) ['...', ...]
  • BPFProgram (a(ss)) [...]
  • SocketBindAllow (a(iiqq)) [...]
  • SocketBindDeny (a(iiqq)) [...]
  • RestrictNetworkInterfaces ((bas)) ...
  • BindNetworkInterface (s) '...'
  • MemoryPressureWatch (s) '...'
  • MemoryPressureThresholdUSec (t) ...

and then the very last line is a dangling @org.freedesktop.DBus.Property.EmitsChangedSignal("false") with nothing after it yet... ๐Ÿ™ˆ which is our cue that this cgroup-property saga is not over, bestie. lowkey cliffhanger. keep scrolling. ๐Ÿ”ฅ

okay bestie we're still deep in the D-Bus property listing and it's giving infinite scroll ๐Ÿ˜ญ grab a strawberry, we're going in ๐Ÿ“

first up: the pressure watch girlies, the NFT set, and a little coredump-receiving moment ๐Ÿ‘‘

                 readonly s CPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;

not me spotting those annotation lines riding along with every single property ๐Ÿ’… they're part of the listing, they're always there, they never leave. iconic consistency honestly.


and now the environment block, where the vibes are strictly "const" โ€” every single one of these is tagged that way, no exceptions, no notes โœจ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as Environment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sb) EnvironmentFiles = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as PassEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as UnsetEnvironment = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u UMask = ...;

Environment, EnvironmentFiles, PassEnvironment, UnsetEnvironment, UMask โ€” the whole environment-and-permissions friend group, all matching, all cute, all "const" ๐ŸŽ€


okay this next chunk is the LONG one. it's the resource-limit section and bestie it does not stop. 32 properties, each with its own annotation above it, and every single one is typed t. hydrate. ๐Ÿงš
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPU = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCPUSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitFSIZESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitDATASoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSTACKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitCORESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRSSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNOFILESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitAS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitASSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROC = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNPROCSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCK = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMEMLOCKSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKS = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitLOCKSSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDING = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitSIGPENDINGSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitMSGQUEUESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICE = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitNICESoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIO = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTPRIOSoft = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIME = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LimitRTTIMESoft = ...;

the way that literally every hard limit has a ...Soft twin right after it?? it's giving matched set, it's giving โœจ symmetry โœจ, it's giving hard-limit-and-soft-limit-besties ๐Ÿซถ and they're ALL "const" obviously, because of course they are.


okay phew, we survived. now: filesystem-and-rooting era ๐ŸŒธ working directories, root images, hashes, signatures, verity, ephemeral roots, extensions, mount images โ€” the whole rooted aesthetic:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s WorkingDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootDirectory = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImage = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) RootImageOptions = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHash = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay RootHashSignature = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootHashSignaturePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootVerity = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b RootEphemeral = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootMStack = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly as ExtensionDirectories = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(sba(ss)) ExtensionImages = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ssba(ss)) MountImages = [...];

look at those type signatures โ€” a(sba(ss)) and a(ssba(ss)) are genuinely doing the most and honestly? they ate ๐Ÿ”ฅ nested-struct realness, no cap. and yup, "const" all the way down, as always ๐Ÿ’œ


now the scheduling-and-vibes department: OOM score, coredump filter, niceness, IO scheduling, CPU scheduling, affinity, NUMA, timer slack, non-blocking. very "main character running a tight ship" energy ๐Ÿ‘‘

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i OOMScoreAdjust = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t CoredumpFilter = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i Nice = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingClass = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i IOSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i CPUSchedulingPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay CPUAffinity = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUAffinityFromNUMA = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i NUMAPolicy = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay NUMAMask = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimerSlackNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b CPUSchedulingResetOnFork = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b NonBlocking = ...;

the range of types here is sending me โ€” i, t, ay, b โ€” a whole alphabet moment ๐Ÿ’€ and yes bestie, every one is "const". we been knew.


standard input, standard output, standard error, and the TTY girls ๐Ÿ’… your three fave file descriptors plus their whole console situation:

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardInputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly ay StandardInputData = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutput = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardOutputFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardError = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s StandardErrorFileDescriptorName = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s TTYPath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYReset = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVHangup = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b TTYVTDisallocate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYRows = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly q TTYColumns = ...;

TTYRows and TTYColumns are typed q which is lowkey the cutest little type letter, and I will not be elaborating ๐ŸŽ€


and finally the logging corner, where the syslog girlies live with the log level, the rate limit, the extra fields and the filter patterns ๐ŸŒˆ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogPriority = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s SyslogIdentifier = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SyslogLevelPrefix = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogLevel = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i SyslogFacility = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i LogLevelMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t LogRateLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u LogRateLimitBurst = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly aay LogExtraFields = [[...], ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(bs) LogFilterPatterns = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")

LogExtraFields is aay with [[...], ...] โ€” an array of arrays of bytes, double-nested, doing the absolute most, and I'm obsessed ๐Ÿ™ˆ and look, the chunk ends on a lone "const" annotation just hanging there with no property after it โ€” which means the next property is coming in the next part bestie, so hold that thought ๐Ÿ’–

okay so we're still deep in the SERVICE unit property list, bestie โ€” this is the sandbox-and-security chunk and it is long, but every single one of these is a D-Bus property you can read back, and they all got EmitsChangedSignal("const") on them, which means โœจ they never change at runtime โœจ so don't be out here waiting for a signal that's never coming. Let's go group by group. ๐Ÿซถ


namespaces, caps, and secure bits ๐Ÿ’…

who even are you, security-wise:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s LogNamespace = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SecureBits = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t CapabilityBoundingSet = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t AmbientCapabilities = ...;

the whole identity crisis section ๐Ÿ‘‘

user, group, dynamic user, login env, IPC cleanup:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s User = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Group = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b DynamicUser = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b SetLoginEnvironment = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;

credentials, the secret handshake ๐ŸŽ€

all the ways a unit gets handed its lil secrets โ€” set 'em, set 'em encrypted, load 'em, load 'em encrypted, import 'em, import 'em extended:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(say) SetCredential = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(say) SetCredentialEncrypted = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) LoadCredential = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) LoadCredentialEncrypted = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ImportCredential = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) ImportCredentialEx = [...];

groups & PAM ๐ŸŒธ

extra groups and the PAM service name, iconic:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';

paths: rw, ro, nope, exec, no-exec ๐Ÿฆ‹

where the unit may write, where it may only read, where it may not even look, where it's allowed to exec from, and where it absolutely is not โ€” plus the mount flags. periodt.

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ReadWritePaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ReadOnlyPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as InaccessiblePaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ExecPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as NoExecPaths = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ExecSearchPath = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t MountFlags = ...;

the big ol' Private & Protect wall ๐Ÿงฑ

okay bestie this is the main character block. every Privateโ€ฆ and every Protectโ€ฆ lives here, and there's a bunch of โ€ฆEx variants too. no skipping, no cap:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateTmp = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PrivateTmpEx = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateDevices = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectClock = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelTunables = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelModules = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectKernelLogs = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectControlGroups = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectControlGroupsEx = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateNetwork = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateUsers = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PrivateUsersEx = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateMounts = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b PrivateIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PrivatePIDs = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectHome = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectSystem = '...';

process group & utmp stuff ๐Ÿ’œ

sharing a process group, plus how it shows up in the utmp/wtmp records:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b SameProcessGroup = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s UtmpIdentifier = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s UtmpMode = '...';

MAC labels (the security-module trio) ๐ŸŒˆ

SELinux, AppArmor, Smack โ€” all three of 'em, all (bs) tuples:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bs) SELinuxContext = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bs) AppArmorProfile = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bs) SmackProcessLabel = ...;

a couple of lil b's ๐Ÿ“

SIGPIPE and privilege escalation, both just booleans:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b IgnoreSIGPIPE = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b NoNewPrivileges = ...;

syscall filtering ๐ŸŽฏ

the seccomp situation โ€” the filter itself, the architectures, the errno to return, and what gets logged:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bas) SystemCallFilter = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SystemCallArchitectures = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly i SystemCallErrorNumber = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bas) SystemCallLog = ...;

personality โœจ

the personality setting and whether it's locked down:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Personality = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b LockPersonality = ...;

address families ๐ŸŒ

which socket families are allowed, as a (bas) tuple:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bas) RestrictAddressFamilies = ...;

the directories saga ๐Ÿ“

runtime, state, cache, logs, config โ€” each one gets a symlink list, a mode, sometimes accounting and quota, and the plain name list. it's giving organized. ๐Ÿ’…

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(sst) RuntimeDirectorySymlink = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s RuntimeDirectoryPreserve = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u RuntimeDirectoryMode = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as RuntimeDirectory = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(sst) StateDirectorySymlink = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u StateDirectoryMode = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b StateDirectoryAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (tus) StateDirectoryQuota = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as StateDirectory = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(sst) CacheDirectorySymlink = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u CacheDirectoryMode = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CacheDirectoryAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (tus) CacheDirectoryQuota = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as CacheDirectory = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(sst) LogsDirectorySymlink = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u LogsDirectoryMode = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b LogsDirectoryAccounting = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (tus) LogsDirectoryQuota = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as LogsDirectory = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly u ConfigurationDirectoryMode = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as ConfigurationDirectory = ['...', ...];
note: config directories only get a mode and a name list โ€” no symlink list, no accounting, no quota. that's just how it is, bestie. ๐Ÿ™ˆ

timeouts, memory, realtime, namespaces, filesystems ๐Ÿ”ฅ

the cleanup timeout, W^X enforcement, realtime restriction, setuid/setgid restriction, namespace restriction, namespace delegation, and filesystem restriction:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t TimeoutCleanUSec = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MemoryDenyWriteExecute = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RestrictRealtime = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RestrictSUIDSGID = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t RestrictNamespaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly t DelegateNamespaces = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly (bas) RestrictFileSystems = ...;

bind mounts & tmpfs ๐Ÿช„

bind mounts (rw and ro), temporary filesystems, whether to mount the API VFS, and whether to bind log sockets:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ssbt) BindPaths = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ssbt) BindReadOnlyPaths = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly a(ss) TemporaryFileSystem = [...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b MountAPIVFS = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b BindLogSockets = ...;

keyring & /proc ๐Ÿ—๏ธ

the keyring mode, plus the two /proc knobs โ€” ProtectProc and ProcSubset:

@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProtectProc = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s ProcSubset = '...';

and that's the whole security-and-sandbox property spread, bestie โ€” every one readonly, every one const, every one exactly what you asked for. more coming, don't go anywhere ๐Ÿ’–

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b ProtectHostname = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (ss) ProtectHostnameEx = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s PrivateBPF = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateCommands = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateMaps = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegatePrograms = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s BPFDelegateAttachments = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MemoryKSM = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MemoryTHP = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s UserNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s NetworkNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s IPCNamespacePath = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s RootImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s MountImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s ExtensionImagePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) StateDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) CacheDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (tt) LogsDirectoryQuotaUsage = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KillMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i KillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i RestartKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FinalKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGKILL = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGHUP = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i WatchdogSignal = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

โœจ Properties โœจ

okay so most of these properties just map straight onto the matching settings in your swap unit files, no plot twist ๐Ÿ’–.

But here's the cute lil detail: swap units literally invoke the swapon(8) command, so their bus objects come with implicit ExecActivate (and similar) fields baked in โ€” those hold the info about which processes get executed. ๐Ÿซถ

They also share most of the execution-context fields that Service objects expose (scroll up bestie, they're right there ๐Ÿ‘†).

And on top of all that, you also get these:

  • ControlPID โ€” holds the PID of the currently running swapon(8) or swapoff(8) command if one's actually running. If nothing's running? It's 0. simple as that ๐Ÿ’…
  • Result โ€” the lil explanation of why a mount unit failed, if it failed. It can be "success", "resources", "timeout", "exit-code", "signal", or "core-dump" โ€” and those have the identical meanings as the corresponding values of the corresponding field of service unit objects (again, see above ๐Ÿ‘€).

๐Ÿฆ‹ PATH UNIT OBJECTS ๐Ÿฆ‹

           node /org/freedesktop/systemd1/unit/cups_2epath {
             interface org.freedesktop.systemd1.Path {
               properties:
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s Unit = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) Paths = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b MakeDirectory = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u DirectoryMode = ...;
                 readonly s Result = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TriggerLimitIntervalUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u TriggerLimitBurst = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

โœจ Properties โœจ

fr fr, most of these properties correspond directly with the matching settings in path unit files. no notes. ๐ŸŒธ

Now the others:

  • Paths โ€” this one's an array of structs ๐Ÿ“š. Each struct holds two things: the condition to watch, and the path to watch (which can totally include glob expressions โœจ).

The condition can be one of "PathExists", "PathExistsGlob", "PathChanged", "PathModified", or "DirectoryNotEmpty" โ€” and those correspond directly to the matching settings in the path unit files. iykyk ๐Ÿ’…

  • Result โ€” a result value that can be either "success" or "resources", and these have the same meaning as the corresponding field of the Service interface. ๐ŸŽ€

๐Ÿ“ SLICE UNIT OBJECTS ๐Ÿ“

Okay bestie, listen up: all slice unit objects implement the org.freedesktop.systemd1.Slice interface (described right here, like literally in this bit ๐Ÿ‘‡) in addition to the generic org.freedesktop.systemd1.Unit interface (see above ๐Ÿ‘†).

okay so this is the part where we actually open up a slice and look at its D-Bus glow-up ๐Ÿ’… like, the object path, the interface, the methods, the entire property roster. it's giving "backstage pass to the cgroup". let's go.

           node /org/freedesktop/systemd1/unit/system_2eslice {
             interface org.freedesktop.systemd1.Slice {
               methods:
                 GetProcesses(out a(sus) processes);
                 AttachProcesses(in  s subcgroup,
                                 in  au pids);
                 RemoveSubgroup(in  s subcgroup,
                                in  t flags);

so the node lives at /org/freedesktop/systemd1/unit/system_2eslice โ€” that _2e is just an escaped ., bestie, don't panic ๐Ÿซถ โ€” and the interface hanging off it is org.freedesktop.systemd1.Slice. three methods on deck:

  • GetProcesses(out a(sus) processes) โ€” hands you back an array of structs, each one a (string, uint32, string) triple. no args in, just vibes out.
  • AttachProcesses(in s subcgroup, in au pids) โ€” you give it a subcgroup string and an array of uint32 PIDs (au = array of unsigned 32-bit).
  • RemoveSubgroup(in s subcgroup, in t flags) โ€” subcgroup string plus a t (that's a 64-bit unsigned, the chunky one) of flags.

now the properties โœจ and listen, every single one of them is stamped with:

@org.freedesktop.DBus.Property.EmitsChangedSignal("false")

which is the annotation that says "don't sit around waiting for a change signal on this one" ๐Ÿ˜Œ it's on all of them. every. single. one. so I'm not gonna re-read it 90 times, but it is genuinely there on each property, no cap.


โœจ the concurrency girls โœจ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ConcurrencyHardMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ConcurrencySoftMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ActivatingConcurrencyMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u NCurrentlyActive = ...;

four us (32-bit unsigned) all readonly, all ... for the value, because the actual number is a runtime thing, not a spec thing. ConcurrencyHardMax, ConcurrencySoftMax, ActivatingConcurrencyMax, NCurrentlyActive. iconic lineup tbh ๐Ÿ‘‘

๐ŸŒธ where it sits in the world ๐ŸŒธ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s Slice = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ControlGroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ControlGroupId = ...;

strings get quoted '...', numbers get bare .... Slice and ControlGroup are s, ControlGroupId is a t. and yes ControlGroupId is readonly t โ€” 64-bit, big girl numbers.

๐Ÿฆ‹ memory, but the live numbers ๐Ÿฆ‹

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryAvailable = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryHigh = ...;

eight ts. current, peak, swap current, swap peak, zswap current, available, and then the two effective ones โ€” EffectiveMemoryMax and EffectiveMemoryHigh. note the word effective, bestie, that's the computed one, not the one you typed in the config ๐Ÿ’€

๐Ÿ’œ cpu + placement tea ๐Ÿ’œ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUUsageNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveMemoryNodes = [...];

CPUUsageNSec is a plain t. then EffectiveCPUs and EffectiveMemoryNodes are ay โ€” arrays of bytes, shown as [...] โ€” that's a bitmask situation, not a list of numbers you can just eyeball ๐Ÿ˜ญ

๐ŸŽ€ tasks + network + io counters ๐ŸŽ€

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveTasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t OOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMKills = ...;

counters counters counters. tasks current + effective max, four IP counters (ingress/egress ร— bytes/packets), four IO counters (read/write ร— bytes/operations), and the two OOM tallies โ€” OOMKills and ManagedOOMKills. all t, all readonly, all vibing ๐Ÿ’€

๐Ÿงš delegation era ๐Ÿงš

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b Delegate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DelegateControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DelegateSubgroup = '...';

Delegate is a b โ€” boolean, true/false energy. DelegateControllers is an as โ€” array of strings, and the sample is ['...', ...] so it's showing "one or more of these". DelegateSubgroup is a single s. cute. concise. obsessed.

๐Ÿ”ฅ cpu weight + quota + affinity ๐Ÿ”ฅ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupCPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPerSecUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPeriodUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUSetPartition = '...';

weights, then both flavours of the quota (PerSecUSec and PeriodUSec), then the four ay bitmask arrays โ€” and notice StartupAllowedCPUs and StartupAllowedMemoryNodes are the startup twins ๐Ÿ‘ฏ plus CPUSetPartition as a lone s at the end, standing there, serving.

๐ŸŒˆ io, the full spread ๐ŸŒˆ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupIOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceWeight = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceLatencyTargetUSec = [...];

IOAccounting is a b, IOWeight and StartupIOWeight are ts, and then six a(st) arrays โ€” that's array-of-struct where each struct is (string, uint64), i.e. a device path paired with a number. IODeviceWeight, IOReadBandwidthMax, IOWriteBandwidthMax, IOReadIOPSMax, IOWriteIOPSMax, IODeviceLatencyTargetUSec. six of them. ate ๐Ÿ’…

๐Ÿ“ memory settings, the whole alphabet ๐Ÿ“

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMin = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryZSwapWriteback = ...;

this is the big one, okay. MemoryAccounting = b. then MemoryMin, MemoryLow, StartupMemoryLow, MemoryHigh, StartupMemoryHigh, MemoryMax, StartupMemoryMax, MemorySwapMax, StartupMemorySwapMax, MemoryZSwapMax, StartupMemoryZSwapMax โ€” all t, and the startup twins are right there beside their originals ๐Ÿซถ โ€” and then MemoryZSwapWriteback rounds it off as a b. periodt.

โญ devices + tasks + ip filtering โญ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DevicePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) DeviceAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b TasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPIngressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPEgressFilterPath = ['...', ...];

DevicePolicy is a single s, DeviceAllow is a(ss) โ€” array of string-pairs. TasksAccounting = b, TasksMax = t. IPAccounting = b, and then IPAddressAllow / IPAddressDeny are a(iayu) โ€” array of structs of (int32, byte-array, uint32). then two as string arrays: IPIngressFilterPath and IPEgressFilterPath. okayyy ๐ŸŒธ

๐Ÿ‘‘ controllers + oom management ๐Ÿ‘‘

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DisableControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMSwap = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMMemoryPressure = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ManagedOOMMemoryPressureLimit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMMemoryPressureDurationUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMPreference = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as OOMRules = ['...', ...];

DisableControllers = as. then the managed-OOM crew: ManagedOOMSwap (s), ManagedOOMMemoryPressure (s), ManagedOOMMemoryPressureLimit (u), ManagedOOMMemoryPressureDurationUSec (t โ€” note the USec, it's microseconds, don't get got), ManagedOOMPreference (s), and OOMRules (as). the whole family is here ๐Ÿ˜ญ

๐Ÿ’– bpf, sockets, network interfaces ๐Ÿ’–

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';

BPFProgram is a(ss). SocketBindAllow and SocketBindDeny are a(iiqq) โ€” array of structs of (int32, int32, uint16, uint16). RestrictNetworkInterfaces is a plain struct (bas) = (bool, array-of-strings) โ€” not an array, just one struct, keep it straight bestie. and BindNetworkInterface is a lone s.

๐Ÿ’œ pressure watch, the finale of this part ๐Ÿ’œ

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;

four left and they're a tidy little pattern: a s watch setting and a t microsecond threshold, once for Memory and once for CPU. MemoryPressureWatch, MemoryPressureThresholdUSec, CPUPressureWatch, CPUPressureThresholdUSec. clean. symmetrical. we love a consistent queen โœจ


and that's where this chunk cuts off โ€” the node's still open, the braces haven't closed, we're literally mid-object ๐Ÿ˜ญ hold on to your seats, the rest is coming ๐ŸŽ€

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

and that's the whole interface, closed out, bow on top ๐ŸŽ€ like yes we did just read every single property together and we're still standing


โœจ Properties โœจ

okay so the tea on these: most of them just mirror the matching settings in slice unit files. like, you know how you write a setting in the unit file? boom, there's a property with basically the same job. no cap, it's giving "the file and the bus are the same person wearing different outfits" ๐Ÿ’…

One lil glow-up exception tho: ManagedOOMMemoryPressureDurationUSec is the one that implements the destination parameter of the unit file setting ManagedOOMMemoryPressureDurationSec= that's listed over in systemd.resource-control(5). ๐Ÿ“–

โš ๏ธ heads up bestie: notice the time unit here is expressed in "ฮผs". that's microseconds, not seconds. the name switches from Sec to USec for a reason and the property is literally spelled with that U โ€” don't come for me, that's just what it says ๐Ÿ˜ญ๐Ÿ™ˆ

โœจ SCOPE UNIT OBJECTS โœจ

so, scope units. every single scope unit object implements the org.freedesktop.systemd1.Scope interface โ€” which is the one described right here, yes, this exact section, hi hello welcome ๐Ÿซถ โ€” plus the generic org.freedesktop.systemd1.Unit interface, which is the one we went over way up above ๐Ÿ‘‘

so like. two interfaces. one object. it's giving layered outfit, it's giving main character with a supporting cast, and honestly? iconic. ๐ŸŒˆโœจ


...and here's where it gets real โ€” this is the actual D-Bus shape of a scope unit, live from the bus. Bestie, this is the โœจreceiptsโœจ part. Every property, every annotation, exactly as it appears on the wire ๐Ÿ‘‘

           node /org/freedesktop/systemd1/unit/session_2d1_2escope {
             interface org.freedesktop.systemd1.Scope {
               methods:
                 Abandon();
                 GetProcesses(out a(sus) processes);
                 AttachProcesses(in  s subcgroup,
                                 in  au pids);
                 RemoveSubgroup(in  s subcgroup,
                                in  t flags);
               signals:
                 RequestStop();
               properties:
                 readonly s Controller = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t TimeoutStopUSec = ...;
                 readonly s Result = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RuntimeMaxUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly t RuntimeRandomizedExtraUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s OOMPolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s Slice = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ControlGroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ControlGroupId = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapPeak = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryAvailable = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUUsageNSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay EffectiveMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksCurrent = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t EffectiveTasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPIngressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IPEgressPackets = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOReadOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteBytes = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWriteOperations = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t OOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMKills = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b Delegate = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DelegateControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DelegateSubgroup = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupCPUWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPerSecUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUQuotaPeriodUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedCPUs = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay AllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly ay StartupAllowedMemoryNodes = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUSetPartition = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IOAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupIOWeight = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceWeight = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteBandwidthMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOReadIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IOWriteIOPSMax = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(st) IODeviceLatencyTargetUSec = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMin = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryLow = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryHigh = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemorySwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t StartupMemoryZSwapMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b MemoryZSwapWriteback = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s DevicePolicy = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) DeviceAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b TasksAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t TasksMax = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b IPAccounting = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iayu) IPAddressDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPIngressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as IPEgressFilterPath = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as DisableControllers = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMSwap = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMMemoryPressure = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly u ManagedOOMMemoryPressureLimit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t ManagedOOMMemoryPressureDurationUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s ManagedOOMPreference = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly as OOMRules = ['...', ...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(ss) BPFProgram = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindAllow = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiqq) SocketBindDeny = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly (bas) RestrictNetworkInterfaces = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s BindNetworkInterface = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s MemoryPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t MemoryPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s CPUPressureWatch = '...';

So what are we even looking at, bestie? This is one node on the system bus. The path /org/freedesktop/systemd1/unit/session_2d1_2escope is the escaped name of a scope unit โ€” _2d is a - and _2e is a ., that's the D-Bus escaping doing its little magic so the name can live in a path ๐Ÿ’…. Inside it sits the interface org.freedesktop.systemd1.Scope, and that's where all the tea is.

The methods, aka the buttons you can press ๐ŸŽ€

  • Abandon() โ€” takes nothing in, gives nothing back. Zero args, zero return, just vibes.
  • GetProcesses(out a(sus) processes) โ€” no inputs, but it hands you back processes, an array of structs shaped (s, u, s).
  • AttachProcesses(in s subcgroup, in au pids) โ€” takes subcgroup (a string) and pids (an array of unsigned 32-bit ints). No return.
  • RemoveSubgroup(in s subcgroup, in t flags) โ€” takes subcgroup (string) and flags (a 64-bit unsigned int). No return.

The signal ๐Ÿฆ‹

  • RequestStop() โ€” no arguments, no return, just a signal showing up in your subscription like a little tap on the shoulder.

The properties ๐Ÿ‘‘

Quick key before we dive, because the annotations are doing a lot of heavy lifting here:

  • @org.freedesktop.DBus.Property.EmitsChangedSignal("const") โ€” this one is const, it doesn't change.
  • @org.freedesktop.DBus.Property.EmitsChangedSignal("false") โ€” no change signal gets emitted for it.

And the type letters, since I know you're gonna ask: s is a string, b is a boolean, t is a 64-bit unsigned integer, u is a 32-bit unsigned integer, ay is an array of bytes, as is an array of strings, and the ones in parens like a(st) are arrays of structs.


Identity and lifecycle era โœจ

  • Controller โ€” type s, and no annotation at all on this one.
  • TimeoutStopUSec โ€” type t, marked const.
  • Result โ€” type s, no annotation.
  • RuntimeMaxUSec โ€” type t, marked const.
  • RuntimeRandomizedExtraUSec โ€” type t, marked const.
  • OOMPolicy โ€” type s, marked const.

cgroup + live accounting (all of these are false, so no change signals, bestie) ๐Ÿ“Š

  • Slice โ€” type s.
  • ControlGroup โ€” type s.
  • ControlGroupId โ€” type t.
  • MemoryCurrent โ€” type t.
  • MemoryPeak โ€” type t.
  • MemorySwapCurrent โ€” type t.
  • MemorySwapPeak โ€” type t.
  • MemoryZSwapCurrent โ€” type t.
  • MemoryAvailable โ€” type t.
  • EffectiveMemoryMax โ€” type t.
  • EffectiveMemoryHigh โ€” type t.
  • CPUUsageNSec โ€” type t.
  • EffectiveCPUs โ€” type ay, an array of bytes.
  • EffectiveMemoryNodes โ€” type ay, an array of bytes.
  • TasksCurrent โ€” type t.
  • EffectiveTasksMax โ€” type t.
  • IPIngressBytes โ€” type t.
  • IPIngressPackets โ€” type t.
  • IPEgressBytes โ€” type t.
  • IPEgressPackets โ€” type t.
  • IOReadBytes โ€” type t.
  • IOReadOperations โ€” type t.
  • IOWriteBytes โ€” type t.
  • IOWriteOperations โ€” type t.
  • OOMKills โ€” type t.
  • ManagedOOMKills โ€” type t.

Delegation corner ๐Ÿซถ

  • Delegate โ€” type b, a boolean.
  • DelegateControllers โ€” type as, an array of strings.
  • DelegateSubgroup โ€” type s.

CPU settings, the whole set โญ

  • CPUWeight โ€” type t.
  • StartupCPUWeight โ€” type t.
  • CPUQuotaPerSecUSec โ€” type t.
  • CPUQuotaPeriodUSec โ€” type t.
  • AllowedCPUs โ€” type ay.
  • StartupAllowedCPUs โ€” type ay.
  • AllowedMemoryNodes โ€” type ay.
  • StartupAllowedMemoryNodes โ€” type ay.
  • CPUSetPartition โ€” type s.

IO settings, she's thorough ๐Ÿ’œ

  • IOAccounting โ€” type b.
  • IOWeight โ€” type t.
  • StartupIOWeight โ€” type t.
  • IODeviceWeight โ€” type a(st), an array of (string, uint64) structs.
  • IOReadBandwidthMax โ€” type a(st).
  • IOWriteBandwidthMax โ€” type a(st).
  • IOReadIOPSMax โ€” type a(st).
  • IOWriteIOPSMax โ€” type a(st).
  • IODeviceLatencyTargetUSec โ€” type a(st).

Memory settings, and yes there are a LOT ๐ŸŒธ

  • MemoryAccounting โ€” type b.
  • MemoryMin โ€” type t.
  • MemoryLow โ€” type t.
  • StartupMemoryLow โ€” type t.
  • MemoryHigh โ€” type t.
  • StartupMemoryHigh โ€” type t.
  • MemoryMax โ€” type t.
  • StartupMemoryMax โ€” type t.
  • MemorySwapMax โ€” type t.
  • StartupMemorySwapMax โ€” type t.
  • MemoryZSwapMax โ€” type t.
  • StartupMemoryZSwapMax โ€” type t.
  • MemoryZSwapWriteback โ€” type b.

Devices + tasks ๐ŸŽ€

  • DevicePolicy โ€” type s.
  • DeviceAllow โ€” type a(ss), an array of (string, string) structs.
  • TasksAccounting โ€” type b.
  • TasksMax โ€” type t.

Network, IP and OOM behaviour ๐Ÿ”ฅ

  • IPAccounting โ€” type b.
  • IPAddressAllow โ€” type a(iayu), an array of (int32, array of bytes, uint32) structs.
  • IPAddressDeny โ€” type a(iayu).
  • IPIngressFilterPath โ€” type as.
  • IPEgressFilterPath โ€” type as.
  • DisableControllers โ€” type as.
  • ManagedOOMSwap โ€” type s.
  • ManagedOOMMemoryPressure โ€” type s.
  • ManagedOOMMemoryPressureLimit โ€” type u, a 32-bit unsigned int.
  • ManagedOOMMemoryPressureDurationUSec โ€” type t.
  • ManagedOOMPreference โ€” type s.
  • OOMRules โ€” type as.

Sandboxing + pressure watch, the final stretch ๐ŸŒˆ

  • BPFProgram โ€” type a(ss), an array of (string, string) structs.
  • SocketBindAllow โ€” type a(iiqq), an array of (int32, int32, int16, int16) structs.
  • SocketBindDeny โ€” type a(iiqq).
  • RestrictNetworkInterfaces โ€” type (bas), a single struct of (boolean, array of strings).
  • BindNetworkInterface โ€” type s.
  • MemoryPressureWatch โ€” type s.
  • MemoryPressureThresholdUSec โ€” type t.
  • CPUPressureWatch โ€” type s.

That's the whole interface, no skips, no crumbs left behind ๐Ÿ“ and there's still more coming, so don't go anywhere ๐Ÿ’–

                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t CPUPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly s IOPressureWatch = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly t IOPressureThresholdUSec = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly a(iiss) NFTSet = [...];
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
                 readonly b CoredumpReceive = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s KillMode = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i KillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i RestartKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i FinalKillSignal = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGKILL = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly b SendSIGHUP = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly i WatchdogSignal = ...;
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
             interface org.freedesktop.systemd1.Unit { ... };
           };

okay so that's the tail end of the scope interface ๐Ÿ’… and now we get into the good stuff โ€” the methods and signals for scopes, bestie, let's GO โœจ


Methods ๐Ÿ› ๏ธ

  • Abandon() โ€” this one is iconic honestly. It lets you drop a scope unit into the "abandoned" state ๐Ÿซถ. Basically you're telling the system manager "hey, the manager that made this scope? it lost interest, k? it's peacing out" โ€” like when it's terminating โ€” without actually wanting to shut the whole scope down. So the scope stays alive, you just stop being its problem. periodt ๐Ÿ’€

Signals ๐Ÿ“ก

  • RequestStop() โ€” this gets sent to whoever is configured in the Controller property when systemd is asked to terminate the scope unit. And here's the slay part: a program that registered a scope can use this to cleanly shut down the processes it added to the scope, instead of just letting systemd come in and do it with the usual SIGTERM logic ๐Ÿ˜ญโœจ. It's giving considerate. It's giving let me handle my own kids.

Properties ๐Ÿท๏ธ

Lowkey the biggest vibe here: all properties correspond directly with the matching properties of service units. No new lore, same energy ๐Ÿ’–.

  • Controller โ€” holds the bus name (could be unique or well-known) that gets notified when the scope unit is about to be shut down, via that RequestStop() signal we just talked about (see above โฌ†๏ธ). This gets set when the scope is created. And if it's not set? Then the scope's processes get terminated with SIGTERM directly. No heads-up, just vibes and signals ๐Ÿ’….
  • ManagedOOMMemoryPressureDurationUSec โ€” this implements the destination parameter of the unit file setting ManagedOOMMemoryPressureDurationSec= listed over in systemd.resource-control(5). And ngl, note that the time unit is expressed in "ฮผs" โ€” yes bestie, microseconds, don't come for me ๐ŸŒธ.

๐ŸŒˆ JOB OBJECTS ๐ŸŒˆ

Okay so job objects?? They encapsulate scheduled or running jobs ๐ŸŽ€. Real talk: each unit can have none or one jobs in the execution queue, and each job is attached to exactly one unit. One unit, one job, no sharing, we don't do situationships here ๐Ÿ™ˆ.

           node /org/freedesktop/systemd1/job/666 {
             interface org.freedesktop.systemd1.Job {
               methods:
                 Cancel();
                 GetAfter(out a(usssoo) jobs);
                 GetBefore(out a(usssoo) jobs);
               properties:
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly u Id = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly (so) Unit = ...;
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly s JobType = '...';
                 readonly s State = '...';
                 @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
                 readonly a(ss) ActivationDetails = [...];
             };
             interface org.freedesktop.DBus.Peer { ... };
             interface org.freedesktop.DBus.Introspectable { ... };
             interface org.freedesktop.DBus.Properties { ... };
           };

Methods ๐Ÿ› ๏ธ

  • Cancel() โ€” cancels the job, bestie ๐Ÿ’…. But lowkey important caveat: this will remove a job from the queue if it is not yet executed, but generally it will not cause a job that's already in the process of being executed to be aborted ๐Ÿ˜ญ. So it's giving "you can cancel the plans but not the thing that's already happening." Also you can request this same operation via the CancelJob() method of the Manager object (see above โฌ†๏ธ), which is sometimes useful to reduce roundtrips โ€” efficiency queen โœจ.

Properties ๐Ÿท๏ธ

  • Id โ€” the numeric Id of the job ๐Ÿ”ข. And here's the tea: during the runtime of a systemd instance, each numeric ID is only assigned once. No recycling, no repeats, each number is its own main character ๐Ÿ‘‘.
  • Unit โ€” refers to the unit this job belongs to. It's a structure consisting of the name of the unit and a bus path to the unit's object ๐Ÿฆ‹.
  • JobType โ€” the job's type, and it's one of "start", "verify-active", "stop", "reload", "restart", "try-restart", or "reload-or-start". And heads up: note that later versions might define additional values ๐Ÿ‘€ so don't hardcode your assumptions, k?
  • State โ€” the job's state, and it's one of "waiting" and "running" ๐Ÿƒ. The former means a job is currently queued but has not begun to execute yet (it's in its waiting era ๐Ÿ˜Œ). The latter means a job is currently being executed (it's booked and busy ๐Ÿ’…).
  • ActivationDetails โ€” has the exact same content as the property of the same name under the org.freedesktop.systemd1.Unit interface. Same content, different day ๐Ÿ’–.

โœจ EXAMPLES โœจ

Get you a manpage that SHOWS you instead of just telling you, fr fr ๐Ÿซถ

Example 1. Introspect org.freedesktop.systemd1.Manager on the bus ๐Ÿ”

$ gdbus introspect --system \
        --dest org.freedesktop.systemd1 \
        --object-path /org/freedesktop/systemd1

Example 2. Introspect a unit on the bus ๐Ÿฆ‹

$ busctl introspect org.freedesktop.systemd1 \
  $(busctl call org.freedesktop.systemd1 \
     /org/freedesktop/systemd1 \
     org.freedesktop.systemd1.Manager \
     GetUnit s systemd-resolved.service | cut -d'"' -f2)

Look at that nested command substitution, bestie ๐Ÿ˜ญ it's giving I contain multitudes.

Example 3. Introspect org.freedesktop.systemd1.Job on the bus ๐Ÿ’ผ

$ gdbus introspect --system --dest org.freedesktop.systemd1 \
  --object-path /org/freedesktop/systemd1/job/1292

๐ŸŽ€ VERSIONING ๐ŸŽ€

These D-Bus interfaces follow the usual interface versioning guidelines<sup>[4]</sup> โ€” yes, there's a footnote, and yes, it's real, go look it up iykyk ๐Ÿ“šโœจ.


๐Ÿ’œ HISTORY ๐Ÿ’œ

This is the lore drop section. Grab a snack, we're going through everything that ever got added and when ๐Ÿ“

The Manager Object ๐Ÿ‘‘

  • RuntimeWatchdogPreUSec and RuntimeWatchdogPreGovernor were added in version 251.
  • WatchdogDevice, WatchdogLastPingTimestamp, WatchdogLastPingTimestampMonotonic, DefaultDeviceTimeoutUSec, DumpUnitsMatchingPatterns(), and DumpUnitsMatchingPatternsByFileDescriptor() were added in version 252.
  • GetUnitByPIDFD() and DisableUnitFilesWithFlagsAndInstallInfo() were added in version 253.
  • ConfidentialVirtualization, DefaultIOAccounting, DefaultIPAccounting, DefaultMemoryPressureThresholdUSec, DefaultMemoryPressureWatch, QueueSignalUnit(), SoftReboot(), and DumpUnitFileDescriptorStore() were added in version 254.
  • StartAuxiliaryScope() was added in version 256, deprecated in version 257, removed in version 258. RIP bozo, we barely knew ye ๐Ÿ’€ (but fr, don't use it, it's gone).
  • ShutdownStartTimestamp, ShutdownStartTimestampMonotonic, and SoftRebootsCount were added in version 256.
  • DefaultRestrictSUIDSGID, RemoveSubgroupFromUnit(), and KillUnitSubgroup() were added in version 258.
  • TransactionsWithOrderingCycle was added in version 259.
  • DefaultMemoryZSwapWriteback, DefaultCPUPressureThresholdUSec, DefaultCPUPressureWatch, DefaultIOPressureThresholdUSec, DefaultIOPressureWatch, ReloadCount, EventLoopRateLimitIntervalUSec, and EventLoopRateLimitBurst were added in version 261.
  • KExecCount, EnqueueUnitJobMany(), ShutdownFinishTimestamp, ShutdownFinishTimestampMonotonic, PreviousShutdownStartTimestamp, PreviousShutdownStartTimestampMonotonic, PreviousShutdownFinishTimestamp, PreviousShutdownFinishTimestampMonotonic, PreviousShutdownLateStartTimestamp, PreviousShutdownLateStartTimestampMonotonic, PreviousShutdownLateFinishTimestamp, and PreviousShutdownLateFinishTimestampMonotonic were added in version 262. That's a whole paragraph of timestamps and I respect the commitment ๐Ÿซถ.

Unit Objects ๐Ÿงฉ

  • Upholds and UpheldBy were added in version 251.
  • AccessSELinuxContext and ActivationDetails were added in version 252.
  • QueueSignal() was added in version 254.
  • SurviveFinalKillSignal was added in version 255.
  • WantsMountsFor was added in version 256.
  • DebugInvocation, and CanLiveMount were added in version 257.

Service Unit Objects ๐Ÿ›Ž๏ธ

  • ControlGroupId and ExtensionDirectories were added in version 251.
  • OpenFile, ReloadSignal, MemoryZSwapMax, and LogFilterPatterns were added in version 253.
  • RestartMode, RestartSteps, RestartMaxDelayUSec, RestartUSecNext, FileDescriptorStorePreserve, DumpFileDescriptorStore(), DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, MemoryPressureThresholdUSec, RootEphemeral, ImportCredential, MemoryKSM, RootImagePolicy, MountImagePolicy, and ExtensionImagePolicy were added in version 254.
  • NFTSet, SetLoginEnvironment, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, MemoryZSwapWriteback, ExecMainHandoffTimestampMonotonic, and ExecMainHandoffTimestamp were added in version 256.
  • StatusBusError, StatusVarlinkError, LiveMountResult, PrivateTmpEx, ImportCredentialEx, ExtraFileDescriptorNames, ManagedOOMMemoryPressureDurationUSec, BindLogSockets, ProtectControlGroupsEx, PrivateUsersEx, and PrivatePIDs were added in version 257.
  • ProtectHostnameEx, DelegateNamespaces, PrivateBPF, BPFDelegateCommands, BPFDelegateMaps, BPFDelegatePrograms, BPFDelegateAttachments, RemoveSubGroup(), StateDirectoryQuota, StateDirectoryQuotaUsage, StateDirectoryAccounting, CacheDirectoryQuota, CacheDirectoryQuotaUsage, CacheDirectoryAccounting, LogsDirectoryQuota, LogsDirectoryQuotaUsage, LogsDirectoryAccounting, and KillSubgroup() were added in version 258.
  • UserNamespacePath, OOMKills, ManagedOOMKills, ExecReloadPost, and ExecReloadPostEx were added in version 259.
  • BindNetworkInterface, MemoryTHP, RefreshOnReload, and RootMStack were added in version 260.
  • CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.
  • LUOSession was added in version 262.
  • RestartRandomizedDelayUSec was added in version 262.

Socket Unit Objects ๐Ÿ”Œ

  • ControlGroupId and ExtensionDirectories were added in version 251.
  • MemoryZSwapMax and LogFilterPatterns were added in version 253.
  • DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, MemoryPressureThresholdUSec, RootEphemeral, ImportCredential, MemoryKSM, RootImagePolicy, MountImagePolicy, and ExtensionImagePolicy were added in version 254.
  • PollLimitIntervalUSec, PollLimitBurst, NFTSet, SetLoginEnvironment, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, MemoryZSwapWriteback, and PassFileDescriptorsToExec were added in version 256.

okay bestie, picking the Device Unit Objects list right back up like nothing happened ๐Ÿ’… no cap, we're in the version-history trenches now and honestly? iconic behaviour from systemd.

  • version 257 โ€” PrivateTmpEx, ImportCredentialEx, BindLogSockets, PrivateUsersEx, ManagedOOMMemoryPressureDurationUSec, ProtectControlGroupsEx, and PrivatePIDs were added in version 257.
  • version 258 โ€” ProtectHostnameEx, PassPIDFD, AcceptFileDescriptors, DelegateNamespaces, PrivateBPF, BPFDelegateCommands, BPFDelegateMaps, BPFDelegatePrograms, BPFDelegateAttachments, RemoveSubgroup(), DeferTrigger, DeferTriggerMaxUSec, StateDirectoryQuota, StateDirectoryQuotaUsage, StateDirectoryAccounting, CacheDirectoryQuota, CacheDirectoryQuotaUsage, CacheDirectoryAccounting, LogsDirectoryQuota, LogsDirectoryQuotaUsage, LogsDirectoryAccounting, and KillSubgroup() were added in version 258.
  • version 259 โ€” UserNamespacePath, OOMKills, and ManagedOOMKills were added in 259.
  • version 260 โ€” BindNetworkInterface, MemoryTHP, and RootMStack were added in version 260.
  • version 261 โ€” CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.
  • version 262 โ€” XAttrEntryPoint, XAttrListen, and XAttrAccept were added in version 262.

๐ŸŽ€ Mount Unit Objects

  • version 251 โ€” ControlGroupId and ExtensionDirectories were added in version 251.
  • version 253 โ€” MemoryZSwapMax and LogFilterPatterns were added in version 253.
  • version 254 โ€” DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, MemoryPressureThresholdUSec, RootEphemeral, ImportCredential, MemoryKSM, RootImagePolicy, MountImagePolicy, and ExtensionImagePolicy were added in version 254.
  • version 255 โ€” NFTSet, SetLoginEnvironment, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • version 256 โ€” EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256.
  • version 257 โ€” PrivateTmpEx, ImportCredentialEx, BindLogSockets, PrivateUsersEx, ManagedOOMMemoryPressureDurationUSec, ProtectControlGroupsEx, and PrivatePIDs were added in version 257.
  • version 258 โ€” ProtectHostnameEx, DelegateNamespaces, PrivateBPF, BPFDelegateCommands, BPFDelegateMaps, BPFDelegatePrograms, BPFDelegateAttachments, RemoveSubgroup(), ReloadResult, CleanResult, StateDirectoryQuota, StateDirectoryQuotaUsage, StateDirectoryAccounting, CacheDirectoryQuota, CacheDirectoryQuotaUsage, CacheDirectoryAccounting, LogsDirectoryQuota, LogsDirectoryQuotaUsage, LogsDirectoryAccounting, and KillSubgroup() were added in version 258.
  • version 259 โ€” UserNamespacePath, OOMKills, and ManagedOOMKills were added in 259.
  • version 260 โ€” BindNetworkInterface, MemoryTHP, and RootMStack were added in version 260.
  • version 261 โ€” CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.

๐Ÿฆ‹ Swap Unit Objects

  • version 251 โ€” ControlGroupId and ExtensionDirectories were added in version 251.
  • version 253 โ€” MemoryZSwapMax and LogFilterPatterns were added in version 253.
  • version 254 โ€” DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, MemoryPressureThresholdUSec, RootEphemeral, ImportCredential, MemoryKSM, RootImagePolicy, MountImagePolicy, and ExtensionImagePolicy were added in version 254.
  • version 255 โ€” NFTSet, SetLoginEnvironment, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • version 256 โ€” EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256.
  • version 257 โ€” PrivateTmpEx, ImportCredentialEx, BindLogSockets, PrivateUsersEx, ManagedOOMMemoryPressureDurationUSec, ProtectControlGroupsEx, and PrivatePIDs were added in version 257.
  • version 258 โ€” ProtectHostnameEx, DelegateNamespaces, PrivateBPF, BPFDelegateCommands, BPFDelegateMaps, BPFDelegatePrograms, BPFDelegateAttachments, RemoveSubgroup(), StateDirectoryQuota, StateDirectoryQuotaUsage, StateDirectoryAccounting, CacheDirectoryQuota, CacheDirectoryQuotaUsage, CacheDirectoryAccounting, LogsDirectoryQuota, LogsDirectoryQuotaUsage, LogsDirectoryAccounting, and KillSubgroup() were added in version 258.
  • version 259 โ€” UserNamespacePath, OOMKills, and ManagedOOMKills were added in 259.
  • version 260 โ€” BindNetworkInterface, MemoryTHP, and RootMStack were added in version 260.
  • version 261 โ€” CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.

๐ŸŒˆ Slice Unit Objects

  • version 251 โ€” ControlGroupId was added in version 251.
  • version 253 โ€” MemoryZSwapMax was added in version 253.
  • version 254 โ€” DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, and MemoryPressureThresholdUSec were added in version 254.
  • version 255 โ€” NFTSet, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • version 256 โ€” EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256.
  • version 257 โ€” ManagedOOMMemoryPressureDurationUSec was added in version 257.
  • version 258 โ€” ConcurrencyHardMax, ConcurrencySoftMax, NCurrentlyActive, RemoveSubgroup(), and KillSubgroup() were added in version 258.
  • version 259 โ€” OOMKills, and ManagedOOMKills were added in 259.
  • version 260 โ€” BindNetworkInterface was added in version 260.
  • version 261 โ€” CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.
  • version 262 โ€” ActivatingConcurrencyMax was added in version 262.

๐Ÿ’œ Scope Unit Objects

  • version 251 โ€” ControlGroupId was added in version 251.
  • version 253 โ€” OOMPolicy and MemoryZSwapMax were added in version 253.
  • version 254 โ€” DelegateSubgroup, DefaultStartupMemoryLow, StartupMemoryLow, StartupMemoryHigh, StartupMemoryMax, StartupMemorySwapMax, StartupMemoryZSwapMax, MemoryPressureWatch, and MemoryPressureThresholdUSec were added in version 254.
  • version 255 โ€” NFTSet, CoredumpReceive, MemoryPeak, MemorySwapCurrent, MemorySwapPeak, and MemoryZSwapCurrent were added in version 255.
  • version 256 โ€” EffectiveMemoryHigh, EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256.
  • version 257 โ€” ManagedOOMMemoryPressureDurationUSec was added in version 257.
  • version 258 โ€” RemoveSubgroup() and KillSubgroup() were added in version 258.
  • version 259 โ€” OOMKills, and ManagedOOMKills were added in 259.
  • version 260 โ€” BindNetworkInterface was added in version 260.
  • version 261 โ€” CPUPressureThresholdUSec, CPUPressureWatch, IOPressureThresholdUSec, IOPressureWatch, CPUSetPartition, and OOMRules were added in version 261.

โœจ Job Objects โœจ

  • version 252 โ€” ActivationDetails was added in version 252.

๐ŸŒธ Timer Objects ๐ŸŒธ

  • version 257 โ€” DeferReactivation was added in version 257.
  • version 258 โ€” RandomizedOffsetUSec was added in version 258.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

like, go read your friends, bestie, they're literally right there ๐Ÿซถ


๐Ÿ“Ž NOTES ๐Ÿ“Ž

  1. polkit https://www.freedesktop.org/software/polkit/docs/latest/
  2. New Control Group Interface https://systemd.io/CONTROL_GROUP_INTERFACE
  3. The Case for the /usr Merge https://systemd.io/THE_CASE_FOR_THE_USR_MERGE
  4. the usual interface versioning guidelines https://0pointer.de/blog/projects/versioning-dbus.html

and that's the whole page, bestie โ€” every single option, every version bump, all of it ๐Ÿ’–

that's a wrap on ORG.FREEDESKTOP.SYSTEMD1(5) fr fr โœจ this one's the systemd 262.1 flavour, dated however your copy of the docs says it is โ€” go forth and systemctl responsibly, you ate that ๐ŸŽ€๐Ÿ‘‘๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms