diff --git a/Cargo.toml b/Cargo.toml index b6322a8..435c118 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,24 +2,24 @@ name = "rustysd" version = "0.1.0" authors = ["Moritz Borcherding "] -edition = "2018" +edition = "2021" [dependencies] signal-hook = "0.3" libc = "0.2" -nix = "0.26" +nix = { version = "0.29", features = ["user", "process", "mount", "poll", "fs", "socket", "signal"] } log = "0.4" fern = "0.6" chrono = "0.4" threadpool = "1.8" serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -toml = "0.7" +toml = "0.8" dbus = {version = "0.9", optional = true} -shlex = "1.1" -clap = { version = "4.1", features = ["derive"] } +shlex = "1.3" +clap = { version = "4.5", features = ["derive"] } shmemfdrs = "0.1" -which = "4.4" +which = "6" [features] dbus_support = ["dbus"] diff --git a/src/entrypoints/exec_helper.rs b/src/entrypoints/exec_helper.rs index 3952b01..ea4deeb 100644 --- a/src/entrypoints/exec_helper.rs +++ b/src/entrypoints/exec_helper.rs @@ -1,4 +1,4 @@ -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; use crate::units::PlatformSpecificServiceFields; diff --git a/src/notification_handler.rs b/src/notification_handler.rs index 7aaaae1..7897340 100644 --- a/src/notification_handler.rs +++ b/src/notification_handler.rs @@ -10,6 +10,7 @@ use crate::runtime_info::*; use crate::services::Service; use crate::services::StdIo; use crate::units::*; +use std::os::fd::BorrowedFd; use std::{collections::HashMap, os::unix::io::AsRawFd}; fn collect_from_srvc(run_info: ArcMutRuntimeInfo, f: F) -> HashMap @@ -41,9 +42,9 @@ pub fn handle_all_streams(run_info: ArcMutRuntimeInfo) { let mut fdset = nix::sys::select::FdSet::new(); for fd in fd_to_srvc_id.keys() { - fdset.insert(*fd); + fdset.insert(unsafe { BorrowedFd::borrow_raw(*fd) }); } - fdset.insert(eventfd.read_end()); + fdset.insert(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }); let result = nix::sys::select::select(None, Some(&mut fdset), None, None, None); @@ -51,14 +52,14 @@ pub fn handle_all_streams(run_info: ArcMutRuntimeInfo) { let unit_table = &run_info_locked.unit_table; match result { Ok(_) => { - if fdset.contains(eventfd.read_end()) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }) { trace!("Interrupted notification select because the eventfd fired"); reset_event_fd(eventfd); trace!("Reset eventfd value"); } let mut buf = [0u8; 512]; for (fd, id) in &fd_to_srvc_id { - if fdset.contains(*fd) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(*fd) }) { if let Some(srvc_unit) = unit_table.get(id) { if let Specific::Service(srvc) = &srvc_unit.specific { let mut_state = &mut *srvc.state.write().unwrap(); @@ -122,9 +123,9 @@ pub fn handle_all_std_out(run_info: ArcMutRuntimeInfo) { let mut fdset = nix::sys::select::FdSet::new(); for fd in fd_to_srvc_id.keys() { - fdset.insert(*fd); + fdset.insert(unsafe { BorrowedFd::borrow_raw(*fd) }); } - fdset.insert(eventfd.read_end()); + fdset.insert(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }); let result = nix::sys::select::select(None, Some(&mut fdset), None, None, None); @@ -132,14 +133,14 @@ pub fn handle_all_std_out(run_info: ArcMutRuntimeInfo) { let unit_table = &run_info_locked.unit_table; match result { Ok(_) => { - if fdset.contains(eventfd.read_end()) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }) { trace!("Interrupted stdout select because the eventfd fired"); reset_event_fd(eventfd); trace!("Reset eventfd value"); } let mut buf = [0u8; 512]; for (fd, id) in &fd_to_srvc_id { - if fdset.contains(*fd) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(*fd) }) { if let Some(srvc_unit) = unit_table.get(id) { let name = srvc_unit.id.name.clone(); if let Specific::Service(srvc) = &srvc_unit.specific { @@ -191,9 +192,9 @@ pub fn handle_all_std_err(run_info: ArcMutRuntimeInfo) { let mut fdset = nix::sys::select::FdSet::new(); for fd in fd_to_srvc_id.keys() { - fdset.insert(*fd); + fdset.insert(unsafe { BorrowedFd::borrow_raw(*fd) }); } - fdset.insert(eventfd.read_end()); + fdset.insert(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }); let result = nix::sys::select::select(None, Some(&mut fdset), None, None, None); let run_info_locked = run_info.read().unwrap(); @@ -201,14 +202,14 @@ pub fn handle_all_std_err(run_info: ArcMutRuntimeInfo) { match result { Ok(_) => { - if fdset.contains(eventfd.read_end()) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }) { trace!("Interrupted stderr select because the eventfd fired"); reset_event_fd(eventfd); trace!("Reset eventfd value"); } let mut buf = [0u8; 512]; for (fd, id) in &fd_to_srvc_id { - if fdset.contains(*fd) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(*fd) }) { if let Some(srvc_unit) = unit_table.get(id) { let name = srvc_unit.id.name.clone(); if let Specific::Service(srvc) = &srvc_unit.specific { diff --git a/src/platform/eventfd.rs b/src/platform/eventfd.rs index 1c007c0..93ab4fd 100644 --- a/src/platform/eventfd.rs +++ b/src/platform/eventfd.rs @@ -9,6 +9,7 @@ pub use pipe_eventfd::*; #[cfg(not(feature = "linux_eventfd"))] mod pipe_eventfd { + use std::os::fd::IntoRawFd; use std::os::unix::io::RawFd; use log::{error, trace}; @@ -28,7 +29,7 @@ mod pipe_eventfd { pub fn make_event_fd() -> Result { let (r, w) = nix::unistd::pipe().map_err(|e| format!("Error creating pipe, {}", e))?; - Ok(EventFd(r, w)) + Ok(EventFd(r.into_raw_fd(), w.into_raw_fd())) } pub fn notify_event_fd(eventfd: EventFd) { diff --git a/src/platform/unix_common.rs b/src/platform/unix_common.rs index 5963c10..262e5b8 100644 --- a/src/platform/unix_common.rs +++ b/src/platform/unix_common.rs @@ -1,3 +1,5 @@ +use nix::sys::socket::Backlog; +use std::os::fd::BorrowedFd; use std::os::unix::io::RawFd; pub fn make_seqpacket_socket(path: &std::path::PathBuf) -> Result { @@ -18,7 +20,11 @@ pub fn make_seqpacket_socket(path: &std::path::PathBuf) -> Result // then bind the socket to the path nix::sys::socket::bind(fd, &unix_addr).unwrap(); // then make the socket an accepting one - nix::sys::socket::listen(fd, 128).unwrap(); + nix::sys::socket::listen( + &unsafe { BorrowedFd::borrow_raw(fd) }, + Backlog::new(128).unwrap(), + ) + .unwrap(); Ok(fd) } diff --git a/src/services/prepare_service.rs b/src/services/prepare_service.rs index f4799ba..c8053f0 100644 --- a/src/services/prepare_service.rs +++ b/src/services/prepare_service.rs @@ -2,6 +2,7 @@ use super::StdIo; use crate::services::Service; use crate::units::ServiceConfig; use crate::units::StdIoOption; +use std::os::fd::IntoRawFd; use std::os::unix::io::AsRawFd; use std::os::unix::net::UnixDatagram; @@ -27,7 +28,7 @@ fn open_stdio(setting: &Option) -> Result { } None => { let (r, w) = nix::unistd::pipe().unwrap(); - Ok(super::StdIo::Piped(r, w)) + Ok(super::StdIo::Piped(r.into_raw_fd(), w.into_raw_fd())) } } } diff --git a/src/services/service_exit_handler.rs b/src/services/service_exit_handler.rs index 2853d12..aed3740 100644 --- a/src/services/service_exit_handler.rs +++ b/src/services/service_exit_handler.rs @@ -150,7 +150,7 @@ pub fn service_exit_handler( name ); loop { - let res = crate::units::deactivate_unit_recursive(&srvc_id, run_info.clone()); + let res = crate::units::deactivate_unit_recursive(&srvc_id, run_info); let retry = if let Err(e) = &res { if let UnitOperationErrorReason::DependencyError(_) = e.reason { // Only retry if this is the case. This only occurs if, while the units are being deactivated, diff --git a/src/services/services.rs b/src/services/services.rs index fb20746..80bbe53 100644 --- a/src/services/services.rs +++ b/src/services/services.rs @@ -184,9 +184,9 @@ impl Service { &run_info.config.notification_sockets_dir, ) .map_err(|e| ServiceErrorReason::PreparingFailed(e))?; - self.run_prestart(conf, id.clone(), name, run_info.clone()) + self.run_prestart(conf, id.clone(), name, run_info) .map_err(|prestart_err| { - match self.run_poststop(conf, id.clone(), name, run_info.clone()) { + match self.run_poststop(conf, id.clone(), name, run_info) { Ok(_) => ServiceErrorReason::PrestartFailed(prestart_err), Err(poststop_err) => ServiceErrorReason::PrestartAndPoststopFailed( prestart_err, @@ -203,7 +203,7 @@ impl Service { &run_info.config.self_path, self, conf, - name.clone(), + name, &*run_info.fd_store.read().unwrap(), ) .map_err(|e| ServiceErrorReason::StartFailed(e))?; @@ -213,16 +213,16 @@ impl Service { } super::fork_parent::wait_for_service(self, conf, name, run_info).map_err( - |start_err| match self.run_poststop(conf, id.clone(), name, run_info.clone()) { + |start_err| match self.run_poststop(conf, id.clone(), name, run_info) { Ok(_) => ServiceErrorReason::StartFailed(start_err), Err(poststop_err) => { ServiceErrorReason::StartAndPoststopFailed(start_err, poststop_err) } }, )?; - self.run_poststart(conf, id.clone(), name, run_info.clone()) + self.run_poststart(conf, id.clone(), name, run_info) .map_err(|poststart_err| { - match self.run_poststop(conf, id.clone(), name, run_info.clone()) { + match self.run_poststop(conf, id.clone(), name, run_info) { Ok(_) => ServiceErrorReason::PrestartFailed(poststart_err), Err(poststop_err) => ServiceErrorReason::PoststartAndPoststopFailed( poststart_err, @@ -267,7 +267,7 @@ impl Service { name: &str, run_info: &RuntimeInfo, ) -> Result<(), RunCmdError> { - self.run_stop_cmd(conf, id, name, run_info.clone()) + self.run_stop_cmd(conf, id, name, run_info) } pub fn kill( &mut self, @@ -469,7 +469,7 @@ impl Service { run_info: &RuntimeInfo, ) -> Result<(), RunCmdError> { for cmd in cmds { - self.run_cmd(cmd, id.clone(), name, timeout, run_info.clone())?; + self.run_cmd(cmd, id.clone(), name, timeout, run_info)?; } Ok(()) } @@ -486,7 +486,7 @@ impl Service { } let timeout = self.get_stop_timeout(conf); let cmds = conf.stop.clone(); - self.run_all_cmds(&cmds, id, name, timeout, run_info.clone()) + self.run_all_cmds(&cmds, id, name, timeout, run_info) } fn run_prestart( &mut self, @@ -500,7 +500,7 @@ impl Service { } let timeout = self.get_start_timeout(conf); let cmds = conf.startpre.clone(); - self.run_all_cmds(&cmds, id, name, timeout, run_info.clone()) + self.run_all_cmds(&cmds, id, name, timeout, run_info) } fn run_poststart( &mut self, @@ -514,7 +514,7 @@ impl Service { } let timeout = self.get_start_timeout(conf); let cmds = conf.startpost.clone(); - self.run_all_cmds(&cmds, id, name, timeout, run_info.clone()) + self.run_all_cmds(&cmds, id, name, timeout, run_info) } fn run_poststop( &mut self, @@ -526,7 +526,7 @@ impl Service { trace!("Run poststop for {}", name); let timeout = self.get_stop_timeout(conf); let cmds = conf.stoppost.clone(); - let res = self.run_all_cmds(&cmds, id, name, timeout, run_info.clone()); + let res = self.run_all_cmds(&cmds, id, name, timeout, run_info); if conf.srcv_type != ServiceType::OneShot { // already happened when the oneshot process exited in the exit handler diff --git a/src/services/start_service.rs b/src/services/start_service.rs index 134e9fb..7ade7a6 100644 --- a/src/services/start_service.rs +++ b/src/services/start_service.rs @@ -142,7 +142,11 @@ fn start_service_with_filedescriptors( let name_arg = std::ffi::CString::new("exec_helper").unwrap(); let self_args = [name_arg.as_ptr(), std::ptr::null()]; - trace!("Start main executable for service: {name}: {:?} {:?}", exec_helper_conf.cmd, exec_helper_conf.args); + trace!( + "Start main executable for service: {name}: {:?} {:?}", + exec_helper_conf.cmd, + exec_helper_conf.args + ); match unsafe { nix::unistd::fork() } { Ok(nix::unistd::ForkResult::Parent { child, .. }) => { // make sure the file exists until after we fork before closing it diff --git a/src/socket_activation.rs b/src/socket_activation.rs index 547eded..45fd7e6 100644 --- a/src/socket_activation.rs +++ b/src/socket_activation.rs @@ -1,6 +1,8 @@ //! Wait for sockets to activate their respective services + use log::error; use log::trace; +use std::os::fd::BorrowedFd; use crate::runtime_info::*; use crate::units::*; @@ -106,11 +108,11 @@ pub fn wait_for_socket(run_info: ArcMutRuntimeInfo) -> Result, Strin if let Specific::Socket(specific) = &unit.specific { let mut_state = &*specific.state.read().unwrap(); if !mut_state.sock.activated { - fdset.insert(*fd); + fdset.insert(unsafe { BorrowedFd::borrow_raw(*fd) }); } } } - fdset.insert(eventfd.read_end()); + fdset.insert(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }); } (fdset, fd_to_sock_id) }; @@ -119,13 +121,13 @@ pub fn wait_for_socket(run_info: ArcMutRuntimeInfo) -> Result, Strin match result { Ok(_) => { let mut activated_ids = Vec::new(); - if fdset.contains(eventfd.read_end()) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(eventfd.read_end()) }) { trace!("Interrupted socketactivation select because the eventfd fired"); crate::platform::reset_event_fd(eventfd); trace!("Reset eventfd value"); } else { for (fd, id) in &fd_to_sock_id { - if fdset.contains(*fd) { + if fdset.contains(unsafe { BorrowedFd::borrow_raw(*fd) }) { activated_ids.push(id.clone()); } } diff --git a/src/units/unitset_manipulation/activate.rs b/src/units/unitset_manipulation/activate.rs index 9adeca5..eef1c95 100644 --- a/src/units/unitset_manipulation/activate.rs +++ b/src/units/unitset_manipulation/activate.rs @@ -165,7 +165,7 @@ pub fn activate_unit( let next_services_ids = unit.common.dependencies.before.clone(); - unit.activate(run_info.clone(), source) + unit.activate(run_info, source) .map(|_| StartResult::Started(next_services_ids)) } diff --git a/src/units/unitset_manipulation/deactivate.rs b/src/units/unitset_manipulation/deactivate.rs index a8be1a5..39816ec 100644 --- a/src/units/unitset_manipulation/deactivate.rs +++ b/src/units/unitset_manipulation/deactivate.rs @@ -24,7 +24,7 @@ pub fn deactivate_unit_recursive( deactivate_units_recursive(&unit.common.dependencies.required_by, run_info)?; - deactivate_unit(id_to_kill, run_info.clone()) + deactivate_unit(id_to_kill, run_info) } pub fn deactivate_unit( @@ -45,7 +45,7 @@ pub fn deactivate_unit( }); } }; - unit.deactivate(run_info.clone())?; + unit.deactivate(run_info)?; Ok(()) } @@ -65,7 +65,7 @@ pub fn deactivate_units( run_info: &RuntimeInfo, ) -> Result<(), UnitOperationError> { for id in ids_to_kill { - deactivate_unit(id, run_info.clone())?; + deactivate_unit(id, run_info)?; } Ok(()) }