87 lines
3.0 KiB
Diff
87 lines
3.0 KiB
Diff
|
|
From a71d702d98d090eb0bc68fa7950a590967de8716 Mon Sep 17 00:00:00 2001
|
||
|
|
From: chenjiayi <chenjiayi22@huawei.com>
|
||
|
|
Date: Thu, 23 Nov 2023 14:23:46 +0800
|
||
|
|
Subject: [PATCH 082/103] fix(device): avoid panic on shallow clone when
|
||
|
|
subsystem is not available
|
||
|
|
|
||
|
|
Some special sysfs device, such as /sys/devices/platform, may not contain
|
||
|
|
available subsystem. This leads to panic in shallow cloning such device
|
||
|
|
object when getting its subsystem.
|
||
|
|
---
|
||
|
|
libs/device/src/device.rs | 51 ++++++++++++++++++++++++---------------
|
||
|
|
1 files changed, 32 insertions(+), 19 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/libs/device/src/device.rs b/libs/device/src/device.rs
|
||
|
|
index e8e2dcc5..a9cb196c 100644
|
||
|
|
--- a/libs/device/src/device.rs
|
||
|
|
+++ b/libs/device/src/device.rs
|
||
|
|
@@ -2396,14 +2396,15 @@ impl Device {
|
||
|
|
|
||
|
|
device.set_syspath(&syspath, false)?;
|
||
|
|
|
||
|
|
- let subsystem = self.get_subsystem()?;
|
||
|
|
+ /* Some devices, such as /sys/devices/platform, do not have subsystem. */
|
||
|
|
+ if let Ok(subsystem) = self.get_subsystem() {
|
||
|
|
+ device.set_subsystem(&subsystem);
|
||
|
|
|
||
|
|
- device.set_subsystem(&subsystem);
|
||
|
|
-
|
||
|
|
- if subsystem == "drivers" {
|
||
|
|
- device
|
||
|
|
- .driver_subsystem
|
||
|
|
- .replace(self.driver_subsystem.borrow().clone());
|
||
|
|
+ if subsystem == "drivers" {
|
||
|
|
+ device
|
||
|
|
+ .driver_subsystem
|
||
|
|
+ .replace(self.driver_subsystem.borrow().clone());
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
if let Ok(ifindex) = self.get_property_value("IFINDEX") {
|
||
|
|
@@ -3506,19 +3507,31 @@ mod tests {
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_shallow_clone() {
|
||
|
|
- #[inline]
|
||
|
|
- fn inner_test(dev: &mut Device) -> Result<(), Error> {
|
||
|
|
- let s1 = dev.get_syspath().unwrap();
|
||
|
|
-
|
||
|
|
- let dev_clone = dev.shallow_clone().unwrap();
|
||
|
|
-
|
||
|
|
- assert_eq!(s1, dev_clone.get_syspath().unwrap());
|
||
|
|
-
|
||
|
|
- Ok(())
|
||
|
|
- }
|
||
|
|
+ /* Enumerator merely collect devices with valid subsystems,
|
||
|
|
+ * while get_parent method may not, e.g., /sys/devices/platform.
|
||
|
|
+ */
|
||
|
|
+ let mut e = DeviceEnumerator::new();
|
||
|
|
+ e.set_enumerator_type(DeviceEnumerationType::All);
|
||
|
|
+
|
||
|
|
+ for mut dev in e.iter() {
|
||
|
|
+ let dev_clone = dev.borrow().shallow_clone().unwrap();
|
||
|
|
+ dev_clone.get_syspath().unwrap();
|
||
|
|
+ dev_clone.get_subsystem().unwrap();
|
||
|
|
+
|
||
|
|
+ loop {
|
||
|
|
+ let ret = dev.borrow().get_parent();
|
||
|
|
+
|
||
|
|
+ if let Ok(parent) = ret {
|
||
|
|
+ parent.borrow().get_syspath().unwrap();
|
||
|
|
+ if let Err(e) = parent.borrow().get_subsystem() {
|
||
|
|
+ assert_eq!(e.get_errno(), Errno::ENOENT);
|
||
|
|
+ }
|
||
|
|
+ dev = parent;
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- if let Err(e) = LoopDev::inner_process("/tmp/test_shallow_clone", 1024 * 10, inner_test) {
|
||
|
|
- assert!(e.is_errno(nix::Error::EACCES) || e.is_errno(nix::Error::EBUSY));
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
2.33.0
|
||
|
|
|