From 0c60fa8268ff52c6f8e2805bf2e0eae25ba27091 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Mon, 25 Jan 2021 11:49:05 +0000 Subject: [PATCH] net_util: tests: Avoid trying to create TAP devices simultaneously The unit tests ask the Linux kernel to generate a TAP device name on demand by passing in a format string. I suspect, but haven't been able to confirm that there might be a rare race that triggers when creating lots of devices in a short period of time. This is appearing in our unit test as the occassional flake of the test_tap_read() which although it has successfully created the device it fails to set the IP address on it when looking it back up by it's name. Since this is the most frequent cause of failures on our CI use a lock to ensure that multiple TAP devices are not created simultaneously. Fixes: #2135 Signed-off-by: Rob Bradford --- net_util/src/tap.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net_util/src/tap.rs b/net_util/src/tap.rs index 4be620518..7b9caad4c 100644 --- a/net_util/src/tap.rs +++ b/net_util/src/tap.rs @@ -579,12 +579,16 @@ mod tests { #[test] fn test_tap_create() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + let t = Tap::new(1).unwrap(); println!("created tap: {:?}", t); } #[test] fn test_tap_from_fd() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + let orig_tap = Tap::new(1).unwrap(); let fd = orig_tap.as_raw_fd(); let _new_tap = Tap::from_tap_fd(fd).unwrap(); @@ -610,6 +614,8 @@ mod tests { #[test] fn test_set_options() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + // This line will fail to provide an initialized FD if the test is not run as root. let tap = Tap::new(1).unwrap(); tap.set_vnet_hdr_size(16).unwrap(); @@ -618,6 +624,8 @@ mod tests { #[test] fn test_tap_enable() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + let tap = Tap::new(1).unwrap(); let ret = tap.enable(); assert!(ret.is_ok()); @@ -625,6 +633,8 @@ mod tests { #[test] fn test_tap_get_ifreq() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + let tap = Tap::new(1).unwrap(); let ret = tap.get_ifreq(); assert_eq!( @@ -635,6 +645,8 @@ mod tests { #[test] fn test_raw_fd() { + let _tap_ip_guard = TAP_IP_LOCK.lock().unwrap(); + let tap = Tap::new(1).unwrap(); assert_eq!(tap.as_raw_fd(), tap.tap_file.as_raw_fd()); }