lockhint: say so when the session can never hold a lock hint
logind refuses SetLockedHint for any session that is not Class=user. When that happens LockedHint is pinned at no, is_locked() is permanently false, every request_blank() times out its ack budget, and the panel goes dark on a session nobody could confirm was locked — the machine keeps working and only the security half is gone. That state ran for weeks on blueline undetected: greetd's default_session is the greeter slot, so any restart produced it, and the only trace was one blank-without-lock per blank, which reads like a timing problem rather than a structural one. Now it is one line naming the cause at startup. A warning, not a refusal to start: a phone that will not boot because its session class is wrong is worse than one that boots and says so.
This commit is contained in:
parent
94988138b4
commit
106c3bb680
1 changed files with 52 additions and 0 deletions
|
|
@ -206,6 +206,57 @@ pub(crate) fn parse_locked_hint(line: &str) -> Option<bool> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Say so, loudly and once, when this session can never hold a lock hint.
|
||||||
|
///
|
||||||
|
/// logind refuses `SetLockedHint` for any session that is not `Class=user` —
|
||||||
|
/// "Session does not support lock screen". When that happens `LockedHint` is
|
||||||
|
/// pinned at `no` forever, so `is_locked()` is permanently false, every
|
||||||
|
/// `request_blank()` times out its ack budget, and the panel goes dark on a
|
||||||
|
/// session nobody could confirm was locked. The machine keeps working and keeps
|
||||||
|
/// blanking; only the security half is gone.
|
||||||
|
///
|
||||||
|
/// That state lasted weeks undetected on blueline (greetd's `default_session`
|
||||||
|
/// runs as the greeter, so any `systemctl restart greetd` produced it), and the
|
||||||
|
/// only trace was one `blank-without-lock` per blank — an entry that reads like
|
||||||
|
/// a timing problem rather than a structural one. This turns it into a single
|
||||||
|
/// line naming the cause.
|
||||||
|
///
|
||||||
|
/// A warning and not a refusal to start: a phone that will not boot because its
|
||||||
|
/// session class is wrong is worse than one that boots and says the lock hint is
|
||||||
|
/// unavailable.
|
||||||
|
fn warn_if_session_cannot_lock(path: &str) {
|
||||||
|
let Ok(out) = Command::new("busctl")
|
||||||
|
.args([
|
||||||
|
"--system",
|
||||||
|
"get-property",
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
path,
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
"Class",
|
||||||
|
])
|
||||||
|
.output()
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if !out.status.success() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// `s "user"`
|
||||||
|
let text = String::from_utf8_lossy(&out.stdout);
|
||||||
|
let Some(class) = text.split('"').nth(1) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if class == "user" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
warn!(
|
||||||
|
"[lock-hint] session {path} is Class={class}, not user — logind will refuse SetLockedHint \
|
||||||
|
for it, so LockedHint can never become true, `locked` stays false, and EVERY blank will \
|
||||||
|
go out on a session that could not be confirmed locked (blank-without-lock). On greetd \
|
||||||
|
this means the desktop is running in the greeter slot; see LOCK-DPMS-LESSONS §1."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Watch `LockedHint` forever, reporting every change.
|
/// Watch `LockedHint` forever, reporting every change.
|
||||||
///
|
///
|
||||||
/// The callback fires once at startup with the current value, then on each
|
/// The callback fires once at startup with the current value, then on each
|
||||||
|
|
@ -225,6 +276,7 @@ pub fn spawn(on_change: Arc<dyn Fn(bool) + Send + Sync>) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
info!("[lock-hint] watching {path}");
|
info!("[lock-hint] watching {path}");
|
||||||
|
warn_if_session_cannot_lock(&path);
|
||||||
|
|
||||||
let mut last = match read_locked_hint(&path) {
|
let mut last = match read_locked_hint(&path) {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue