kratart/
autoloop.rs

1use std::{sync::Arc, time::Duration};
2
3use anyhow::{anyhow, Result};
4use krataloopdev::{LoopControl, LoopDevice};
5use log::debug;
6use tokio::time::sleep;
7use xenclient::BlockDeviceRef;
8
9#[derive(Clone)]
10pub struct AutoLoop {
11    control: Arc<LoopControl>,
12}
13
14impl AutoLoop {
15    pub fn new(control: LoopControl) -> AutoLoop {
16        AutoLoop {
17            control: Arc::new(control),
18        }
19    }
20
21    pub fn loopify(&self, file: &str) -> Result<BlockDeviceRef> {
22        debug!("creating loop for file {}", file);
23        let device = self.control.next_free()?;
24        device.with().read_only(true).attach(file)?;
25        let path = device
26            .path()
27            .ok_or(anyhow!("unable to get loop device path"))?
28            .to_str()
29            .ok_or(anyhow!("unable to convert loop device path to string",))?
30            .to_string();
31        let major = device.major()?;
32        let minor = device.minor()?;
33        Ok(BlockDeviceRef { path, major, minor })
34    }
35
36    pub async fn unloop(&self, device: &str) -> Result<()> {
37        let device = LoopDevice::open(device)?;
38        device.detach()?;
39        sleep(Duration::from_millis(200)).await;
40        Ok(())
41    }
42}