fix(session): relancer cosmic-settings-daemon s'il sort proprement en session
launch-pad ne relance que les processus qui sortent en erreur: une sortie propre du demon (par ex. un pkill -x cosmic-settings qui touche aussi le demon a cause de la troncature comm a 15 caracteres) laissait la session sans service varlink audio jusqu'au logout. Le demon est desormais relance par cosmic-session tant que la session n'est pas en cours d'extinction, avec une limite de 5 relances rapprochées pour éviter une boucle sur un démon cassé.
This commit is contained in:
parent
d97b142f35
commit
bc61bfddcc
2 changed files with 130 additions and 41 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
|
@ -299,7 +299,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cosmic-session"
|
||||
version = "1.0.0"
|
||||
version = "1.3.0"
|
||||
dependencies = [
|
||||
"color-eyre",
|
||||
"cosmic-dbus-a11y",
|
||||
|
|
@ -1885,6 +1885,18 @@ dependencies = [
|
|||
"winnow",
|
||||
]
|
||||
|
||||
[[patch.unused]]
|
||||
name = "softbuffer"
|
||||
version = "0.4.1"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "cosmic-freedesktop-icons"
|
||||
version = "0.4.0"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "smithay-clipboard"
|
||||
version = "0.8.0"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "dpi"
|
||||
version = "0.1.2"
|
||||
|
|
@ -1932,15 +1944,3 @@ version = "0.31.0-beta.2"
|
|||
[[patch.unused]]
|
||||
name = "winit-x11"
|
||||
version = "0.31.0-beta.2"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "smithay-clipboard"
|
||||
version = "0.8.0"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "cosmic-freedesktop-icons"
|
||||
version = "0.4.0"
|
||||
|
||||
[[patch.unused]]
|
||||
name = "softbuffer"
|
||||
version = "0.4.1"
|
||||
|
|
|
|||
145
src/main.rs
145
src/main.rs
|
|
@ -221,38 +221,24 @@ async fn start(
|
|||
None
|
||||
};
|
||||
|
||||
let stdout_span = info_span!(parent: None, "cosmic-settings-daemon");
|
||||
let stderr_span = stdout_span.clone();
|
||||
let (settings_exit_tx, settings_exit_rx) = oneshot::channel();
|
||||
let settings_exit_tx = Arc::new(std::sync::Mutex::new(Some(settings_exit_tx)));
|
||||
let shutting_down = Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
let settings_daemon_key = Arc::new(std::sync::Mutex::new(None));
|
||||
let respawn_count = Arc::new(std::sync::atomic::AtomicUsize::new(0));
|
||||
let last_respawn = Arc::new(std::sync::Mutex::new(std::time::Instant::now()));
|
||||
let settings_daemon = process_manager
|
||||
.start(
|
||||
Process::new()
|
||||
.with_executable("cosmic-settings-daemon")
|
||||
.with_env(env_vars.iter().cloned())
|
||||
.with_on_stdout(move |_, _, line| {
|
||||
let stdout_span = stdout_span.clone();
|
||||
async move {
|
||||
info!("{}", line);
|
||||
}
|
||||
.instrument(stdout_span)
|
||||
})
|
||||
.with_on_stderr(move |_, _, line| {
|
||||
let stderr_span = stderr_span.clone();
|
||||
async move {
|
||||
warn!("{}", line);
|
||||
}
|
||||
.instrument(stderr_span)
|
||||
})
|
||||
.with_on_exit(move |_, _, _, will_restart| {
|
||||
if !will_restart && let Some(tx) = settings_exit_tx.lock().unwrap().take() {
|
||||
_ = tx.send(());
|
||||
}
|
||||
async {}
|
||||
}),
|
||||
)
|
||||
.start(settings_daemon_process(
|
||||
env_vars.clone(),
|
||||
Arc::clone(&shutting_down),
|
||||
Arc::clone(&settings_exit_tx),
|
||||
Arc::clone(&settings_daemon_key),
|
||||
Arc::clone(&respawn_count),
|
||||
Arc::clone(&last_respawn),
|
||||
))
|
||||
.await
|
||||
.expect("failed to start settings daemon");
|
||||
*settings_daemon_key.lock().unwrap() = Some(settings_daemon);
|
||||
|
||||
// notifying the user service manager that we've reached the
|
||||
// graphical-session.target, which should only happen after:
|
||||
|
|
@ -487,7 +473,13 @@ async fn start(
|
|||
|
||||
compositor_handle.abort();
|
||||
token.cancel();
|
||||
if let Err(err) = process_manager.stop_process(settings_daemon).await {
|
||||
shutting_down.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
let settings_daemon_stop = settings_daemon_key
|
||||
.lock()
|
||||
.unwrap()
|
||||
.take()
|
||||
.unwrap_or(settings_daemon);
|
||||
if let Err(err) = process_manager.stop_process(settings_daemon_stop).await {
|
||||
tracing::error!(?err, "Failed to gracefully stop settings daemon.");
|
||||
} else {
|
||||
match tokio::time::timeout(Duration::from_secs(1), settings_exit_rx).await {
|
||||
|
|
@ -502,6 +494,103 @@ async fn start(
|
|||
Ok(status)
|
||||
}
|
||||
|
||||
/// Build the cosmic-settings-daemon process.
|
||||
///
|
||||
/// The daemon is respawned whenever it exits while the session is still
|
||||
/// running: launch-pad only restarts processes that exit with an error, so a
|
||||
/// clean exit (for example a stray `pkill` matching the daemon's truncated
|
||||
/// comm name) would otherwise leave the session without the varlink audio
|
||||
/// service until logout. Rapid successive exits are capped to avoid a respawn
|
||||
/// loop of a daemon that cannot stay alive.
|
||||
fn settings_daemon_process(
|
||||
env_vars: Vec<(String, String)>,
|
||||
shutting_down: Arc<std::sync::atomic::AtomicBool>,
|
||||
settings_exit_tx: Arc<std::sync::Mutex<Option<oneshot::Sender<()>>>>,
|
||||
settings_daemon_key: Arc<std::sync::Mutex<Option<launch_pad::ProcessKey>>>,
|
||||
respawn_count: Arc<std::sync::atomic::AtomicUsize>,
|
||||
last_respawn: Arc<std::sync::Mutex<std::time::Instant>>,
|
||||
) -> Process {
|
||||
let stdout_span = info_span!(parent: None, "cosmic-settings-daemon");
|
||||
let stderr_span = stdout_span.clone();
|
||||
let respawn_env = env_vars.clone();
|
||||
|
||||
Process::new()
|
||||
.with_executable("cosmic-settings-daemon")
|
||||
.with_env(env_vars.iter().cloned())
|
||||
.with_on_stdout(move |_, _, line| {
|
||||
let stdout_span = stdout_span.clone();
|
||||
async move {
|
||||
info!("{}", line);
|
||||
}
|
||||
.instrument(stdout_span)
|
||||
})
|
||||
.with_on_stderr(move |_, _, line| {
|
||||
let stderr_span = stderr_span.clone();
|
||||
async move {
|
||||
warn!("{}", line);
|
||||
}
|
||||
.instrument(stderr_span)
|
||||
})
|
||||
.with_on_exit(move |pman, _key, _err_code, will_restart| {
|
||||
let shutting_down = Arc::clone(&shutting_down);
|
||||
let settings_exit_tx = Arc::clone(&settings_exit_tx);
|
||||
let settings_daemon_key = Arc::clone(&settings_daemon_key);
|
||||
let respawn_count = Arc::clone(&respawn_count);
|
||||
let last_respawn = Arc::clone(&last_respawn);
|
||||
let respawn_env = respawn_env.clone();
|
||||
|
||||
async move {
|
||||
if will_restart {
|
||||
// launch-pad restarts processes that exit with an error on its own.
|
||||
return;
|
||||
}
|
||||
|
||||
if shutting_down.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
if let Some(tx) = settings_exit_tx.lock().unwrap().take() {
|
||||
_ = tx.send(());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let now = std::time::Instant::now();
|
||||
{
|
||||
let mut last = last_respawn.lock().unwrap();
|
||||
if now.duration_since(*last) > Duration::from_secs(60) {
|
||||
respawn_count.store(0, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
*last = now;
|
||||
}
|
||||
let count =
|
||||
respawn_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + 1;
|
||||
if count > 5 {
|
||||
error!(
|
||||
"cosmic-settings-daemon exited {count} times in quick succession; giving up on respawns"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
warn!("cosmic-settings-daemon exited unexpectedly; respawning it");
|
||||
let new_process = settings_daemon_process(
|
||||
respawn_env,
|
||||
shutting_down.clone(),
|
||||
settings_exit_tx.clone(),
|
||||
settings_daemon_key.clone(),
|
||||
respawn_count.clone(),
|
||||
last_respawn.clone(),
|
||||
);
|
||||
|
||||
match pman.start(new_process).await {
|
||||
Ok(new_key) => {
|
||||
*settings_daemon_key.lock().unwrap() = Some(new_key);
|
||||
}
|
||||
Err(err) => {
|
||||
error!(?err, "Failed to respawn cosmic-settings-daemon");
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_component(
|
||||
cmd: impl Into<Cow<'static, str>>,
|
||||
span: tracing::Span,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue