wip: better handling of cloexec with reused fds for panel and notifications daemon

This commit is contained in:
Ashley Wulber 2023-06-29 16:39:24 -04:00 committed by Ashley Wulber
parent 183fc329c1
commit 8bff06e9a7
4 changed files with 122 additions and 30 deletions

32
Cargo.lock generated
View file

@ -458,15 +458,6 @@ version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.3.1"
@ -510,7 +501,7 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.1",
"hermit-abi",
"libc",
"windows-sys",
]
@ -524,7 +515,7 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "launch-pad"
version = "0.1.0"
source = "git+https://github.com/pop-os/launch-pad#943e112ce381b4aef94ed3dba68f0dd2ed6c19ec"
source = "git+https://github.com/pop-os/launch-pad?branch=stdin-msg#6c27271f05f19d0cb8801717c218540f9ed00b3b"
dependencies = [
"log",
"slotmap",
@ -656,16 +647,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi 0.2.6",
"libc",
]
[[package]]
name = "object"
version = "0.30.4"
@ -787,9 +768,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.28"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
dependencies = [
"proc-macro2",
]
@ -1131,7 +1112,6 @@ dependencies = [
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
@ -1337,9 +1317,9 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.48.0"
version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",

View file

@ -11,7 +11,7 @@ publish = false
async-signals = "0.4"
color-eyre = "0.6"
futures-util = "0.3"
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
launch-pad = { git = "https://github.com/pop-os/launch-pad", branch = "stdin-msg" }
libc = "0.2"
log-panics = { version = "2", features = ["with-backtrace"] }
nix = { version = "0.25", features = ["fs"], default-features = false }
@ -20,7 +20,19 @@ sendfd = { version = "0.4", features = ["tokio"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
systemd_client = "0.2"
tokio = { version = "1", features = ["full"] }
tokio = { version = "1", features = [
"fs",
"io-util",
"io-std",
"macros",
"net",
"parking_lot",
"process",
"rt",
"signal",
"sync",
"time",
] }
tokio-util = "0.7"
tracing = "0.1"
tracing-journald = "0.3"

View file

@ -8,7 +8,11 @@ mod process;
mod service;
mod systemd;
use std::os::fd::AsRawFd;
use std::{
ops::Deref,
os::fd::AsRawFd,
sync::{Arc, Mutex},
};
use async_signals::Signals;
use color_eyre::{eyre::WrapErr, Result};
@ -24,6 +28,8 @@ use tracing::{metadata::LevelFilter, Instrument};
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
use zbus::ConnectionBuilder;
use crate::process::{mark_as_cloexec, mark_as_not_cloexec};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
color_eyre::install().wrap_err("failed to install color_eyre error handler")?;
@ -75,10 +81,43 @@ async fn main() -> Result<()> {
panel_notifications_fd.as_raw_fd().to_string(),
));
let panel_notifications_fd_pre = Arc::new(Mutex::new(panel_notifications_fd));
let panel_notifications_fd_post = panel_notifications_fd_pre.clone();
let span = info_span!(parent: None, "cosmic-panel");
let stdout_span = span.clone();
let stderr_span = span;
process_manager
.start(
Process::new()
.with_executable("cosmic-panel")
.with_pre_start(move |_, _, _| {
let panel_notifications_fd = panel_notifications_fd_pre.clone();
let fd = panel_notifications_fd.lock().unwrap();
let fd = fd.deref();
mark_as_not_cloexec(&fd)
.expect("Failed to mark panel notifications socket as not CLOEXEC");
})
.with_post_start(move |_, _, _| {
let panel_notifications_fd = panel_notifications_fd_post.clone();
let fd = panel_notifications_fd.lock().unwrap();
let fd = fd.deref();
mark_as_cloexec(&fd)
.expect("Failed to mark panel notifications socket as CLOEXEC");
})
.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_env(panel_env_vars.clone()),
)
.await
@ -90,7 +129,53 @@ async fn main() -> Result<()> {
daemon_notifications_fd.as_raw_fd().to_string(),
));
let span = info_span!(parent: None, "cosmic-notifications");
start_component("cosmic-notifications", span, &process_manager, &env_vars).await;
let stdout_span = span.clone();
let stderr_span = span;
let daemon_notifications_fd_pre = Arc::new(Mutex::new(daemon_notifications_fd));
let daemon_notifications_fd_post = daemon_notifications_fd_pre.clone();
process_manager
.start(
Process::new()
.with_executable("cosmic-notifications")
.with_pre_start(move |_, _, _| {
let daemon_notifications_fd = daemon_notifications_fd_pre.clone();
let fd = daemon_notifications_fd.lock().unwrap();
let fd = fd.deref();
mark_as_not_cloexec(&fd)
.expect("Failed to mark daemon notifications socket as not CLOEXEC");
})
.with_post_start(move |_, _, _| {
let daemon_notifications_fd = daemon_notifications_fd_post.clone();
let fd = daemon_notifications_fd.lock().unwrap();
let fd = fd.deref();
mark_as_cloexec(&fd)
.expect("Failed to mark daemon notifications socket as CLOEXEC");
})
.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_env(daemon_env_vars.clone()),
)
.await
.expect("failed to start notifications daemon");
// mark_as_cloexec(&daemon_notifications_fd)
// .expect("Failed to mark daemon notifications socket as CLOEXEC");
// start_component("cosmic-notifications", span, &process_manager, &env_vars).await;
// mark_as_not_cloexec(&daemon_notifications_fd)
// .expect("Failed to mark daemon notifications socket as not CLOEXEC");
let span = info_span!(parent: None, "cosmic-app-library");
start_component("cosmic-app-library", span, &process_manager, &env_vars).await;

View file

@ -17,3 +17,18 @@ pub(crate) fn mark_as_not_cloexec(file: &impl AsFd) -> Result<()> {
.wrap_err("failed to set CLOEXEC on file")?;
Ok(())
}
pub(crate) fn mark_as_cloexec(file: &impl AsFd) -> Result<()> {
let raw_fd = file.as_fd().as_raw_fd();
let fd_flags = fcntl::FdFlag::from_bits(
fcntl::fcntl(raw_fd, fcntl::FcntlArg::F_GETFD)
.wrap_err("failed to get GETFD value of stream")?,
)
.wrap_err("failed to get fd flags from file")?;
fcntl::fcntl(
raw_fd,
fcntl::FcntlArg::F_SETFD(fd_flags.union(fcntl::FdFlag::FD_CLOEXEC)),
)
.wrap_err("failed to set CLOEXEC on file")?;
Ok(())
}