From 400c6e270583c62724dd2bfd8b92ad96a2f0cfcb Mon Sep 17 00:00:00 2001
From: chenjiayi <chenjiayi22@huawei.com>
Date: Wed, 8 Nov 2023 22:59:44 +0800
Subject: [PATCH 053/103] fix(device): set driver subsystem after generating
 device from nulstr

The driver subsystem is omitted when receiving device object from nulstr,
which leads to incorrect device id in /run/devmaster/data/ for driver
subsystems.
---
 libs/device/src/device.rs         | 32 ++++++++++++++++++++++++++++---
 libs/device/src/device_monitor.rs |  5 +++--
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
index 4f5779ce..3845e21c 100644
--- a/libs/device/src/device.rs
+++ b/libs/device/src/device.rs
@@ -246,7 +246,29 @@ impl Device {
 
         device.update_properties_bufs()?;
 
-        Ok(device)
+        device.verify()
+    }
+
+    /// Verify the legality of a device object from nulstr.
+    fn verify(self) -> Result<Device, Error> {
+        if self.devpath.borrow().is_empty()
+            || self.subsystem.borrow().is_empty()
+            || *self.action.borrow() == DeviceAction::Invalid
+            || *self.seqnum.borrow() == 0
+        {
+            return Err(Error::Nix {
+                msg: "Received invalid device object from uevent".to_string(),
+                source: Errno::EINVAL,
+            });
+        }
+
+        if &*self.subsystem.borrow() == "drivers" {
+            self.set_drivers_subsystem()?;
+        }
+
+        self.sealed.replace(true);
+
+        Ok(self)
     }
 
     /// create a Device instance from devname
@@ -1237,7 +1259,7 @@ impl Device {
     /// shadow clone a device object and import properties from db
     pub fn clone_with_db(&self) -> Result<Device, Error> {
         let device = self.shallow_clone()?;
-        device.read_db()?;
+        device.read_db_internal(true)?;
         device.sealed.replace(true);
         Ok(device)
     }
@@ -3535,9 +3557,13 @@ mod tests {
             let syspath = dev.get_syspath().unwrap();
             let devnum = dev.get_devnum().unwrap();
             let id = dev.get_device_id().unwrap();
-            let (nulstr, _) = dev.get_properties_nulstr().unwrap();
             let devname = dev.get_devname().unwrap();
 
+            dev.set_action_from_string("change").unwrap();
+            dev.set_seqnum_from_string("1000").unwrap();
+
+            let (nulstr, _) = dev.get_properties_nulstr().unwrap();
+
             let dev_new = Device::from_syspath(&syspath, true).unwrap();
             assert_eq!(dev, &dev_new);
 
diff --git a/libs/device/src/device_monitor.rs b/libs/device/src/device_monitor.rs
index db51c40f..3f1d1ba6 100644
--- a/libs/device/src/device_monitor.rs
+++ b/libs/device/src/device_monitor.rs
@@ -249,8 +249,9 @@ mod tests {
 
         ///
         fn dispatch(&self, e: &Events) -> i32 {
-            let device = self.device_monitor.receive_device().unwrap();
-            println!("{}", device.get_device_id().unwrap());
+            if let Ok(device) = self.device_monitor.receive_device() {
+                println!("{}", device.get_device_id().unwrap());
+            }
             e.set_exit();
             0
         }
-- 
2.33.0

