summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls Piņķis <emils@mullvad.net>2022-08-23 16:28:48 +0200
committerEmīls Piņķis <emils@mullvad.net>2022-09-21 12:26:26 +0200
commit27fa1d9f00fe4a078a1d64348a806890d0aea4bd (patch)
tree4606298e86a0e4c1ebff24ff4bd0d8d350dd06e2
parentd4b7d8004ac0074aa27048d0c97b988e740abab7 (diff)
downloadmullvadvpn-27fa1d9f00fe4a078a1d64348a806890d0aea4bd.tar.xz
mullvadvpn-27fa1d9f00fe4a078a1d64348a806890d0aea4bd.zip
Add systemd module to talpid-dbus
-rw-r--r--talpid-dbus/src/lib.rs1
-rw-r--r--talpid-dbus/src/systemd.rs67
2 files changed, 68 insertions, 0 deletions
diff --git a/talpid-dbus/src/lib.rs b/talpid-dbus/src/lib.rs
index c4b9bb7e12..f85581864a 100644
--- a/talpid-dbus/src/lib.rs
+++ b/talpid-dbus/src/lib.rs
@@ -4,6 +4,7 @@ pub use dbus;
use dbus::blocking::SyncConnection;
use std::sync::{Arc, Mutex};
pub mod network_manager;
+pub mod systemd;
pub mod systemd_resolved;
lazy_static::lazy_static! {
diff --git a/talpid-dbus/src/systemd.rs b/talpid-dbus/src/systemd.rs
new file mode 100644
index 0000000000..521f2a1b8e
--- /dev/null
+++ b/talpid-dbus/src/systemd.rs
@@ -0,0 +1,67 @@
+use dbus::blocking::{stdintf::org_freedesktop_dbus::Properties, Proxy, SyncConnection};
+use std::{sync::Arc, time::Duration};
+
+type Result<T> = std::result::Result<T, Error>;
+
+#[derive(err_derive::Error, Debug)]
+#[error(no_from)]
+pub enum Error {
+ #[error(display = "Failed to create a DBus connection")]
+ ConnectError(#[error(source)] dbus::Error),
+
+ #[error(display = "Failed to read SystemState property")]
+ ReadSystemStateError(#[error(source)] dbus::Error),
+}
+
+const SYSTEMD_BUS: &str = "org.freedesktop.systemd1";
+const SYSTEMD_PATH: &str = "/org/freedesktop/systemd1";
+const MANAGER_INTERFACE: &str = "org.freedesktop.systemd1.Manager";
+const SYSTEM_STATE: &str = "SystemState";
+const SYSTEM_STATE_STARTING: &str = "starting";
+const SYSTEM_STATE_INITIALIZING: &str = "initializing";
+const SYSTEM_STATE_RUNNING: &str = "running";
+const SYSTEM_STATE_DEGRADED: &str = "degraded";
+
+const RPC_TIMEOUT: Duration = Duration::from_secs(1);
+
+/// Returns true if the host is not shutting down or entering maintenance mode or some other weird
+/// state.
+pub fn is_host_running() -> Result<bool> {
+ Systemd::new()?.system_is_running()
+}
+
+struct Systemd {
+ pub dbus_connection: Arc<SyncConnection>,
+}
+
+impl Systemd {
+ fn new() -> Result<Self> {
+ Ok(Self {
+ dbus_connection: crate::get_connection().map_err(Error::ConnectError)?,
+ })
+ }
+
+ fn system_is_running(&self) -> Result<bool> {
+ self.as_manager_object()
+ .get(MANAGER_INTERFACE, SYSTEM_STATE)
+ .map(|state: String| {
+ ![
+ SYSTEM_STATE_STARTING,
+ SYSTEM_STATE_INITIALIZING,
+ SYSTEM_STATE_RUNNING,
+ SYSTEM_STATE_DEGRADED,
+ ]
+ .contains(&state.as_str())
+ })
+ .map_err(Error::ReadSystemStateError)
+ }
+
+ fn as_manager_object(&self) -> Proxy<'_, &SyncConnection> {
+ Proxy::new(
+ SYSTEMD_BUS,
+ SYSTEMD_PATH,
+ RPC_TIMEOUT,
+ &self.dbus_connection,
+ )
+ }
+}