Skip to content

Commit 7c2b70b

Browse files
mana: return early in save() when there are no endpoints (#2515)
#2461 found a bug in MANA's keepalive implementation, where we can race on an empty collection which results in a divide by zero in futures-concurrency. This checks for that condition and returns early if there are no endpoints configured.
1 parent 655fa48 commit 7c2b70b

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

openhcl/underhill_core/src/dispatch/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub trait LoadedVmNetworkSettings: Inspect {
133133
) -> anyhow::Result<PacketCaptureParams<Socket>>;
134134

135135
/// Save the network state for restoration after servicing.
136-
async fn save(&mut self) -> Vec<ManaSavedState>;
136+
async fn save(&mut self) -> Option<Vec<ManaSavedState>>;
137137
}
138138

139139
/// A VM that has been loaded and can be run.
@@ -815,7 +815,7 @@ impl LoadedVm {
815815
let mana_state = if let Some(network_settings) = &mut self.network_settings
816816
&& mana_keepalive_mode.is_enabled()
817817
{
818-
Some(network_settings.save().await)
818+
network_settings.save().await
819819
} else {
820820
None
821821
};

openhcl/underhill_core/src/worker.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,9 +1061,15 @@ impl LoadedVmNetworkSettings for UhVmNetworkSettings {
10611061
Ok(params)
10621062
}
10631063

1064-
async fn save(&mut self) -> Vec<ManaSavedState> {
1064+
async fn save(&mut self) -> Option<Vec<ManaSavedState>> {
10651065
let mut vf_managers: Vec<(Guid, Arc<HclNetworkVFManager>)> =
10661066
self.vf_managers.drain().collect();
1067+
1068+
// Nothing to save
1069+
if vf_managers.is_empty() {
1070+
return None;
1071+
}
1072+
10671073
let (vf_managers, mut nic_channels) = self.begin_vf_teardown(&mut vf_managers, false);
10681074

10691075
let mut endpoints: Vec<_> =
@@ -1097,7 +1103,7 @@ impl LoadedVmNetworkSettings for UhVmNetworkSettings {
10971103
let state = (run_endpoints, save_vf_managers).race().await;
10981104

10991105
// Discard any vf_managers that failed to return valid save state.
1100-
state.into_iter().flatten().collect()
1106+
Some(state.into_iter().flatten().collect())
11011107
}
11021108
}
11031109

0 commit comments

Comments
 (0)