From 84183288ecdd06c51b641c42f6272d582c2e7bd7 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Tue, 23 Jan 2024 22:44:20 +1300 Subject: [PATCH] Fix inotify watch failing thanks to vim idiocy --- asusd/src/ctrl_platform.rs | 83 ++++++++++++++++++++++++++------------ asusd/src/daemon.rs | 6 ++- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/asusd/src/ctrl_platform.rs b/asusd/src/ctrl_platform.rs index d089421a..46aa40fa 100644 --- a/asusd/src/ctrl_platform.rs +++ b/asusd/src/ctrl_platform.rs @@ -16,7 +16,7 @@ use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_ use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_NAME, AURA_ZBUS_PATH}; use crate::ctrl_fancurves::{CtrlFanCurveZbus, FAN_CURVE_ZBUS_NAME, FAN_CURVE_ZBUS_PATH}; use crate::error::RogError; -use crate::{task_watch_item, task_watch_item_notify, CtrlTask, Reloadable}; +use crate::{task_watch_item, task_watch_item_notify, CtrlTask, ReloadAndNotify, Reloadable}; const PLATFORM_ZBUS_NAME: &str = "Platform"; const PLATFORM_ZBUS_PATH: &str = "/org/asuslinux/Platform"; @@ -116,7 +116,11 @@ pub struct CtrlPlatform { } impl CtrlPlatform { - pub fn new(config: Arc>, config_path: &Path) -> Result { + pub fn new( + config: Arc>, + config_path: &Path, + signal_context: SignalContext<'static>, + ) -> Result { let platform = RogPlatform::new()?; let power = AsusPower::new()?; @@ -126,19 +130,7 @@ impl CtrlPlatform { } let config1 = config.clone(); - let inotify = inotify::Inotify::init()?; - inotify - .watches() - .add(config_path, inotify::WatchMask::MODIFY) - .map_err(|e| { - if e.kind() == std::io::ErrorKind::NotFound { - error!("Not found: {:?}", config_path); - } else { - error!("Could not set asusd config inotify: {:?}", config_path); - } - e - }) - .ok(); + let config_path = config_path.to_owned(); let ret_self = CtrlPlatform { power, @@ -148,17 +140,47 @@ impl CtrlPlatform { .map_err(|e| error!("Couldn't get CPU control sysfs: {e}")) .ok(), }; - let inotify_self = ret_self.clone(); + let mut inotify_self = ret_self.clone(); tokio::spawn(async move { use zbus::export::futures_util::StreamExt; info!("Starting inotify watch for asusd config file"); let mut buffer = [0; 32]; - inotify - .into_event_stream(&mut buffer) - .unwrap() - .for_each(|_| async { + loop { + // vi and vim do stupid shit causing the file watch to be removed + let inotify = inotify::Inotify::init().unwrap(); + inotify + .watches() + .add( + &config_path, + inotify::WatchMask::MODIFY + | inotify::WatchMask::CLOSE_WRITE + | inotify::WatchMask::ATTRIB + | inotify::WatchMask::CREATE, + ) + .map_err(|e| { + if e.kind() == std::io::ErrorKind::NotFound { + error!("Not found: {:?}", config_path); + } else { + error!("Could not set asusd config inotify: {:?}", config_path); + } + e + }) + .ok(); + let mut events = inotify.into_event_stream(&mut buffer).unwrap(); + + while let Some(ev) = events.next().await { + if let Ok(ev) = ev { + if ev.mask == inotify::EventMask::IGNORED { + warn!( + "Something modified asusd.ron vi/vim style. Now need to reload \ + inotify watch" + ); + break; + } + } + let res = config1.lock().await.read_new(); if let Some(new_cfg) = res { let mut old_cfg = config1.lock().await; @@ -168,14 +190,14 @@ impl CtrlPlatform { reloading" ); *old_cfg = new_cfg; - // shitty way to handle this but it works. Only require the reload() - let mut inotify_self = inotify_self.clone(); - // TODO: better reload with ReloadAndNotify - inotify_self.reload().await.unwrap(); + inotify_self + .reload_and_notify(signal_context.clone()) + .await + .unwrap(); } } - }) - .await; + } + } }); Ok(ret_self) @@ -683,6 +705,15 @@ impl crate::ZbusRun for CtrlPlatform { } } +impl ReloadAndNotify for CtrlPlatform { + async fn reload_and_notify( + &mut self, + _signal_context: SignalContext<'static>, + ) -> Result<(), RogError> { + self.reload().await + } +} + impl crate::Reloadable for CtrlPlatform { async fn reload(&mut self) -> Result<(), RogError> { if self.platform.has_panel_od() { diff --git a/asusd/src/daemon.rs b/asusd/src/daemon.rs index 34234340..2ef09350 100644 --- a/asusd/src/daemon.rs +++ b/asusd/src/daemon.rs @@ -69,7 +69,11 @@ async fn start_daemon() -> Result<(), Box> { // supported.add_to_server(&mut connection).await; - match CtrlPlatform::new(config.clone(), &cfg_path) { + match CtrlPlatform::new( + config.clone(), + &cfg_path, + CtrlPlatform::signal_context(&connection)?, + ) { Ok(ctrl) => { let sig_ctx = CtrlPlatform::signal_context(&connection)?; start_tasks(ctrl, &mut connection, sig_ctx).await?;