Browse Source

fix baremetal runnings

Samuka007 2 weeks ago
parent
commit
f6eea8e625
2 changed files with 93 additions and 41 deletions
  1. 4 5
      dadk/src/actions/rootfs/disk_img.rs
  2. 89 36
      dadk/src/actions/rootfs/loopdev.rs

+ 4 - 5
dadk/src/actions/rootfs/disk_img.rs

@@ -88,6 +88,7 @@ fn mount_partitioned_image(
     let mut loop_device = ManuallyDrop::new(
         LoopDeviceBuilder::new()
             .img_path(disk_image_path.clone())
+            .detach_on_drop(false)
             .build()
             .map_err(|e| anyhow!("Failed to create loop device: {}", e))?,
     );
@@ -166,11 +167,10 @@ pub fn umount(ctx: &DADKExecContext) -> Result<()> {
         }
     }
 
-    if let Ok(mut loop_device) = loop_device {
+    if let Ok(loop_device) = loop_device {
         let loop_dev_path = loop_device.dev_path().cloned();
-        loop_device.detach().ok();
 
-        log::info!("Loop device detached: {:?}", loop_dev_path);
+        log::info!("Loop device going to detached: {:?}", loop_dev_path);
     }
 
     Ok(())
@@ -207,7 +207,6 @@ fn create_partitioned_image(ctx: &DADKExecContext, disk_image_path: &PathBuf) ->
     let partition_path = loop_device.partition_path(1)?;
     let fs_type = ctx.rootfs().metadata.fs_type;
     DiskFormatter::format_disk(&partition_path, &fs_type)?;
-    loop_device.detach()?;
     Ok(())
 }
 
@@ -262,7 +261,7 @@ pub fn show_mount_point(ctx: &DADKExecContext) -> Result<()> {
 
 pub fn show_loop_device(ctx: &DADKExecContext) -> Result<()> {
     let disk_image_path = ctx.disk_image_path();
-    let mut loop_device = LoopDeviceBuilder::new().img_path(disk_image_path).build()?;
+    let mut loop_device = LoopDeviceBuilder::new().detach_on_drop(false).img_path(disk_image_path).build()?;
     if let Err(e) = loop_device.attach_by_exists() {
         log::error!("Failed to attach loop device: {}", e);
     } else {

+ 89 - 36
dadk/src/actions/rootfs/loopdev.rs

@@ -12,8 +12,11 @@ pub struct LoopDevice {
     img_path: Option<PathBuf>,
     loop_device_path: Option<String>,
     /// 尝试在drop时自动detach
-    try_detach_when_drop: bool,
+    detach_on_drop: bool,
+    /// mapper created
+    mapper: bool,
 }
+
 impl LoopDevice {
     pub fn attached(&self) -> bool {
         self.loop_device_path.is_some()
@@ -95,18 +98,17 @@ impl LoopDevice {
     /// # 错误
     ///
     /// 如果循环设备未附加,则返回 `anyhow!("Loop device not attached")` 错误。
-    pub fn partition_path(&self, nth: u8) -> Result<PathBuf> {
+    pub fn partition_path(&mut self, nth: u8) -> Result<PathBuf> {
         if !self.attached() {
             return Err(anyhow!("Loop device not attached"));
         }
-        let s = format!("{}p{}", self.loop_device_path.as_ref().unwrap(), nth);
-        let direct_path = PathBuf::from(s);
+        let dev_path = self.loop_device_path.as_ref().unwrap();
+        let direct_path = PathBuf::from(format!("{}p{}", dev_path, nth));
+
         // 判断路径是否存在
-        if !direct_path.exists() || !direct_path.is_file() {
-            Command::new("kpartx")
-                .arg("-a")
-                .arg(self.loop_device_path.as_ref().unwrap())
-                .output()?;
+        if !direct_path.exists() {
+            mapper::create_mapper(self.loop_device_path.as_ref().unwrap())?;
+            self.mapper = true;
             let device_name = direct_path.file_name().unwrap();
             let parent_path = direct_path.parent().unwrap();
             let new_path = parent_path.join("mapper").join(device_name);
@@ -114,14 +116,14 @@ impl LoopDevice {
                 return Ok(new_path);
             }
             log::error!("Both {} and {} not exist!", direct_path.display(), new_path.display());
-            return Err(anyhow!("Partition not exist"));
+            return Err(anyhow!("Unable to find partition path {}", nth));
         }
         Ok(direct_path)
     }
 
-    pub fn detach(&mut self) -> Result<()> {
+    pub fn detach(&mut self) {
         if self.loop_device_path.is_none() {
-            return Ok(());
+            return;
         }
         let loop_device = self.loop_device_path.take().unwrap();
         let p = PathBuf::from(&loop_device);
@@ -130,43 +132,93 @@ impl LoopDevice {
             p.display(),
             p.exists()
         );
-        let _kpart_detach = Command::new("kpartx")
-            .arg("-dv")
-            .arg(&loop_device)
-            .output()?;
+
+        if self.mapper {
+            mapper::detach_mapper(&loop_device);
+            log::trace!("Detach mapper device: {}", &loop_device);
+            self.mapper = false;
+        }
+
         let output = Command::new("losetup")
             .arg("-d")
-            .arg(loop_device)
-            .output()?;
+            .arg(&loop_device)
+            .output();
 
-        if output.status.success() {
-            self.loop_device_path = None;
-            Ok(())
-        } else {
-            Err(anyhow::anyhow!(
-                "Failed to detach loop device: {}, {}",
+        if !output.is_ok() {
+            log::error!("losetup failed to detach loop device [{}]: {}", &loop_device, output.unwrap_err());
+            return;
+        }
+
+        let output = output.unwrap();
+
+        if !output.status.success() {
+            log::error!(
+                "losetup failed to detach loop device [{}]: {}, {}",
+                loop_device,
                 output.status,
                 str::from_utf8(output.stderr.as_slice()).unwrap_or("<Unknown>")
-            ))
+            );
         }
+
     }
 
-    pub fn try_detach_when_drop(&self) -> bool {
-        self.try_detach_when_drop
+    #[allow(dead_code)]
+    pub fn detach_on_drop(&self) -> bool {
+        self.detach_on_drop
     }
 
     #[allow(dead_code)]
     pub fn set_try_detach_when_drop(&mut self, try_detach_when_drop: bool) {
-        self.try_detach_when_drop = try_detach_when_drop;
+        self.detach_on_drop = try_detach_when_drop;
     }
 }
 
 impl Drop for LoopDevice {
     fn drop(&mut self) {
-        if self.try_detach_when_drop() {
-            if let Err(e) = self.detach() {
-                log::warn!("Failed to detach loop device: {}", e);
+        if self.detach_on_drop {
+            self.detach();
+        }
+    }
+}
+
+mod mapper {
+    use std::process::Command;
+    use anyhow::Result;
+    use anyhow::anyhow;
+
+    pub(super) fn create_mapper(dev_path: &str) -> Result<()> {
+        let output = Command::new("kpartx")
+            .arg("-a")
+            .arg("-v")
+            .arg(dev_path)
+            .output()
+            .map_err(|e| anyhow!("Failed to run kpartx: {}", e))?;
+        if output.status.success() {
+            let output_str = String::from_utf8(output.stdout)?;
+            log::trace!("kpartx output: {}", output_str);
+            return Ok(());
+        }
+        Err(anyhow!("Failed to create mapper"))
+    }
+
+    pub(super) fn detach_mapper(dev_path: &str) {
+        let output = Command::new("kpartx")
+            .arg("-d")
+            .arg("-v")
+            .arg(dev_path)
+            .output();
+        if output.is_ok() {
+            let output = output.unwrap();
+            if !output.status.success() {
+                log::error!(
+                    "kpartx failed to detach mapper device [{}]: {}, {}",
+                    dev_path,
+                    output.status,
+                    String::from_utf8(output.stderr).unwrap_or("<Unknown>".to_string())
+                );
             }
+        } else {
+            log::error!("Failed to detach mapper device [{}]: {}", dev_path, output.unwrap_err());
         }
     }
 }
@@ -174,7 +226,7 @@ impl Drop for LoopDevice {
 pub struct LoopDeviceBuilder {
     img_path: Option<PathBuf>,
     loop_device_path: Option<String>,
-    try_detach_when_drop: bool,
+    detach_on_drop: bool,
 }
 
 impl LoopDeviceBuilder {
@@ -182,7 +234,7 @@ impl LoopDeviceBuilder {
         LoopDeviceBuilder {
             img_path: None,
             loop_device_path: None,
-            try_detach_when_drop: true,
+            detach_on_drop: true,
         }
     }
 
@@ -192,8 +244,8 @@ impl LoopDeviceBuilder {
     }
 
     #[allow(dead_code)]
-    pub fn try_detach_when_drop(mut self, try_detach_when_drop: bool) -> Self {
-        self.try_detach_when_drop = try_detach_when_drop;
+    pub fn detach_on_drop(mut self, detach_on_drop: bool) -> Self {
+        self.detach_on_drop = detach_on_drop;
         self
     }
 
@@ -201,7 +253,8 @@ impl LoopDeviceBuilder {
         let loop_dev = LoopDevice {
             img_path: self.img_path,
             loop_device_path: self.loop_device_path,
-            try_detach_when_drop: self.try_detach_when_drop,
+            detach_on_drop: self.detach_on_drop,
+            mapper: false
         };
 
         Ok(loop_dev)