KamoCRM

The swap file was smaller than the check that measures it

FixKlusterServices
Ya
23 Septemba 2026, 19:17 UTC
Mwandishi
Kamo
Ahadi ya
4673e45

With the restart landing, the first computer came up with resumeConfigured true and stopped on the next precondition — which turns out to be unsatisfiable by construction: swapBytes 2095468544 the USABLE area, from /proc/swaps swapNeededBytes 2095474483 int(MemTotal * 1.05) ───────── short by 5,939 of a 2 GB file readiness() measures the area mkswap left usable. _ensure_swap allocated the file at exactly the number that area is compared against, and mkswap takes a header page and rounds the rest down to whole pages — so the usable area is always a few KB short of its own target. Then _ensure_swap early-returns on `have == want_bytes`, so it never grows, and swapLargeEnough stays false forever. The file is now allocated with a margin, and the margin is 16 MiB rather than the one page mkswap needs, because MemTotal is not a constant: the kernel excludes what firmware and the initrd reserve, and that moved by 5.6 KB between two boots of this same VM. A margin measured in pages would leave a computer one kernel upgrade away from never sleeping again. The early return is now `have >= target`, not `==`. Equality meant a MemTotal wobble in either direction rewrote a 2 GB file on a Longhorn volume on a machine that was already fine. Also here, because both were found by the same investigation: The restart is now chased by the idle watcher rather than by whoever happens to call /prepare-sleep. Both of the moments that look like the right one are wrong. The agent's boot thread runs before computeservice has pushed anything, so there is nothing yet to protect. And /prepare-sleep is not called by computeservice at all — the client method exists and has no caller; the real caller is a runcmd in cloud-init.userdata.yaml, which fires in the MIDDLE of provisioning. So the question is simply re-asked every thirty seconds by the watcher that was already polling, gated on the provisioning push having landed and on there being no desktop session. That second gate is stronger than it looks: an xrdp session outlives a disconnect, so an empty list means nobody has logged in yet or everybody has logged out, not merely that nobody is at the keyboard. Refusals log once per distinct reason. Never silent, and not two thousand identical lines a day. A refused `systemctl hibernate` now reaches the journal. On success the command never returns, so the only thing it can ever print is why it said no — and that went to DEVNULL, leaving computeservice to notice ten minutes later that a computer "did not go to sleep when asked" with no reason anywhere. run_forever is split into the loop and tick(), so the decisions can be tested. 43 tests.

Mabadiliko yote

Je, unaona nini kuhusu usafiri?

Kila kitu kinaingia kwenye tovuti yako mwenyewe. Anza kwenye mpango wa bure na usome ukurasa huu tena katika mwezi mmoja.

Kuwa Huru MileleMtazamo wa bei