Author SHA256 Message Date
sisungo cb4c459175 feat: add by-label disk support
Signed-off-by: sisungo <[email protected]>
2026-09-15 09:43:32 +00:00
sisungo 43b723ac49 feat: add udev_device_new_* stub
Signed-off-by: sisungo <[email protected]>
2026-09-07 03:49:15 +00:00
sisungo 835f213e49 feat: add wait-for-idle
Signed-off-by: sisungo <[email protected]>
2026-09-06 10:52:23 +00:00
8 changed files with 123 additions and 0 deletions
+3
View File
@@ -1,16 +1,19 @@
mod trigger; mod trigger;
mod wait_for_idle;
use clap::Parser; use clap::Parser;
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
enum Cli { enum Cli {
Trigger(trigger::Cli), Trigger(trigger::Cli),
WaitForIdle(wait_for_idle::Cli),
} }
fn main() { fn main() {
let cli = Cli::parse(); let cli = Cli::parse();
let result = match cli { let result = match cli {
Cli::Trigger(cli) => trigger::main(cli), Cli::Trigger(cli) => trigger::main(cli),
Cli::WaitForIdle(cli) => wait_for_idle::main(cli),
}; };
if let Err(err) = result { if let Err(err) = result {
eprintln!("device: error: {err}"); eprintln!("device: error: {err}");
+11
View File
@@ -0,0 +1,11 @@
use clap::Parser;
use ipc::client::Client;
#[derive(Debug, Parser)]
pub struct Cli {}
pub fn main(_: Cli) -> anyhow::Result<()> {
let mut client = Client::connect()?;
client.wait_for_idle()?;
Ok(())
}
+20
View File
@@ -201,6 +201,26 @@ pub async fn list_devices(when: When) -> Vec<String> {
ret ret
} }
pub async fn wait_for_idle() {
loop {
let mut waited = false;
let keys: Vec<String> = DEVICES.read().unwrap().keys().map(Into::into).collect();
for key in keys {
let Some(device) = DEVICES.read().unwrap().get(&key).cloned() else {
continue;
};
if device.lock.try_lock().is_ok() {
continue;
}
waited = true;
_ = device.lock.lock().await;
}
if !waited {
return;
}
}
}
fn dev_root() -> PathBuf { fn dev_root() -> PathBuf {
std::env::var("LXDEVICED_DEV_ROOT") std::env::var("LXDEVICED_DEV_ROOT")
.as_deref() .as_deref()
+6
View File
@@ -34,6 +34,7 @@ async fn handle_connection(mut connection: Connection) -> std::io::Result<()> {
Request::Trigger(set, action) => handler(trigger(set, action)), Request::Trigger(set, action) => handler(trigger(set, action)),
Request::ReloadRules => handler(reload_rules()), Request::ReloadRules => handler(reload_rules()),
Request::ListDevices(when) => handler(list_devices(when)), Request::ListDevices(when) => handler(list_devices(when)),
Request::WaitForIdle => handler(wait_for_idle()),
}; };
let reply = handler.await; let reply = handler.await;
connection.send(reply).await?; connection.send(reply).await?;
@@ -57,6 +58,11 @@ async fn list_devices(when: When) -> Result<Vec<String>, Error> {
Ok(crate::device::list_devices(when).await) Ok(crate::device::list_devices(when).await)
} }
async fn wait_for_idle() -> Result<(), Error> {
crate::device::wait_for_idle().await;
Ok(())
}
fn handler<R: Serialize>( fn handler<R: Serialize>(
fut: impl Future<Output = Result<R, Error>> + Send + 'static, fut: impl Future<Output = Result<R, Error>> + Send + 'static,
) -> Pin<Box<dyn Future<Output = Result<serde_json::Value, Error>> + Send>> { ) -> Pin<Box<dyn Future<Output = Result<serde_json::Value, Error>> + Send>> {
+53
View File
@@ -181,6 +181,59 @@ impl Drop for UdevDevice {
} }
} }
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_new_from_syspath(
_udev: *mut Udev,
_syspath: *const libc::c_char,
) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_new_from_devnum(
_udev: *mut Udev,
_type: libc::c_char,
_devnum: libc::dev_t,
) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_new_from_subsystem_sysname(
_udev: *mut Udev,
_subsystem: *const libc::c_char,
_sysname: *const libc::c_char,
) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_new_from_device_id(
_udev: *mut Udev,
_id: *const libc::c_char,
) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_new_from_environment(_udev: *mut Udev) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_get_parent(_dev: *mut UdevDevice) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_get_parent_with_subsystem_devtype(
_dev: *mut UdevDevice,
_subsystem: *const libc::c_char,
_devtype: *const libc::c_char,
) -> *mut UdevDevice {
std::ptr::null_mut()
}
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn udev_device_ref(dev: *mut UdevDevice) -> *mut UdevDevice { pub unsafe extern "C" fn udev_device_ref(dev: *mut UdevDevice) -> *mut UdevDevice {
unsafe { unsafe {
+4
View File
@@ -60,4 +60,8 @@ impl Client {
pub fn list_devices(&mut self, when: When) -> Result<Vec<String>, Error> { pub fn list_devices(&mut self, when: When) -> Result<Vec<String>, Error> {
self.invoke(&Request::ListDevices(when)) self.invoke(&Request::ListDevices(when))
} }
pub fn wait_for_idle(&mut self) -> Result<(), Error> {
self.invoke(&Request::WaitForIdle)
}
} }
+3
View File
@@ -12,6 +12,9 @@ pub enum Request {
#[serde(rename = "/org.semilabs.os/LxDeviced/ListDevices@LXDEVICED_0.1.0")] #[serde(rename = "/org.semilabs.os/LxDeviced/ListDevices@LXDEVICED_0.1.0")]
ListDevices(When), ListDevices(When),
#[serde(rename = "/org.semilabs.os/LxDeviced/WaitForIdle@LXDEVICED_0.1.0")]
WaitForIdle,
} }
pub fn ser_reply<T: Serialize>(result: Result<T, Error>) -> String { pub fn ser_reply<T: Serialize>(result: Result<T, Error>) -> String {
+23
View File
@@ -15,6 +15,21 @@
when: Match("FSUUID", ""), when: Match("FSUUID", ""),
do: [Unset("FSUUID")], do: [Unset("FSUUID")],
), ),
(
when: All([
Match("ACTION", "add"),
Match("SUBSYSTEM", "block"),
Match("DEVNODE", ".*"),
]),
do: [
UseProvider("FSLABEL", f("blkid -o value -s LABEL {DEVNODE}")),
],
on_error: Continue,
),
(
when: Match("FSLABEL", ""),
do: [Unset("FSLABEL")],
),
// Create link aliases for block devices // Create link aliases for block devices
( (
@@ -42,6 +57,14 @@
]), ]),
do: [Add("SYMLINKS", f("{DEVROOT}/disk/by-uuid/{FSUUID}"))], do: [Add("SYMLINKS", f("{DEVROOT}/disk/by-uuid/{FSUUID}"))],
), ),
(
when: All([
Match("ACTION", "add"),
Match("SUBSYSTEM", "block"),
Match("FSLABEL", ".+"),
]),
do: [Add("SYMLINKS", f("{DEVROOT}/disk/by-label/{FSLABEL}"))],
),
( (
when: All([ when: All([
Match("ACTION", "add"), Match("ACTION", "add"),