power: the sleep hooks are wanted by the sleep targets, not declared as services
The host reads a one-shot that is not running as having run, so a before-sleep or after-wake unit declared stopped failed on its first apply; drop-ins on the sleep targets pull them in instead.
This commit is contained in:
@@ -73,3 +73,10 @@ again. A machine that said `sleeping` is asleep, not out of touch.
|
||||
|
||||
The lesson from the day this module was written belongs to the dbus module: a full upgrade restarted
|
||||
the system bus live on a workstation, and logins hung until a reboot.
|
||||
|
||||
**Why the sleep hooks are wanted, not enabled.** The host reads a one-shot unit that is not running
|
||||
and has not failed as having run and worked, so a hook unit waiting for a sleep could never be
|
||||
declared stopped. The first version tried that and was refused on its first apply. The two sleep
|
||||
units are therefore not services the mesh manages. They have no install section, and the sleep
|
||||
targets want them through this module's drop-ins (`sleep.target.d`, and `suspend.target.d` with
|
||||
its three siblings) — the same way the laptop module asks for the NVIDIA driver's sleep actions.
|
||||
|
||||
@@ -32,8 +32,11 @@ func (m *Machine) Check(ctx context.Context, w *Watcher) map[string]any {
|
||||
enabled, _ := m.Run(ctx, "systemctl", "is-enabled", u)
|
||||
enabled = strings.TrimSpace(enabled)
|
||||
want := "enabled"
|
||||
if u == "mesh-power-supply.service" {
|
||||
switch u {
|
||||
case "mesh-power-supply.service":
|
||||
want = "static" // started by the udev rule, never by a target
|
||||
case "mesh-power-before-sleep.service", "mesh-power-after-wake.service":
|
||||
want = "static" // wanted by the sleep targets through the module's drop-ins, never enabled
|
||||
}
|
||||
add(u, present && enabled == want, "%s: file present %v, %s (want %s)", Units[u], present, orWord(enabled, "unknown"), want)
|
||||
}
|
||||
|
||||
+67
-16
@@ -127,14 +127,14 @@
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-before-sleep.service",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nDescription=Every module's code before sleep (mesh power)\nBefore=sleep.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/lib/mesh-power/bin/power-moment before-sleep\n\n[Install]\nWantedBy=sleep.target\n"
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n#\n# Pulled in by sleep.target through this module's drop-in on it, never enabled: a one-shot waiting\n# for a sleep is not a service whose state the mesh can declare.\n[Unit]\nDescription=Every module's code before sleep (mesh power)\nBefore=sleep.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/lib/mesh-power/bin/power-moment before-sleep\n"
|
||||
},
|
||||
{
|
||||
"id": "after-wake-unit",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/mesh-power-after-wake.service",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nDescription=Every module's code after waking (mesh power)\nAfter=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/lib/mesh-power/bin/power-moment after-wake\n\n[Install]\nWantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target\n"
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n#\n# Pulled in by the four sleep targets through this module's drop-ins on them, and ordered after\n# them, so it runs once the machine is awake again. Never enabled.\n[Unit]\nDescription=Every module's code after waking (mesh power)\nAfter=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target\n\n[Service]\nType=oneshot\nExecStart=/usr/local/lib/mesh-power/bin/power-moment after-wake\n"
|
||||
},
|
||||
{
|
||||
"id": "supply-unit",
|
||||
@@ -143,6 +143,71 @@
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n#\n# Started by the module's udev rule when a power supply changes; runs on-mains or on-battery once per\n# change of source.\n[Unit]\nDescription=Every module's code for the power source (mesh power)\n\n[Service]\nType=oneshot\nExecStart=/usr/local/lib/mesh-power/bin/power-moment supply\n"
|
||||
},
|
||||
{
|
||||
"id": "sleep-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/sleep.target.d",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "sleep-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/sleep.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nWants=mesh-power-before-sleep.service\n"
|
||||
},
|
||||
{
|
||||
"id": "suspend-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/suspend.target.d",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "suspend-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/suspend.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nWants=mesh-power-after-wake.service\n"
|
||||
},
|
||||
{
|
||||
"id": "hibernate-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/hibernate.target.d",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "hibernate-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/hibernate.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nWants=mesh-power-after-wake.service\n"
|
||||
},
|
||||
{
|
||||
"id": "hybrid-sleep-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/hybrid-sleep.target.d",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "hybrid-sleep-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/hybrid-sleep.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nWants=mesh-power-after-wake.service\n"
|
||||
},
|
||||
{
|
||||
"id": "suspend-then-hibernate-drop-ins",
|
||||
"type": "directory",
|
||||
"path": "/etc/systemd/system/suspend-then-hibernate.target.d",
|
||||
"mode": "0755"
|
||||
},
|
||||
{
|
||||
"id": "suspend-then-hibernate-wants",
|
||||
"type": "file",
|
||||
"path": "/etc/systemd/system/suspend-then-hibernate.target.d/mesh-power.conf",
|
||||
"mode": "0644",
|
||||
"content": "# Written by the mesh (module power, novox/hq ADR 0211). Replaced on every push.\n[Unit]\nWants=mesh-power-after-wake.service\n"
|
||||
},
|
||||
{
|
||||
"id": "udev-rule",
|
||||
"type": "file",
|
||||
@@ -163,20 +228,6 @@
|
||||
"unit": "mesh-power-before-shutdown.service",
|
||||
"state": "running",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "before-sleep",
|
||||
"type": "service",
|
||||
"unit": "mesh-power-before-sleep.service",
|
||||
"state": "stopped",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "after-wake",
|
||||
"type": "service",
|
||||
"unit": "mesh-power-after-wake.service",
|
||||
"state": "stopped",
|
||||
"boot": "enabled"
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
|
||||
Reference in New Issue
Block a user