agent: optimize the code of systemd cgroup manager

1. Directly support CgroupManager::freeze through systemd API.
2. Avoid always passing unit_name by storing it into DBusClient.
3. Realize CgroupManager::destroy more accurately by killing systemd unit rather than stop it.
4. Ignore no such unit error when destroying systemd unit.
5. Update zbus version and corresponding interface file.

Acknowledgement: error handling for no such systemd unit error refers to

Fixes: #7080, #7142, #7143, #7166

Signed-off-by: Yuan-Zhuo <yuanzhuo0118@outlook.com>
Signed-off-by: Yohei Ueda <yohei@jp.ibm.com>
This commit is contained in:
Yuan-Zhuo 2023-09-09 13:56:43 +08:00
parent fa818bfad1
commit 470d065415
6 changed files with 587 additions and 264 deletions

538
src/agent/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ futures = "0.3.17"
async-trait = "0.1.31" async-trait = "0.1.31"
inotify = "0.9.2" inotify = "0.9.2"
libseccomp = { version = "0.3.0", optional = true } libseccomp = { version = "0.3.0", optional = true }
zbus = "2.3.0" zbus = "3.12.0"
bit-vec= "0.6.3" bit-vec= "0.6.3"
xattr = "0.2.3" xattr = "0.2.3"

View File

@ -6,7 +6,10 @@
pub const DEFAULT_SLICE: &str = "system.slice"; pub const DEFAULT_SLICE: &str = "system.slice";
pub const SLICE_SUFFIX: &str = ".slice"; pub const SLICE_SUFFIX: &str = ".slice";
pub const SCOPE_SUFFIX: &str = ".scope"; pub const SCOPE_SUFFIX: &str = ".scope";
pub const UNIT_MODE: &str = "replace"; pub const WHO_ENUM_ALL: &str = "all";
pub const SIGNAL_KILL: i32 = nix::sys::signal::SIGKILL as i32;
pub const UNIT_MODE_REPLACE: &str = "replace";
pub const NO_SUCH_UNIT_ERROR: &str = "org.freedesktop.systemd1.NoSuchUnit";
pub type Properties<'a> = Vec<(&'a str, zbus::zvariant::Value<'a>)>; pub type Properties<'a> = Vec<(&'a str, zbus::zvariant::Value<'a>)>;

View File

@ -1,56 +1,50 @@
// Copyright 2021-2022 Kata Contributors // Copyright 2021-2023 Kata Contributors
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
use std::vec; use std::vec;
use super::common::CgroupHierarchy; use super::common::{
use super::common::{Properties, SLICE_SUFFIX, UNIT_MODE}; CgroupHierarchy, Properties, NO_SUCH_UNIT_ERROR, SIGNAL_KILL, SLICE_SUFFIX, UNIT_MODE_REPLACE,
WHO_ENUM_ALL,
};
use super::interface::system::ManagerProxyBlocking as SystemManager; use super::interface::system::ManagerProxyBlocking as SystemManager;
use anyhow::{Context, Result}; use anyhow::{anyhow, Context, Result};
use zbus::zvariant::Value; use zbus::zvariant::Value;
pub trait SystemdInterface { pub trait SystemdInterface {
fn start_unit( fn start_unit(&self, pid: i32, parent: &str, cg_hierarchy: &CgroupHierarchy) -> Result<()>;
&self, fn set_properties(&self, properties: &Properties) -> Result<()>;
pid: i32, fn kill_unit(&self) -> Result<()>;
parent: &str, fn freeze_unit(&self) -> Result<()>;
unit_name: &str, fn thaw_unit(&self) -> Result<()>;
cg_hierarchy: &CgroupHierarchy, fn add_process(&self, pid: i32) -> Result<()>;
) -> Result<()>;
fn set_properties(&self, unit_name: &str, properties: &Properties) -> Result<()>;
fn stop_unit(&self, unit_name: &str) -> Result<()>;
fn get_version(&self) -> Result<String>; fn get_version(&self) -> Result<String>;
fn unit_exists(&self) -> Result<bool>;
fn unit_exists(&self, unit_name: &str) -> Result<bool>;
fn add_process(&self, pid: i32, unit_name: &str) -> Result<()>;
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DBusClient {} pub struct DBusClient {
unit_name: String,
}
impl DBusClient { impl DBusClient {
pub fn new(unit_name: String) -> Self {
Self { unit_name }
}
fn build_proxy(&self) -> Result<SystemManager<'static>> { fn build_proxy(&self) -> Result<SystemManager<'static>> {
let connection = let connection =
zbus::blocking::Connection::system().context("Establishing a D-Bus connection")?; zbus::blocking::Connection::system().context("Establishing a D-Bus connection")?;
let proxy = SystemManager::new(&connection).context("Building a D-Bus proxy manager")?; let proxy = SystemManager::new(&connection).context("Building a D-Bus proxy manager")?;
Ok(proxy) Ok(proxy)
} }
} }
impl SystemdInterface for DBusClient { impl SystemdInterface for DBusClient {
fn start_unit( fn start_unit(&self, pid: i32, parent: &str, cg_hierarchy: &CgroupHierarchy) -> Result<()> {
&self,
pid: i32,
parent: &str,
unit_name: &str,
cg_hierarchy: &CgroupHierarchy,
) -> Result<()> {
let proxy = self.build_proxy()?; let proxy = self.build_proxy()?;
// enable CPUAccounting & MemoryAccounting & (Block)IOAccounting by default // enable CPUAccounting & MemoryAccounting & (Block)IOAccounting by default
@ -68,7 +62,7 @@ impl SystemdInterface for DBusClient {
CgroupHierarchy::Unified => properties.push(("BlockIOAccounting", Value::Bool(true))), CgroupHierarchy::Unified => properties.push(("BlockIOAccounting", Value::Bool(true))),
} }
if unit_name.ends_with(SLICE_SUFFIX) { if self.unit_name.ends_with(SLICE_SUFFIX) {
properties.push(("Wants", Value::Str(parent.into()))); properties.push(("Wants", Value::Str(parent.into())));
} else { } else {
properties.push(("Slice", Value::Str(parent.into()))); properties.push(("Slice", Value::Str(parent.into())));
@ -76,27 +70,57 @@ impl SystemdInterface for DBusClient {
} }
proxy proxy
.start_transient_unit(unit_name, UNIT_MODE, &properties, &[]) .start_transient_unit(&self.unit_name, UNIT_MODE_REPLACE, &properties, &[])
.with_context(|| format!("failed to start transient unit {}", unit_name))?; .context(format!("failed to start transient unit {}", self.unit_name))?;
Ok(())
}
fn set_properties(&self, unit_name: &str, properties: &Properties) -> Result<()> {
let proxy = self.build_proxy()?;
proxy
.set_unit_properties(unit_name, true, properties)
.with_context(|| format!("failed to set unit properties {}", unit_name))?;
Ok(()) Ok(())
} }
fn stop_unit(&self, unit_name: &str) -> Result<()> { fn set_properties(&self, properties: &Properties) -> Result<()> {
let proxy = self.build_proxy()?; let proxy = self.build_proxy()?;
proxy proxy
.stop_unit(unit_name, UNIT_MODE) .set_unit_properties(&self.unit_name, true, properties)
.with_context(|| format!("failed to stop unit {}", unit_name))?; .context(format!("failed to set unit {} properties", self.unit_name))?;
Ok(())
}
fn kill_unit(&self) -> Result<()> {
let proxy = self.build_proxy()?;
proxy
.kill_unit(&self.unit_name, WHO_ENUM_ALL, SIGNAL_KILL)
.or_else(|e| match e {
zbus::Error::MethodError(error_name, _, _)
if error_name.as_str() == NO_SUCH_UNIT_ERROR =>
{
Ok(())
}
_ => Err(e),
})
.context(format!("failed to kill unit {}", self.unit_name))?;
Ok(())
}
fn freeze_unit(&self) -> Result<()> {
let proxy = self.build_proxy()?;
proxy
.freeze_unit(&self.unit_name)
.context(format!("failed to freeze unit {}", self.unit_name))?;
Ok(())
}
fn thaw_unit(&self) -> Result<()> {
let proxy = self.build_proxy()?;
proxy
.thaw_unit(&self.unit_name)
.context(format!("failed to thaw unit {}", self.unit_name))?;
Ok(()) Ok(())
} }
@ -105,24 +129,37 @@ impl SystemdInterface for DBusClient {
let systemd_version = proxy let systemd_version = proxy
.version() .version()
.with_context(|| "failed to get systemd version".to_string())?; .context("failed to get systemd version".to_string())?;
Ok(systemd_version) Ok(systemd_version)
} }
fn unit_exists(&self, unit_name: &str) -> Result<bool> { fn unit_exists(&self) -> Result<bool> {
let proxy = self let proxy = self.build_proxy()?;
.build_proxy()
.with_context(|| format!("Checking if systemd unit {} exists", unit_name))?;
Ok(proxy.get_unit(unit_name).is_ok()) match proxy.get_unit(&self.unit_name) {
Ok(_) => Ok(true),
Err(zbus::Error::MethodError(error_name, _, _))
if error_name.as_str() == NO_SUCH_UNIT_ERROR =>
{
Ok(false)
}
Err(e) => Err(anyhow!(format!(
"failed to check if unit {} exists: {:?}",
self.unit_name, e
))),
}
} }
fn add_process(&self, pid: i32, unit_name: &str) -> Result<()> { fn add_process(&self, pid: i32) -> Result<()> {
let proxy = self.build_proxy()?; let proxy = self.build_proxy()?;
proxy proxy
.attach_processes_to_unit(unit_name, "/", &[pid as u32]) .attach_processes_to_unit(&self.unit_name, "/", &[pid as u32])
.with_context(|| format!("failed to add process {}", unit_name))?; .context(format!(
"failed to add process into unit {}",
self.unit_name
))?;
Ok(()) Ok(())
} }

View File

@ -1,4 +1,4 @@
// Copyright 2021-2022 Kata Contributors // Copyright 2021-2023 Kata Contributors
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// //
@ -8,7 +8,7 @@
//! # DBus interface proxy for: `org.freedesktop.systemd1.Manager` //! # DBus interface proxy for: `org.freedesktop.systemd1.Manager`
//! //!
//! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data. //! This code was generated by `zbus-xmlgen` `3.1.1` from DBus introspection data.
//! Source: `Interface '/org/freedesktop/systemd1' from service 'org.freedesktop.systemd1' on system bus`. //! Source: `Interface '/org/freedesktop/systemd1' from service 'org.freedesktop.systemd1' on system bus`.
//! //!
//! You may prefer to adapt it, instead of using it verbatim. //! You may prefer to adapt it, instead of using it verbatim.
@ -189,12 +189,14 @@ trait Manager {
) -> zbus::Result<zbus::zvariant::OwnedObjectPath>; ) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
/// GetUnitByInvocationID method /// GetUnitByInvocationID method
#[dbus_proxy(name = "GetUnitByInvocationID")]
fn get_unit_by_invocation_id( fn get_unit_by_invocation_id(
&self, &self,
invocation_id: &[u8], invocation_id: &[u8],
) -> zbus::Result<zbus::zvariant::OwnedObjectPath>; ) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
/// GetUnitByPID method /// GetUnitByPID method
#[dbus_proxy(name = "GetUnitByPID")]
fn get_unit_by_pid(&self, pid: u32) -> zbus::Result<zbus::zvariant::OwnedObjectPath>; fn get_unit_by_pid(&self, pid: u32) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
/// GetUnitFileLinks method /// GetUnitFileLinks method
@ -210,6 +212,7 @@ trait Manager {
fn halt(&self) -> zbus::Result<()>; fn halt(&self) -> zbus::Result<()>;
/// KExec method /// KExec method
#[dbus_proxy(name = "KExec")]
fn kexec(&self) -> zbus::Result<()>; fn kexec(&self) -> zbus::Result<()>;
/// KillUnit method /// KillUnit method
@ -330,6 +333,7 @@ trait Manager {
fn lookup_dynamic_user_by_name(&self, name: &str) -> zbus::Result<u32>; fn lookup_dynamic_user_by_name(&self, name: &str) -> zbus::Result<u32>;
/// LookupDynamicUserByUID method /// LookupDynamicUserByUID method
#[dbus_proxy(name = "LookupDynamicUserByUID")]
fn lookup_dynamic_user_by_uid(&self, uid: u32) -> zbus::Result<String>; fn lookup_dynamic_user_by_uid(&self, uid: u32) -> zbus::Result<String>;
/// MaskUnitFiles method /// MaskUnitFiles method
@ -571,139 +575,139 @@ trait Manager {
fn ctrl_alt_del_burst_action(&self) -> zbus::Result<String>; fn ctrl_alt_del_burst_action(&self) -> zbus::Result<String>;
/// DefaultBlockIOAccounting property /// DefaultBlockIOAccounting property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultBlockIOAccounting")]
fn default_block_ioaccounting(&self) -> zbus::Result<bool>; fn default_block_ioaccounting(&self) -> zbus::Result<bool>;
/// DefaultCPUAccounting property /// DefaultCPUAccounting property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultCPUAccounting")]
fn default_cpuaccounting(&self) -> zbus::Result<bool>; fn default_cpuaccounting(&self) -> zbus::Result<bool>;
/// DefaultLimitAS property /// DefaultLimitAS property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitAS")]
fn default_limit_as(&self) -> zbus::Result<u64>; fn default_limit_as(&self) -> zbus::Result<u64>;
/// DefaultLimitASSoft property /// DefaultLimitASSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitASSoft")]
fn default_limit_assoft(&self) -> zbus::Result<u64>; fn default_limit_assoft(&self) -> zbus::Result<u64>;
/// DefaultLimitCORE property /// DefaultLimitCORE property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitCORE")]
fn default_limit_core(&self) -> zbus::Result<u64>; fn default_limit_core(&self) -> zbus::Result<u64>;
/// DefaultLimitCORESoft property /// DefaultLimitCORESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitCORESoft")]
fn default_limit_coresoft(&self) -> zbus::Result<u64>; fn default_limit_coresoft(&self) -> zbus::Result<u64>;
/// DefaultLimitCPU property /// DefaultLimitCPU property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitCPU")]
fn default_limit_cpu(&self) -> zbus::Result<u64>; fn default_limit_cpu(&self) -> zbus::Result<u64>;
/// DefaultLimitCPUSoft property /// DefaultLimitCPUSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitCPUSoft")]
fn default_limit_cpusoft(&self) -> zbus::Result<u64>; fn default_limit_cpusoft(&self) -> zbus::Result<u64>;
/// DefaultLimitDATA property /// DefaultLimitDATA property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitDATA")]
fn default_limit_data(&self) -> zbus::Result<u64>; fn default_limit_data(&self) -> zbus::Result<u64>;
/// DefaultLimitDATASoft property /// DefaultLimitDATASoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitDATASoft")]
fn default_limit_datasoft(&self) -> zbus::Result<u64>; fn default_limit_datasoft(&self) -> zbus::Result<u64>;
/// DefaultLimitFSIZE property /// DefaultLimitFSIZE property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitFSIZE")]
fn default_limit_fsize(&self) -> zbus::Result<u64>; fn default_limit_fsize(&self) -> zbus::Result<u64>;
/// DefaultLimitFSIZESoft property /// DefaultLimitFSIZESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitFSIZESoft")]
fn default_limit_fsizesoft(&self) -> zbus::Result<u64>; fn default_limit_fsizesoft(&self) -> zbus::Result<u64>;
/// DefaultLimitLOCKS property /// DefaultLimitLOCKS property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitLOCKS")]
fn default_limit_locks(&self) -> zbus::Result<u64>; fn default_limit_locks(&self) -> zbus::Result<u64>;
/// DefaultLimitLOCKSSoft property /// DefaultLimitLOCKSSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitLOCKSSoft")]
fn default_limit_lockssoft(&self) -> zbus::Result<u64>; fn default_limit_lockssoft(&self) -> zbus::Result<u64>;
/// DefaultLimitMEMLOCK property /// DefaultLimitMEMLOCK property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitMEMLOCK")]
fn default_limit_memlock(&self) -> zbus::Result<u64>; fn default_limit_memlock(&self) -> zbus::Result<u64>;
/// DefaultLimitMEMLOCKSoft property /// DefaultLimitMEMLOCKSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitMEMLOCKSoft")]
fn default_limit_memlocksoft(&self) -> zbus::Result<u64>; fn default_limit_memlocksoft(&self) -> zbus::Result<u64>;
/// DefaultLimitMSGQUEUE property /// DefaultLimitMSGQUEUE property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitMSGQUEUE")]
fn default_limit_msgqueue(&self) -> zbus::Result<u64>; fn default_limit_msgqueue(&self) -> zbus::Result<u64>;
/// DefaultLimitMSGQUEUESoft property /// DefaultLimitMSGQUEUESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitMSGQUEUESoft")]
fn default_limit_msgqueuesoft(&self) -> zbus::Result<u64>; fn default_limit_msgqueuesoft(&self) -> zbus::Result<u64>;
/// DefaultLimitNICE property /// DefaultLimitNICE property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNICE")]
fn default_limit_nice(&self) -> zbus::Result<u64>; fn default_limit_nice(&self) -> zbus::Result<u64>;
/// DefaultLimitNICESoft property /// DefaultLimitNICESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNICESoft")]
fn default_limit_nicesoft(&self) -> zbus::Result<u64>; fn default_limit_nicesoft(&self) -> zbus::Result<u64>;
/// DefaultLimitNOFILE property /// DefaultLimitNOFILE property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNOFILE")]
fn default_limit_nofile(&self) -> zbus::Result<u64>; fn default_limit_nofile(&self) -> zbus::Result<u64>;
/// DefaultLimitNOFILESoft property /// DefaultLimitNOFILESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNOFILESoft")]
fn default_limit_nofilesoft(&self) -> zbus::Result<u64>; fn default_limit_nofilesoft(&self) -> zbus::Result<u64>;
/// DefaultLimitNPROC property /// DefaultLimitNPROC property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNPROC")]
fn default_limit_nproc(&self) -> zbus::Result<u64>; fn default_limit_nproc(&self) -> zbus::Result<u64>;
/// DefaultLimitNPROCSoft property /// DefaultLimitNPROCSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitNPROCSoft")]
fn default_limit_nprocsoft(&self) -> zbus::Result<u64>; fn default_limit_nprocsoft(&self) -> zbus::Result<u64>;
/// DefaultLimitRSS property /// DefaultLimitRSS property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRSS")]
fn default_limit_rss(&self) -> zbus::Result<u64>; fn default_limit_rss(&self) -> zbus::Result<u64>;
/// DefaultLimitRSSSoft property /// DefaultLimitRSSSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRSSSoft")]
fn default_limit_rsssoft(&self) -> zbus::Result<u64>; fn default_limit_rsssoft(&self) -> zbus::Result<u64>;
/// DefaultLimitRTPRIO property /// DefaultLimitRTPRIO property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRTPRIO")]
fn default_limit_rtprio(&self) -> zbus::Result<u64>; fn default_limit_rtprio(&self) -> zbus::Result<u64>;
/// DefaultLimitRTPRIOSoft property /// DefaultLimitRTPRIOSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRTPRIOSoft")]
fn default_limit_rtpriosoft(&self) -> zbus::Result<u64>; fn default_limit_rtpriosoft(&self) -> zbus::Result<u64>;
/// DefaultLimitRTTIME property /// DefaultLimitRTTIME property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRTTIME")]
fn default_limit_rttime(&self) -> zbus::Result<u64>; fn default_limit_rttime(&self) -> zbus::Result<u64>;
/// DefaultLimitRTTIMESoft property /// DefaultLimitRTTIMESoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitRTTIMESoft")]
fn default_limit_rttimesoft(&self) -> zbus::Result<u64>; fn default_limit_rttimesoft(&self) -> zbus::Result<u64>;
/// DefaultLimitSIGPENDING property /// DefaultLimitSIGPENDING property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitSIGPENDING")]
fn default_limit_sigpending(&self) -> zbus::Result<u64>; fn default_limit_sigpending(&self) -> zbus::Result<u64>;
/// DefaultLimitSIGPENDINGSoft property /// DefaultLimitSIGPENDINGSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitSIGPENDINGSoft")]
fn default_limit_sigpendingsoft(&self) -> zbus::Result<u64>; fn default_limit_sigpendingsoft(&self) -> zbus::Result<u64>;
/// DefaultLimitSTACK property /// DefaultLimitSTACK property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitSTACK")]
fn default_limit_stack(&self) -> zbus::Result<u64>; fn default_limit_stack(&self) -> zbus::Result<u64>;
/// DefaultLimitSTACKSoft property /// DefaultLimitSTACKSoft property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultLimitSTACKSoft")]
fn default_limit_stacksoft(&self) -> zbus::Result<u64>; fn default_limit_stacksoft(&self) -> zbus::Result<u64>;
/// DefaultMemoryAccounting property /// DefaultMemoryAccounting property
@ -711,11 +715,11 @@ trait Manager {
fn default_memory_accounting(&self) -> zbus::Result<bool>; fn default_memory_accounting(&self) -> zbus::Result<bool>;
/// DefaultOOMPolicy property /// DefaultOOMPolicy property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultOOMPolicy")]
fn default_oompolicy(&self) -> zbus::Result<String>; fn default_oompolicy(&self) -> zbus::Result<String>;
/// DefaultRestartUSec property /// DefaultRestartUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultRestartUSec")]
fn default_restart_usec(&self) -> zbus::Result<u64>; fn default_restart_usec(&self) -> zbus::Result<u64>;
/// DefaultStandardError property /// DefaultStandardError property
@ -731,7 +735,7 @@ trait Manager {
fn default_start_limit_burst(&self) -> zbus::Result<u32>; fn default_start_limit_burst(&self) -> zbus::Result<u32>;
/// DefaultStartLimitIntervalUSec property /// DefaultStartLimitIntervalUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultStartLimitIntervalUSec")]
fn default_start_limit_interval_usec(&self) -> zbus::Result<u64>; fn default_start_limit_interval_usec(&self) -> zbus::Result<u64>;
/// DefaultTasksAccounting property /// DefaultTasksAccounting property
@ -743,19 +747,19 @@ trait Manager {
fn default_tasks_max(&self) -> zbus::Result<u64>; fn default_tasks_max(&self) -> zbus::Result<u64>;
/// DefaultTimeoutAbortUSec property /// DefaultTimeoutAbortUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultTimeoutAbortUSec")]
fn default_timeout_abort_usec(&self) -> zbus::Result<u64>; fn default_timeout_abort_usec(&self) -> zbus::Result<u64>;
/// DefaultTimeoutStartUSec property /// DefaultTimeoutStartUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultTimeoutStartUSec")]
fn default_timeout_start_usec(&self) -> zbus::Result<u64>; fn default_timeout_start_usec(&self) -> zbus::Result<u64>;
/// DefaultTimeoutStopUSec property /// DefaultTimeoutStopUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultTimeoutStopUSec")]
fn default_timeout_stop_usec(&self) -> zbus::Result<u64>; fn default_timeout_stop_usec(&self) -> zbus::Result<u64>;
/// DefaultTimerAccuracyUSec property /// DefaultTimerAccuracyUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "DefaultTimerAccuracyUSec")]
fn default_timer_accuracy_usec(&self) -> zbus::Result<u64>; fn default_timer_accuracy_usec(&self) -> zbus::Result<u64>;
/// Environment property /// Environment property
@ -803,65 +807,64 @@ trait Manager {
fn generators_start_timestamp_monotonic(&self) -> zbus::Result<u64>; fn generators_start_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDGeneratorsFinishTimestamp property /// InitRDGeneratorsFinishTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDGeneratorsFinishTimestamp")]
fn init_rdgenerators_finish_timestamp(&self) -> zbus::Result<u64>; fn init_rdgenerators_finish_timestamp(&self) -> zbus::Result<u64>;
/// InitRDGeneratorsFinishTimestampMonotonic property /// InitRDGeneratorsFinishTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDGeneratorsFinishTimestampMonotonic")]
fn init_rdgenerators_finish_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdgenerators_finish_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDGeneratorsStartTimestamp property /// InitRDGeneratorsStartTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDGeneratorsStartTimestamp")]
fn init_rdgenerators_start_timestamp(&self) -> zbus::Result<u64>; fn init_rdgenerators_start_timestamp(&self) -> zbus::Result<u64>;
/// InitRDGeneratorsStartTimestampMonotonic property /// InitRDGeneratorsStartTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDGeneratorsStartTimestampMonotonic")]
fn init_rdgenerators_start_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdgenerators_start_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDSecurityFinishTimestamp property /// InitRDSecurityFinishTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDSecurityFinishTimestamp")]
fn init_rdsecurity_finish_timestamp(&self) -> zbus::Result<u64>; fn init_rdsecurity_finish_timestamp(&self) -> zbus::Result<u64>;
/// InitRDSecurityFinishTimestampMonotonic property /// InitRDSecurityFinishTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDSecurityFinishTimestampMonotonic")]
fn init_rdsecurity_finish_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdsecurity_finish_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDSecurityStartTimestamp property /// InitRDSecurityStartTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDSecurityStartTimestamp")]
fn init_rdsecurity_start_timestamp(&self) -> zbus::Result<u64>; fn init_rdsecurity_start_timestamp(&self) -> zbus::Result<u64>;
/// InitRDSecurityStartTimestampMonotonic property /// InitRDSecurityStartTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDSecurityStartTimestampMonotonic")]
fn init_rdsecurity_start_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdsecurity_start_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDTimestamp property /// InitRDTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDTimestamp")]
fn init_rdtimestamp(&self) -> zbus::Result<u64>; fn init_rdtimestamp(&self) -> zbus::Result<u64>;
/// InitRDTimestampMonotonic property /// InitRDTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDTimestampMonotonic")]
fn init_rdtimestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdtimestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDUnitsLoadFinishTimestamp property /// InitRDUnitsLoadFinishTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDUnitsLoadFinishTimestamp")]
fn init_rdunits_load_finish_timestamp(&self) -> zbus::Result<u64>; fn init_rdunits_load_finish_timestamp(&self) -> zbus::Result<u64>;
/// InitRDUnitsLoadFinishTimestampMonotonic property /// InitRDUnitsLoadFinishTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDUnitsLoadFinishTimestampMonotonic")]
fn init_rdunits_load_finish_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdunits_load_finish_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// InitRDUnitsLoadStartTimestamp property /// InitRDUnitsLoadStartTimestamp property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDUnitsLoadStartTimestamp")]
fn init_rdunits_load_start_timestamp(&self) -> zbus::Result<u64>; fn init_rdunits_load_start_timestamp(&self) -> zbus::Result<u64>;
/// InitRDUnitsLoadStartTimestampMonotonic property /// InitRDUnitsLoadStartTimestampMonotonic property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "InitRDUnitsLoadStartTimestampMonotonic")]
fn init_rdunits_load_start_timestamp_monotonic(&self) -> zbus::Result<u64>; fn init_rdunits_load_start_timestamp_monotonic(&self) -> zbus::Result<u64>;
/// KExecWatchdogUSec property /// KExecWatchdogUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "KExecWatchdogUSec")]
fn kexec_watchdog_usec(&self) -> zbus::Result<u64>; fn kexec_watchdog_usec(&self) -> zbus::Result<u64>;
#[dbus_proxy(property)]
fn set_kexec_watchdog_usec(&self, value: u64) -> zbus::Result<()>; fn set_kexec_watchdog_usec(&self, value: u64) -> zbus::Result<()>;
/// KernelTimestamp property /// KernelTimestamp property
@ -883,33 +886,31 @@ trait Manager {
/// LogLevel property /// LogLevel property
#[dbus_proxy(property)] #[dbus_proxy(property)]
fn log_level(&self) -> zbus::Result<String>; fn log_level(&self) -> zbus::Result<String>;
#[dbus_proxy(property)]
fn set_log_level(&self, value: &str) -> zbus::Result<()>; fn set_log_level(&self, value: &str) -> zbus::Result<()>;
/// LogTarget property /// LogTarget property
#[dbus_proxy(property)] #[dbus_proxy(property)]
fn log_target(&self) -> zbus::Result<String>; fn log_target(&self) -> zbus::Result<String>;
#[dbus_proxy(property)]
fn set_log_target(&self, value: &str) -> zbus::Result<()>; fn set_log_target(&self, value: &str) -> zbus::Result<()>;
/// NFailedJobs property /// NFailedJobs property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "NFailedJobs")]
fn nfailed_jobs(&self) -> zbus::Result<u32>; fn nfailed_jobs(&self) -> zbus::Result<u32>;
/// NFailedUnits property /// NFailedUnits property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "NFailedUnits")]
fn nfailed_units(&self) -> zbus::Result<u32>; fn nfailed_units(&self) -> zbus::Result<u32>;
/// NInstalledJobs property /// NInstalledJobs property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "NInstalledJobs")]
fn ninstalled_jobs(&self) -> zbus::Result<u32>; fn ninstalled_jobs(&self) -> zbus::Result<u32>;
/// NJobs property /// NJobs property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "NJobs")]
fn njobs(&self) -> zbus::Result<u32>; fn njobs(&self) -> zbus::Result<u32>;
/// NNames property /// NNames property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "NNames")]
fn nnames(&self) -> zbus::Result<u32>; fn nnames(&self) -> zbus::Result<u32>;
/// Progress property /// Progress property
@ -917,15 +918,13 @@ trait Manager {
fn progress(&self) -> zbus::Result<f64>; fn progress(&self) -> zbus::Result<f64>;
/// RebootWatchdogUSec property /// RebootWatchdogUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "RebootWatchdogUSec")]
fn reboot_watchdog_usec(&self) -> zbus::Result<u64>; fn reboot_watchdog_usec(&self) -> zbus::Result<u64>;
#[dbus_proxy(property)]
fn set_reboot_watchdog_usec(&self, value: u64) -> zbus::Result<()>; fn set_reboot_watchdog_usec(&self, value: u64) -> zbus::Result<()>;
/// RuntimeWatchdogUSec property /// RuntimeWatchdogUSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "RuntimeWatchdogUSec")]
fn runtime_watchdog_usec(&self) -> zbus::Result<u64>; fn runtime_watchdog_usec(&self) -> zbus::Result<u64>;
#[dbus_proxy(property)]
fn set_runtime_watchdog_usec(&self, value: u64) -> zbus::Result<()>; fn set_runtime_watchdog_usec(&self, value: u64) -> zbus::Result<()>;
/// SecurityFinishTimestamp property /// SecurityFinishTimestamp property
@ -947,7 +946,6 @@ trait Manager {
/// ServiceWatchdogs property /// ServiceWatchdogs property
#[dbus_proxy(property)] #[dbus_proxy(property)]
fn service_watchdogs(&self) -> zbus::Result<bool>; fn service_watchdogs(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
fn set_service_watchdogs(&self, value: bool) -> zbus::Result<()>; fn set_service_watchdogs(&self, value: bool) -> zbus::Result<()>;
/// ShowStatus property /// ShowStatus property
@ -963,7 +961,7 @@ trait Manager {
fn tainted(&self) -> zbus::Result<String>; fn tainted(&self) -> zbus::Result<String>;
/// TimerSlackNSec property /// TimerSlackNSec property
#[dbus_proxy(property)] #[dbus_proxy(property, name = "TimerSlackNSec")]
fn timer_slack_nsec(&self) -> zbus::Result<u64>; fn timer_slack_nsec(&self) -> zbus::Result<u64>;
/// UnitPath property /// UnitPath property

View File

@ -5,7 +5,7 @@
use crate::cgroups::Manager as CgroupManager; use crate::cgroups::Manager as CgroupManager;
use crate::protocols::agent::CgroupStats; use crate::protocols::agent::CgroupStats;
use anyhow::Result; use anyhow::{anyhow, Result};
use cgroups::freezer::FreezerState; use cgroups::freezer::FreezerState;
use libc::{self, pid_t}; use libc::{self, pid_t};
use oci::LinuxResources; use oci::LinuxResources;
@ -29,7 +29,6 @@ pub struct Manager {
pub mounts: HashMap<String, String>, pub mounts: HashMap<String, String>,
pub cgroups_path: CgroupsPath, pub cgroups_path: CgroupsPath,
pub cpath: String, pub cpath: String,
pub unit_name: String,
// dbus client for set properties // dbus client for set properties
dbus_client: DBusClient, dbus_client: DBusClient,
// fs manager for get properties // fs manager for get properties
@ -40,14 +39,12 @@ pub struct Manager {
impl CgroupManager for Manager { impl CgroupManager for Manager {
fn apply(&self, pid: pid_t) -> Result<()> { fn apply(&self, pid: pid_t) -> Result<()> {
let unit_name = self.unit_name.as_str(); if self.dbus_client.unit_exists()? {
if self.dbus_client.unit_exists(unit_name)? { self.dbus_client.add_process(pid)?;
self.dbus_client.add_process(pid, self.unit_name.as_str())?;
} else { } else {
self.dbus_client.start_unit( self.dbus_client.start_unit(
(pid as u32).try_into().unwrap(), (pid as u32).try_into().unwrap(),
self.cgroups_path.slice.as_str(), self.cgroups_path.slice.as_str(),
self.unit_name.as_str(),
&self.cg_hierarchy, &self.cg_hierarchy,
)?; )?;
} }
@ -66,8 +63,7 @@ impl CgroupManager for Manager {
Pids::apply(r, &mut properties, &self.cg_hierarchy, systemd_version_str)?; Pids::apply(r, &mut properties, &self.cg_hierarchy, systemd_version_str)?;
CpuSet::apply(r, &mut properties, &self.cg_hierarchy, systemd_version_str)?; CpuSet::apply(r, &mut properties, &self.cg_hierarchy, systemd_version_str)?;
self.dbus_client self.dbus_client.set_properties(&properties)?;
.set_properties(self.unit_name.as_str(), &properties)?;
Ok(()) Ok(())
} }
@ -77,11 +73,15 @@ impl CgroupManager for Manager {
} }
fn freeze(&self, state: FreezerState) -> Result<()> { fn freeze(&self, state: FreezerState) -> Result<()> {
self.fs_manager.freeze(state) match state {
FreezerState::Thawed => self.dbus_client.thaw_unit(),
FreezerState::Frozen => self.dbus_client.freeze_unit(),
_ => Err(anyhow!("Invalid FreezerState")),
}
} }
fn destroy(&mut self) -> Result<()> { fn destroy(&mut self) -> Result<()> {
self.dbus_client.stop_unit(self.unit_name.as_str())?; self.dbus_client.kill_unit()?;
self.fs_manager.destroy() self.fs_manager.destroy()
} }
@ -120,8 +120,7 @@ impl Manager {
mounts: fs_manager.mounts.clone(), mounts: fs_manager.mounts.clone(),
cgroups_path, cgroups_path,
cpath, cpath,
unit_name, dbus_client: DBusClient::new(unit_name),
dbus_client: DBusClient {},
fs_manager, fs_manager,
cg_hierarchy: if cgroups::hierarchies::is_cgroup2_unified_mode() { cg_hierarchy: if cgroups::hierarchies::is_cgroup2_unified_mode() {
CgroupHierarchy::Unified CgroupHierarchy::Unified