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.
|
||||
///
|
||||
/// 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}");
|
||||
warn_if_session_cannot_lock(&path);
|
||||
|
||||
let mut last = match read_locked_hint(&path) {
|
||||
Ok(v) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue