diff --git a/include/Host.h b/include/Host.h index f40124f2fe..c27f926ee6 100644 --- a/include/Host.h +++ b/include/Host.h @@ -269,6 +269,15 @@ public: } }; + /** + * Revert changes in PCI Devices after migrate failure + * @param sr host share capacity info + */ + void revert_pci(HostShareCapacity& sr) + { + host_share.revert_pci(sr); + } + /** * Tests whether a VM device capacity can be allocated in the host * @param sr capacity requested by the VM diff --git a/include/HostShare.h b/include/HostShare.h index 1778bcfe72..69d3e06b9f 100644 --- a/include/HostShare.h +++ b/include/HostShare.h @@ -74,6 +74,12 @@ public: */ void del(HostShareCapacity &sr); + /** + * Revert changes in PCI Devices + * @param sr capacity info by the VM + */ + void revert_pci(HostShareCapacity &sr); + /** * Check if this share can host a VM. * @param cpu requested by the VM diff --git a/include/HostSharePCI.h b/include/HostSharePCI.h index b746a116fa..238dce7e73 100644 --- a/include/HostSharePCI.h +++ b/include/HostSharePCI.h @@ -84,7 +84,12 @@ public: /** * Remove the VM assignment from the PCI device list */ - void del(const vector &devs); + void del(const std::vector &devs, int vmid); + + /** + * Revert the VM assignment from the PCI device list + */ + void revert(std::vector &devs); /** * Updates the PCI list with monitor data, it will create or diff --git a/src/host/HostShare.cc b/src/host/HostShare.cc index cb4d46d774..7fa375056b 100644 --- a/src/host/HostShare.cc +++ b/src/host/HostShare.cc @@ -370,7 +370,7 @@ void HostShare::del(HostShareCapacity &sr) ds.del(sr); - pci.del(sr.pci); + pci.del(sr.pci, sr.vmid); numa.del(sr); @@ -379,6 +379,13 @@ void HostShare::del(HostShareCapacity &sr) /* -------------------------------------------------------------------------- */ +void HostShare::revert_pci(HostShareCapacity &sr) +{ + pci.revert(sr.pci); +} + +/* -------------------------------------------------------------------------- */ + bool HostShare::test(HostShareCapacity& sr, string& error) const { if ( !test_compute(sr.cpu, sr.mem, error) ) diff --git a/src/host/HostSharePCI.cc b/src/host/HostSharePCI.cc index 3faa1c1128..660d80b6d3 100644 --- a/src/host/HostSharePCI.cc +++ b/src/host/HostSharePCI.cc @@ -186,7 +186,7 @@ void HostSharePCI::add(vector &devs, int vmid) /* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/ -void HostSharePCI::del(const vector &devs) +void HostSharePCI::del(const vector &devs, int vmid) { vector::const_iterator it; map::iterator pci_it; @@ -195,7 +195,7 @@ void HostSharePCI::del(const vector &devs) { pci_it = pci_devices.find((*it)->vector_value("PREV_ADDRESS")); - if (pci_it != pci_devices.end()) + if (pci_it != pci_devices.end() && pci_it->second->vmid == vmid) { pci_it->second->vmid = -1; pci_it->second->attrs->replace("VMID",-1); @@ -207,7 +207,7 @@ void HostSharePCI::del(const vector &devs) pci_it = pci_devices.find((*it)->vector_value("ADDRESS")); - if (pci_it != pci_devices.end()) + if (pci_it != pci_devices.end() && pci_it->second->vmid == vmid) { pci_it->second->vmid = -1; pci_it->second->attrs->replace("VMID",-1); @@ -221,6 +221,44 @@ void HostSharePCI::del(const vector &devs) /* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/ +void HostSharePCI::revert(vector &devs) +{ + string address; + + for (auto device : devs) + { + device->vector_value("PREV_ADDRESS", address); + + if (!address.empty()) + { + auto dev = pci_devices[address]; + + if (!dev) + { + continue; + } + + device->replace("DOMAIN", dev->attrs->vector_value("DOMAIN")); + device->replace("BUS", dev->attrs->vector_value("BUS")); + device->replace("SLOT", dev->attrs->vector_value("SLOT")); + device->replace("FUNCTION",dev->attrs->vector_value("FUNCTION")); + device->replace("ADDRESS", address); + device->remove("PREV_ADDRESS"); + + int node = -1; + if (dev->attrs->vector_value("NUMA_NODE", node)==0 && node !=-1) + { + device->replace("NUMA_NODE", node); + } + + break; + } + } +} + +/* ------------------------------------------------------------------------*/ +/* ------------------------------------------------------------------------*/ + void HostSharePCI::set_monitorization(Template& ht) { vector::iterator it; diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 8761fb753e..246bea7384 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -87,6 +87,17 @@ void LifeCycleManager::revert_migrate_after_failure(VirtualMachine* vm) { hpool->del_capacity(vm->get_hid(), sr); + if (!sr.pci.empty()) + { + if (auto host = hpool->get(vm->get_previous_hid())) + { + // Revert PCI assignment in sr + host->revert_pci(sr); + + host->unlock(); + } + } + vm->rollback_previous_vnc_port(); }