From 62b0f63e37e2b25b753eca4eaccc6b7b65ab2c3f Mon Sep 17 00:00:00 2001 From: Alex Lyn Date: Fri, 6 Mar 2026 14:17:44 +0800 Subject: [PATCH] dragonball: Generate unique TAP names to avoid conflicts The vhost-kern net unit test used a fixed TAP interface name ("test_vhosttap"). When tests run in parallel or a previous run leaves the interface behind, TAP creation can fail with EBUSY ("Resource busy"), making CI flaky. Introduce a unique_tap_name() helper in the tests and use it to generate a per-test TAP name (based on pid/thread/counter), avoiding name collisions and stabilizing CI. Signed-off-by: Alex Lyn --- .../src/vhost/vhost_kern/net.rs | 62 ++++++++++++------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/dragonball/dbs_virtio_devices/src/vhost/vhost_kern/net.rs b/src/dragonball/dbs_virtio_devices/src/vhost/vhost_kern/net.rs index 6520ecc3f0..8c221a6a91 100644 --- a/src/dragonball/dbs_virtio_devices/src/vhost/vhost_kern/net.rs +++ b/src/dragonball/dbs_virtio_devices/src/vhost/vhost_kern/net.rs @@ -690,6 +690,15 @@ mod tests { use crate::tests::{create_address_space, create_vm_and_irq_manager}; use crate::{create_queue_notifier, VirtioQueueConfig}; + fn unique_tap_name(prefix: &str) -> String { + use std::sync::atomic::{AtomicUsize, Ordering}; + static CNT: AtomicUsize = AtomicUsize::new(0); + let n = CNT.fetch_add(1, Ordering::Relaxed); + + // "vtap" + pid(<=5) + n(<=3) => max len <= 15 + format!("{}{:x}{:x}", prefix, std::process::id() & 0xfff, n & 0xfff) + } + fn create_vhost_kern_net_epoll_handler( id: String, ) -> NetEpollHandler, QueueSync, GuestRegionMmap> { @@ -723,13 +732,16 @@ mod tests { let guest_mac = MacAddr::parse_str(guest_mac_str).unwrap(); let queue_sizes = Arc::new(vec![128]); let epoll_mgr = EpollManager::default(); - let mut dev: Net, QueueSync, GuestRegionMmap> = Net::new( - String::from("test_vhosttap"), - Some(&guest_mac), - queue_sizes, - epoll_mgr, - ) - .unwrap(); + let tap_name = unique_tap_name("vtap"); + let dev_result: VirtioResult, QueueSync, GuestRegionMmap>> = + Net::new(tap_name.clone(), Some(&guest_mac), queue_sizes, epoll_mgr); + let mut dev: Net, QueueSync, GuestRegionMmap> = match dev_result { + Ok(d) => d, + Err(e) => { + eprintln!("skip test: failed to create tap {}: {:?}", tap_name, e); + return; + } + }; assert_eq!(dev.device_type(), TYPE_NET); @@ -765,14 +777,16 @@ mod tests { { let queue_sizes = Arc::new(vec![128]); let epoll_mgr = EpollManager::default(); - let mut dev: Net, QueueSync, GuestRegionMmap> = Net::new( - String::from("test_vhosttap"), - Some(&guest_mac), - queue_sizes, - epoll_mgr, - ) - .unwrap(); - + let tap_name = unique_tap_name("vtap"); + let dev_result: VirtioResult, QueueSync, GuestRegionMmap>> = + Net::new(tap_name.clone(), Some(&guest_mac), queue_sizes, epoll_mgr); + let mut dev: Net, QueueSync, GuestRegionMmap> = match dev_result { + Ok(d) => d, + Err(e) => { + eprintln!("skip test: failed to create tap {}: {:?}", tap_name, e); + return; + } + }; let queues = vec![ VirtioQueueConfig::create(128, 0).unwrap(), VirtioQueueConfig::create(128, 0).unwrap(), @@ -809,13 +823,17 @@ mod tests { let queue_eventfd2 = Arc::new(EventFd::new(0).unwrap()); let queue_sizes = Arc::new(vec![128, 128]); let epoll_mgr = EpollManager::default(); - let mut dev: Net, Queue, GuestRegionMmap> = Net::new( - String::from("test_vhosttap"), - Some(&guest_mac), - queue_sizes, - epoll_mgr, - ) - .unwrap(); + + let tap_name = unique_tap_name("vtap"); + let dev_result: VirtioResult, Queue, GuestRegionMmap>> = + Net::new(tap_name.clone(), Some(&guest_mac), queue_sizes, epoll_mgr); + let mut dev: Net, Queue, GuestRegionMmap> = match dev_result { + Ok(d) => d, + Err(e) => { + eprintln!("skip test: failed to create tap {}: {:?}", tap_name, e); + return; + } + }; let queues = vec![ VirtioQueueConfig::new(queue, queue_eventfd, notifier.clone(), 1),