Reload VMs directory and sync with memory state while preserving statistics
(&self)
| 622 | |
| 623 | /// Reload VMs directory and sync with memory state while preserving statistics |
| 624 | pub async fn reload_vms_sync(&self) -> Result<ReloadVmsResponse> { |
| 625 | let vm_path = self.vm_dir(); |
| 626 | let mut loaded = 0u32; |
| 627 | let mut updated = 0u32; |
| 628 | let mut removed = 0u32; |
| 629 | |
| 630 | // Get running VMs to preserve CIDs and process info |
| 631 | let running_vms = self.supervisor.list().await.context("Failed to list VMs")?; |
| 632 | let running_vms_map: HashMap<String, _> = running_vms |
| 633 | .into_iter() |
| 634 | .map(|p| (p.config.id.clone(), p)) |
| 635 | .collect(); |
| 636 | let occupied_cids = running_vms_map |
| 637 | .iter() |
| 638 | .filter(|(_, p)| { |
| 639 | serde_json::from_str::<ProcessAnnotation>(&p.config.note) |
| 640 | .unwrap_or_default() |
| 641 | .is_cvm() |
| 642 | }) |
| 643 | .flat_map(|(id, p)| p.config.cid.map(|cid| (id.clone(), cid))) |
| 644 | .collect::<HashMap<_, _>>(); |
| 645 | |
| 646 | // Update CID pool with running VMs |
| 647 | { |
| 648 | let mut state = self.lock(); |
| 649 | // First clear the pool and re-occupy running VM CIDs |
| 650 | state.cid_pool.clear(); |
| 651 | for cid in occupied_cids.values() { |
| 652 | state.cid_pool.occupy(*cid)?; |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | // Get VM IDs from filesystem |
| 657 | let mut fs_vm_ids = HashSet::new(); |
| 658 | if vm_path.exists() { |
| 659 | for entry in fs::read_dir(&vm_path).context("Failed to read VM directory")? { |
| 660 | let entry = entry.context("Failed to read directory entry")?; |
| 661 | let vm_dir_path = entry.path(); |
| 662 | if vm_dir_path.is_dir() { |
| 663 | // Try to get VM ID from directory name or manifest |
| 664 | if let Some(vm_id) = vm_dir_path.file_name().and_then(|n| n.to_str()) { |
| 665 | fs_vm_ids.insert(vm_id.to_string()); |
| 666 | } |
| 667 | } |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | // Get VM IDs currently in memory and their CIDs |
| 672 | let (memory_vm_ids, existing_cids): (HashSet<String>, HashSet<u32>) = { |
| 673 | let state = self.lock(); |
| 674 | ( |
| 675 | state.vms.keys().cloned().collect(), |
| 676 | state.vms.values().map(|vm| vm.config.cid).collect(), |
| 677 | ) |
| 678 | }; |
| 679 | |
| 680 | // Remove VMs that no longer exist in filesystem |
| 681 | let to_remove: Vec<String> = memory_vm_ids.difference(&fs_vm_ids).cloned().collect(); |
no test coverage detected