refactor: pass an extra pirivileged socket to xdp-cosmic

This commit is contained in:
Ashley Wulber 2024-01-10 10:47:44 -05:00 committed by Ashley Wulber
parent efe4b58279
commit 8fd40b588a
4 changed files with 95 additions and 28 deletions

View file

@ -8,13 +8,16 @@ mod process;
mod service;
mod systemd;
use std::{os::fd::AsRawFd, sync::Arc};
use std::{
os::fd::{AsRawFd, OwnedFd},
sync::Arc,
};
use async_signals::Signals;
use color_eyre::{eyre::WrapErr, Result};
use comp::create_privileged_socket;
use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD};
use futures_util::StreamExt;
use futures_util::{SinkExt, StreamExt};
use launch_pad::{process::Process, ProcessManager};
use service::SessionRequest;
use tokio::{
@ -53,10 +56,9 @@ async fn main() -> Result<()> {
let session_tx_clone = session_tx.clone();
let _conn = ConnectionBuilder::session()?
.name("com.system76.CosmicSession")?
.serve_at(
"/com/system76/CosmicSession",
service::SessionService { session_tx },
)?
.serve_at("/com/system76/CosmicSession", service::SessionService {
session_tx,
})?
.build()
.await?;
@ -191,6 +193,7 @@ async fn start(
&process_manager,
&env_vars,
&socket_tx,
Vec::new(),
)
.await;
@ -201,6 +204,7 @@ async fn start(
&process_manager,
&env_vars,
&socket_tx,
Vec::new(),
)
.await;
@ -211,22 +215,50 @@ async fn start(
&process_manager,
&env_vars,
&socket_tx,
Vec::new(),
)
.await;
let span = info_span!(parent: None, "cosmic-osd");
start_component("cosmic-osd", span, &process_manager, &env_vars, &socket_tx).await;
start_component(
"cosmic-osd",
span,
&process_manager,
&env_vars,
&socket_tx,
Vec::new(),
)
.await;
let span = info_span!(parent: None, "cosmic-bg");
start_component("cosmic-bg", span, &process_manager, &env_vars, &socket_tx).await;
start_component(
"cosmic-bg",
span,
&process_manager,
&env_vars,
&socket_tx,
Vec::new(),
)
.await;
let span = info_span!(parent: None, "xdg-desktop-portal-cosmic");
let mut sockets = Vec::with_capacity(1);
let extra_env = Vec::with_capacity(1);
let portal_extras =
if let Ok((mut env, fd)) = create_privileged_socket(&mut sockets, &extra_env) {
let mut env = env.remove(0);
env.0 = "PORTAL_WAYLAND_SOCKET".to_string();
vec![(fd, env, sockets.remove(0))]
} else {
Vec::new()
};
start_component(
XDP_COSMIC.unwrap_or("/usr/libexec/xdg-desktop-portal-cosmic"),
span,
&process_manager,
&env_vars,
&socket_tx,
portal_extras,
)
.await;
@ -279,16 +311,27 @@ async fn start_component(
process_manager: &ProcessManager,
env_vars: &[(String, String)],
socket_tx: &mpsc::UnboundedSender<Vec<UnixStream>>,
extra_fds: Vec<(OwnedFd, (String, String), UnixStream)>,
) {
let mut sockets = Vec::with_capacity(1);
let (env_vars, fd) = create_privileged_socket(&mut sockets, env_vars).unwrap();
if let Err(why) = socket_tx.send(sockets) {
error!(?why, "Failed to send the privileged socket");
}
let mut sockets = Vec::with_capacity(2);
let (mut env_vars, fd) = create_privileged_socket(&mut sockets, &env_vars).unwrap();
let socket_tx_clone = socket_tx.clone();
let stdout_span = span.clone();
let stderr_span = span.clone();
let cmd_clone = cmd.to_string();
let (mut fds, extra_fd_env, mut streams): (Vec<_>, Vec<_>, Vec<_>) =
itertools::multiunzip(extra_fds);
for kv in &extra_fd_env {
env_vars.push(kv.clone());
}
sockets.append(&mut streams);
if let Err(why) = socket_tx.send(sockets) {
error!(?why, "Failed to send the privileged socket");
}
let (extra_fd_env, _): (Vec<_>, Vec<_>) = extra_fd_env.into_iter().unzip();
fds.push(fd);
process_manager
.start(
Process::new()
@ -312,16 +355,25 @@ async fn start_component(
if let Some(err) = err_code {
error!("{cmd_clone} exited with error {}", err.to_string());
}
let extra_fd_env = extra_fd_env.clone();
let socket_tx_clone = socket_tx_clone.clone();
async move {
if !will_restart {
return;
}
let mut sockets = Vec::with_capacity(1);
let env_vars = Vec::with_capacity(1);
let (env_vars, new_fd) =
create_privileged_socket(&mut sockets, &env_vars).unwrap();
let mut sockets = Vec::with_capacity(1 + extra_fd_env.len());
let mut fds = Vec::with_capacity(1 + extra_fd_env.len());
let (mut env_vars, fd) =
create_privileged_socket(&mut sockets, &[]).unwrap();
fds.push(fd);
for k in extra_fd_env {
let (mut fd_env_vars, fd) =
create_privileged_socket(&mut sockets, &[]).unwrap();
fd_env_vars.last_mut().unwrap().0 = k;
env_vars.append(&mut fd_env_vars);
fds.push(fd)
}
if let Err(why) = socket_tx_clone.send(sockets) {
error!(?why, "Failed to send the privileged socket");
@ -329,13 +381,12 @@ async fn start_component(
if let Err(why) = pman.update_process_env(&key, env_vars).await {
error!(?why, "Failed to update environment variables");
}
if let Err(why) = pman.update_process_fds(&key, move || vec![new_fd]).await
{
if let Err(why) = pman.update_process_fds(&key, move || fds).await {
error!(?why, "Failed to update fds");
}
}
})
.with_fds(move || vec![fd]),
.with_fds(move || fds),
)
.await
.unwrap_or_else(|_| panic!("failed to start {}", cmd));

View file

@ -1,12 +1,11 @@
use color_eyre::eyre::Context;
use color_eyre::Result;
use color_eyre::{eyre::Context, Result};
use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD};
use launch_pad::process::Process;
use launch_pad::ProcessKey;
use launch_pad::{process::Process, ProcessKey};
use rustix::fd::AsRawFd;
use std::os::fd::OwnedFd;
use std::os::unix::net::UnixStream;
use std::sync::Arc;
use std::{
os::{fd::OwnedFd, unix::net::UnixStream},
sync::Arc,
};
use tokio::sync::{mpsc, Mutex};
use tracing::Instrument;