Skip to content

Commit

Permalink
fix(CompositeDevice): use early and late rules to fix hiding devices …
Browse files Browse the repository at this point in the history
…at boot time
  • Loading branch information
ShadowApex committed Feb 16, 2025
1 parent 0e84066 commit fcd1e1d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
6 changes: 0 additions & 6 deletions src/input/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,6 @@ impl Manager {
/// Starts listening for [Command] messages to be sent from clients and
/// dispatch those events.
pub async fn run(&mut self) -> Result<(), Box<dyn Error + Send + Sync>> {
// Delay initial discovery by a short amount of time to allow udev
// rules to process for the first time.
// TODO: Figure out a better way to prevent udev from not running hiding
// rules too early in boot.
tokio::time::sleep(Duration::from_millis(4000)).await;

let dbus_for_listen_on_dbus = self.dbus.clone();

let cmd_tx_all_devices = self.tx.clone();
Expand Down
42 changes: 32 additions & 10 deletions src/udev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use udev::Enumerator;

use self::device::Device;

const RULE_HIDE_DEVICE_PRIORITY: &str = "50";
const RULE_HIDE_DEVICE_EARLY_PRIORITY: &str = "50";
const RULE_HIDE_DEVICE_LATE_PRIORITY: &str = "96";
const RULES_PREFIX: &str = "/run/udev/rules.d";

/// Hide the given input device from regular users.
Expand All @@ -36,7 +37,7 @@ pub async fn hide_device(path: &str) -> Result<(), Box<dyn Error>> {
"/usr/bin/chmod"
};

// Create a udev rule to hide the device
// Create an early udev rule to hide the device
let rule = format!(
r#"# Hides devices stemming from {name}
# Managed by InputPlumber, this file will be autoremoved during configuration changes.
Expand All @@ -48,11 +49,28 @@ KERNEL=="hidraw[0-9]*", SUBSYSTEM=="{subsystem}", MODE:="0000", GROUP:="root", R
LABEL="inputplumber_end"
"#
);

// Write the udev rule
fs::create_dir_all(RULES_PREFIX)?;
let rule_path =
format!("{RULES_PREFIX}/{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide-{name}.rules");
let rule_path = format!(
"{RULES_PREFIX}/{RULE_HIDE_DEVICE_EARLY_PRIORITY}-inputplumber-hide-{name}-early.rules"
);
fs::write(rule_path, rule)?;

// Create a late udev rule to hide the device. This is needed for devices that
// are available at boot time because the early rule will not be applied.
let rule = format!(
r#"# Hides devices stemming from {name}
# Managed by InputPlumber, this file will be autoremoved during configuration changes.
{match_rule}, GOTO="inputplumber_valid"
GOTO="inputplumber_end"
LABEL="inputplumber_valid"
KERNEL=="js[0-9]*|event[0-9]*", SUBSYSTEM=="{subsystem}", MODE="000", GROUP="root", TAG-="uaccess", RUN+="{chmod_cmd} 000 /dev/input/%k"
KERNEL=="hidraw[0-9]*", SUBSYSTEM=="{subsystem}", MODE="000", GROUP="root", TAG-="uaccess", RUN+="{chmod_cmd} 000 /dev/%k"
LABEL="inputplumber_end"
"#
);
let rule_path = format!(
"{RULES_PREFIX}/{RULE_HIDE_DEVICE_LATE_PRIORITY}-inputplumber-hide-{name}-late.rules"
);
fs::write(rule_path, rule)?;

// Reload udev
Expand All @@ -69,8 +87,13 @@ pub async fn unhide_device(path: String) -> Result<(), Box<dyn Error>> {
let Some(parent) = device.get_parent() else {
return Err("Unable to determine parent for device".into());
};
let rule_path =
format!("{RULES_PREFIX}/{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide-{name}.rules");
let rule_path = format!(
"{RULES_PREFIX}/{RULE_HIDE_DEVICE_EARLY_PRIORITY}-inputplumber-hide-{name}-early.rules"
);
fs::remove_file(rule_path)?;
let rule_path = format!(
"{RULES_PREFIX}/{RULE_HIDE_DEVICE_LATE_PRIORITY}-inputplumber-hide-{name}-late.rules"
);
fs::remove_file(rule_path)?;

// Reload udev
Expand All @@ -87,8 +110,7 @@ pub async fn unhide_all() -> Result<(), Box<dyn Error>> {
continue;
};
let filename = entry.file_name().to_string_lossy().to_string();
if !filename.starts_with(format!("{RULE_HIDE_DEVICE_PRIORITY}-inputplumber-hide").as_str())
{
if !filename.contains("-inputplumber-hide-") {
continue;
}
let path = entry.path().to_string_lossy().to_string();
Expand Down

0 comments on commit fcd1e1d

Please sign in to comment.