diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index ab6304a47e..835f93ce69 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -55,6 +55,7 @@ public: MONITOR_SUSPEND, /**< Sent by the VMM when a VM is paused while active */ MONITOR_DONE, /**< Sent by the VMM when a Host cannot be monitored*/ MONITOR_POWEROFF, /**< Sent by the VMM when a VM is not found */ + MONITOR_POWERON, /**< Sent by the VMM when a VM is found again */ PROLOG_SUCCESS, /**< Sent by the TM when the prolog phase succeeds */ PROLOG_FAILURE, /**< Sent by the TM when the prolog phase fails */ EPILOG_SUCCESS, /**< Sent by the TM when the epilog phase succeeds */ @@ -200,6 +201,8 @@ private: void monitor_poweroff_action(int vid); + void monitor_poweron_action(int vid); + void prolog_success_action(int vid); void prolog_failure_action(int vid); diff --git a/src/im/MonitorThread.cc b/src/im/MonitorThread.cc index 827c51ae91..82cd1b6d33 100644 --- a/src/im/MonitorThread.cc +++ b/src/im/MonitorThread.cc @@ -194,6 +194,8 @@ void MonitorThread::do_message() return; } + time_t prev_last_monitor = host->get_last_monitored(); + rc = host->update_info(tmpl, vm_poll, lost, found, non_shared_ds, reserved_cpu, reserved_mem); @@ -213,8 +215,6 @@ void MonitorThread::do_message() NebulaLog::log("InM", Log::DEBUG, oss); - time_t last_monitored = host->get_last_monitored(); - host->unlock(); //-------------------------------------------------------------------------- @@ -235,9 +235,13 @@ void MonitorThread::do_message() continue; } + // Move the VM to power off if it is not reported by the Host and: + // 1.- It has a history record + // 2.- It is supposed to be in RUNNING state + // 3.- It has been monitored at least once if (vm->hasHistory() && vm->get_lcm_state() == VirtualMachine::RUNNING && - (vm->get_running_stime() + 2*monitor_interval) < last_monitored) + prev_last_monitor <= vm->get_last_poll() ) { lcm->trigger(LifeCycleManager::MONITOR_POWEROFF, *its); } diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index c3bcb10206..bf668e5c4d 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -117,6 +117,10 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = "MONITOR_POWEROFF"; break; + case MONITOR_POWERON: + aname = "MONITOR_POWERON"; + break; + case PROLOG_SUCCESS: aname = "PROLOG_SUCCESS"; break; @@ -342,6 +346,10 @@ void LifeCycleManager::do_action(const string &action, void * arg) { monitor_poweroff_action(vid); } + else if (action == "MONITOR_POWERON") + { + monitor_poweron_action(vid); + } else if (action == "PROLOG_SUCCESS") { prolog_success_action(vid); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index b34e37714f..b70ebd7d7a 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1320,6 +1320,45 @@ void LifeCycleManager::monitor_poweroff_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void LifeCycleManager::monitor_poweron_action(int vid) +{ + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + //This event should be ignored if the VM is not POWEROFF + if ( vm->get_state() == VirtualMachine::POWEROFF ) + { + time_t the_time = time(0); + + vm->set_state(VirtualMachine::ACTIVE); + + vm->set_state(VirtualMachine::RUNNING); + + vm->cp_history(); + + vmpool->update(vm); + + vm->set_stime(the_time); + + vm->set_running_stime(the_time); + + vmpool->update_history(vm); + + vm->log("LCM", Log::INFO, "New VM state is RUNNING"); + } + + vm->unlock(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void LifeCycleManager::failure_action(VirtualMachine * vm) { Nebula& nd = Nebula::instance(); diff --git a/src/vmm/VirtualMachineManagerDriver.cc b/src/vmm/VirtualMachineManagerDriver.cc index 87f06145f4..afa076b3ce 100644 --- a/src/vmm/VirtualMachineManagerDriver.cc +++ b/src/vmm/VirtualMachineManagerDriver.cc @@ -614,48 +614,56 @@ void VirtualMachineManagerDriver::process_poll( VirtualMachinePool* vmpool = ne.get_vmpool(); /* ---------------------------------------------------------------------- */ - /* Parse VM info and update VM */ + /* Parse VM info */ /* ---------------------------------------------------------------------- */ - if (vm->get_state() != VirtualMachine::ACTIVE) - { - return; - } - rc = parse_vm_info(monitor_str, cpu, memory, net_tx, net_rx, state, custom); - if (rc == -1) + if (rc == -1) //Parse error, ignore this monitor data { - oss << "Error parsing monitoring information: " << monitor_str; + oss << "Ignoring monitoring information, parse error." + << " Monitor information was: " + << monitor_str; + NebulaLog::log("VMM", Log::ERROR, oss); vm->set_template_error_message(oss.str()); + vm->log("VMM", Log::ERROR, oss); vmpool->update(vm); - lcm->trigger(LifeCycleManager::MONITOR_DONE, vm->get_oid()); - return; } oss << "VM " << vm->get_oid() << " successfully monitored: " << monitor_str; NebulaLog::log("VMM", Log::DEBUG, oss); - vm->update_info(memory, cpu, net_tx, net_rx, custom); + /* ---------------------------------------------------------------------- */ + /* Update VM info only for VMs in ACTIVE */ + /* ---------------------------------------------------------------------- */ - vmpool->update(vm); + if (vm->get_state() == VirtualMachine::ACTIVE) + { + vm->update_info(memory, cpu, net_tx, net_rx, custom); - vmpool->update_history(vm); + vmpool->update(vm); - vmpool->update_monitoring(vm); + vmpool->update_history(vm); + + vmpool->update_monitoring(vm); + } /* ---------------------------------------------------------------------- */ /* Process the VM state from the monitoring info */ /* ---------------------------------------------------------------------- */ - if (vm->get_lcm_state() != VirtualMachine::RUNNING && - vm->get_lcm_state() != VirtualMachine::UNKNOWN) + bool process_state = vm->get_state() == VirtualMachine::POWEROFF || ( + vm->get_state() == VirtualMachine::ACTIVE && ( + vm->get_lcm_state() == VirtualMachine::RUNNING || + vm->get_lcm_state() == VirtualMachine::UNKNOWN)); + + if (!process_state) { return; } @@ -670,6 +678,12 @@ void VirtualMachineManagerDriver::process_poll( vm->set_state(VirtualMachine::RUNNING); vmpool->update(vm); } + else if ( vm->get_state() == VirtualMachine::POWEROFF ) + { + vm->log("VMM", Log::INFO, "VM found again, state is RUNNING"); + + lcm->trigger(LifeCycleManager::MONITOR_POWERON, vm->get_oid()); + } break; case 'p': // It's paused diff --git a/src/vmm_mad/remotes/vmware/vmware_driver.rb b/src/vmm_mad/remotes/vmware/vmware_driver.rb index 79ebdb43fe..585e991f7b 100644 --- a/src/vmm_mad/remotes/vmware/vmware_driver.rb +++ b/src/vmm_mad/remotes/vmware/vmware_driver.rb @@ -161,39 +161,6 @@ class VMwareDriver exit info if rc == false end - # ------------------------------------------------------------------------ # - # Monitor a VM # - # ------------------------------------------------------------------------ # - def poll(deploy_id) - rc, info = do_action("virsh -c #{@uri} --readonly dominfo #{deploy_id}") - - return "STATE=d" if rc == false - - state = "" - - info.split('\n').each{ |line| - mdata = line.match("^State: (.*)") - - if mdata - state = mdata[1].strip - break - end - } - - case state - when "running","blocked","shutdown","dying" - state_short = 'a' - when "paused" - state_short = 'p' - when "crashed" - state_short = 'c' - else - state_short = 'd' - end - - return "STATE=#{state_short}" - end - # ------------------------------------------------------------------------ # # Restore a VM from a previously saved checkpoint # # ------------------------------------------------------------------------ # @@ -358,7 +325,7 @@ class VMwareDriver # Undefines a domain in the ESX hypervisor def undefine_domain(id) if @vcenter and !@vcenter.empty? and @datacenter and !@datacenter.empty? - undefine_uri = + undefine_uri = "vpx://#{@vcenter}/#{@datacenter}/#{@host}/?no_verify=1" else undefine_uri = @uri