diff --git a/include/Host.h b/include/Host.h index 161eee7cd2..fc27d80e98 100644 --- a/include/Host.h +++ b/include/Host.h @@ -165,6 +165,7 @@ public: bool &with_vm_info, set &lost, map &found, + set &found_twice, const set &non_shared_ds, long long reserved_cpu, long long reserved_mem); @@ -527,6 +528,12 @@ private: */ set tmp_zombie_vms; + /** + * Tmp set of found VM IDs. Used to give recovered poweroff VMs one + * grace cycle, in case they reappear in outdated poll info. + */ + set tmp_found_vms; + // ------------------------------------------------------------------------- // VM Collection // ------------------------------------------------------------------------- diff --git a/src/host/Host.cc b/src/host/Host.cc index 679f159e51..21ed451249 100644 --- a/src/host/Host.cc +++ b/src/host/Host.cc @@ -248,6 +248,7 @@ int Host::update_info(Template &tmpl, bool &with_vm_info, set &lost, map &found, + set &found_twice, const set &non_shared_ds, long long reserved_cpu, long long reserved_mem) @@ -271,6 +272,7 @@ int Host::update_info(Template &tmpl, set prev_tmp_lost = tmp_lost_vms; set prev_tmp_zombie = tmp_zombie_vms; + set prev_tmp_found = tmp_found_vms; int num_zombies = 0; int num_wilds = 0; @@ -337,6 +339,8 @@ int Host::update_info(Template &tmpl, tmp_zombie_vms.clear(); + tmp_found_vms.clear(); + for (it = vm_att.begin(); it != vm_att.end(); it++) { vatt = dynamic_cast(*it); @@ -362,6 +366,13 @@ int Host::update_info(Template &tmpl, if (tmp_lost_vms.erase(vmid) == 1) //Good, known { found.insert(make_pair(vmid, vatt->vector_value("POLL"))); + + tmp_found_vms.insert(vmid); + + if (prev_tmp_found.count(vmid) == 1) + { + found_twice.insert(vmid); + } } else //Bad, known but should not be here { diff --git a/src/im/MonitorThread.cc b/src/im/MonitorThread.cc index e8708de555..46208373f8 100644 --- a/src/im/MonitorThread.cc +++ b/src/im/MonitorThread.cc @@ -184,6 +184,7 @@ void MonitorThread::do_message() set lost; map found; + set found_twice; ostringstream oss; @@ -194,8 +195,8 @@ void MonitorThread::do_message() return; } - rc = host->update_info(tmpl, vm_poll, lost, found, non_shared_ds, - reserved_cpu, reserved_mem); + rc = host->update_info(tmpl, vm_poll, lost, found, found_twice, + non_shared_ds, reserved_cpu, reserved_mem); hpool->update(host); @@ -252,7 +253,26 @@ void MonitorThread::do_message() for (itm = found.begin(); itm != found.end(); itm++) { - VirtualMachineManagerDriver::process_poll(itm->first, itm->second); + VirtualMachine * vm = vmpool->get(itm->first, true); + + if (vm == 0) + { + continue; + } + + // When a VM in poweroff is found again, it may be because of + // outdated poll information. To make sure, we check if VM was + // reported twice + if (vm->get_state() == VirtualMachine::POWEROFF && + found_twice.count(itm->first) == 0) + { + vm->unlock(); + continue; + } + + VirtualMachineManagerDriver::process_poll(vm, itm->second); + + vm->unlock(); } } };