From 325db91bcb1e2be40d90efee915a613d3cb2a883 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 24 Jul 2020 16:00:59 +0200 Subject: [PATCH] F #4936:Refactor ActionManager and Timers co-authored-by: Pavel Czerny --- include/AclManager.h | 69 +- include/ActionManager.h | 250 -- include/AuthManager.h | 149 +- include/AuthRequest.h | 4 +- include/DispatchManager.h | 179 +- include/FedReplicaManager.h | 47 +- include/HookLog.h | 6 - include/HookManager.h | 107 +- include/IPAMManager.h | 165 +- include/ImageManager.h | 66 +- include/InformationManager.h | 42 +- include/LifeCycleManager.h | 410 +- include/Listener.h | 201 + include/MarketPlaceManager.h | 105 +- include/Nebula.h | 1 + include/RaftManager.h | 196 +- include/RequestManager.h | 42 +- include/SyncRequest.h | 45 +- include/TransferManager.h | 157 +- include/VirtualMachineManager.h | 186 +- src/acl/AclManager.cc | 330 +- src/authm/AuthManager.cc | 204 +- src/common/ActionManager.cc | 134 - src/common/SConstruct | 1 - src/dm/DispatchManager.cc | 70 +- src/dm/DispatchManagerActions.cc | 111 +- src/dm/DispatchManagerStates.cc | 523 ++- src/group/Group.cc | 1 + src/hm/HookLog.cc | 2 +- src/hm/HookManager.cc | 89 +- src/hm/HookStateVM.cc | 1 + src/host/HostPool.cc | 4 +- src/im/InformationManager.cc | 82 +- src/image/Image.cc | 4 +- src/image/ImageManager.cc | 35 +- src/image/ImageManagerProtocol.cc | 2 +- src/ipamm/IPAMManager.cc | 112 +- src/lcm/LifeCycleActions.cc | 2216 +++++------ src/lcm/LifeCycleManager.cc | 252 +- src/lcm/LifeCycleStates.cc | 4335 +++++++++++----------- src/market/MarketPlaceManager.cc | 55 +- src/nebula/Nebula.cc | 41 +- src/pool/PoolObjectSQL.cc | 1 + src/raft/FedReplicaManager.cc | 95 +- src/raft/RaftManager.cc | 576 ++- src/rm/Request.cc | 2 +- src/rm/RequestManager.cc | 43 +- src/rm/RequestManagerAcl.cc | 1 + src/rm/RequestManagerSecurityGroup.cc | 2 +- src/rm/RequestManagerSystem.cc | 1 + src/scheduler/include/Scheduler.h | 75 +- src/scheduler/src/pool/AclXML.cc | 1 + src/scheduler/src/sched/Scheduler.cc | 46 +- src/secgroup/SecurityGroup.cc | 2 +- src/sql/LogDB.cc | 2 +- src/tm/TransferManager.cc | 2981 ++++++++------- src/tm/TransferManagerProtocol.cc | 32 +- src/um/UserPool.cc | 8 +- src/vdc/Vdc.cc | 1 + src/vm/VirtualMachine.cc | 2 +- src/vm/VirtualMachinePool.cc | 4 +- src/vmm/VirtualMachineManager.cc | 3665 +++++++++--------- src/vmm/VirtualMachineManagerProtocol.cc | 80 +- src/vnm/AddressRangeIPAM.cc | 8 +- src/vnm/AddressRangePool.cc | 4 +- 65 files changed, 8187 insertions(+), 10476 deletions(-) delete mode 100644 include/ActionManager.h create mode 100644 include/Listener.h delete mode 100644 src/common/ActionManager.cc diff --git a/include/AclManager.h b/include/AclManager.h index 192aa335c0..d22053856b 100644 --- a/include/AclManager.h +++ b/include/AclManager.h @@ -17,21 +17,18 @@ #ifndef ACL_MANAGER_H_ #define ACL_MANAGER_H_ -#include "AuthManager.h" +#include "Listener.h" #include "AuthRequest.h" #include "PoolObjectSQL.h" -#include "AclRule.h" -#include "NebulaLog.h" +class AclRule; class PoolObjectAuth; class SqlDB; -extern "C" void * acl_action_loop(void *arg); - /** * This class manages the ACL rules and the authorization engine */ -class AclManager : public Callbackable, public ActionListener +class AclManager : public Callbackable { public: /** @@ -54,6 +51,8 @@ public: void finalize(); + void join_thread(); + /** * Reload the ACL rules from the DB. This function needs to be used when * a server becomes leader of the zone as the ACL cache maybe out-dated @@ -215,19 +214,6 @@ public: */ virtual int dump(std::ostringstream& oss); - // ------------------------------------------------------------------------- - // Refresh loop thread - // ------------------------------------------------------------------------- - /** - * Gets the AclManager thread identification. The thread is only - * initialized if the refresh_cache flag is true. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return acl_thread; - }; - protected: /** * Constructor for derived ACL managers. Classes derived from this one @@ -235,9 +221,11 @@ protected: * from DB) */ AclManager(int _zone_id) - :zone_id(_zone_id), db(0), is_federation_slave(false) + : zone_id(_zone_id) + , db(0) + , is_federation_slave(false) + , timer_period(-1) { - pthread_mutex_init(&mutex, 0); }; // ------------------------------------------------------------------------- @@ -346,23 +334,7 @@ private: // Mutex synchronization // ------------------------------------------------------------------------- - pthread_mutex_t mutex; - - /** - * Function to lock the manager - */ - void lock() - { - pthread_mutex_lock(&mutex); - }; - - /** - * Function to unlock the manager - */ - void unlock() - { - pthread_mutex_unlock(&mutex); - }; + std::mutex acl_mutex; // ------------------------------------------------------------------------- // DataBase implementation variables @@ -429,33 +401,18 @@ private: time_t timer_period; /** - * Thread id for the ACL Manager + * Timer action async execution */ - pthread_t acl_thread; - - /** - * Action engine for the Manager - */ - ActionManager am; - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * acl_action_loop(void *arg); + std::unique_ptr timer_thread; // ------------------------------------------------------------------------- // Action Listener interface // ------------------------------------------------------------------------- - void timer_action(const ActionRequest& ar) + void timer_action() { select(); }; - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("ACL",Log::INFO,"Stopping ACL Manager..."); - }; }; #endif /*ACL_MANAGER_H*/ diff --git a/include/ActionManager.h b/include/ActionManager.h deleted file mode 100644 index 97a9d63e90..0000000000 --- a/include/ActionManager.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -#ifndef ACTION_MANAGER_H_ -#define ACTION_MANAGER_H_ - -#include -#include -#include -#include - -/** - * Represents a generic request, pending actions are stored in a queue. - * Each element stores the base action type, additional data is added by each - * ActionListener implementation. - */ -class ActionRequest -{ -public: - /** - * Base Action types - */ - enum Type - { - FINALIZE, - TIMER, - USER - }; - - Type type() const - { - return _type; - } - - ActionRequest(Type __type): _type(__type){}; - - virtual ~ActionRequest(){}; - - virtual ActionRequest * clone() const - { - return new ActionRequest(_type); - } - -protected: - Type _type; -}; - -/** - * ActionListener class. Interface to be implemented by any class that need to - * handle actions. - */ -class ActionListener -{ -protected: - ActionListener(){}; - - virtual ~ActionListener(){}; - - /** - * the user_action() function is executed upon action arrival. - * This function should check the action type, and perform the - * corresponding action. - * @param ar the ActionRequest - */ - virtual void user_action(const ActionRequest& ar){}; - - /** - * Periodic timer action, executed each time the time_out expires. Listener - * needs to re-implement the default timer action if needed. - * @param ar the ActionRequest - */ - virtual void timer_action(const ActionRequest& ar){}; - - /** - * Action executed when the Manager finlizes. Listener needs to re-implement - * the default action if needed. - * @param ar the ActionRequest - */ - virtual void finalize_action(const ActionRequest& ar){}; - -private: - friend class ActionManager; - - /** - * Invoke the action handler - */ - void _do_action(const ActionRequest& ar) - { - switch(ar.type()) - { - case ActionRequest::FINALIZE: - finalize_action(ar); - break; - - case ActionRequest::TIMER: - timer_action(ar); - break; - - case ActionRequest::USER: - user_action(ar); - break; - } - } -}; - - -/** - * ActionManager. Provides action support for a class implementing - * the ActionListener interface. - */ -class ActionManager -{ -public: - - ActionManager(); - - virtual ~ActionManager(); - - /** - * Function to trigger an action to this manager. - * @param action the action name - * @param args arguments for the action - */ - void trigger(const ActionRequest& ar); - - /** - * Trigger the FINALIZE event - */ - void finalize() - { - ActionRequest frequest(ActionRequest::FINALIZE); - - trigger(frequest); - } - - /** - * The calling thread will be suspended until an action is triggered. - * @param timeout for the periodic action. - * @param timer_args arguments for the timer action - */ - void loop(struct timespec& _timeout, const ActionRequest& trequest); - - void loop(time_t timeout, const ActionRequest& trequest) - { - struct timespec _timeout; - - _timeout.tv_sec = timeout; - _timeout.tv_nsec = 0; - - loop(_timeout, trequest); - } - - /** - * The calling thread will be suspended until an action is triggered. - * @param timeout for the periodic action, the timer action will recieve - * an "empty" ActionRequest. - */ - void loop(time_t timeout) - { - ActionRequest trequest(ActionRequest::TIMER); - - struct timespec _timeout; - - _timeout.tv_sec = timeout; - _timeout.tv_nsec = 0; - - loop(_timeout, trequest); - } - - void loop(struct timespec& _timeout) - { - ActionRequest trequest(ActionRequest::TIMER); - - loop(_timeout, trequest); - } - - /** - * The calling thread will be suspended until an action is triggered. No - * periodic action is defined. - */ - void loop() - { - ActionRequest trequest(ActionRequest::TIMER); - struct timespec _timeout; - - _timeout.tv_sec = 0; - _timeout.tv_nsec = 0; - - loop(_timeout, trequest); - } - - /** - * Register the calling object in this action manager. - * @param listener a pointer to the action listner - */ - void addListener(ActionListener * listener) - { - this->listener = listener; - }; - -private: - /** - * Queue of pending actions, processed in a FIFO manner - */ - std::queue actions; - - /** - * Action synchronization is implemented using the pthread library, - * with condition variable and its associated mutex - */ - pthread_mutex_t mutex; - pthread_cond_t cond; - - /** - * The listener notified by this manager - */ - ActionListener * listener; - - /** - * Function to lock the Manager mutex - */ - void lock() - { - pthread_mutex_lock(&mutex); - }; - - /** - * Function to unlock the Manager mutex - */ - void unlock() - { - pthread_mutex_unlock(&mutex); - }; - -}; - -#endif /*ACTION_MANAGER_H_*/ diff --git a/include/AuthManager.h b/include/AuthManager.h index dbf5dace19..dd084e7773 100644 --- a/include/AuthManager.h +++ b/include/AuthManager.h @@ -20,85 +20,27 @@ #include #include "NebulaLog.h" -#include "ActionManager.h" +#include "Listener.h" #include "ProtocolMessages.h" #include "DriverManager.h" //Forward definitions class AuthRequest; -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -class AMAction : public ActionRequest -{ -public: - enum Actions - { - AUTHENTICATE, - AUTHORIZE - }; - - AMAction(Actions a, AuthRequest *r):ActionRequest(ActionRequest::USER), - _action(a), _request(r) {} - - AMAction(const AMAction& o):ActionRequest(o._type), _action(o._action), - _request(o._request) {} - - Actions action() const - { - return _action; - } - - AuthRequest * request() const - { - return _request; - } - - ActionRequest * clone() const - { - return new AMAction(*this); - } - -private: - Actions _action; - - AuthRequest * _request; -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -extern "C" void * authm_action_loop(void *arg); class AuthManager : public DriverManager>, - public ActionListener + public Listener { public: AuthManager( - time_t timer, - const std::string& mads_location): + time_t timer, + const std::string& mads_location): DriverManager(mads_location), - timer_period(timer) + Listener("Authorization Manager"), + timer_thread(timer, [this](){timer_action();}) { - am.addListener(this); - } - - ~AuthManager() {} - - /** - * Triggers specific actions to the Auth Manager. This function - * wraps the ActionManager trigger function. - * @param action the Auth Manager action - * @param request an auth request - */ - void trigger(AMAction::Actions action, AuthRequest* request) - { - AMAction auth_ar(action, request); - - am.trigger(auth_ar); } /** @@ -109,29 +51,12 @@ public: */ int start(); - /** - * - */ - void finalize() - { - am.finalize(); - } - /** * Loads Virtual Machine Manager Mads defined in configuration file * @param _mads configuration of drivers */ int load_drivers(const std::vector& _mads); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return authm_thread; - } - /** * Returns true if there is an authorization driver enabled * @@ -142,31 +67,36 @@ public: return authz_enabled; } + /** + * This function authenticates a user + */ + void trigger_authenticate(AuthRequest& ar); + + /** + * This function authorizes a user request + */ + void trigger_authorize(AuthRequest& ar); + private: /** - * Thread id for the Transfer Manager + * Timer action async execution */ - pthread_t authm_thread; - - /** - * Action engine for the Manager - */ - ActionManager am; - - /** - * Timer for the Manager (periocally triggers timer action) - */ - time_t timer_period; + Timer timer_thread; /** * Generic name for the Auth driver */ - static const char * auth_driver_name; + static const char * auth_driver_name; /** * True if there is an authorization driver enabled */ - bool authz_enabled; + bool authz_enabled; + + /** + * + */ + static const int drivers_timeout = 10; /** * Returns a pointer to a Auth Manager driver. @@ -192,22 +122,6 @@ private: return DriverManager::get_driver(auth_driver_name); } - /** - * This function authenticates a user - */ - void authenticate_action(AuthRequest * ar); - - /** - * This function authorizes a user request - */ - void authorize_action(AuthRequest * ar); - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * authm_action_loop(void *arg); - // ------------------------------------------------------------------------- // Protocol implementation, procesing messages from driver // ------------------------------------------------------------------------- @@ -234,21 +148,12 @@ private: // ------------------------------------------------------------------------- // Action Listener interface // ------------------------------------------------------------------------- - void timer_action(const ActionRequest& ar) + void timer_action() { check_time_outs_action(); } - static const int drivers_timeout = 10; - - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("AuM",Log::INFO,"Stopping Authorization Manager..."); - - DriverManager::stop(drivers_timeout); - } - - void user_action(const ActionRequest& ar); + void finalize_action() override; }; #endif /*AUTH_MANAGER_H*/ diff --git a/include/AuthRequest.h b/include/AuthRequest.h index cf97501612..24dbb66d8f 100644 --- a/include/AuthRequest.h +++ b/include/AuthRequest.h @@ -19,13 +19,13 @@ #include -#include "ActionManager.h" #include "PoolObjectAuth.h" -#include "AuthManager.h" #include "NebulaUtil.h" #include "SyncRequest.h" +class AuthManager; + /** * The AuthRequest class is used to pass an Authorization or Authentication * request to the AuthManager. The result of the request will be stored diff --git a/include/DispatchManager.h b/include/DispatchManager.h index 81d1391bd7..7bf870f885 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -17,11 +17,7 @@ #ifndef DISPATCH_MANAGER_H_ #define DISPATCH_MANAGER_H_ -#include "ActionManager.h" -#include "VirtualMachinePool.h" - - -extern "C" void * dm_action_loop(void *arg); +#include "Listener.h" //Forward definitions class TransferManager; @@ -30,63 +26,23 @@ class VirtualMachineManager; class ImageManager; class ClusterPool; class HostPool; +class VirtualMachinePool; class VirtualRouterPool; class UserPool; +class VirtualMachine; +class VirtualMachineTemplate; struct RequestAttributes; -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -class DMAction : public ActionRequest -{ -public: - enum Actions - { - SUSPEND_SUCCESS, /**< Send by LCM when a VM is suspended*/ - STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/ - UNDEPLOY_SUCCESS, /**< Send by LCM when a VM is undeployed and saved*/ - POWEROFF_SUCCESS, /**< Send by LCM when a VM is powered off */ - DONE, /**< Send by LCM when a VM is shut down*/ - RESUBMIT /**< Send by LCM when a VM is ready for resubmission*/ - }; - - DMAction(Actions a, int v):ActionRequest(ActionRequest::USER), - _action(a), _vm_id(v){} - - DMAction(const DMAction& o):ActionRequest(o._type), _action(o._action), - _vm_id(o._vm_id){} - - Actions action() const - { - return _action; - } - - int vm_id() const - { - return _vm_id; - } - - ActionRequest * clone() const - { - return new DMAction(*this); - } - -private: - Actions _action; - - int _vm_id; -}; - -class DispatchManager : public ActionListener +class DispatchManager : public Listener { public: - DispatchManager(): - hpool(0), vmpool(0), clpool(0), vrouterpool(0), tm(0), vmm(0), lcm(0), imagem(0) + DispatchManager() + : Listener("Dispatch Manager") { - am.addListener(this); - }; + } ~DispatchManager() = default; @@ -96,25 +52,6 @@ public: */ void init_managers(); - /** - * Triggers specific actions to the Dispatch Manager. This function - * wraps the ActionManager trigger function. - * @param action the DM action - * @param vid VM unique id. This is the argument of the passed to the - * invoked action. - */ - void trigger(DMAction::Actions action, int vid) - { - DMAction dm_ar(action, vid); - - am.trigger(dm_ar); - } - - void finalize() - { - am.finalize(); - } - /** * This functions creates a new thread for the Dispatch Manager. This * thread will wait in an action loop till it receives ACTION_FINALIZE. @@ -122,15 +59,6 @@ public: */ int start(); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return dm_thread; - }; - //-------------------------------------------------------------------------- // DM Actions, the RM and the Scheduler will invoke this methods //-------------------------------------------------------------------------- @@ -272,20 +200,7 @@ public: /** * VM ID interface */ - int delete_vm(int vid, const RequestAttributes& ra, std::string& error_str) - { - VirtualMachine * vm; - - vm = vmpool->get(vid); - - if ( vm == 0 ) - { - error_str = "Virtual machine does not exist"; - return -1; - } - - return delete_vm(vm, ra, error_str); - } + int delete_vm(int vid, const RequestAttributes& ra, std::string& error_str); /** * Moves a VM to PENDING state preserving any resource (i.e. leases) and id @@ -504,99 +419,73 @@ public: int live_updateconf(int vid, const RequestAttributes& ra, std::string& error_str); -private: - /** - * Thread id for the Dispatch Manager - */ - pthread_t dm_thread; + //-------------------------------------------------------------------------- + // DM Actions associated with a VM state transition + //-------------------------------------------------------------------------- + void trigger_suspend_success(int vid); + + void trigger_stop_success(int vid); + + void trigger_undeploy_success(int vid); + + void trigger_poweroff_success(int vid); + + void trigger_done(int vid); + + void trigger_resubmit(int vid); + +private: /** * Pointer to the Host Pool, to access hosts */ - HostPool * hpool; + HostPool * hpool = nullptr; /** * Pointer to the Virtual Machine Pool, to access VMs */ - VirtualMachinePool * vmpool; + VirtualMachinePool * vmpool = nullptr; /** * Pointer to the User Pool, to access user */ - UserPool * upool; + UserPool * upool = nullptr; /** * Pointer to the Cluster Pool */ - ClusterPool * clpool; + ClusterPool * clpool = nullptr; /** * Pointer to the Virtual Router Pool */ - VirtualRouterPool * vrouterpool; + VirtualRouterPool * vrouterpool = nullptr; /** * Pointer to TransferManager */ - TransferManager * tm; + TransferManager * tm = nullptr; /** * Pointer to VirtualMachineManager */ - VirtualMachineManager * vmm; + VirtualMachineManager * vmm = nullptr; /** * Pointer to LifeCycleManager */ - LifeCycleManager * lcm; + LifeCycleManager * lcm = nullptr; /** * Pointer to ImageManager */ - ImageManager * imagem; - - /** - * Action engine for the Manager - */ - ActionManager am; + ImageManager * imagem = nullptr; /** * Frees the resources associated to a VM: disks, ip addresses and Quotas */ void free_vm_resources(VirtualMachine * vm, bool check_images); - //-------------------------------------------------------------------------- - // DM Actions associated with a VM state transition - //-------------------------------------------------------------------------- - - void suspend_success_action(int vid); - - void stop_success_action(int vid); - - void undeploy_success_action(int vid); - - void poweroff_success_action(int vid); - - void done_action(int vid); - - void resubmit_action(int vid); - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * dm_action_loop(void *arg); - - // ------------------------------------------------------------------------- - // Action Listener interface - // ------------------------------------------------------------------------- - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("DiM",Log::INFO,"Stopping Dispatch Manager..."); - }; - - void user_action(const ActionRequest& ar); - /** * Fill a template only with the necessary attributes to update the quotas * @param vm with the attributes diff --git a/include/FedReplicaManager.h b/include/FedReplicaManager.h index cca84920ed..6ddb78228b 100644 --- a/include/FedReplicaManager.h +++ b/include/FedReplicaManager.h @@ -20,16 +20,15 @@ #include #include #include +#include #include "ReplicaManager.h" -#include "ActionManager.h" - -extern "C" void * frm_loop(void *arg); class LogDB; class LogDBRecord; -class FedReplicaManager : public ReplicaManager, ActionListener + +class FedReplicaManager : public ReplicaManager { public: @@ -83,19 +82,6 @@ public: int xmlrpc_replicate_log(int zone_id, bool& success, uint64_t& last, std::string& err); - /** - * Finalizes the Federation Replica Manager - */ - void finalize() - { - am.finalize(); - } - - /** - * Starts the Federation Replica Manager - */ - int start(); - /** * Start the replication threads, and updates the server list of the zone */ @@ -130,31 +116,16 @@ public: */ void delete_zone(int zone_id); - /** - * @return the id of fed. replica thread - */ - pthread_t get_thread_id() const - { - return frm_thread; - }; - private: - friend void * frm_loop(void *arg); - /** * Creates federation replica thread objects */ ReplicaThread * thread_factory(int follower_id); - /** - * Thread id of the main event loop - */ - pthread_t frm_thread; - /** * Controls access to the zone list and server data */ - pthread_mutex_t mutex; + std::mutex fed_mutex; // ------------------------------------------------------------------------- // Synchronization variables @@ -185,16 +156,6 @@ private: LogDB * logdb; - // ------------------------------------------------------------------------- - // Action Listener interface - // ------------------------------------------------------------------------- - ActionManager am; - - /** - * Termination function - */ - void finalize_action(const ActionRequest& ar); - /** * Get the nerxt record to replicate in a zone * @param zone_id of the zone diff --git a/include/HookLog.h b/include/HookLog.h index 1d147f93c0..906ae24e48 100644 --- a/include/HookLog.h +++ b/include/HookLog.h @@ -19,16 +19,10 @@ #include -#include "ActionManager.h" #include "Attribute.h" class SqlDB; -/** - * Thread loop (timer action to purge the log) - */ -extern "C" void * hlog_action_loop(void *arg); - /** * This class represents the execution log of Hooks. It writes/reads execution * records in the DB. diff --git a/include/HookManager.h b/include/HookManager.h index d639d4cdc1..c656f65d55 100644 --- a/include/HookManager.h +++ b/include/HookManager.h @@ -19,63 +19,23 @@ #include "ProtocolMessages.h" #include "DriverManager.h" -#include "ActionManager.h" +#include "Listener.h" #include /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class HMAction : public ActionRequest -{ -public: - enum Actions - { - SEND_EVENT, /**< Send event to hook manager driver*/ - RETRY /**< Send RETRY action to hook manager driver*/ - }; - - HMAction(Actions a, const std::string& m):ActionRequest(ActionRequest::USER), - _action(a), _message(m){}; - - HMAction(const HMAction& o):ActionRequest(o._type), _action(o._action), - _message(o._message){}; - - Actions action() const - { - return _action; - } - - const std::string& message() const - { - return _message; - } - - ActionRequest * clone() const - { - return new HMAction(*this); - } - -private: - Actions _action; - - std::string _message; -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -extern "C" void * hm_action_loop(void *arg); - class HookManager : public DriverManager>, - public ActionListener + public Listener { public: - HookManager(const std::string& mad_location): DriverManager(mad_location) + HookManager(const std::string& mad_location) + : DriverManager(mad_location) + , Listener("Hook Manager") { - am.addListener(this); } virtual ~HookManager() = default; @@ -88,41 +48,12 @@ public: */ int start(); - /** - * Gets the HookManager thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return hm_thread; - }; - /** * Loads Hook Manager Mads defined in configuration file * @param _mads configuration of drivers */ int load_drivers(const std::vector& _mads); - /** - * Triggers specific actions to the Hook Manager. - * @param action the HM action - * @param message to send to the driver - */ - void trigger(HMAction::Actions action, const std::string& message) - { - HMAction hm_ar(action, message); - - am.trigger(hm_ar); - } - - /** - * Terminates the hook manager thread listener - */ - void finalize() - { - am.finalize(); - } - /** * Returns a pointer to a Information Manager MAD. The driver is * searched by its name and owned by oneadmin with uid=0. @@ -139,40 +70,24 @@ public: const std::string& remote_host, int hook_id); -private: - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * hm_action_loop(void *arg); - /** * Generic name for the Hook driver */ static const char * hook_driver_name; - /** - * Thread id for the HookManager - */ - pthread_t hm_thread; - - /** - * Action engine for the Manager - */ - ActionManager am; - /** * Send event message to the driver * @param message to pass to the driver */ - void send_event_action(const std::string& message); + void trigger_send_event(const std::string& message); /** * Send retry message to the driver * @param message to pass to the driver */ - void retry_action(const std::string& message); + void trigger_retry(const std::string& message); +private: // ------------------------------------------------------------------------- // Protocol implementation, procesing messages from driver // ------------------------------------------------------------------------- @@ -201,14 +116,10 @@ private: // ------------------------------------------------------------------------- static const int drivers_timeout = 10; - void finalize_action(const ActionRequest& ar) + void finalize_action() override { - NebulaLog::log("HKM",Log::INFO,"Stopping Hook Manager..."); - DriverManager::stop(drivers_timeout); }; - - void user_action(const ActionRequest& ar); }; #endif /*HOOK_MANAGER_H*/ diff --git a/include/IPAMManager.h b/include/IPAMManager.h index 6adb3bb04d..e2bd0081c7 100644 --- a/include/IPAMManager.h +++ b/include/IPAMManager.h @@ -21,7 +21,7 @@ #include "ProtocolMessages.h" #include "DriverManager.h" -#include "ActionManager.h" +#include "Listener.h" #include "NebulaLog.h" //Forward definitions @@ -31,77 +31,21 @@ class VectorAttribute; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class IPMAction : public ActionRequest -{ -public: - enum Actions - { - REGISTER_ADDRESS_RANGE, /**< Register/Request a new IP network */ - UNREGISTER_ADDRESS_RANGE, /**< Unregister IP network */ - ALLOCATE_ADDRESS, /**< Request a specific IP (or range) */ - GET_ADDRESS, /**< Request any free IP (or range) */ - FREE_ADDRESS /**< Frees a previously requested IP */ - }; - - IPMAction(Actions a, IPAMRequest *r):ActionRequest(ActionRequest::USER), - _action(a), _request(r){}; - - IPMAction(const IPMAction& o):ActionRequest(o._type), _action(o._action), - _request(o._request){}; - - Actions action() const - { - return _action; - } - - IPAMRequest * request() const - { - return _request; - } - - ActionRequest * clone() const - { - return new IPMAction(*this); - } - -private: - Actions _action; - - IPAMRequest * _request; -}; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -extern "C" void * ipamm_action_loop(void *arg); - class IPAMManager : public DriverManager>, - public ActionListener + public Listener { public: - IPAMManager(time_t timer, const std::string mad_location): - DriverManager(mad_location), timer_period(timer) + IPAMManager(time_t timer, const std::string mad_location) + : DriverManager(mad_location) + , Listener("IPAM Manager") + , timer_thread(timer, [this](){timer_action();}) { - am.addListener(this); - }; - - ~IPAMManager(){}; - - /** - * Triggers specific action to the IPAM Manager. This function - * wraps the ActionManager trigger function. - * @param action to the IPAM Manager action - * @param request an IPAM request - */ - void trigger(IPMAction::Actions action, IPAMRequest* request) - { - IPMAction ipam_ar(action, request); - - am.trigger(ipam_ar); } + ~IPAMManager() = default; + /** * This functions starts the associated listener thread, and creates a * new thread for the IPAMManager. This thread will wait in @@ -117,42 +61,40 @@ public: int load_drivers(const std::vector& _mads); /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). + * Register (or requests) a new address range to the IPAM. */ - pthread_t get_thread_id() const - { - return ipamm_thread; - }; + void trigger_register_address_range(IPAMRequest& ir); /** - * Finalizes the IPAM Manager + * Unregisters an address range. */ - void finalize() - { - am.finalize(); - }; + void trigger_unregister_address_range(IPAMRequest& ir); + + /** + * Requests the IPAM a free address (or range) + */ + void trigger_get_address(IPAMRequest& ir); + + /** + * Requests to set an address (or range) as used + */ + void trigger_allocate_address(IPAMRequest& ir); + + /** + * Free an address in the IPAM + */ + void trigger_free_address(IPAMRequest& ir); private: /** - * Thread id for the IPAM Manager + * Timer action async execution */ - pthread_t ipamm_thread; - - /** - * Action engine for the Manager - */ - ActionManager am; - - /** - * Timer for the Manager (periocally triggers timer action) - */ - time_t timer_period; + Timer timer_thread; /** * Generic name for the IPAM driver */ - static const char * ipam_driver_name; + static const char * ipam_driver_name; /** * Returns a pointer to a IPAM Manager driver. The driver is @@ -164,45 +106,14 @@ private: const Driver * get() const { return DriverManager::get_driver(ipam_driver_name); - }; - - /** - * Register (or requests) a new address range to the IPAM. - */ - void register_address_range_action(IPAMRequest * ir); - - /** - * Unregisters an address range. - */ - void unregister_address_range_action(IPAMRequest * ir); - - /** - * Requests the IPAM a free address (or range) - */ - void get_address_action(IPAMRequest * ir); - - /** - * Requests to set an address (or range) as used - */ - void allocate_address_action(IPAMRequest * ir); - - /** - * Free an address in the IPAM - */ - void free_address_action(IPAMRequest * ir); + } /** * This function initializes a request to call the IPAM driver * @param ir the IPAM request * @return pointer to the IPAM driver to use, 0 on failure */ - void send_request(IPAMManagerMessages type, IPAMRequest * ir); - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * ipamm_action_loop(void *arg); + void send_request(IPAMManagerMessages type, IPAMRequest& ir); // ------------------------------------------------------------------------- // Protocol implementation, procesing messages from driver @@ -225,21 +136,17 @@ private: // ------------------------------------------------------------------------- // Action Listener interface // ------------------------------------------------------------------------- - void timer_action(const ActionRequest& ar) + void timer_action() { check_time_outs_action(); - }; + } static const int drivers_timeout = 10; - void finalize_action(const ActionRequest& ar) + void finalize_action() override { - NebulaLog::log("IPM",Log::INFO,"Stopping IPAM Manager..."); - DriverManager::stop(drivers_timeout); - }; - - void user_action(const ActionRequest& ar); + } }; #endif /*IPAM_MANAGER_H*/ diff --git a/include/ImageManager.h b/include/ImageManager.h index e4685feeb3..6d4c494d68 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -19,10 +19,7 @@ #include "DriverManager.h" #include "ProtocolMessages.h" -#include "ActionManager.h" -#include "NebulaLog.h" - -extern "C" void * image_action_loop(void *arg); +#include "Listener.h" class DatastorePool; class Image; @@ -31,9 +28,7 @@ class Snapshots; class Template; -class ImageManager : - public DriverManager>, - public ActionListener +class ImageManager : public DriverManager> { public: @@ -44,16 +39,16 @@ public: const std::string& _mads_location, int _monitor_vm_disk): DriverManager(_mads_location), - timer_period(_timer_period), + timer_thread(_timer_period, [this](){timer_action();}), + timer_period(_monitor_period), monitor_period(_monitor_period), monitor_vm_disk(_monitor_vm_disk), ipool(_ipool), dspool(_dspool) { - am.addListener(this); - }; + } - ~ImageManager(){}; + ~ImageManager() = default; /** * This functions starts the associated listener thread, and creates a @@ -63,29 +58,19 @@ public: */ int start(); + void finalize() + { + timer_thread.stop(); + + stop(drivers_timeout); + }; + /** * Loads the Image Driver defined in configuration file * @param _mads configuration of drivers */ int load_drivers(const std::vector& _mads); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return imagem_thread; - }; - - /** - * Finalizes the Image Manager - */ - void finalize() - { - am.finalize(); - }; - /**************************************************************************/ /* Image Manager Actions */ /* Operates in a semi-sinchronous mode. Operations will be granted or not */ @@ -315,9 +300,9 @@ private: static const char * image_driver_name; /** - * Thread id for the Image Manager + * Timer action async execution */ - pthread_t imagem_thread; + Timer timer_thread; /** * Timer period for the Image Manager. @@ -346,9 +331,9 @@ private: DatastorePool * dspool; /** - * Action engine for the Manager + * */ - ActionManager am; + static const int drivers_timeout = 10; /** * Returns a pointer to the Image Manager Driver used for the Repository @@ -359,12 +344,6 @@ private: return DriverManager::get_driver(image_driver_name); }; - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * image_action_loop(void *arg); - /** * The action function executed when an action is triggered. * @param action the name of the action @@ -457,21 +436,12 @@ private: */ static void _log(std::unique_ptr msg); - // ------------------------------------------------------------------------- - // Action Listener interface - // ------------------------------------------------------------------------- /** * This function is executed periodically to monitor Datastores. */ - void timer_action(const ActionRequest& ar); + void timer_action(); - static const int drivers_timeout = 10; - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("ImM",Log::INFO,"Stopping Image Manager..."); - stop(drivers_timeout); - }; }; #endif /*IMAGE_MANAGER_H*/ diff --git a/include/InformationManager.h b/include/InformationManager.h index 4ed6d15b5c..e98662dc77 100644 --- a/include/InformationManager.h +++ b/include/InformationManager.h @@ -18,7 +18,7 @@ #define INFORMATION_MANAGER_H_ #include "DriverManager.h" -#include "ActionManager.h" +#include "Listener.h" #include "ProtocolMessages.h" #include "RaftManager.h" @@ -26,9 +26,7 @@ class HostPool; class Host; class VirtualMachinePool; -class InformationManager : - public DriverManager>, - public ActionListener +class InformationManager : public DriverManager> { public: InformationManager( @@ -39,7 +37,6 @@ public: , hpool(_hpool) , vmpool(_vmpool) { - am.addListener(this); } ~InformationManager() = default; @@ -52,20 +49,9 @@ public: */ int start(); - /** - * Join the action loop thread - */ - void join_thread() - { - return im_thread.join(); - }; - - /** - * - */ void finalize() { - am.finalize(); + stop(drivers_timeout); }; /** @@ -123,11 +109,6 @@ protected: void _vm_state(std::unique_ptr msg); private: - /** - * Thread for the Information Manager - */ - std::thread im_thread; - /** * Pointer to the Host Pool */ @@ -138,26 +119,11 @@ private: */ VirtualMachinePool * vmpool; - /** - * Action engine for the Manager - */ - ActionManager am; - /** * Default timeout to wait for Information Driver (monitord) */ static const int drivers_timeout = 10; - - // ------------------------------------------------------------------------ - // ActioListener Interface - // ------------------------------------------------------------------------ - void finalize_action(const ActionRequest& ar) override - { - NebulaLog::log("InM",Log::INFO,"Stopping Information Manager..."); - - stop(drivers_timeout); - }; }; -#endif /*VIRTUAL_MACHINE_MANAGER_H*/ +#endif /*INFORMATION_MANAGER_H_*/ diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index a7370a9642..cdeb21aa54 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -17,10 +17,8 @@ #ifndef LIFE_CYCLE_MANAGER_H_ #define LIFE_CYCLE_MANAGER_H_ -#include "ActionManager.h" -#include "NebulaLog.h" - -extern "C" void * lcm_action_loop(void *arg); +#include "Listener.h" +#include "VMActions.h" //Forward definitions class TransferManager; @@ -38,158 +36,21 @@ struct RequestAttributes; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class LCMAction : public ActionRequest -{ -public: - - enum Actions - { - NONE, - SAVE_SUCCESS, /**< Sent by the VMM when a save action succeeds */ - SAVE_FAILURE, /**< Sent by the VMM when a save action fails */ - DEPLOY_SUCCESS, /**< Sent by the VMM deploy/restore/migrate succeeds*/ - DEPLOY_FAILURE, /**< Sent by the VMM deploy/restore/migrate fails */ - SHUTDOWN_SUCCESS, /**< Sent by the VMM when a shutdown action succeeds*/ - SHUTDOWN_FAILURE, /**< Sent by the VMM when a shutdown action fails */ - CANCEL_SUCCESS, /**< Sent by the VMM when a cancel action succeeds */ - CANCEL_FAILURE, /**< Sent by the VMM when a cancel action fails */ - MONITOR_SUSPEND, /**< Sent by the VMM when a VM is paused in 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 */ - EPILOG_FAILURE, /**< Sent by the TM when the epilog phase fails */ - ATTACH_SUCCESS, /**< Sent by the VMM when an attach action succeeds */ - ATTACH_FAILURE, /**< Sent by the VMM when an attach action fails */ - DETACH_SUCCESS, /**< Sent by the VMM when a detach action succeeds */ - DETACH_FAILURE, /**< Sent by the VMM when a detach action fails */ - ATTACH_NIC_SUCCESS,/**< Sent by the VMM when attach nic action succeeds*/ - ATTACH_NIC_FAILURE,/**< Sent by the VMM when attach nic action fails */ - DETACH_NIC_SUCCESS,/**< Sent by the VMM when detach nic action succeeds*/ - DETACH_NIC_FAILURE,/**< Sent by the VMM when detach nic action fails */ - CLEANUP_SUCCESS, /**< Sent by the VMM when a cleanup action succeeds */ - CLEANUP_FAILURE, /**< Sent by the VMM when a cleanup action fails */ - SAVEAS_SUCCESS, /**< Sent by the VMM when saveas succeeds */ - SAVEAS_FAILURE, /**< Sent by the VMM when saveas fails */ - SNAPSHOT_CREATE_SUCCESS, /**< Sent by the VMM on snap. create success */ - SNAPSHOT_CREATE_FAILURE, /**< Sent by the VMM on snap. create failure */ - SNAPSHOT_REVERT_SUCCESS, /**< Sent by the VMM on snap. revert success */ - SNAPSHOT_REVERT_FAILURE, /**< Sent by the VMM on snap. revert failure */ - SNAPSHOT_DELETE_SUCCESS, /**< Sent by the VMM on snap. revert success */ - SNAPSHOT_DELETE_FAILURE, /**< Sent by the VMM on snap. revert failure */ - DISK_SNAPSHOT_SUCCESS, /**< Sent by TM when a snap. succeeds */ - DISK_SNAPSHOT_FAILURE, /**< Sent by TM when a snap. fails */ - DEPLOY, /**< Sent by the DM to deploy a VM on a host */ - SUSPEND, /**< Sent by the DM to suspend an running VM */ - RESTORE, /**< Sent by the DM to restore a suspended VM */ - STOP, /**< Sent by the DM to stop an running VM */ - CANCEL, /**< Sent by the DM to cancel an running VM */ - MIGRATE, /**< Sent by the DM to migrate a VM to other host */ - LIVE_MIGRATE, /**< Sent by the DM to live-migrate a VM */ - POFF_MIGRATE, /**< Sent by the DM to migrate a VM in a poff cycle */ - POFF_HARD_MIGRATE,/**< Sent by the DM to migrate a VM in a poff hard cycle */ - SHUTDOWN, /**< Sent by the DM to shutdown a running VM */ - UNDEPLOY, /**< Sent by the DM to undeploy a running VM */ - UNDEPLOY_HARD, /**< Sent by the DM to force undeploy a running VM */ - POWEROFF, /**< Sent by the DM to power off a running VM */ - POWEROFF_HARD, /**< Sent by the DM to power off hard a running VM */ - RESTART, /**< Sent by the DM to restart a deployed VM */ - DELETE, /**< Sent by the DM to delete a VM */ - DELETE_RECREATE, /**< Sent by the DM to cleanup a VM for resubmission*/ - UPDATESG, /**< Sent by RM/VMM to trigger the secgroup update*/ - DISK_LOCK_SUCCESS, /**< Sent by IM, image moves from locked to ready */ - DISK_LOCK_FAILURE, /**< Sent by IM, image moves from locked to error */ - DISK_RESIZE_SUCCESS,/**< Sent by TM/VMM when a disk resize succeeds */ - DISK_RESIZE_FAILURE,/**< Sent by TM/VMM when a disk resize fails */ - UPDATE_CONF_SUCCESS,/**< Sent by TM/VMM when a update conf succeeds */ - UPDATE_CONF_FAILURE /**< Sent by TM/VMM when a update conf fails */ - }; - - LCMAction(Actions a, int v, int u, int g, int r): - ActionRequest(ActionRequest::USER), _action(a), _vm_id(v), _uid(u), - _gid(g), _req_id(r){} - - LCMAction(const LCMAction& o):ActionRequest(o._type), _action(o._action), - _vm_id(o._vm_id), _uid(o._uid), _gid(o._gid), _req_id(o._req_id){} - - Actions action() const - { - return _action; - } - - int vm_id() const - { - return _vm_id; - } - - int uid() const - { - return _uid; - } - - int gid() const - { - return _gid; - } - - int req_id() const - { - return _req_id; - } - - ActionRequest * clone() const - { - return new LCMAction(*this); - } - -private: - Actions _action; - - int _vm_id; - - int _uid; - int _gid; - - int _req_id; -}; - /** * The Virtual Machine Life-cycle Manager module. This class is responsible for * managing the life-cycle of a Virtual Machine. */ -class LifeCycleManager : public ActionListener +class LifeCycleManager : public Listener { public: - LifeCycleManager(): - vmpool(0), hpool(0), ipool(0), sgpool(0), clpool(0), tm(0), vmm(0), - dm(0), imagem(0) + LifeCycleManager() + : Listener("Life Cycle Manager") { - am.addListener(this); }; ~LifeCycleManager() = default; - /** - * Triggers specific actions to the Life-cycle Manager. This function - * wraps the ActionManager trigger function. - * @param action the LCM action - * @param vid VM unique id. This is the argument of the passed to the - * invoked action. - * @param r RM request attributes to copy to the action request: uid, - * gid and request_id. - */ - void trigger(LCMAction::Actions action, int id, const RequestAttributes& r); - - void trigger(LCMAction::Actions action, int id); - - void finalize() - { - am.finalize(); - } - /** * This functions starts a new thread for the Life-cycle Manager. This * thread will wait in an action loop till it receives ACTION_FINALIZE. @@ -203,15 +64,6 @@ public: */ void init_managers(); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return lcm_thread; - }; - /** * Recovers a VM by self-triggering the associated lost transition. * @param vm to be recovered @@ -225,77 +77,157 @@ public: */ void retry(VirtualMachine * vm); -private: - /** - * Thread id for the Virtual Machine Manager - */ - pthread_t lcm_thread; + // ------------------------------------------------------------------------- + // Internal Actions, triggered by OpenNebula components & drivers + // ------------------------------------------------------------------------- + void start_prolog_migrate(VirtualMachine* vm); + void revert_migrate_after_failure(VirtualMachine* vm); + + void trigger_save_success(int vid); + void trigger_save_failure(int vid); + + void trigger_deploy_success(int vid); + void trigger_deploy_failure(int vid); + + void trigger_shutdown_success(int vid); + void trigger_shutdown_failure(int vid); + + void trigger_monitor_suspend(int vid); + void trigger_monitor_done(int vid); + void trigger_monitor_poweroff(int vid); + void trigger_monitor_poweron(int vid); + + void trigger_prolog_success(int vid); + void trigger_prolog_failure(int vid); + + void trigger_epilog_success(int vid); + void trigger_epilog_failure(int vid); + + void trigger_attach_success(int vid); + void trigger_attach_failure(int vid); + + void trigger_detach_success(int vid); + void trigger_detach_failure(int vid); + + void trigger_saveas_success(int vid); + void trigger_saveas_failure(int vid); + + void trigger_attach_nic_success(int vid); + void trigger_attach_nic_failure(int vid); + + void trigger_detach_nic_success(int vid); + void trigger_detach_nic_failure(int vid); + + void trigger_cleanup_callback(int vid); + + void trigger_snapshot_create_success(int vid); + void trigger_snapshot_create_failure(int vid); + + void trigger_snapshot_revert_success(int vid); + void trigger_snapshot_revert_failure(int vid); + + void trigger_snapshot_delete_success(int vid); + void trigger_snapshot_delete_failure(int vid); + + void trigger_disk_snapshot_success(int vid); + void trigger_disk_snapshot_failure(int vid); + + void trigger_disk_lock_success(int vid); + void trigger_disk_lock_failure(int vid); + + void trigger_disk_resize_success(int vid); + void trigger_disk_resize_failure(int vid); + + void trigger_update_conf_success(int vid); + void trigger_update_conf_failure(int vid); + + // ------------------------------------------------------------------------- + // External Actions, triggered by user requests + // ------------------------------------------------------------------------- + void trigger_deploy(int vid); + void trigger_suspend(int vid, const RequestAttributes& ra); + void trigger_restore(int vid, const RequestAttributes& ra); + void trigger_stop(int vid, const RequestAttributes& ra); + void trigger_checkpoint(int vid); + void trigger_migrate(int vid, const RequestAttributes& ra, + VMActions::Action vm_action); + void trigger_migrate(int vid, const RequestAttributes& ra) + { + trigger_migrate(vid, ra, VMActions::MIGRATE_ACTION); + } + void trigger_migrate_poweroff(int vid, const RequestAttributes& ra) + { + trigger_migrate(vid, ra, VMActions::POFF_MIGRATE_ACTION); + } + void trigger_migrate_poweroff_hard(int vid, const RequestAttributes& ra) + { + trigger_migrate(vid, ra, VMActions::POFF_HARD_MIGRATE_ACTION); + } + void trigger_live_migrate(int vid, const RequestAttributes& ra); + void trigger_shutdown(int vid, bool hard, const RequestAttributes& ra); + void trigger_undeploy(int vid, bool hard, const RequestAttributes& ra); + void trigger_undeploy(int vid, const RequestAttributes& ra) + { + trigger_undeploy(vid, false, ra); + } + void trigger_undeploy_hard(int vid, const RequestAttributes& ra) + { + trigger_undeploy(vid, true, ra); + } + void trigger_poweroff(int vid, const RequestAttributes& ra); + void trigger_poweroff_hard(int vid, const RequestAttributes& ra); + void trigger_poweroff(int vid, bool hard, const RequestAttributes& ra); + void trigger_updatesg(int vid); + void trigger_restart(int vid, const RequestAttributes& ra); + void trigger_delete(int vid, const RequestAttributes& ra); + void trigger_delete_recreate(int vid, const RequestAttributes& ra); + +private: /** * Pointer to the Virtual Machine Pool, to access VMs */ - VirtualMachinePool * vmpool; + VirtualMachinePool * vmpool = nullptr; /** * Pointer to the Host Pool, to access hosts */ - HostPool * hpool; + HostPool * hpool = nullptr; /** * Pointer to the Image Pool, to access images */ - ImagePool * ipool; + ImagePool * ipool = nullptr; /** * Pointer to the SecurityGroup Pool */ - SecurityGroupPool * sgpool; + SecurityGroupPool * sgpool = nullptr; /** * Pointer to the Cluster Pool */ - ClusterPool * clpool; + ClusterPool * clpool = nullptr; /** * Pointer to TransferManager */ - TransferManager * tm; + TransferManager * tm = nullptr; /** * Pointer to VirtualMachineManager */ - VirtualMachineManager * vmm; + VirtualMachineManager * vmm = nullptr; /** * Pointer to DispatchManager */ - DispatchManager * dm; - - /** - * Action engine for the Manager - */ - ActionManager am; + DispatchManager * dm = nullptr; /** * Pointer to ImageManager */ - ImageManager * imagem; - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * lcm_action_loop(void *arg); - - // ------------------------------------------------------------------------- - // Action Listener interface - // ------------------------------------------------------------------------- - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("LCM",Log::INFO,"Stopping Life-cycle Manager..."); - }; - - void user_action(const ActionRequest& ar); + ImageManager * imagem = nullptr; /** * Cleans up a VM, canceling any pending or ongoing action and closing @@ -307,107 +239,7 @@ private: * image may need to be set to error state. */ void clean_up_vm(VirtualMachine *vm, bool dispose, int& image_id, - const LCMAction& la); - - // ------------------------------------------------------------------------- - // Internal Actions, triggered by OpenNebula components & drivers - // ------------------------------------------------------------------------- - void start_prolog_migrate(VirtualMachine* vm); - - void revert_migrate_after_failure(VirtualMachine* vm); - - void save_success_action(int vid); - void save_failure_action(int vid); - - void deploy_success_action(int vid); - void deploy_failure_action(int vid); - - void shutdown_success_action(int vid); - void shutdown_failure_action(int vid); - - void monitor_suspend_action(int vid); - void monitor_done_action(int vid); - void monitor_poweroff_action(int vid); - void monitor_poweron_action(int vid); - - void prolog_success_action(int vid); - void prolog_failure_action(int vid); - - void epilog_success_action(int vid); - void epilog_failure_action(int vid); - - void attach_success_action(int vid); - void attach_failure_action(int vid); - - void detach_success_action(int vid); - void detach_failure_action(int vid); - - void saveas_success_action(int vid); - void saveas_failure_action(int vid); - - void attach_nic_success_action(int vid); - void attach_nic_failure_action(int vid); - - void detach_nic_success_action(int vid); - void detach_nic_failure_action(int vid); - - void cleanup_callback_action(int vid); - - void snapshot_create_success(int vid); - void snapshot_create_failure(int vid); - - void snapshot_revert_success(int vid); - void snapshot_revert_failure(int vid); - - void snapshot_delete_success(int vid); - void snapshot_delete_failure(int vid); - - void disk_snapshot_success(int vid); - void disk_snapshot_failure(int vid); - - void disk_lock_success(int vid); - void disk_lock_failure(int vid); - - void disk_resize_success(int vid); - void disk_resize_failure(int vid); - - void update_conf_success(int vid); - void update_conf_failure(int vid); - - // ------------------------------------------------------------------------- - // External Actions, triggered by user requests - // ------------------------------------------------------------------------- - void deploy_action(const LCMAction& la); - - void suspend_action(const LCMAction& la); - - void restore_action(const LCMAction& la); - - void stop_action(const LCMAction& la); - - void checkpoint_action(const LCMAction& la); - - void migrate_action(const LCMAction& la); - - void live_migrate_action(const LCMAction& la); - - void shutdown_action(const LCMAction& la, bool hard); - - void undeploy_action(const LCMAction& la, bool hard); - - void poweroff_action(const LCMAction& la); - - void poweroff_hard_action(const LCMAction& la); - - void poweroff_action(int vid, bool hard, const LCMAction& la); - - void updatesg_action(const LCMAction& la); - - void restart_action(const LCMAction& la); - - void delete_action(const LCMAction& la); - - void delete_recreate_action(const LCMAction& la); + int uid, int gid, int req_id); }; #endif /*LIFE_CYCLE_MANAGER_H_*/ diff --git a/include/Listener.h b/include/Listener.h new file mode 100644 index 0000000000..9abf45094a --- /dev/null +++ b/include/Listener.h @@ -0,0 +1,201 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef LISTENER_H_ +#define LISTENER_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "NebulaLog.h" + +/** + * The Timer class executes a given action periodically in a separate thread. + * The thread is terminated when the object is deleted + */ +class Timer +{ +public: + Timer(double s, std::function timer) + { + end = false; + + timer_thread = std::thread([&, s, timer]{ + + std::unique_lock ul(lock); + + while (true) + { + bool tout = cond.wait_for(ul, std::chrono::duration(s), [&]{ + return end == true; + }); + + if (end) + { + return; + } + else if (!tout) + { + timer(); + } + } + }); + }; + + ~Timer() + { + stop(); + + timer_thread.join(); + } + + void stop() + { + std::unique_lock ul(lock); + + end = true; + + cond.notify_one(); + } +private: + std::atomic end; + + std::thread timer_thread; + + std::mutex lock; + std::condition_variable cond; +}; + +/** + * This class implements basic functionality to listen for events. Events are + * triggered in separate threads. The class store them in a queue and executed + * them in the listner thread. + */ +class Listener +{ +public: + Listener(std::string _name) + : name(_name) + { + } + + virtual ~Listener() + { + join_thread(); + } + + /** + * Trigger an event in the listner. For example: + * listener.trigger(std::bind(&Class::callback, this, param1, param2); + * + * @param f, callback function for the event + */ + void trigger(std::function f) + { + std::unique_lock ul(lock); + + pending.push(f); + + ul.unlock(); + + cond.notify_one(); + } + + /** + * Async stops the event loop + */ + void finalize() + { + trigger([&] { + NebulaLog::info("Lis", "Stopping " + name); + + finalize_action(); + + end = true; + + cond.notify_one(); + }); + } + + void join_thread() + { + if (loop_thread.joinable()) + { + loop_thread.join(); + } + } + +protected: + /** + * Async starts the event loop waiting for events. + */ + void start() + { + end = false; + + loop_thread = std::thread([&] { + NebulaLog::info("Lis", name + " started."); + + loop(); + + NebulaLog::info("Lis", name + " stopped."); + }); + } + + void loop() + { + std::unique_lock ul(lock); + + while (true) + { + cond.wait(ul, [&]{return (end || !pending.empty());}); + + if (end) + { + break; + } + + auto fn = pending.front(); + pending.pop(); + + fn(); + } + } + + /** + * Action called on finalize action + */ + virtual void finalize_action() {}; + +private: + std::string name; + + std::thread loop_thread; + + std::atomic end; + + std::mutex lock; + std::condition_variable cond; + + std::queue> pending; +}; + +#endif /*LISTENER_H_*/ diff --git a/include/MarketPlaceManager.h b/include/MarketPlaceManager.h index 85126b34f8..ed58e8bd1b 100644 --- a/include/MarketPlaceManager.h +++ b/include/MarketPlaceManager.h @@ -19,10 +19,7 @@ #include "ProtocolMessages.h" #include "DriverManager.h" -#include "ActionManager.h" -#include "NebulaLog.h" - -extern "C" void * marketplace_action_loop(void *arg); +#include "Listener.h" class MarketPlacePool; class MarketPlaceAppPool; @@ -32,9 +29,7 @@ class DatastorePool; class ImageManager; class RaftManager; -class MarketPlaceManager : - public DriverManager>, - public ActionListener +class MarketPlaceManager : public DriverManager> { public: @@ -46,7 +41,7 @@ public: */ MarketPlaceManager(time_t t, time_t m, const std::string& _mad_location); - ~MarketPlaceManager(){}; + ~MarketPlaceManager() = default; /** * Initializes internal pointers to other managers. Must be called when @@ -55,36 +50,27 @@ public: void init_managers(); /** - * This functions starts the associated listener thread, and creates a - * new thread for the MarketPlace Manager. This thread will wait in - * an action loop till it receives ACTION_FINALIZE. + * This functions starts the associated timer thread and drivers. * @return 0 on success. */ int start(); + /** + * Stops timer and drivers + */ + void finalize() + { + timer_thread.stop(); + + DriverManager::stop(drivers_timeout); + }; + /** * Loads the MarketPlace Driver defined in configuration file * @param _mads configuration of drivers */ int load_drivers(const std::vector& _mads); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return marketm_thread; - }; - - /** - * Finalizes the Image Manager - */ - void finalize() - { - am.finalize(); - }; - /** * Imports a new app into the marketplace. The marketplace app needs to * include the ORIGIN_ID attribute so the driver can locate the app. An @@ -137,9 +123,9 @@ private: static const char * market_driver_name; /** - * Thread id for the MarketPlace Manager + * Timer action async execution */ - pthread_t marketm_thread; + Timer timer_thread; /** * Timer period for the Image Manager. @@ -154,37 +140,32 @@ private: /** * Pointer to the marketplace pool */ - MarketPlacePool * mppool; + MarketPlacePool * mppool = nullptr; /** * Pointer to the app pool */ - MarketPlaceAppPool * apppool; - - /** - * Pointer to the image pool - */ - ImagePool * ipool; - - /** - * Pointer to the image pool - */ - DatastorePool * dspool; - - /** - * Pointer to the Image Manger - */ - ImageManager * imagem; - - /** - * Pointer to the Raft Manger - */ - RaftManager * raftm; + MarketPlaceAppPool * apppool = nullptr; /** - * Action engine for the Manager + * Pointer to the image pool */ - ActionManager am; + ImagePool * ipool = nullptr; + + /** + * Pointer to the image pool + */ + DatastorePool * dspool = nullptr; + + /** + * Pointer to the Image Manger + */ + ImageManager * imagem = nullptr; + + /** + * Pointer to the Raft Manger + */ + RaftManager * raftm = nullptr; /** * Returns a pointer to the marketplace driver. @@ -193,13 +174,7 @@ private: const Driver * get() const { return DriverManager::get_driver(market_driver_name); - }; - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * marketplace_action_loop(void *arg); + } /** * Formats an XML message for the MAD @@ -230,15 +205,9 @@ private: /** * This function is executed periodically to monitor marketplaces.. */ - void timer_action(const ActionRequest& ar); + void timer_action(); static const int drivers_timeout = 10; - - void finalize_action(const ActionRequest& ar) - { - NebulaLog::log("MKP", Log::INFO, "Stopping Marketplace Manager..."); - DriverManager::stop(drivers_timeout); - }; }; #endif /*MARKETPLACE_MANAGER_H*/ diff --git a/include/Nebula.h b/include/Nebula.h index 27feb5b6fd..c99ab48766 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -22,6 +22,7 @@ #include "DefaultQuotas.h" #include "UserPool.h" +#include "NebulaLog.h" class LogDB; class FedLogDB; diff --git a/include/RaftManager.h b/include/RaftManager.h index e09cc4f5ea..c9f9efcf14 100644 --- a/include/RaftManager.h +++ b/include/RaftManager.h @@ -17,22 +17,18 @@ #ifndef RAFT_MANAGER_H_ #define RAFT_MANAGER_H_ -#include "ActionManager.h" +#include "Listener.h" #include "ReplicaManager.h" #include "ReplicaRequest.h" #include "Template.h" #include "ExecuteHook.h" -extern "C" void * raft_manager_loop(void *arg); - -extern "C" void * reconciling_thread(void *arg); - class LogDBRecord; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class RaftManager : public ActionListener +class RaftManager { public: /** @@ -64,8 +60,6 @@ public: { delete leader_hook; delete follower_hook; - - pthread_mutex_destroy(&mutex); }; // ------------------------------------------------------------------------- @@ -97,28 +91,15 @@ public: * Allocate a replica request fot the given index. * @param rindex of the record for the request */ - void replicate_allocate(uint64_t rindex) - { - requests.allocate(rindex); - } - - /** - * Finalizes the Raft Consensus Manager - */ - void finalize() + void replicate_allocate(uint64_t rindex) { - am.finalize(); + requests.allocate(rindex); } /** - * Starts the Raft Consensus Manager + * Termination function */ - int start(); - - pthread_t get_thread_id() const - { - return raft_thread; - }; + void finalize(); // ------------------------------------------------------------------------- // Raft state query functions @@ -158,50 +139,32 @@ public: State get_state() { - State _state; + std::lock_guard lock(raft_mutex); - pthread_mutex_lock(&mutex); - - _state = state; - - pthread_mutex_unlock(&mutex); - - return _state; + return state; } unsigned int get_term() { - unsigned int _term; + std::lock_guard lock(raft_mutex); - pthread_mutex_lock(&mutex); - - _term = term; - - pthread_mutex_unlock(&mutex); - - return _term; + return term; } uint64_t get_commit() { - uint64_t _commit; + std::lock_guard lock(raft_mutex); - pthread_mutex_lock(&mutex); - - _commit = commit; - - pthread_mutex_unlock(&mutex); - - return _commit; + return commit; } - /** + /** * Update the commit index = min(leader_commit, log index). - * @param leader_commit index sent by leader in a replicate xml-rpc call - * @param index of the last record inserted in the database - * @return the updated commit index - */ - uint64_t update_commit(uint64_t leader_commit, uint64_t index); + * @param leader_commit index sent by leader in a replicate xml-rpc call + * @param index of the last record inserted in the database + * @return the updated commit index + */ + uint64_t update_commit(uint64_t leader_commit, uint64_t index); /** * Evaluates a vote request. It is granted if no vote has been granted in @@ -211,26 +174,26 @@ public: */ int update_votedfor(int _votedfor); - /** - * Update the last_heartbeat time recieved from server. It stores the id + /** + * Update the last_heartbeat time recieved from server. It stores the id * of the leader. * @param leader_id id of server, -1 if there is no leader set (e.g. * during a election because a vote request was received) - */ - void update_last_heartbeat(int leader_id); + */ + void update_last_heartbeat(int leader_id); /** * @return true if the server is the leader of the zone, runs in solo mode - * or is a follower + * or is a follower */ bool is_leader() { - return test_state(LEADER); + return test_state(LEADER); } bool is_follower() { - return test_state(FOLLOWER); + return test_state(FOLLOWER); } bool is_candidate() @@ -247,12 +210,10 @@ public: { bool _reconciling; - pthread_mutex_lock(&mutex); + std::lock_guard lock(raft_mutex); _reconciling = reconciling; - pthread_mutex_unlock(&mutex); - return _reconciling; } @@ -266,7 +227,7 @@ public: std::map::iterator it; uint64_t _index = UINT64_MAX; - pthread_mutex_lock(&mutex); + std::lock_guard lock(raft_mutex); it = next.find(follower_id); @@ -275,8 +236,6 @@ public: _index = it->second; } - pthread_mutex_unlock(&mutex); - return _index; } @@ -292,24 +251,24 @@ public: // ------------------------------------------------------------------------- /** * Calls the follower xml-rpc method - * @param follower_id to make the call + * @param follower_id to make the call * @param lr the record to replicate * @param success of the xml-rpc method * @param ft term in the follower as returned by the replicate call - * @param error describing error if any + * @param error describing error if any * @return -1 if a XMl-RPC (network) error occurs, 0 otherwise */ - int xmlrpc_replicate_log(int follower_id, LogDBRecord * lr, bool& success, - unsigned int& ft, std::string& error); + int xmlrpc_replicate_log(int follower_id, LogDBRecord * lr, bool& success, + unsigned int& ft, std::string& error); /** * Calls the request vote xml-rpc method - * @param follower_id to make the call + * @param follower_id to make the call * @param lindex highest last log index * @param lterm highest last log term * @param success of the xml-rpc method * @param ft term in the follower as returned by the replicate call - * @param error describing error if any + * @param error describing error if any * @return -1 if a XMl-RPC (network) error occurs, 0 otherwise */ int xmlrpc_request_vote(int follower_id, uint64_t lindex, @@ -325,37 +284,23 @@ public: * @param follower_id id of new server * @param xmlep xmlrpc endpoint for new server */ - void add_server(int follower_id, const std::string& xmlep); + void add_server(int follower_id, const std::string& xmlep); /** * Deletes a new server to the follower list and stops associated replica * thread. * @param follower_id id of server */ - void delete_server(int follower_id); + void delete_server(int follower_id); /** * Reset index for a follower. * @param follower_id id of server */ - void reset_index(int follower_id); + void reset_index(int follower_id); private: - friend void * raft_manager_loop(void *arg); - - friend void * reconciling_thread(void *arg); - - /** - * Thread id of the main event loop - */ - pthread_t raft_thread; - - pthread_mutex_t mutex; - - /** - * Event engine for the RaftManager - */ - ActionManager am; + std::mutex raft_mutex; /** * Clients waiting for a log replication @@ -370,10 +315,10 @@ private: */ State state; - /** - * Server id - */ - int server_id; + /** + * Server id + */ + int server_id; /** * Current term @@ -385,10 +330,10 @@ private: */ unsigned int num_servers; - /** - * Time when the last heartbeat was sent (LEADER) or received (FOLLOWER) - */ - struct timespec last_heartbeat; + /** + * Time when the last heartbeat was sent (LEADER) or received (FOLLOWER) + */ + struct timespec last_heartbeat; /** * ID of the last candidate we voted for ( -1 if none ) @@ -422,8 +367,8 @@ private: // - timer_period_ms. Base timer to wake up the manager (10ms) // - purge_period_ms. How often the LogDB is purged (600s) // - xmlrpc_timeout. To timeout xml-rpc api calls to replicate log - // - election_timeout. Timeout leader heartbeats (followers) - // - broadcast_timeout. To send heartbeat to followers (leader) + // - election_timeout. Timeout leader heartbeats (followers) + // - broadcast_timeout. To send heartbeat to followers (leader) //-------------------------------------------------------------------------- static const time_t timer_period_ms; @@ -431,9 +376,14 @@ private: time_t xmlrpc_timeout_ms; - struct timespec election_timeout; + struct timespec election_timeout; - struct timespec broadcast_timeout; + struct timespec broadcast_timeout; + + /** + * Timer action async execution + */ + Timer timer_thread; //-------------------------------------------------------------------------- // Volatile log index variables @@ -444,7 +394,7 @@ private: // // - next, next log to send to each follower // - match, highest log replicated in this server - // - servers, list of servers in zone and xml-rpc edp + // - servers, list of servers in zone and xml-rpc edp // ------------------------------------------------------------------------- RaftReplicaManager replica_manager; @@ -466,41 +416,31 @@ private: ExecuteHook * follower_hook; // ------------------------------------------------------------------------- - // Action Listener interface + // Internal Raft functions // ------------------------------------------------------------------------- - /** - * Termination function - */ - void finalize_action(const ActionRequest& ar); - /** * This function is executed periodically to purge the state log */ - void timer_action(const ActionRequest& ar); + void timer_action(); - /** - * @param s the state to check - * @return true if the server states matches the provided one - */ - bool test_state(State s) - { + /** + * @param s the state to check + * @return true if the server states matches the provided one + */ + bool test_state(State s) + { bool _is_state; - pthread_mutex_lock(&mutex); + std::lock_guard lock(raft_mutex); _is_state = state == s; - pthread_mutex_unlock(&mutex); - return _is_state; - } + } - // ------------------------------------------------------------------------- - // Internal Raft functions - // ------------------------------------------------------------------------- - /** - * Request votes of followers - */ + /** + * Request votes of followers + */ void request_vote(); /** diff --git a/include/RequestManager.h b/include/RequestManager.h index ccc386c49a..5426a314e4 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -17,8 +17,6 @@ #ifndef REQUEST_MANAGER_H_ #define REQUEST_MANAGER_H_ -#include "ActionManager.h" - #include #include #include @@ -26,11 +24,9 @@ #include -extern "C" void * rm_action_loop(void *arg); - extern "C" void * rm_xml_server_loop(void *arg); -class RequestManager : public ActionListener +class RequestManager { public: @@ -46,7 +42,7 @@ public: const std::string& _listen_address, int message_size); - ~RequestManager(){}; + ~RequestManager() = default; /** * This functions starts the associated listener thread (XML server), and @@ -56,22 +52,7 @@ public: */ int start(); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return rm_thread; - }; - - /** - * Stops the main RM thread. - */ - void finalize() - { - am.finalize(); - }; + void finalize(); /** * @return an AbyssServer to run xmlrpc connections @@ -108,13 +89,6 @@ private: friend void * rm_xml_server_loop(void *arg); - friend void * rm_action_loop(void *arg); - - /** - * Thread id for the RequestManager - */ - pthread_t rm_thread; - /** * Thread id for the XML Server */ @@ -165,11 +139,6 @@ private: */ std::string listen_address; - /** - * Action engine for the Manager - */ - ActionManager am; - /** * To register XML-RPC methods */ @@ -181,11 +150,6 @@ private: void register_xml_methods(); int setup_socket(); - - // ------------------------------------------------------------------------ - // ActioListener Interface - // ------------------------------------------------------------------------ - void finalize_action(const ActionRequest& ar) override; }; #endif diff --git a/include/SyncRequest.h b/include/SyncRequest.h index cba5c6e1b3..4787a90fbe 100644 --- a/include/SyncRequest.h +++ b/include/SyncRequest.h @@ -19,26 +19,26 @@ #include -#include "ActionManager.h" +#include "Listener.h" /** * Base class to implement synchronous operation in the MadManagers. This class * cannot be directly instantiated. */ -class SyncRequest: public ActionListener +class SyncRequest: public Listener { public: SyncRequest(): + Listener(""), result(false), message(""), timeout(false), id(-1), time_out(0) { - am.addListener(this); - }; + } - virtual ~SyncRequest(){}; + virtual ~SyncRequest() = default; /** * The result of the request, true if the operation succeeded @@ -65,8 +65,8 @@ public: */ void notify() { - am.finalize(); - }; + finalize(); + } /** * Wait for the AuthRequest to be completed @@ -75,40 +75,13 @@ public: { time_out = time(0) + 90;//Requests will expire in 1.5 minutes - am.loop(); - }; - - /** - * Wait for the AuthRequest to be completed - */ - void wait(time_t t) - { - am.loop(t); - }; + loop(); + } /** * Time in seconds when this request will expire */ time_t time_out; - -protected: - - /** - * The ActionManager that will be notify when the request is ready. - */ - ActionManager am; - - /** - * Timer action to finalize time-out waits - */ - void timer_action(const ActionRequest& ar) - { - result = false; - timeout = true; - message = "Operation time out"; - - am.finalize(); - }; }; #endif /*SYNC_REQUEST_H_*/ diff --git a/include/TransferManager.h b/include/TransferManager.h index 3186865e3c..ccf2f17495 100644 --- a/include/TransferManager.h +++ b/include/TransferManager.h @@ -19,74 +19,20 @@ #include "ProtocolMessages.h" #include "DriverManager.h" -#include "ActionManager.h" - -extern "C" void * tm_action_loop(void *arg); +#include "Listener.h" class HostPool; class VirtualMachine; class VirtualMachineDisk; class VirtualMachinePool; +class LifeCycleManager; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class TMAction : public ActionRequest -{ -public: - enum Actions - { - PROLOG, - PROLOG_MIGR, - PROLOG_RESUME, - PROLOG_ATTACH, - EPILOG, - EPILOG_LOCAL, - EPILOG_STOP, - EPILOG_DELETE, - EPILOG_DELETE_PREVIOUS, - EPILOG_DELETE_STOP, - EPILOG_DELETE_BOTH, - EPILOG_DETACH, - CHECKPOINT, - DRIVER_CANCEL, - SAVEAS_HOT, - SNAPSHOT_CREATE, - SNAPSHOT_REVERT, - SNAPSHOT_DELETE, - RESIZE - }; - - TMAction(Actions a, int v):ActionRequest(ActionRequest::USER), - _action(a), _vm_id(v){} - - TMAction(const TMAction& o):ActionRequest(o._type), _action(o._action), - _vm_id(o._vm_id){} - - Actions action() const - { - return _action; - } - - int vm_id() const - { - return _vm_id; - } - - ActionRequest * clone() const - { - return new TMAction(*this); - } - -private: - Actions _action; - - int _vm_id; -}; - class TransferManager : public DriverManager>, - public ActionListener + public Listener { public: @@ -95,33 +41,14 @@ public: HostPool * _hpool, const std::string& _mad_location): DriverManager(_mad_location), + Listener("Transfer Manager"), vmpool(_vmpool), hpool(_hpool) { - am.addListener(this); }; ~TransferManager() = default; - /** - * Triggers specific actions to the Information Manager. This function - * wraps the ActionManager trigger function. - * @param action the IM action - * @param vid VM unique id. This is the argument of the passed to the - * invoked action. - */ - void trigger(TMAction::Actions action, int vid) - { - TMAction tm_ar(action, vid); - - am.trigger(tm_ar); - } - - void finalize() - { - am.finalize(); - } - /** * This functions starts the associated listener thread, and creates a * new thread for the Information Manager. This thread will wait in @@ -136,15 +63,6 @@ public: */ int load_drivers(const std::vector& _mads); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return tm_thread; - }; - /** * Inserts a transfer command in the xfs stream * @@ -245,11 +163,6 @@ public: const VirtualMachineDisk * disk, std::ostream& xfr); private: - /** - * Thread id for the Transfer Manager - */ - pthread_t tm_thread; - /** * Pointer to the Virtual Machine Pool, to access VMs */ @@ -260,11 +173,6 @@ private: */ HostPool * hpool; - /** - * Action engine for the Manager - */ - ActionManager am; - /** * Generic name for the TransferManager driver */ @@ -292,17 +200,13 @@ private: return DriverManager::get_driver(transfer_driver_name); }; - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * tm_action_loop(void *arg); - // ------------------------------------------------------------------------- // Protocol implementation, procesing messages from driver // ------------------------------------------------------------------------- static void _undefined(std::unique_ptr msg); + void _transfer(std::unique_ptr msg); + static void _log(std::unique_ptr msg); // ------------------------------------------------------------------------- @@ -310,52 +214,49 @@ private: // ------------------------------------------------------------------------- static const int drivers_timeout = 10; - void finalize_action(const ActionRequest& ar) + void finalize_action() { - NebulaLog::log("TM",Log::INFO,"Stopping Transfer Manager..."); - DriverManager::stop(drivers_timeout); }; - void user_action(const ActionRequest& ar); - +public: /** * This function starts the prolog sequence */ - void prolog_action(int vid); + void trigger_prolog(VirtualMachine * vm); /** * This function starts the prolog migration sequence */ - void prolog_migr_action(int vid); + void trigger_prolog_migr(VirtualMachine * vm); /** * This function starts the prolog resume sequence */ - void prolog_resume_action(int vid); + void trigger_prolog_resume(VirtualMachine * vm); /** * This function starts the prolog attach sequence */ - void prolog_attach_action(int vid); + void trigger_prolog_attach(VirtualMachine * vm); /** * This function starts the epilog sequence */ - void epilog_action(bool local, int vid); + void trigger_epilog(bool local, VirtualMachine * vm); /** * This function starts the epilog_stop sequence */ - void epilog_stop_action(int vid); + void trigger_epilog_stop(VirtualMachine * vm); /** * This function starts the epilog_delete sequence in the current host * @param vid the Virtual Machine ID */ - void epilog_delete_action(int vid) + void trigger_epilog_delete(VirtualMachine * vm) { - epilog_delete_action(false, vid); + trigger_epilog_delete(false, vm); } /** @@ -363,48 +264,48 @@ private: * i.e. the front-end (the VM is not running) * @param vid the Virtual Machine ID */ - void epilog_delete_stop_action(int vid) + void trigger_epilog_delete_stop(VirtualMachine * vm) { - epilog_delete_action(true, vid); + trigger_epilog_delete(true, vm); } /** * This function starts the epilog_delete sequence on the previous host * @param vid the Virtual Machine ID */ - void epilog_delete_previous_action(int vid); + void trigger_epilog_delete_previous(VirtualMachine * vm); /** * This function starts the epilog_delete sequence on the current and * previous hosts * @param vid the Virtual Machine ID */ - void epilog_delete_both_action(int vid); + void trigger_epilog_delete_both(VirtualMachine * vm); /** * This function starts the epilog_delete sequence */ - void epilog_delete_action(bool local, int vid); + void trigger_epilog_delete(bool local, VirtualMachine * vm); /** * This function starts the epilog detach sequence */ - void epilog_detach_action(int vid); + void trigger_epilog_detach(VirtualMachine * vm); /** * This function starts the epilog sequence */ - void checkpoint_action(int vid); + void trigger_checkpoint(int vid); /** * This function cancels the operation being performed by the driver */ - void driver_cancel_action(int vid); + void trigger_driver_cancel(int vid); /** * This function starts the saveas of the given disk */ - void saveas_hot_action(int vid); + void trigger_saveas_hot(int vid); /** * This function performs a generic snapshot action @@ -414,22 +315,22 @@ private: /** * This function takes an snapshot of a disk */ - void snapshot_create_action(int vid); + void trigger_snapshot_create(int vid); /** * This function takes an snapshot of a disk */ - void snapshot_revert_action(int vid); + void trigger_snapshot_revert(int vid); /** * This function deletes an snapshot of a disk */ - void snapshot_delete_action(int vid); + void trigger_snapshot_delete(int vid); /** * This function resizes a VM disk */ - void resize_action(int vid); + void trigger_resize(int vid); }; #endif /*TRANSFER_MANAGER_H*/ diff --git a/include/VirtualMachineManager.h b/include/VirtualMachineManager.h index a4f1876e17..46cc27b8d5 100644 --- a/include/VirtualMachineManager.h +++ b/include/VirtualMachineManager.h @@ -19,106 +19,27 @@ #include "VirtualMachineManagerDriver.h" #include "DriverManager.h" -#include "ActionManager.h" +#include "Listener.h" class DatastorePool; class HostPool; class VirtualMachinePool; -extern "C" void * vmm_action_loop(void *arg); - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -class VMMAction : public ActionRequest -{ -public: - enum Actions - { - DEPLOY, - SAVE, - SHUTDOWN, - CANCEL, - CANCEL_PREVIOUS, - CLEANUP, - CLEANUP_BOTH, - CLEANUP_PREVIOUS, - MIGRATE, - RESTORE, - REBOOT, - RESET, - DRIVER_CANCEL, - ATTACH, - DETACH, - ATTACH_NIC, - DETACH_NIC, - SNAPSHOT_CREATE, - SNAPSHOT_REVERT, - SNAPSHOT_DELETE, - DISK_SNAPSHOT_CREATE, - DISK_RESIZE, - UPDATE_CONF - }; - - VMMAction(Actions a, int v):ActionRequest(ActionRequest::USER), - _action(a), _vm_id(v){}; - - VMMAction(const VMMAction& o):ActionRequest(o._type), _action(o._action), - _vm_id(o._vm_id){}; - - Actions action() const - { - return _action; - } - - int vm_id() const - { - return _vm_id; - } - - ActionRequest * clone() const - { - return new VMMAction(*this); - } - -private: - Actions _action; - - int _vm_id; -}; - class VirtualMachineManager : public DriverManager, - public ActionListener + public Listener { public: VirtualMachineManager( - time_t _timer_period, int _vm_limit, const std::string& _mads); ~VirtualMachineManager() = default; - /** - * Triggers specific actions to the Virtual Machine Manager. This function - * wraps the ActionManager trigger function. - * @param action the VMM action - * @param vid VM unique id. This is the argument of the passed to the - * invoked action. - */ - void trigger(VMMAction::Actions action, int vid) - { - VMMAction vmm_ar(action, vid); - - am.trigger(vmm_ar); - } - - void finalize() - { - am.finalize(); - } - /** * This functions starts the associated listener thread, and creates a * new thread for the Virtual Machine Manager. This thread will wait in @@ -127,15 +48,6 @@ public: */ int start(); - /** - * Gets the thread identification. - * @return pthread_t for the manager thread (that in the action loop). - */ - pthread_t get_thread_id() const - { - return vmm_thread; - }; - /** * Loads Virtual Machine Manager Mads defined in configuration file * @param _mads configuration of drivers @@ -223,11 +135,6 @@ public: int validate_raw(const Template * vmt, std::string& error_str); private: - /** - * Thread id for the Virtual Machine Manager - */ - pthread_t vmm_thread; - /** * Pointer to the Virtual Machine Pool, to access VMs */ @@ -243,27 +150,11 @@ private: */ DatastorePool * ds_pool; - /** - * Timer period for the Virtual Machine Manager. - */ - time_t timer_period; - /** * Virtual Machine polling limit */ int vm_limit; - /** - * Action engine for the Manager - */ - ActionManager am; - - /** - * Function to execute the Manager action loop method within a new pthread - * (requires C linkage) - */ - friend void * vmm_action_loop(void *arg); - // ------------------------------------------------------------------------- // Protocol implementation, procesing messages from driver // ------------------------------------------------------------------------- @@ -413,15 +304,11 @@ private: static const int drivers_timeout = 10; - void finalize_action(const ActionRequest& ar) + void finalize_action() { - NebulaLog::log("VMM",Log::INFO,"Stopping Virtual Machine Manager..."); - DriverManager::stop(drivers_timeout); }; - void user_action(const ActionRequest& ar); - /** * Function to format a VMM Driver message in the form: * @@ -465,43 +352,39 @@ private: int ds_id, int sgid); +public: /** * Function executed when a DEPLOY action is received. It deploys a VM on * a Host. * @param vid the id of the VM to be deployed. */ - void deploy_action( - int vid); + void trigger_deploy(int vid); /** * Function to stop a running VM and generate a checkpoint file. This * function is executed when a SAVE action is triggered. * @param vid the id of the VM. */ - void save_action( - int vid); + void trigger_save(int vid); /** * Shutdowns a VM when a SHUTDOWN action is received. * @param vid the id of the VM. */ - void shutdown_action( - int vid); + void trigger_shutdown(int vid); /** * Cancels a VM when a CANCEL action is received. * @param vid the id of the VM. */ - void cancel_action( - int vid); + void trigger_cancel(int vid); /** * Cancels a VM (in the previous host) when a CANCEL action is received. * Note that the domain-id is the last one returned by a boot action * @param vid the id of the VM. */ - void cancel_previous_action( - int vid); + void trigger_cancel_previous(int vid); /** * Cleanups a host (cancel VM + delete disk images). @@ -509,81 +392,70 @@ private: * @param cancel_previous if true the VM will be canceled in the previous * host (only relevant to delete VM's in MIGRATE state) */ - void cleanup_action( - int vid, bool cancel_previous); + void trigger_cleanup(int vid, bool cancel_previous); /** * Cleanups the previous host (cancel VM + delete disk images). * @param vid the id of the VM. */ - void cleanup_previous_action( - int vid); + void trigger_cleanup_previous(int vid); /** * Function to migrate (live) a VM (MIGRATE action). * @param vid the id of the VM. */ - void migrate_action( - int vid); + void trigger_migrate(int vid); /** * Restores a VM from a checkpoint file. * @param vid the id of the VM. */ - void restore_action( - int vid); + void trigger_restore(int vid); /** * Reboots a running VM. * @param vid the id of the VM. */ - void reboot_action( - int vid); + void trigger_reboot(int vid); /** * Resets a running VM. * @param vid the id of the VM. */ - void reset_action( - int vid); + void trigger_reset(int vid); /** * Attaches a new disk to a VM. The VM must have a disk with the * attribute ATTACH = YES * @param vid the id of the VM. */ - void attach_action( - int vid); + void trigger_attach(int vid); /** * Detaches a disk from a VM. The VM must have a disk with the * attribute ATTACH = YES * @param vid the id of the VM. */ - void detach_action( - int vid); + void trigger_detach(int vid); /** * Attaches a new NIC to a VM. The VM must have a NIC with the * attribute ATTACH = YES * @param vid the id of the VM. */ - void attach_nic_action( - int vid); + void trigger_attach_nic(int vid); /** * Detaches a NIC from a VM. The VM must have a NIC with the * attribute ATTACH = YES * @param vid the id of the VM. */ - void detach_nic_action( - int vid); + void trigger_detach_nic(int vid); /** * This function cancels the current driver operation */ - void driver_cancel_action( - int vid); + void trigger_driver_cancel(int vid); /** * Creates a new system snapshot. The VM must have a snapshot with the @@ -591,8 +463,7 @@ private: * * @param vid the id of the VM. */ - void snapshot_create_action( - int vid); + void trigger_snapshot_create(int vid); /** * Reverts to a snapshot. The VM must have a snapshot with the @@ -600,8 +471,7 @@ private: * * @param vid the id of the VM. */ - void snapshot_revert_action( - int vid); + void trigger_snapshot_revert(int vid); /** * Deletes a snapshot. The VM must have a snapshot with the @@ -609,32 +479,28 @@ private: * * @param vid the id of the VM. */ - void snapshot_delete_action( - int vid); + void trigger_snapshot_delete(int vid); /** * Creates a new disk system snapshot. * * @param vid the id of the VM. */ - void disk_snapshot_create_action( - int vid); + void trigger_disk_snapshot_create(int vid); /** * Resize a VM disk * * @param vid the id of the VM. */ - void disk_resize_action( - int vid); + void trigger_disk_resize(int vid); /** * Update VM context * * @param vid the id of the VM. */ - void update_conf_action( - int vid); + void trigger_update_conf(int vid); }; #endif /*VIRTUAL_MACHINE_MANAGER_H*/ diff --git a/src/acl/AclManager.cc b/src/acl/AclManager.cc index 5953bd0cbd..b58d61a863 100644 --- a/src/acl/AclManager.cc +++ b/src/acl/AclManager.cc @@ -17,6 +17,7 @@ #include #include "AclManager.h" +#include "AclRule.h" #include "PoolObjectAuth.h" #include "SqlDB.h" #include "OneDB.h" @@ -65,15 +66,13 @@ AclManager::AclManager( int _zone_id, bool _is_federation_slave, time_t _timer_period) - :zone_id(_zone_id), db(_db), is_federation_slave(_is_federation_slave), - timer_period(_timer_period) + : zone_id(_zone_id) + , db(_db) + , is_federation_slave(_is_federation_slave) + , timer_period(_timer_period) { int lastOID; - pthread_mutex_init(&mutex, 0); - - am.addListener(this); - //Federation slaves do not need to init the pool if (is_federation_slave) { @@ -124,29 +123,6 @@ AclManager::AclManager( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -extern "C" void * acl_action_loop(void *arg) -{ - AclManager * aclm; - - if ( arg == 0 ) - { - return 0; - } - - NebulaLog::log("ACL",Log::INFO,"ACL Manager started."); - - aclm = static_cast(arg); - - aclm->am.loop(aclm->timer_period); - - NebulaLog::log("ACL",Log::INFO,"ACL Manager stopped."); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int AclManager::start() { int rc; @@ -157,18 +133,11 @@ int AclManager::start() if (is_federation_slave) { - pthread_attr_t pattr; - - pthread_attr_init (&pattr); - pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); - - rc += pthread_create(&acl_thread,&pattr,acl_action_loop,(void *) this); - } - else - { - NebulaLog::log("ACL",Log::INFO,"ACL Manager started."); + timer_thread.reset(new Timer(timer_period, [this](){timer_action();})); } + NebulaLog::log("ACL",Log::INFO,"ACL Manager started."); + return rc; } @@ -177,14 +146,25 @@ int AclManager::start() void AclManager::finalize() { + NebulaLog::info("ACL", "Stopping ACL Manager..."); + if (is_federation_slave) { - am.finalize(); + timer_thread->stop(); } - else +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void AclManager::join_thread() +{ + if (is_federation_slave) { - NebulaLog::log("ACL",Log::INFO,"ACL Manager stopped."); + timer_thread->stop(); } + + NebulaLog::info("ACL", "ACL Manager stopped."); } /* -------------------------------------------------------------------------- */ @@ -192,18 +172,12 @@ void AclManager::finalize() AclManager::~AclManager() { - multimap::iterator it; + lock_guard ul(acl_mutex); - lock(); - - for ( it = acl_rules.begin(); it != acl_rules.end(); it++ ) + for (auto& rule : acl_rules) { - delete it->second; + delete rule.second; } - - unlock(); - - pthread_mutex_destroy(&mutex); } /* -------------------------------------------------------------------------- */ @@ -464,7 +438,7 @@ bool AclManager::match_rules_wrapper( } // Match against the internal rules - lock(); + lock_guard ul(acl_mutex); auth = match_rules( user_req, @@ -478,8 +452,6 @@ bool AclManager::match_rules_wrapper( cluster_obj_type, acl_rules); - unlock(); - return auth; } @@ -596,7 +568,7 @@ int AclManager::add_rule(long long user, long long resource, long long rights, return -1; } - lock(); + lock_guard ul(acl_mutex); int lastOID = get_lastOID(db); @@ -645,8 +617,6 @@ int AclManager::add_rule(long long user, long long resource, long long rights, set_lastOID(db, lastOID); - unlock(); - return lastOID; @@ -673,8 +643,6 @@ error_common: delete rule; - unlock(); - return rc; } @@ -702,7 +670,7 @@ int AclManager::del_rule(int oid, string& error_str) return -1; } - lock(); + lock_guard ul(acl_mutex); // Check the rule exists found = acl_rules_oids.count(oid) > 0; @@ -713,7 +681,6 @@ int AclManager::del_rule(int oid, string& error_str) oss << "Rule " << oid << " does not exist"; error_str = oss.str(); - unlock(); return -1; } @@ -744,7 +711,6 @@ int AclManager::del_rule(int oid, string& error_str) NebulaLog::log("ACL",Log::ERROR,oss); - unlock(); return -1; } @@ -755,7 +721,6 @@ int AclManager::del_rule(int oid, string& error_str) { error_str = "SQL DB error"; - unlock(); return -1; } @@ -766,7 +731,6 @@ int AclManager::del_rule(int oid, string& error_str) delete rule; - unlock(); return 0; } @@ -780,31 +744,27 @@ int AclManager::del_rule( long long zone, string& error_str) { - lock(); - AclRule rule(-1, user, resource, rights, zone); - int oid = -1; + int oid = -1; bool found = false; - multimap::iterator it; - pair::iterator, - multimap::iterator> index; - - index = acl_rules.equal_range( user ); - - for ( it = index.first; (it != index.second && !found); it++) { - found = *(it->second) == rule; + lock_guard ul(acl_mutex); - if (found) + auto index = acl_rules.equal_range(user); + + for (auto it = index.first; (it != index.second && !found); it++) { - oid = it->second->get_oid(); + found = *(it->second) == rule; + + if (found) + { + oid = it->second->get_oid(); + } } } - unlock(); - if (oid != -1) { return del_rule(oid, error_str); @@ -893,24 +853,20 @@ void AclManager::del_resource_rules(int oid, PoolObjectSQL::ObjectType obj_type) void AclManager::del_user_matching_rules(long long user_req) { - multimap::iterator it; - pair::iterator, - multimap::iterator> index; - vector oids; vector::iterator oid_it; string error_str; - lock(); - - index = acl_rules.equal_range( user_req ); - - for ( it = index.first; it != index.second; it++) { - oids.push_back(it->second->oid); - } + lock_guard ul(acl_mutex); - unlock(); + auto index = acl_rules.equal_range( user_req ); + + for ( auto it = index.first; it != index.second; it++) + { + oids.push_back(it->second->oid); + } + } for ( oid_it = oids.begin() ; oid_it < oids.end(); oid_it++ ) { @@ -924,25 +880,22 @@ void AclManager::del_user_matching_rules(long long user_req) void AclManager::del_resource_matching_rules(long long resource_req, long long resource_mask) { - multimap::iterator it; + vector oids; + string error_str; - vector oids; - vector::iterator oid_it; - string error_str; - - lock(); - - for ( it = acl_rules.begin(); it != acl_rules.end(); it++ ) { - if ( ( it->second->resource & resource_mask ) == resource_req ) + lock_guard ul(acl_mutex); + + for ( auto it = acl_rules.begin(); it != acl_rules.end(); it++ ) { - oids.push_back(it->second->oid); + if ( ( it->second->resource & resource_mask ) == resource_req ) + { + oids.push_back(it->second->oid); + } } } - unlock(); - - for ( oid_it = oids.begin() ; oid_it < oids.end(); oid_it++ ) + for ( auto oid_it = oids.begin() ; oid_it < oids.end(); oid_it++ ) { del_rule(*oid_it, error_str); } @@ -953,25 +906,22 @@ void AclManager::del_resource_matching_rules(long long resource_req, void AclManager::del_zone_matching_rules(long long zone_req) { - multimap::iterator it; + vector oids; + string error_str; - vector oids; - vector::iterator oid_it; - string error_str; - - lock(); - - for ( it = acl_rules.begin(); it != acl_rules.end(); it++ ) { - if ( it->second->zone == zone_req ) + lock_guard ul(acl_mutex); + + for (auto it = acl_rules.begin(); it != acl_rules.end(); it++) { - oids.push_back(it->second->oid); + if ( it->second->zone == zone_req ) + { + oids.push_back(it->second->oid); + } } } - unlock(); - - for ( oid_it = oids.begin() ; oid_it < oids.end(); oid_it++ ) + for (auto oid_it = oids.begin() ; oid_it < oids.end(); oid_it++) { del_rule(*oid_it, error_str); } @@ -994,10 +944,6 @@ void AclManager::reverse_search(int uid, { ostringstream oss; - multimap::iterator it; - pair::iterator, - multimap::iterator> index; - // Build masks for request long long resource_oid_req = obj_type | AclRule::INDIVIDUAL_ID; long long resource_gid_req = obj_type | AclRule::GROUP_ID; @@ -1040,10 +986,7 @@ void AclManager::reverse_search(int uid, // Look for the rules that match // --------------------------------------------------- - vector user_reqs; - vector::iterator reqs_it; - - set::iterator g_it; + vector user_reqs; // rules that apply to everyone user_reqs.push_back(AclRule::ALL_ID); @@ -1052,72 +995,72 @@ void AclManager::reverse_search(int uid, user_reqs.push_back(AclRule::INDIVIDUAL_ID | uid); // rules that apply to each one of the user's groups - for (g_it = user_groups.begin(); g_it != user_groups.end(); g_it++) + for (auto g_it = user_groups.begin(); g_it != user_groups.end(); g_it++) { user_reqs.push_back(AclRule::GROUP_ID | *g_it); } all = false; - for (reqs_it = user_reqs.begin(); reqs_it != user_reqs.end(); reqs_it++) { - lock(); + lock_guard ul(acl_mutex); - index = acl_rules.equal_range( *reqs_it ); - - for ( it = index.first; it != index.second; it++) + for (auto r_it : user_reqs) { - // Rule grants the requested rights - if ( ( ( it->second->rights & rights_req ) == rights_req ) - && - // Rule applies in this zone or in all zones - ( ( it->second->zone == zone_oid_req ) - || - ( it->second->zone == zone_all_req ) - ) - ) - { - if (NebulaLog::log_level() >= Log::DDEBUG) - { - oss.str(""); - oss << "> Rule " << it->second->to_str(); - NebulaLog::log("ACL",Log::DDEBUG,oss); - } + auto index = acl_rules.equal_range( r_it ); - // Rule grants permission for all objects of this type - if ((!disable_all_acl) && - ((it->second->resource & resource_all_req) == resource_all_req)) + for (auto it = index.first; it != index.second; it++) + { + // Rule grants the requested rights + if ( ( ( it->second->rights & rights_req ) == rights_req ) + && + // Rule applies in this zone or in all zones + ( ( it->second->zone == zone_oid_req ) + || + ( it->second->zone == zone_all_req ) + ) + ) { - all = true; - break; - } - // Rule grants permission for all objects of a group - else if ((!disable_group_acl) && - ((it->second->resource & resource_gid_mask) == resource_gid_req)) - { - gids.push_back(it->second->resource_id()); - } - // Rule grants permission for all objects of a cluster - else if ((!disable_cluster_acl) && - ((it->second->resource & resource_cid_mask) == resource_cid_req)) - { - cids.push_back(it->second->resource_id()); - } - // Rule grants permission for an individual object - else if ((it->second->resource & resource_oid_mask) == resource_oid_req) - { - oids.push_back(it->second->resource_id()); + if (NebulaLog::log_level() >= Log::DDEBUG) + { + oss.str(""); + oss << "> Rule " << it->second->to_str(); + NebulaLog::log("ACL",Log::DDEBUG,oss); + } + + // Rule grants permission for all objects of this type + if ((!disable_all_acl) && + ((it->second->resource & resource_all_req) == resource_all_req)) + { + all = true; + break; + } + // Rule grants permission for all objects of a group + else if ((!disable_group_acl) && + ((it->second->resource & resource_gid_mask) == resource_gid_req)) + { + gids.push_back(it->second->resource_id()); + } + // Rule grants permission for all objects of a cluster + else if ((!disable_cluster_acl) && + ((it->second->resource & resource_cid_mask) == resource_cid_req)) + { + cids.push_back(it->second->resource_id()); + } + // Rule grants permission for an individual object + else if ((it->second->resource & resource_oid_mask) == resource_oid_req) + { + oids.push_back(it->second->resource_id()); + } } } - } - unlock(); - - if ( all == true ) - { - oids.clear(); - gids.clear(); - cids.clear(); + if ( all == true ) + { + oids.clear(); + gids.clear(); + cids.clear(); + } } } } @@ -1193,8 +1136,6 @@ int AclManager::select_cb(void *nil, int num, char **values, char **names) int AclManager::select() { - multimap::iterator it; - ostringstream oss; int rc; @@ -1202,20 +1143,20 @@ int AclManager::select() set_callback(static_cast(&AclManager::select_cb)); - lock(); - - for ( it = acl_rules.begin(); it != acl_rules.end(); it++ ) { - delete it->second; + lock_guard ul(acl_mutex); + + for (auto it = acl_rules.begin(); it != acl_rules.end(); it++) + { + delete it->second; + } + + acl_rules.clear(); + acl_rules_oids.clear(); + + rc = db->exec_rd(oss, this); } - acl_rules.clear(); - acl_rules_oids.clear(); - - rc = db->exec_rd(oss,this); - - unlock(); - unset_callback(); return rc; @@ -1266,22 +1207,19 @@ int AclManager::drop(int oid) int AclManager::dump(ostringstream& oss) { - map::iterator it; string xml; - lock(); + lock_guard ul(acl_mutex); oss << ""; - for ( it = acl_rules_oids.begin() ; it != acl_rules_oids.end(); it++ ) + for (auto& rule : acl_rules) { - oss << it->second->to_xml(xml); + oss << rule.second->to_xml(xml); } oss << ""; - unlock(); - return 0; } diff --git a/src/authm/AuthManager.cc b/src/authm/AuthManager.cc index ebaf706993..de844b49ac 100644 --- a/src/authm/AuthManager.cc +++ b/src/authm/AuthManager.cc @@ -120,32 +120,8 @@ void AuthRequest::add_auth(Operation op, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -extern "C" void * authm_action_loop(void *arg) -{ - AuthManager * authm; - - if ( arg == nullptr ) - { - return 0; - } - - authm = static_cast(arg); - - NebulaLog::log("AuM",Log::INFO,"Authorization Manager started."); - - authm->am.loop(authm->timer_period); - - NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped."); - - return 0; -} - -/* -------------------------------------------------------------------------- */ - int AuthManager::start() { - pthread_attr_t pattr; - using namespace std::placeholders; // for _1 register_action(AuthManagerMessages::UNDEFINED, @@ -171,132 +147,108 @@ int AuthManager::start() NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager..."); - pthread_attr_init(&pattr); - pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE); + Listener::start(); - int rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this); - - return rc; + return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void AuthManager::user_action(const ActionRequest& ar) +void AuthManager::trigger_authenticate(AuthRequest& ar) { - const AMAction& auth_ar = static_cast(ar); - AuthRequest * request = auth_ar.request(); + trigger([&] { + // ------------------------------------------------------------------------ + // Get the driver + // ------------------------------------------------------------------------ - if ( request == nullptr ) - { - return; - } + auto authm_md = get(); - switch (auth_ar.action()) - { - case AMAction::AUTHENTICATE: - authenticate_action(request); - break; + if (authm_md == nullptr) + { + ar.result = false; + ar.message = "Could not find Authorization driver"; + ar.notify(); - case AMAction::AUTHORIZE: - authorize_action(request); - break; - } + return; + } + + // ------------------------------------------------------------------------ + // Queue the request + // ------------------------------------------------------------------------ + + add_request(&ar); + + // ------------------------------------------------------------------------ + // Make the request to the driver + // ---- -------------------------------------------------------------------- + + ostringstream oss; + + oss << ar.uid << " " + << ar.driver << " " + << ar.username << " " + << ar.password << " " + << ar.session << " " << endl; + + auth_msg_t msg(AuthManagerMessages::AUTHENTICATE, "", ar.id, oss.str()); + + authm_md->write(msg); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void AuthManager::authenticate_action(AuthRequest * ar) +void AuthManager::trigger_authorize(AuthRequest& ar) { - // ------------------------------------------------------------------------ - // Get the driver - // ------------------------------------------------------------------------ + trigger([&] { + // ------------------------------------------------------------------------ + // Get the driver + // ------------------------------------------------------------------------ - auto authm_md = get(); + auto authm_md = get(); - if (authm_md == nullptr) - { - ar->result = false; - ar->message = "Could not find Authorization driver"; - ar->notify(); + if (authm_md == nullptr) + { + ar.message = "Could not find Authorization driver"; + ar.result = false; + ar.notify(); - return; - } + return; + } - // ------------------------------------------------------------------------ - // Queue the request - // ------------------------------------------------------------------------ + auto auths = ar.get_auths(); - add_request(ar); + if (auths.empty()) + { + ar.message = "Empty authorization string"; + ar.result = false; + ar.notify(); - // ------------------------------------------------------------------------ - // Make the request to the driver - // ---- -------------------------------------------------------------------- + return; + } - ostringstream oss; + // ------------------------------------------------------------------------ + // Queue the request + // ------------------------------------------------------------------------ - oss << ar->uid << " " - << ar->driver << " " - << ar->username << " " - << ar->password << " " - << ar->session << " " << endl; + add_request(&ar); - auth_msg_t msg(AuthManagerMessages::AUTHENTICATE, "", ar->id, oss.str()); + // ------------------------------------------------------------------------ + // Make the request to the driver + // ------------------------------------------------------------------------ - authm_md->write(msg); -} + ostringstream oss; -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ + oss << ar.uid << " " + << auths << " " + << ar.self_authorize << endl; -void AuthManager::authorize_action(AuthRequest * ar) -{ - // ------------------------------------------------------------------------ - // Get the driver - // ------------------------------------------------------------------------ + auth_msg_t msg(AuthManagerMessages::AUTHORIZE, "", ar.id, oss.str()); - auto authm_md = get(); - - if (authm_md == nullptr) - { - ar->message = "Could not find Authorization driver"; - ar->result = false; - ar->notify(); - - return; - } - - auto auths = ar->get_auths(); - - if (auths.empty()) - { - ar->message = "Empty authorization string"; - ar->result = false; - ar->notify(); - - return; - } - - // ------------------------------------------------------------------------ - // Queue the request - // ------------------------------------------------------------------------ - - add_request(ar); - - // ------------------------------------------------------------------------ - // Make the request to the driver - // ------------------------------------------------------------------------ - - ostringstream oss; - - oss << ar->uid << " " - << auths << " " - << ar->self_authorize << endl; - - auth_msg_t msg(AuthManagerMessages::AUTHORIZE, "", ar->id, oss.str()); - - authm_md->write(msg); + authm_md->write(msg); + }); } /* ************************************************************************** */ @@ -358,3 +310,13 @@ int AuthManager::load_drivers(const std::vector& _mads) return 0; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void AuthManager::finalize_action() +{ + timer_thread.stop(); + + DriverManager::stop(drivers_timeout); +} diff --git a/src/common/ActionManager.cc b/src/common/ActionManager.cc deleted file mode 100644 index bd13115684..0000000000 --- a/src/common/ActionManager.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* Copyright 2002-2020, OpenNebula Project, OpenNebula Systems */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ -/* not use this file except in compliance with the License. You may obtain */ -/* a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ -/* See the License for the specific language governing permissions and */ -/* limitations under the License. */ -/* -------------------------------------------------------------------------- */ - -#include "ActionManager.h" -#include -#include - -/* ************************************************************************** */ -/* ActionManager constructor & destructor */ -/* ************************************************************************** */ - -ActionManager::ActionManager(): listener(0) -{ - pthread_mutex_init(&mutex,0); - - pthread_cond_init(&cond,0); -} - -/* -------------------------------------------------------------------------- */ - -ActionManager::~ActionManager() -{ - while (!actions.empty()) - { - delete actions.front(); - actions.pop(); - } - - pthread_mutex_destroy(&mutex); - - pthread_cond_destroy(&cond); -} - -/* ************************************************************************** */ -/* NeActionManager public interface */ -/* ************************************************************************** */ - -void ActionManager::trigger(const ActionRequest& ar ) -{ - lock(); - - actions.push(ar.clone()); - - pthread_cond_signal(&cond); - - unlock(); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -static void set_timeout(struct timespec& timeout, struct timespec& _tout) -{ - clock_gettime(CLOCK_REALTIME, &timeout); - - timeout.tv_sec += _tout.tv_sec; - timeout.tv_nsec += _tout.tv_nsec; - - while ( timeout.tv_nsec >= 1000000000 ) - { - timeout.tv_sec += 1; - timeout.tv_nsec -= 1000000000; - } -} - -void ActionManager::loop(struct timespec& _tout, const ActionRequest& trequest) -{ - struct timespec timeout; - - int finalize = 0; - int rc; - - ActionRequest * action; - - set_timeout(timeout, _tout); - - //Action Loop, end when a finalize action is triggered to this manager - while (finalize == 0) - { - lock(); - - while ( actions.empty() == true ) - { - if ( _tout.tv_sec != 0 || _tout.tv_nsec != 0 ) - { - rc = pthread_cond_timedwait(&cond, &mutex, &timeout); - - if ( rc == ETIMEDOUT ) - actions.push(trequest.clone()); - } - else - pthread_cond_wait(&cond,&mutex); - } - - action = actions.front(); - actions.pop(); - - unlock(); - - listener->_do_action(*action); - - switch(action->type()) - { - case ActionRequest::TIMER: - set_timeout(timeout, _tout); - break; - - case ActionRequest::FINALIZE: - finalize = 1; - break; - - default: - break; - } - - delete action; - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ diff --git a/src/common/SConstruct b/src/common/SConstruct index 23d70edf85..4c1db316de 100644 --- a/src/common/SConstruct +++ b/src/common/SConstruct @@ -22,7 +22,6 @@ lib_name='nebula_common' # Sources to generate the library source_files=[ - 'ActionManager.cc', 'Attribute.cc', 'ExtendedAttribute.cc', 'NebulaService.cc', diff --git a/src/dm/DispatchManager.cc b/src/dm/DispatchManager.cc index 29fa7b3438..8ae23e2fb0 100644 --- a/src/dm/DispatchManager.cc +++ b/src/dm/DispatchManager.cc @@ -17,83 +17,19 @@ #include "DispatchManager.h" #include "Nebula.h" #include "NebulaLog.h" +#include "VirtualMachine.h" using namespace std; -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -extern "C" void * dm_action_loop(void *arg) -{ - DispatchManager * dm; - - if ( arg == 0 ) - { - return 0; - } - - dm = static_cast(arg); - - NebulaLog::log("DiM",Log::INFO,"Dispatch Manager started."); - - dm->am.loop(); - - NebulaLog::log("DiM",Log::INFO,"Dispatch Manager stopped."); - - return 0; -} - /* -------------------------------------------------------------------------- */ int DispatchManager::start() { - int rc; - pthread_attr_t pattr; - - pthread_attr_init (&pattr); - pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); - NebulaLog::log("DiM",Log::INFO,"Starting Dispatch Manager..."); - rc = pthread_create(&dm_thread, &pattr, dm_action_loop,(void *) this); + Listener::start(); - return rc; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void DispatchManager::user_action(const ActionRequest& ar) -{ - const DMAction& dm_ar = static_cast(ar); - int vid = dm_ar.vm_id(); - - switch (dm_ar.action()) - { - case DMAction::SUSPEND_SUCCESS: - suspend_success_action(vid); - break; - - case DMAction::STOP_SUCCESS: - stop_success_action(vid); - break; - - case DMAction::UNDEPLOY_SUCCESS: - undeploy_success_action(vid); - break; - - case DMAction::POWEROFF_SUCCESS: - poweroff_success_action(vid); - break; - - case DMAction::DONE: - done_action(vid); - break; - - case DMAction::RESUBMIT: - resubmit_action(vid); - break; - } + return 0; } /* -------------------------------------------------------------------------- */ diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 70d3ded629..1f92f2b85f 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -26,6 +26,7 @@ #include "Nebula.h" #include "ClusterPool.h" #include "HostPool.h" +#include "VirtualMachinePool.h" #include "VirtualRouterPool.h" using namespace std; @@ -75,7 +76,7 @@ int DispatchManager::deploy(VirtualMachine * vm, const RequestAttributes& ra) get_quota_template(vm, quota_tmpl, true); } - lcm->trigger(LCMAction::DEPLOY, vid, ra); + lcm->trigger_deploy(vid); } else { @@ -208,17 +209,17 @@ int DispatchManager::migrate(VirtualMachine * vm, int poff_migrate, { switch (poff_migrate) { case 0: - lcm->trigger(LCMAction::MIGRATE, vid, ra); + lcm->trigger_migrate(vid, ra); break; case 1: - lcm->trigger(LCMAction::POFF_MIGRATE, vid, ra); + lcm->trigger_migrate_poweroff(vid, ra); break; case 2: - lcm->trigger(LCMAction::POFF_HARD_MIGRATE, vid, ra); + lcm->trigger_migrate_poweroff_hard(vid, ra); break; default: /* Defaults to <5.8 behavior */ - lcm->trigger(LCMAction::MIGRATE, vid, ra); + lcm->trigger_migrate(vid, ra); break; } } @@ -260,7 +261,7 @@ int DispatchManager::live_migrate(VirtualMachine * vm, if (vm->get_state() == VirtualMachine::ACTIVE && vm->get_lcm_state() == VirtualMachine::RUNNING ) { - lcm->trigger(LCMAction::LIVE_MIGRATE, vid, ra); + lcm->trigger_live_migrate(vid, ra); } else { @@ -406,7 +407,7 @@ int DispatchManager::terminate(int vid, bool hard, const RequestAttributes& ra, case VirtualMachine::POWEROFF: case VirtualMachine::STOPPED: case VirtualMachine::UNDEPLOYED: - lcm->trigger(LCMAction::SHUTDOWN, vid, ra); + lcm->trigger_shutdown(vid, false, ra); vm->unlock(); break; @@ -427,14 +428,7 @@ int DispatchManager::terminate(int vid, bool hard, const RequestAttributes& ra, { case VirtualMachine::RUNNING: case VirtualMachine::UNKNOWN: - if (hard) - { - lcm->trigger(LCMAction::CANCEL, vid, ra); - } - else - { - lcm->trigger(LCMAction::SHUTDOWN, vid, ra); - } + lcm->trigger_shutdown(vid, hard, ra); break; case VirtualMachine::BOOT_FAILURE: @@ -451,7 +445,7 @@ int DispatchManager::terminate(int vid, bool hard, const RequestAttributes& ra, case VirtualMachine::PROLOG_RESUME_FAILURE: case VirtualMachine::PROLOG_UNDEPLOY_FAILURE: case VirtualMachine::PROLOG_MIGRATE_UNKNOWN_FAILURE: - lcm->trigger(LCMAction::DELETE, vid, ra); + lcm->trigger_delete(vid, ra); break; default: @@ -497,11 +491,11 @@ int DispatchManager::undeploy(int vid, bool hard, const RequestAttributes& ra, { if (hard) { - lcm->trigger(LCMAction::UNDEPLOY_HARD, vid, ra); + lcm->trigger_undeploy_hard(vid, ra); } else { - lcm->trigger(LCMAction::UNDEPLOY, vid, ra); + lcm->trigger_undeploy(vid, ra); } } else @@ -551,11 +545,11 @@ int DispatchManager::poweroff(int vid, bool hard, const RequestAttributes& ra, { if (hard) { - lcm->trigger(LCMAction::POWEROFF_HARD, vid, ra); + lcm->trigger_poweroff_hard(vid, ra); } else { - lcm->trigger(LCMAction::POWEROFF, vid, ra); + lcm->trigger_poweroff(vid, ra); } } else @@ -720,7 +714,7 @@ int DispatchManager::stop(int vid, const RequestAttributes& ra, (vm->get_state() == VirtualMachine::ACTIVE && vm->get_lcm_state() == VirtualMachine::RUNNING )) { - lcm->trigger(LCMAction::STOP, vid, ra); + lcm->trigger_stop(vid, ra); } else { @@ -766,7 +760,7 @@ int DispatchManager::suspend(int vid, const RequestAttributes& ra, if (vm->get_state() == VirtualMachine::ACTIVE && vm->get_lcm_state() == VirtualMachine::RUNNING ) { - lcm->trigger(LCMAction::SUSPEND, vid, ra); + lcm->trigger_suspend(vid, ra); } else { @@ -828,13 +822,13 @@ int DispatchManager::resume(int vid, const RequestAttributes& ra, } else if (vm->get_state() == VirtualMachine::SUSPENDED) { - lcm->trigger(LCMAction::RESTORE, vid, ra); + lcm->trigger_restore(vid, ra); } else if ( vm->get_state() == VirtualMachine::POWEROFF || (vm->get_state() == VirtualMachine::ACTIVE && vm->get_lcm_state() == VirtualMachine::UNKNOWN)) { - lcm->trigger(LCMAction::RESTART, vid, ra); + lcm->trigger_restart(vid, ra); } else { @@ -893,11 +887,11 @@ int DispatchManager::reboot(int vid, bool hard, const RequestAttributes& ra, { if (hard) { - vmm->trigger(VMMAction::RESET, vid); + vmm->trigger_reset(vid); } else { - vmm->trigger(VMMAction::REBOOT, vid); + vmm->trigger_reboot(vid); } vm->set_resched(false); //Rebooting cancels re-scheduling actions @@ -1016,11 +1010,11 @@ int DispatchManager::recover(VirtualMachine * vm, bool success, case VirtualMachine::CLONING_FAILURE: if (success) { - lcm->trigger(LCMAction::DISK_LOCK_SUCCESS, vid, ra); + lcm->trigger_disk_lock_success(vid); } else { - lcm->trigger(LCMAction::DISK_LOCK_FAILURE, vid, ra); + lcm->trigger_disk_lock_failure(vid); } break; @@ -1126,11 +1120,11 @@ int DispatchManager::delete_vm(VirtualMachine * vm, const RequestAttributes& ra, if (is_public_host) { - vmm->trigger(VMMAction::CLEANUP, vid); + vmm->trigger_cleanup(vid, false); } else { - tm->trigger(TMAction::EPILOG_DELETE, vid); + tm->trigger_epilog_delete(vm); } free_vm_resources(vm, true); @@ -1140,11 +1134,11 @@ int DispatchManager::delete_vm(VirtualMachine * vm, const RequestAttributes& ra, case VirtualMachine::UNDEPLOYED: if (is_public_host) { - vmm->trigger(VMMAction::CLEANUP, vid); + vmm->trigger_cleanup(vid, false); } else { - tm->trigger(TMAction::EPILOG_DELETE, vid); + tm->trigger_epilog_delete(vm); } free_vm_resources(vm, true); @@ -1159,7 +1153,7 @@ int DispatchManager::delete_vm(VirtualMachine * vm, const RequestAttributes& ra, break; case VirtualMachine::ACTIVE: - lcm->trigger(LCMAction::DELETE, vid, ra); + lcm->trigger_delete(vid, ra); vm->unlock(); break; @@ -1174,6 +1168,23 @@ int DispatchManager::delete_vm(VirtualMachine * vm, const RequestAttributes& ra, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int DispatchManager::delete_vm(int vid, const RequestAttributes& ra, + std::string& error_str) +{ + VirtualMachine * vm = vmpool->get(vid); + + if ( vm == nullptr ) + { + error_str = "Virtual machine does not exist"; + return -1; + } + + return delete_vm(vm, ra, error_str); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int DispatchManager::delete_recreate(VirtualMachine * vm, const RequestAttributes& ra, string& error) { @@ -1242,7 +1253,7 @@ int DispatchManager::delete_recreate(VirtualMachine * vm, break; case VirtualMachine::ACTIVE: //Cleanup VM resources before PENDING - lcm->trigger(LCMAction::DELETE_RECREATE, vm->get_oid(), ra); + lcm->trigger_delete_recreate(vm->get_oid(), ra); break; case VirtualMachine::DONE: @@ -1411,11 +1422,11 @@ int DispatchManager::attach(int vid, VirtualMachineTemplate * tmpl, if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG ) { - vmm->trigger(VMMAction::ATTACH, vid); + vmm->trigger_attach(vid); } else { - tm->trigger(TMAction::PROLOG_ATTACH, vid); + tm->trigger_prolog_attach(vm); } vmpool->update(vm); @@ -1479,14 +1490,14 @@ int DispatchManager::detach(int vid, int disk_id, const RequestAttributes& ra, { vm->set_state(VirtualMachine::HOTPLUG); - vmm->trigger(VMMAction::DETACH, vid); + vmm->trigger_detach(vid); } else { vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::HOTPLUG_EPILOG_POWEROFF); - tm->trigger(TMAction::EPILOG_DETACH, vid); + tm->trigger_epilog_detach(vm); } vmpool->update(vm); @@ -1540,7 +1551,7 @@ int DispatchManager::snapshot_create(int vid, string& name, int& snap_id, vm->unlock(); - vmm->trigger(VMMAction::SNAPSHOT_CREATE, vid); + vmm->trigger_snapshot_create(vid); return 0; } @@ -1603,7 +1614,7 @@ int DispatchManager::snapshot_revert(int vid, int snap_id, vm->unlock(); - vmm->trigger(VMMAction::SNAPSHOT_REVERT, vid); + vmm->trigger_snapshot_revert(vid); return 0; } @@ -1675,7 +1686,7 @@ int DispatchManager::snapshot_delete(int vid, int snap_id, vm->unlock(); - vmm->trigger(VMMAction::SNAPSHOT_DELETE, vid); + vmm->trigger_snapshot_delete(vid); return 0; } @@ -1781,7 +1792,7 @@ int DispatchManager::attach_nic(int vid, VirtualMachineTemplate* tmpl, if (vm->get_state() == VirtualMachine::ACTIVE) { - vmm->trigger(VMMAction::ATTACH_NIC, vid); + vmm->trigger_attach_nic(vid); } else { @@ -1890,7 +1901,7 @@ int DispatchManager::detach_nic(int vid, int nic_id, const RequestAttributes& ra vm->unlock(); - vmm->trigger(VMMAction::DETACH_NIC, vid); + vmm->trigger_detach_nic(vid); } else { @@ -1984,12 +1995,12 @@ int DispatchManager::disk_snapshot_create(int vid, int did, const string& name, { case VirtualMachine::POWEROFF: case VirtualMachine::SUSPENDED: - tm->trigger(TMAction::SNAPSHOT_CREATE, vid); + tm->trigger_snapshot_create(vid); break; case VirtualMachine::ACTIVE: - vmm->trigger(VMMAction::DISK_SNAPSHOT_CREATE, vid); + vmm->trigger_disk_snapshot_create(vid); break; default: break; @@ -2080,7 +2091,7 @@ int DispatchManager::disk_snapshot_revert(int vid, int did, int snap_id, vm->unlock(); - tm->trigger(TMAction::SNAPSHOT_REVERT, vid); + tm->trigger_snapshot_revert(vid); return 0; } @@ -2171,7 +2182,7 @@ int DispatchManager::disk_snapshot_delete(int vid, int did, int snap_id, close_cp_history(vmpool, vm, VMActions::DISK_SNAPSHOT_DELETE_ACTION, ra); - tm->trigger(TMAction::SNAPSHOT_DELETE, vid); + tm->trigger_snapshot_delete(vid); vmpool->update(vm); @@ -2254,11 +2265,11 @@ int DispatchManager::disk_resize(int vid, int did, long long new_size, { case VirtualMachine::POWEROFF: case VirtualMachine::UNDEPLOYED: - tm->trigger(TMAction::RESIZE, vid); + tm->trigger_resize(vid); break; case VirtualMachine::ACTIVE: - vmm->trigger(VMMAction::DISK_RESIZE, vid); + vmm->trigger_disk_resize(vid); break; default: break; @@ -2303,7 +2314,7 @@ int DispatchManager::live_updateconf(int vid, const RequestAttributes& ra, strin vm->set_resched(false); // Trigger UPDATE CONF action - vmm->trigger(VMMAction::UPDATE_CONF, vid); + vmm->trigger_update_conf(vid); vmpool->update(vm); vmpool->update_search(vm); diff --git a/src/dm/DispatchManagerStates.cc b/src/dm/DispatchManagerStates.cc index 66bed8ea2d..412a57b06d 100644 --- a/src/dm/DispatchManagerStates.cc +++ b/src/dm/DispatchManagerStates.cc @@ -18,319 +18,314 @@ #include "NebulaLog.h" #include "Quotas.h" #include "Nebula.h" +#include "VirtualMachinePool.h" using namespace std; -void DispatchManager::suspend_success_action(int vid) +void DispatchManager::trigger_suspend_success(int vid) { - VirtualMachine * vm; - VirtualMachineTemplate quota_tmpl; - string error_str; + trigger([this, vid] { + VirtualMachineTemplate quota_tmpl; + string error_str; - int uid, gid; + int uid, gid; - vm = vmpool->get(vid); + VirtualMachine * vm = vmpool->get(vid); - if ( vm == 0 ) - { - return; - } - - if ((vm->get_state() == VirtualMachine::ACTIVE) && - (vm->get_lcm_state() == VirtualMachine::SAVE_SUSPEND || - vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_SUSPEND || - vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_SUSPEND_FAILURE|| - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_SUSPENDED || - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_SUSPENDED|| - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED)) - { - get_quota_template(vm, quota_tmpl, true); - - vm->set_state(VirtualMachine::SUSPENDED); - - vm->set_state(VirtualMachine::LCM_INIT); - - vmpool->update(vm); - } - else - { - ostringstream oss; - - oss << "suspend_success action received but VM " << vid - << " not in ACTIVE state"; - NebulaLog::log("DiM",Log::ERROR,oss); - - vm->unlock(); - return; - } - - uid = vm->get_uid(); - gid = vm->get_gid(); - - vm->unlock(); - - Quotas::vm_del(uid, gid, "a_tmpl); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void DispatchManager::stop_success_action(int vid) -{ - VirtualMachine * vm; - VirtualMachineTemplate quota_tmpl; - string error_str; - - int uid, gid; - - vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if ((vm->get_state() == VirtualMachine::ACTIVE) && - (vm->get_lcm_state() == VirtualMachine::EPILOG_STOP || - vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME)) - { - get_quota_template(vm, quota_tmpl, true); - - vm->set_state(VirtualMachine::STOPPED); - - vm->set_state(VirtualMachine::LCM_INIT); - - //Set history action field to perform the right TM command on resume - if (vm->get_action() == VMActions::NONE_ACTION) + if (vm == nullptr) { - vm->set_internal_action(VMActions::STOP_ACTION); - - vmpool->update_history(vm); + return; } - vmpool->update(vm); - } - else - { - ostringstream oss; - - oss << "stop_success action received but VM " << vid - << " not in ACTIVE state"; - NebulaLog::log("DiM",Log::ERROR,oss); - vm->unlock(); - return; - } - - uid = vm->get_uid(); - gid = vm->get_gid(); - - vm->unlock(); - - Quotas::vm_del(uid, gid, "a_tmpl); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void DispatchManager::undeploy_success_action(int vid) -{ - VirtualMachine * vm; - VirtualMachineTemplate quota_tmpl; - string error_str; - - int uid, gid; - - vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if ((vm->get_state() == VirtualMachine::ACTIVE) && - (vm->get_lcm_state() == VirtualMachine::EPILOG_UNDEPLOY || - vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_UNDEPLOYED || - vm->get_lcm_state() == VirtualMachine::PROLOG_UNDEPLOY)) - { - get_quota_template(vm, quota_tmpl, true); - - vm->set_state(VirtualMachine::UNDEPLOYED); - - vm->set_state(VirtualMachine::LCM_INIT); - - //Set history action field to perform the right TM command on resume - if (vm->get_action() == VMActions::NONE_ACTION) + if ((vm->get_state() == VirtualMachine::ACTIVE) && + (vm->get_lcm_state() == VirtualMachine::SAVE_SUSPEND || + vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_SUSPEND || + vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_SUSPEND_FAILURE|| + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_SUSPENDED || + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_SUSPENDED|| + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED)) { - vm->set_internal_action(VMActions::UNDEPLOY_ACTION); + get_quota_template(vm, quota_tmpl, true); - vmpool->update_history(vm); + vm->set_state(VirtualMachine::SUSPENDED); + + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } + else + { + ostringstream oss; + + oss << "suspend_success action received but VM " << vid + << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + return; } - vmpool->update(vm); - } - else - { - ostringstream oss; - - oss << "undeploy_success action received but VM " << vid - << " not in ACTIVE state"; - NebulaLog::log("DiM",Log::ERROR,oss); + uid = vm->get_uid(); + gid = vm->get_gid(); vm->unlock(); - return; - } - uid = vm->get_uid(); - gid = vm->get_gid(); - - vm->unlock(); - - Quotas::vm_del(uid, gid, "a_tmpl); - - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void DispatchManager::poweroff_success_action(int vid) -{ - VirtualMachine * vm; - VirtualMachineTemplate quota_tmpl; - string error_str; - - int uid, gid; - - vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - VirtualMachine::LcmState prev_state = vm->get_lcm_state(); - - if ((vm->get_state() == VirtualMachine::ACTIVE) && - (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF || - vm->get_lcm_state() == VirtualMachine::HOTPLUG_PROLOG_POWEROFF || - vm->get_lcm_state() == VirtualMachine::HOTPLUG_EPILOG_POWEROFF || - vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF || - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF || - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF || - vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF || - vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_POWEROFF || - vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC_POWEROFF || - vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE)) - { - get_quota_template(vm, quota_tmpl, true); - - vm->set_state(VirtualMachine::POWEROFF); - - vm->set_state(VirtualMachine::LCM_INIT); - - vmpool->update(vm); - } - else - { - ostringstream oss; - - oss << "poweroff_success action received but VM " << vid - << " not in ACTIVE state"; - NebulaLog::log("DiM",Log::ERROR,oss); - - vm->unlock(); - return; - } - - uid = vm->get_uid(); - gid = vm->get_gid(); - - vm->unlock(); - - if (prev_state != VirtualMachine::DISK_SNAPSHOT_POWEROFF && - prev_state != VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF && - prev_state != VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF) - { Quotas::vm_del(uid, gid, "a_tmpl); - } - - return; + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void DispatchManager::done_action(int vid) +void DispatchManager::trigger_stop_success(int vid) { - VirtualMachine * vm; - string error_str; + trigger([this, vid] { + VirtualMachineTemplate quota_tmpl; + string error_str; - VirtualMachine::LcmState lcm_state; - VirtualMachine::VmState dm_state; + int uid, gid; - vm = vmpool->get(vid); + VirtualMachine * vm = vmpool->get(vid); - if ( vm == 0 ) - { - return; - } + if (vm == nullptr) + { + return; + } - lcm_state = vm->get_lcm_state(); - dm_state = vm->get_state(); + if ((vm->get_state() == VirtualMachine::ACTIVE) && + (vm->get_lcm_state() == VirtualMachine::EPILOG_STOP || + vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME)) + { + get_quota_template(vm, quota_tmpl, true); - if ((dm_state == VirtualMachine::ACTIVE) && - (lcm_state == VirtualMachine::EPILOG || - lcm_state == VirtualMachine::CLEANUP_DELETE)) - { - free_vm_resources(vm, true); - } - else - { - ostringstream oss; + vm->set_state(VirtualMachine::STOPPED); - oss << "done action received but VM " << vid << " not in ACTIVE state"; - NebulaLog::log("DiM",Log::ERROR,oss); + vm->set_state(VirtualMachine::LCM_INIT); + + //Set history action field to perform the right TM command on resume + if (vm->get_action() == VMActions::NONE_ACTION) + { + vm->set_internal_action(VMActions::STOP_ACTION); + + vmpool->update_history(vm); + } + + vmpool->update(vm); + } + else + { + ostringstream oss; + + oss << "stop_success action received but VM " << vid + << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + vm->unlock(); + return; + } + + uid = vm->get_uid(); + gid = vm->get_gid(); vm->unlock(); - } - return; + Quotas::vm_del(uid, gid, "a_tmpl); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void DispatchManager::resubmit_action(int vid) +void DispatchManager::trigger_undeploy_success(int vid) { - VirtualMachine * vm; + trigger([this, vid] { + VirtualMachineTemplate quota_tmpl; + string error_str; - vm = vmpool->get(vid); + int uid, gid; - if ( vm == 0 ) - { - return; - } + VirtualMachine * vm = vmpool->get(vid); - if (vm->get_lcm_state() == VirtualMachine::CLEANUP_RESUBMIT) - { - // Automatic requirements are not recalculated on purpose + if (vm == nullptr) + { + return; + } - vm->set_state(VirtualMachine::LCM_INIT); + if ((vm->get_state() == VirtualMachine::ACTIVE) && + (vm->get_lcm_state() == VirtualMachine::EPILOG_UNDEPLOY || + vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_UNDEPLOYED || + vm->get_lcm_state() == VirtualMachine::PROLOG_UNDEPLOY)) + { + get_quota_template(vm, quota_tmpl, true); - vm->set_state(VirtualMachine::PENDING); + vm->set_state(VirtualMachine::UNDEPLOYED); - vm->set_deploy_id(""); //reset the deploy-id + vm->set_state(VirtualMachine::LCM_INIT); - vmpool->update(vm); + //Set history action field to perform the right TM command on resume + if (vm->get_action() == VMActions::NONE_ACTION) + { + vm->set_internal_action(VMActions::UNDEPLOY_ACTION); + + vmpool->update_history(vm); + } + + vmpool->update(vm); + } + else + { + ostringstream oss; + + oss << "undeploy_success action received but VM " << vid + << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + return; + } + + uid = vm->get_uid(); + gid = vm->get_gid(); vm->unlock(); - } + + Quotas::vm_del(uid, gid, "a_tmpl); + }); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void DispatchManager::trigger_poweroff_success(int vid) +{ + trigger([this, vid] { + VirtualMachineTemplate quota_tmpl; + string error_str; + + int uid, gid; + + VirtualMachine * vm = vmpool->get(vid); + + if (vm == nullptr) + { + return; + } + + VirtualMachine::LcmState prev_state = vm->get_lcm_state(); + + if ((vm->get_state() == VirtualMachine::ACTIVE) && + (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF || + vm->get_lcm_state() == VirtualMachine::HOTPLUG_PROLOG_POWEROFF || + vm->get_lcm_state() == VirtualMachine::HOTPLUG_EPILOG_POWEROFF || + vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF || + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF || + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF || + vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF || + vm->get_lcm_state() == VirtualMachine::DISK_RESIZE_POWEROFF || + vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC_POWEROFF || + vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE)) + { + get_quota_template(vm, quota_tmpl, true); + + vm->set_state(VirtualMachine::POWEROFF); + + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } + else + { + ostringstream oss; + + oss << "poweroff_success action received but VM " << vid + << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + return; + } + + uid = vm->get_uid(); + gid = vm->get_gid(); + + vm->unlock(); + + if (prev_state != VirtualMachine::DISK_SNAPSHOT_POWEROFF && + prev_state != VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF && + prev_state != VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF) + { + Quotas::vm_del(uid, gid, "a_tmpl); + } + }); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void DispatchManager::trigger_done(int vid) +{ + trigger([this, vid] { + string error_str; + + VirtualMachine::LcmState lcm_state; + VirtualMachine::VmState dm_state; + + VirtualMachine * vm = vmpool->get(vid); + + if (vm == nullptr) + { + return; + } + + lcm_state = vm->get_lcm_state(); + dm_state = vm->get_state(); + + if ((dm_state == VirtualMachine::ACTIVE) && + (lcm_state == VirtualMachine::EPILOG || + lcm_state == VirtualMachine::CLEANUP_DELETE)) + { + free_vm_resources(vm, true); + } + else + { + ostringstream oss; + + oss << "done action received but VM " << vid << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + } + }); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void DispatchManager::trigger_resubmit(int vid) +{ + trigger([this, vid] { + VirtualMachine * vm = vmpool->get(vid); + + if (vm == nullptr) + { + return; + } + + if (vm->get_lcm_state() == VirtualMachine::CLEANUP_RESUBMIT) + { + // Automatic requirements are not recalculated on purpose + + vm->set_state(VirtualMachine::LCM_INIT); + + vm->set_state(VirtualMachine::PENDING); + + vm->set_deploy_id(""); //reset the deploy-id + + vmpool->update(vm); + + vm->unlock(); + } + }); } /* -------------------------------------------------------------------------- */ diff --git a/src/group/Group.cc b/src/group/Group.cc index 3549b06b4d..fd18fa831b 100644 --- a/src/group/Group.cc +++ b/src/group/Group.cc @@ -17,6 +17,7 @@ #include "Group.h" #include "Nebula.h" #include "AclManager.h" +#include "AclRule.h" #include "OneDB.h" #include diff --git a/src/hm/HookLog.cc b/src/hm/HookLog.cc index 22a2c8a62f..c4e696355c 100644 --- a/src/hm/HookLog.cc +++ b/src/hm/HookLog.cc @@ -262,7 +262,7 @@ int HookLog::retry(int hkid, int exeid, std::string& err_msg) string message = HookManager::format_message(args64, host, hkid); - hm->trigger(HMAction::RETRY, message); + hm->trigger_retry(message); return 0; } diff --git a/src/hm/HookManager.cc b/src/hm/HookManager.cc index c6043de6a9..abc9386e85 100644 --- a/src/hm/HookManager.cc +++ b/src/hm/HookManager.cc @@ -24,33 +24,8 @@ const char * HookManager::hook_driver_name = "hook_exe"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -extern "C" void * hm_action_loop(void *arg) -{ - HookManager * hm; - - if ( arg == nullptr ) - { - return 0; - } - - NebulaLog::log("HKM",Log::INFO,"Hook Manager started."); - - hm = static_cast(arg); - - hm->am.loop(); - - NebulaLog::log("HKM",Log::INFO,"Hook Manager stopped."); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int HookManager::start() { - pthread_attr_t pattr; - using namespace std::placeholders; // for _1 register_action(HookManagerMessages::UNDEFINED, @@ -74,12 +49,9 @@ int HookManager::start() NebulaLog::log("HKM",Log::INFO,"Starting Hook Manager..."); - pthread_attr_init(&pattr); - pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE); + Listener::start(); - int rc = pthread_create(&hm_thread,&pattr,hm_action_loop,(void *) this); - - return rc; + return 0; } /* -------------------------------------------------------------------------- */ @@ -120,52 +92,37 @@ int HookManager::load_drivers(const std::vector& _mads) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void HookManager::user_action(const ActionRequest& ar) +void HookManager::trigger_send_event(const std::string& message) { - const HMAction& hm_ar = static_cast(ar); - const std::string& message = hm_ar.message(); + trigger([this, message] { + auto hmd = get(); - switch (hm_ar.action()) - { - case HMAction::SEND_EVENT: - send_event_action(message); - break; - case HMAction::RETRY: - retry_action(message); - break; - } + if ( hmd == nullptr ) + { + return; + } + + hook_msg_t msg(HookManagerMessages::EXECUTE, "", -1, message); + hmd->write(msg); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void HookManager::send_event_action(const std::string& message) +void HookManager::trigger_retry(const std::string& message) { - auto hmd = get(); + trigger([this, message] { + auto hmd = get(); - if ( hmd == nullptr ) - { - return; - } + if ( hmd == nullptr ) + { + return; + } - hook_msg_t msg(HookManagerMessages::EXECUTE, "", -1, message); - hmd->write(msg); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void HookManager::retry_action(const std::string& message) -{ - auto hmd = get(); - - if ( hmd == nullptr ) - { - return; - } - - hook_msg_t msg(HookManagerMessages::RETRY, "", -1, message); - hmd->write(msg); + hook_msg_t msg(HookManagerMessages::RETRY, "", -1, message); + hmd->write(msg); + }); } /* -------------------------------------------------------------------------- */ diff --git a/src/hm/HookStateVM.cc b/src/hm/HookStateVM.cc index 86f6dbe26d..a002a254fa 100644 --- a/src/hm/HookStateVM.cc +++ b/src/hm/HookStateVM.cc @@ -17,6 +17,7 @@ #include "HookStateVM.h" #include "VirtualMachine.h" #include "NebulaUtil.h" +#include "SSLUtil.h" using namespace std; diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index a73c69a9ac..6ea98f8285 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -102,7 +102,7 @@ int HostPool::allocate ( { std::string event = HookStateHost::format_message(host); - Nebula::instance().get_hm()->trigger(HMAction::SEND_EVENT, event); + Nebula::instance().get_hm()->trigger_send_event(event); auto *im = Nebula::instance().get_im(); im->update_host(host); @@ -148,7 +148,7 @@ int HostPool::update(PoolObjectSQL * objsql) { std::string event = HookStateHost::format_message(host); - Nebula::instance().get_hm()->trigger(HMAction::SEND_EVENT, event); + Nebula::instance().get_hm()->trigger_send_event(event); } host->set_prev_state(); diff --git a/src/im/InformationManager.cc b/src/im/InformationManager.cc index f9d6bb3dc9..35a148a5c7 100644 --- a/src/im/InformationManager.cc +++ b/src/im/InformationManager.cc @@ -31,6 +31,8 @@ int InformationManager::start() using namespace std::placeholders; // for _1 + NebulaLog::info("InM", "Starting Information Manager..."); + register_action(InformationManagerMessages::UNDEFINED, &InformationManager::_undefined); @@ -51,16 +53,6 @@ int InformationManager::start() return -1; } - NebulaLog::info("InM", "Starting Information Manager..."); - - im_thread = std::thread([&] { - NebulaLog::info("InM", "Information Manager started."); - - am.loop(); - - NebulaLog::info("InM", "Information Manager stopped."); - }); - auto rftm = Nebula::instance().get_raftm(); raft_status(rftm->get_state()); @@ -265,7 +257,7 @@ void InformationManager::_host_state(unique_ptr msg) for (const auto& vmid : host->get_vm_ids()) { - lcm->trigger(LCMAction::MONITOR_DONE, vmid); + lcm->trigger_monitor_done(vmid); } } else @@ -334,10 +326,12 @@ void InformationManager::_host_system(unique_ptr msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -static LCMAction::Actions test_and_trigger(const string& state_str, - VirtualMachine::VmState state, VirtualMachine::LcmState lcm_state, - string& vm_message) +static void test_and_trigger(const string& state_str, VirtualMachine * vm) { + auto state = vm->get_state(); + auto lcm_state = vm->get_lcm_state(); + auto lcm = Nebula::instance().get_lcm(); + if (state_str == "RUNNING") { if (state == VirtualMachine::POWEROFF || @@ -356,7 +350,8 @@ static LCMAction::Actions test_and_trigger(const string& state_str, lcm_state == VirtualMachine::BOOT_UNDEPLOY_FAILURE || lcm_state == VirtualMachine::BOOT_FAILURE))) { - return LCMAction::MONITOR_POWERON; + lcm->trigger_monitor_poweron(vm->get_oid()); + return; } } else if (state_str == "FAILURE") @@ -365,9 +360,12 @@ static LCMAction::Actions test_and_trigger(const string& state_str, (lcm_state == VirtualMachine::RUNNING || lcm_state == VirtualMachine::UNKNOWN)) { - vm_message = "VM running but monitor state is ERROR."; + lcm->trigger_monitor_done(vm->get_oid()); - return LCMAction::MONITOR_DONE; + vm->log("VMM", Log::INFO, + "VM running but monitor state is ERROR."); + + return; } } else if (state_str == "SUSPENDED") @@ -376,9 +374,12 @@ static LCMAction::Actions test_and_trigger(const string& state_str, (lcm_state == VirtualMachine::RUNNING || lcm_state == VirtualMachine::UNKNOWN)) { - vm_message = "VM running but monitor state is PAUSED."; + lcm->trigger_monitor_suspend(vm->get_oid()); - return LCMAction::MONITOR_SUSPEND; + vm->log("VMM", Log::INFO, + "VM running but monitor state is PAUSED."); + + return; } } else if (state_str == "POWEROFF") @@ -390,11 +391,10 @@ static LCMAction::Actions test_and_trigger(const string& state_str, lcm_state == VirtualMachine::SHUTDOWN_POWEROFF || lcm_state == VirtualMachine::SHUTDOWN_UNDEPLOY)) { - return LCMAction::MONITOR_POWEROFF; + lcm->trigger_monitor_poweroff(vm->get_oid()); + return; } } - - return LCMAction::NONE; } @@ -424,7 +424,6 @@ void InformationManager::_vm_state(unique_ptr msg) string deploy_id; string state_str; - string vm_msg; vector vms; tmpl.get("VM", vms); @@ -483,18 +482,7 @@ void InformationManager::_vm_state(unique_ptr msg) /* ------------------------------------------------------------------ */ /* Apply state changes */ /* ------------------------------------------------------------------ */ - LCMAction::Actions action = test_and_trigger(state_str, vm->get_state(), - vm->get_lcm_state(), vm_msg); - - if ( action != LCMAction::NONE ) - { - lcm->trigger(action, vm->get_oid()); - - if ( !vm_msg.empty() ) - { - vm->log("VMM", Log::INFO, vm_msg); - } - } + test_and_trigger(state_str, vm); vm->unlock(); } @@ -562,26 +550,18 @@ void InformationManager::_vm_state(unique_ptr msg) continue; } - LCMAction::Actions action; - - if ( missing_state == "POWEROFF" ) - { - action = LCMAction::MONITOR_POWEROFF; - } - else if ( missing_state == "UNKNOWN" ) - { - action = LCMAction::MONITOR_DONE; - } - else - { - action = LCMAction::MONITOR_POWEROFF; - } - NebulaLog::debug("InM", "VM_STATE update from host: " + to_string(msg->oid()) + ". VM id: " + to_string(vm->get_oid()) + ", state: " + missing_state); - lcm->trigger(action, vm->get_oid()); + if (missing_state == "UNKNOWN") + { + lcm->trigger_monitor_done(vm->get_oid()); + } + else + { + lcm->trigger_monitor_poweroff(vm->get_oid()); + } vm->unlock(); } diff --git a/src/image/Image.cc b/src/image/Image.cc index 913781d25a..b61f214fa2 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -848,7 +848,7 @@ void Image::set_state(ImageState _state) for (set::iterator i = vms.begin(); i != vms.end(); i++) { - lcm->trigger(LCMAction::DISK_LOCK_FAILURE, *i); + lcm->trigger_disk_lock_failure(*i); } } else if (state == LOCKED) @@ -918,7 +918,7 @@ void Image::set_state_unlock() for (set::iterator i = vms.begin(); i != vms.end(); i++) { - lcm->trigger(LCMAction::DISK_LOCK_SUCCESS, *i); + lcm->trigger_disk_lock_success(*i); } } } diff --git a/src/image/ImageManager.cc b/src/image/ImageManager.cc index 623fe64fb2..af848b50df 100644 --- a/src/image/ImageManager.cc +++ b/src/image/ImageManager.cc @@ -27,29 +27,6 @@ const char * ImageManager::image_driver_name = "image_exe"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -extern "C" void * image_action_loop(void *arg) -{ - ImageManager * im; - - if ( arg == 0 ) - { - return 0; - } - - NebulaLog::log("ImM",Log::INFO,"Image Manager started."); - - im = static_cast(arg); - - im->am.loop(im->timer_period); - - NebulaLog::log("ImM",Log::INFO,"Image Manager stopped."); - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int ImageManager::load_drivers(const std::vector& _mads) { const VectorAttribute * vattr = 0; @@ -87,9 +64,6 @@ int ImageManager::load_drivers(const std::vector& _mads) int ImageManager::start() { - int rc; - pthread_attr_t pattr; - using namespace std::placeholders; // for _1 register_action(ImageManagerMessages::UNDEFINED, @@ -135,18 +109,13 @@ int ImageManager::start() return -1; } - pthread_attr_init(&pattr); - pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE); - - rc = pthread_create(&imagem_thread,&pattr,image_action_loop,(void *) this); - - return rc; + return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::timer_action(const ActionRequest& ar) +void ImageManager::timer_action() { static int mark = 0; static int tics = monitor_period; diff --git a/src/image/ImageManagerProtocol.cc b/src/image/ImageManagerProtocol.cc index 770e5431f7..1afd08f9df 100644 --- a/src/image/ImageManagerProtocol.cc +++ b/src/image/ImageManagerProtocol.cc @@ -314,7 +314,7 @@ void ImageManager::_mkfs(unique_ptr msg) goto error_save_state; } - tm->trigger(TMAction::SAVEAS_HOT, vm_id); + tm->trigger_saveas_hot(vm_id); vmpool->update(vm); diff --git a/src/ipamm/IPAMManager.cc b/src/ipamm/IPAMManager.cc index bd281139f1..d88e42c42e 100644 --- a/src/ipamm/IPAMManager.cc +++ b/src/ipamm/IPAMManager.cc @@ -24,35 +24,10 @@ using std::string; const char * IPAMManager::ipam_driver_name = "ipam_exe"; -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -extern "C" void * ipamm_action_loop(void *arg) -{ - IPAMManager * ipamm; - - if ( arg == nullptr ) - { - return 0; - } - - ipamm = static_cast(arg); - - NebulaLog::log("IPM",Log::INFO,"IPAM Manager started."); - - ipamm->am.loop(ipamm->timer_period); - - NebulaLog::log("IPM",Log::INFO,"IPAM Manager stopped."); - - return 0; -} - /* -------------------------------------------------------------------------- */ int IPAMManager::start() { - pthread_attr_t pattr; - using namespace std::placeholders; // for _1 register_action(IPAMManagerMessages::UNDEFINED, @@ -85,110 +60,79 @@ int IPAMManager::start() NebulaLog::log("IPM",Log::INFO,"Starting IPAM Manager..."); - pthread_attr_init(&pattr); - pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE); + Listener::start(); - int rc = pthread_create(&ipamm_thread, &pattr, ipamm_action_loop, (void *)this); - - return rc; + return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void IPAMManager::user_action(const ActionRequest& ar) -{ - const IPMAction& ipam_ar = static_cast(ar); - - IPAMRequest * request = ipam_ar.request(); - - if ( request == nullptr ) - { - return; - } - - switch(ipam_ar.action()) - { - case IPMAction::REGISTER_ADDRESS_RANGE: - register_address_range_action(request); - break; - - case IPMAction::UNREGISTER_ADDRESS_RANGE: - unregister_address_range_action(request); - break; - - case IPMAction::ALLOCATE_ADDRESS: - allocate_address_action(request); - break; - - case IPMAction::GET_ADDRESS: - get_address_action(request); - break; - - case IPMAction::FREE_ADDRESS: - free_address_action(request); - break; - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void IPAMManager::send_request(IPAMManagerMessages type, IPAMRequest * ir) +void IPAMManager::send_request(IPAMManagerMessages type, IPAMRequest& ir) { auto ipammd = get(); if (ipammd == nullptr) { - ir->result = false; - ir->message = "Could not find the IPAM driver"; + ir.result = false; + ir.message = "Could not find the IPAM driver"; - ir->notify(); + ir.notify(); return; } - add_request(ir); + add_request(&ir); string action_data; - ipam_msg_t msg(type, "", ir->id, ir->to_xml64(action_data)); + ipam_msg_t msg(type, "", ir.id, ir.to_xml64(action_data)); ipammd->write(msg); } /* -------------------------------------------------------------------------- */ -void IPAMManager::register_address_range_action(IPAMRequest * ir) +void IPAMManager::trigger_register_address_range(IPAMRequest& ir) { - send_request(IPAMManagerMessages::REGISTER_ADDRESS_RANGE, ir); + trigger([&] { + send_request(IPAMManagerMessages::REGISTER_ADDRESS_RANGE, ir); + }); } /* -------------------------------------------------------------------------- */ -void IPAMManager::unregister_address_range_action(IPAMRequest * ir) +void IPAMManager::trigger_unregister_address_range(IPAMRequest& ir) { - send_request(IPAMManagerMessages::UNREGISTER_ADDRESS_RANGE, ir); + trigger([&] { + send_request(IPAMManagerMessages::UNREGISTER_ADDRESS_RANGE, ir); + }); } /* -------------------------------------------------------------------------- */ -void IPAMManager::get_address_action(IPAMRequest * ir) +void IPAMManager::trigger_get_address(IPAMRequest& ir) { - send_request(IPAMManagerMessages::GET_ADDRESS, ir); + trigger([&] { + send_request(IPAMManagerMessages::GET_ADDRESS, ir); + }); } /* -------------------------------------------------------------------------- */ -void IPAMManager::allocate_address_action(IPAMRequest * ir) +void IPAMManager::trigger_allocate_address(IPAMRequest& ir) { - send_request(IPAMManagerMessages::ALLOCATE_ADDRESS, ir); + trigger([&] { + send_request(IPAMManagerMessages::ALLOCATE_ADDRESS, ir); + }); } /* -------------------------------------------------------------------------- */ -void IPAMManager::free_address_action(IPAMRequest * ir) +void IPAMManager::trigger_free_address(IPAMRequest& ir) { - send_request(IPAMManagerMessages::FREE_ADDRESS, ir); + trigger([&] { + send_request(IPAMManagerMessages::FREE_ADDRESS, ir); + }); } /* ************************************************************************** */ diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 58cb8624b2..c5d7fd5555 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -22,952 +22,963 @@ #include "HostPool.h" #include "ImagePool.h" #include "SecurityGroupPool.h" +#include "VirtualMachinePool.h" #include "Request.h" using namespace std; -void LifeCycleManager::deploy_action(const LCMAction& la) +void LifeCycleManager::trigger_deploy(int vid) { - VirtualMachine * vm; - ostringstream os; + trigger([this, vid] { + ostringstream os; - int vid = la.vm_id(); + VirtualMachine * vm = vmpool->get(vid); - vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if ( vm->get_state() == VirtualMachine::ACTIVE ) - { - HostShareCapacity sr; - - time_t thetime = time(0); - int rc; - - VirtualMachine::LcmState vm_state; - TMAction::Actions tm_action; - - //---------------------------------------------------- - // PROLOG STATE - //---------------------------------------------------- - - vm->get_capacity(sr); - - vm_state = VirtualMachine::PROLOG; - tm_action = TMAction::PROLOG; - - if (vm->hasPreviousHistory()) + if ( vm == nullptr ) { - if (vm->get_previous_action() == VMActions::STOP_ACTION) - { - vm_state = VirtualMachine::PROLOG_RESUME; - tm_action = TMAction::PROLOG_RESUME; - } - else if (vm->get_previous_action() == VMActions::UNDEPLOY_ACTION || - vm->get_previous_action() == VMActions::UNDEPLOY_HARD_ACTION) - { - vm_state = VirtualMachine::PROLOG_UNDEPLOY; - tm_action = TMAction::PROLOG_RESUME; - } + return; } - vm->set_state(vm_state); - - rc = hpool->add_capacity(vm->get_hid(), sr); - - vm->set_stime(thetime); - - vm->set_prolog_stime(thetime); - - vmpool->update_history(vm); - - vmpool->update(vm); - - if ( rc == -1) + if ( vm->get_state() == VirtualMachine::ACTIVE ) { - //The host has been deleted, move VM to FAILURE - this->trigger(LCMAction::PROLOG_FAILURE, vid); + HostShareCapacity sr; + + time_t thetime = time(0); + int rc; + + VirtualMachine::LcmState vm_state; + + //---------------------------------------------------- + // PROLOG STATE + //---------------------------------------------------- + + vm->get_capacity(sr); + + vm_state = VirtualMachine::PROLOG; + + void (TransferManager::*tm_action)(VirtualMachine *) = + &TransferManager::trigger_prolog; + + if (vm->hasPreviousHistory()) + { + if (vm->get_previous_action() == VMActions::STOP_ACTION) + { + vm_state = VirtualMachine::PROLOG_RESUME; + tm_action = &TransferManager::trigger_prolog_resume; + } + else if (vm->get_previous_action() == VMActions::UNDEPLOY_ACTION || + vm->get_previous_action() == VMActions::UNDEPLOY_HARD_ACTION) + { + vm_state = VirtualMachine::PROLOG_UNDEPLOY; + tm_action = &TransferManager::trigger_prolog_resume; + } + } + + vm->set_state(vm_state); + + rc = hpool->add_capacity(vm->get_hid(), sr); + + vm->set_stime(thetime); + + vm->set_prolog_stime(thetime); + + vmpool->update_history(vm); + + vmpool->update(vm); + + if ( rc == -1) + { + //The host has been deleted, move VM to FAILURE + trigger_prolog_failure(vid); + } + else + { + (tm->*tm_action)(vm); + } } else { - tm->trigger(tm_action, vid); + vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state."); } - } - else - { - vm->log("LCM", Log::ERROR, "deploy_action, VM in a wrong state."); - } - vm->unlock(); - - return; + vm->unlock(); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::suspend_action(const LCMAction& la) +void LifeCycleManager::trigger_suspend(int vid, const RequestAttributes& ra) { - int vid = la.vm_id(); + int uid = ra.uid; + int gid = ra.gid; + int req_id = ra.req_id; - VirtualMachine * vm = vmpool->get(vid); + trigger([this, vid, uid, gid, req_id] { + VirtualMachine * vm = vmpool->get(vid); - if ( vm == 0 ) - { - return; - } + if ( vm == nullptr ) + { + return; + } - if (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::RUNNING) - { - //---------------------------------------------------- - // SAVE_SUSPEND STATE - //---------------------------------------------------- + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) + { + //---------------------------------------------------- + // SAVE_SUSPEND STATE + //---------------------------------------------------- - vm->set_state(VirtualMachine::SAVE_SUSPEND); + vm->set_state(VirtualMachine::SAVE_SUSPEND); - vm->set_resched(false); + vm->set_resched(false); - vm->set_action(VMActions::SUSPEND_ACTION, la.uid(), la.gid(), la.req_id()); + vm->set_action(VMActions::SUSPEND_ACTION, uid, gid, req_id); - vmpool->update_history(vm); + vmpool->update_history(vm); - vmpool->update(vm); + vmpool->update(vm); - //---------------------------------------------------- + //---------------------------------------------------- - vmm->trigger(VMMAction::SAVE,vid); - } - else - { - vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state."); - } + vmm->trigger_save(vid); + } + else + { + vm->log("LCM", Log::ERROR, "suspend_action, VM in a wrong state."); + } - vm->unlock(); - - return; + vm->unlock(); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::stop_action(const LCMAction& la) +void LifeCycleManager::trigger_stop(int vid, const RequestAttributes& ra) { - int vid = la.vm_id(); + int uid = ra.uid; + int gid = ra.gid; + int req_id = ra.req_id; - VirtualMachine * vm = vmpool->get(vid); + trigger([this, vid, uid, gid, req_id] { + VirtualMachine * vm = vmpool->get(vid); - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::RUNNING) - { - //---------------------------------------------------- - // SAVE_STOP STATE - //---------------------------------------------------- - - vm->set_state(VirtualMachine::SAVE_STOP); - - vm->set_resched(false); - - vm->set_action(VMActions::STOP_ACTION, la.uid(), la.gid(), la.req_id()); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - vmm->trigger(VMMAction::SAVE,vid); - } - else if (vm->get_state() == VirtualMachine::SUSPENDED) - { - //---------------------------------------------------- - // Bypass SAVE_STOP - //---------------------------------------------------- - vm->set_state(VirtualMachine::ACTIVE); - vm->set_state(VirtualMachine::EPILOG_STOP); - - vm->set_action(VMActions::STOP_ACTION, la.uid(), la.gid(), la.req_id()); - - vm->set_epilog_stime(time(0)); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - tm->trigger(TMAction::EPILOG_STOP,vid); - } - else - { - vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::migrate_action(const LCMAction& la) -{ - HostShareCapacity sr; - - time_t the_time = time(0); - - int vid = la.vm_id(); - - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::RUNNING) - { - //---------------------------------------------------- - // SAVE_MIGRATE STATE - //---------------------------------------------------- - - VMActions::Action action; - - switch (la.action()) + if ( vm == nullptr ) { - case LCMAction::POFF_MIGRATE : - action = VMActions::POFF_MIGRATE_ACTION; - break; - case LCMAction::POFF_HARD_MIGRATE : - action = VMActions::POFF_HARD_MIGRATE_ACTION; - break; - default : - action = VMActions::MIGRATE_ACTION; - break; + return; } - vm->set_state(VirtualMachine::SAVE_MIGRATE); - - vm->set_resched(false); - - vm->get_capacity(sr); - - hpool->add_capacity(vm->get_hid(), sr); - - vm->set_stime(the_time); - - vm->set_action(action, la.uid(), la.gid(), la.req_id()); - - vmpool->update_history(vm); - - vm->set_previous_action(action, la.uid(), la.gid(), la.req_id()); - - vmpool->update_previous_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - switch (la.action()) + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) { - case LCMAction::POFF_MIGRATE : - vmm->trigger(VMMAction::SHUTDOWN,vid); - break; - case LCMAction::POFF_HARD_MIGRATE : - vmm->trigger(VMMAction::CANCEL,vid); - break; - default : - vmm->trigger(VMMAction::SAVE,vid); - break; - } + //---------------------------------------------------- + // SAVE_STOP STATE + //---------------------------------------------------- - } - else if (vm->get_state() == VirtualMachine::POWEROFF || - vm->get_state() == VirtualMachine::SUSPENDED || - (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::UNKNOWN )) - { - //---------------------------------------------------------------------- - // Bypass SAVE_MIGRATE & go to PROLOG_MIGRATE_POWEROFF/SUSPENDED/UNKNOWN - //---------------------------------------------------------------------- - if (vm->get_state() == VirtualMachine::POWEROFF) - { - vm->set_state(VirtualMachine::PROLOG_MIGRATE_POWEROFF); + vm->set_state(VirtualMachine::SAVE_STOP); + + vm->set_resched(false); + + vm->set_action(VMActions::STOP_ACTION, uid, gid, req_id); + + vmpool->update_history(vm); + + vmpool->update(vm); + + //---------------------------------------------------- + + vmm->trigger_save(vid); } else if (vm->get_state() == VirtualMachine::SUSPENDED) { - vm->set_state(VirtualMachine::PROLOG_MIGRATE_SUSPEND); + //---------------------------------------------------- + // Bypass SAVE_STOP + //---------------------------------------------------- + vm->set_state(VirtualMachine::ACTIVE); + vm->set_state(VirtualMachine::EPILOG_STOP); + + vm->set_action(VMActions::STOP_ACTION, uid, gid, req_id); + + vm->set_epilog_stime(time(0)); + + vmpool->update_history(vm); + + vmpool->update(vm); + + //---------------------------------------------------- + + tm->trigger_epilog_stop(vm); } - else //VirtualMachine::UNKNOWN + else { - vm->set_state(VirtualMachine::PROLOG_MIGRATE_UNKNOWN); - - vm->set_previous_action(VMActions::MIGRATE_ACTION, la.uid(), - la.gid(), la.req_id()); + vm->log("LCM", Log::ERROR, "stop_action, VM in a wrong state."); } - vm->set_previous_running_etime(the_time); - - vm->set_previous_etime(the_time); - - vmpool->update_previous_history(vm); - - vm->set_state(VirtualMachine::ACTIVE); - - vm->set_resched(false); - - if ( !vmm->is_keep_snapshots(vm->get_vmm_mad()) ) - { - vm->delete_snapshots(); - } - - vm->set_action(VMActions::MIGRATE_ACTION, la.uid(), la.gid(), la.req_id()); - - vm->get_capacity(sr); - - hpool->add_capacity(vm->get_hid(), sr); - - if ( vm->get_hid() != vm->get_previous_hid() ) - { - hpool->del_capacity(vm->get_previous_hid(), sr); - } - - vm->set_stime(the_time); - - vm->set_prolog_stime(the_time); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - tm->trigger(TMAction::PROLOG_MIGR,vid); - } - else - { - vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state."); - } - - vm->unlock(); - - return; + vm->unlock(); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::live_migrate_action(const LCMAction& la) +void LifeCycleManager::trigger_migrate(int vid, const RequestAttributes& ra, + VMActions::Action vm_action) { - ostringstream os; + int uid = ra.uid; + int gid = ra.gid; + int req_id = ra.req_id; - int vid = la.vm_id(); - - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::RUNNING) - { + trigger([this, vid, uid, gid, req_id, vm_action] { HostShareCapacity sr; - //---------------------------------------------------- - // MIGRATE STATE - //---------------------------------------------------- - - vm->set_state(VirtualMachine::MIGRATE); - - vm->set_resched(false); - - vm->get_capacity(sr); - - hpool->add_capacity(vm->get_hid(), sr); - - vm->set_stime(time(0)); - - vmpool->update_history(vm); - - vm->set_previous_action(VMActions::LIVE_MIGRATE_ACTION, la.uid(),la.gid(), - la.req_id()); - - vmpool->update_previous_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - vmm->trigger(VMMAction::MIGRATE,vid); - } - else - { - vm->log("LCM", Log::ERROR, "live_migrate_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::shutdown_action(const LCMAction& la, bool hard) -{ - int vid = la.vm_id(); - VirtualMachine * vm = vmpool->get(vid); - VirtualMachineTemplate quota_tmpl; - string error; - - if ( vm == 0 ) - { - return; - } - - int uid = vm->get_uid(); - int gid = vm->get_gid(); - - std::string memory, cpu; - - vm->get_template_attribute("MEMORY", memory); - vm->get_template_attribute("CPU", cpu); - - if ( (vm->get_state() == VirtualMachine::SUSPENDED) || - (vm->get_state() == VirtualMachine::POWEROFF) || - (vm->get_state() == VirtualMachine::STOPPED) || - (vm->get_state() == VirtualMachine::UNDEPLOYED)) - { - quota_tmpl.add("RUNNING_MEMORY", memory); - quota_tmpl.add("RUNNING_CPU", cpu); - quota_tmpl.add("RUNNING_VMS", 1); - - quota_tmpl.add("MEMORY", 0); - quota_tmpl.add("CPU", 0); - quota_tmpl.add("VMS", 0); - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - (vm->get_lcm_state() == VirtualMachine::RUNNING || - vm->get_lcm_state() == VirtualMachine::UNKNOWN)) - { - //---------------------------------------------------- - // SHUTDOWN STATE - //---------------------------------------------------- - - vm->set_state(VirtualMachine::SHUTDOWN); - - if (hard) - { - vm->set_action(VMActions::TERMINATE_HARD_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::CANCEL,vid); - } - else - { - vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::SHUTDOWN,vid); - } - - vm->set_resched(false); - - vmpool->update_history(vm); - - vmpool->update(vm); - } - else if (vm->get_state() == VirtualMachine::SUSPENDED || - vm->get_state() == VirtualMachine::POWEROFF) - { - vm->set_state(VirtualMachine::ACTIVE); - vm->set_state(VirtualMachine::EPILOG); - - Quotas::vm_check(uid, gid, "a_tmpl, error); - - vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), - la.req_id()); - - vm->set_epilog_stime(time(0)); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - tm->trigger(TMAction::EPILOG, vid); - } - else if (vm->get_state() == VirtualMachine::STOPPED || - vm->get_state() == VirtualMachine::UNDEPLOYED) - { - vm->set_state(VirtualMachine::ACTIVE); - vm->set_state(VirtualMachine::EPILOG); - - Quotas::vm_check(uid, gid, "a_tmpl, error); - - vm->set_action(VMActions::TERMINATE_ACTION, la.uid(), la.gid(), - la.req_id()); - - vm->set_epilog_stime(time(0)); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - tm->trigger(TMAction::EPILOG_LOCAL, vid); - } - else - { - vm->log("LCM", Log::ERROR, "shutdown_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::undeploy_action(const LCMAction& la, bool hard) -{ - int vid = la.vm_id(); - unsigned int port; - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - (vm->get_lcm_state() == VirtualMachine::RUNNING || - vm->get_lcm_state() == VirtualMachine::UNKNOWN)) - { - //---------------------------------------------------- - // SHUTDOWN_UNDEPLOY STATE - //---------------------------------------------------- - - vm->set_state(VirtualMachine::SHUTDOWN_UNDEPLOY); - - vm->set_resched(false); - - if (hard) - { - vm->set_action(VMActions::UNDEPLOY_HARD_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::CANCEL,vid); - } - else - { - vm->set_action(VMActions::UNDEPLOY_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::SHUTDOWN,vid); - } - - VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS"); - - if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0)) - { - graphics->remove("PORT"); - clpool->release_vnc_port(vm->get_cid(), port); - } - - vmpool->update_history(vm); - - vmpool->update(vm); - } - else if (vm->get_state() == VirtualMachine::POWEROFF) - { - //---------------------------------------------------- - // Bypass SHUTDOWN_UNDEPLOY - //---------------------------------------------------- - - vm->set_state(VirtualMachine::ACTIVE); - vm->set_state(VirtualMachine::EPILOG_UNDEPLOY); - - vm->set_action(VMActions::UNDEPLOY_ACTION, la.uid(), la.gid(), - la.req_id()); - - vm->set_epilog_stime(time(0)); - - vmpool->update_history(vm); - - vmpool->update(vm); - - //---------------------------------------------------- - - tm->trigger(TMAction::EPILOG_STOP,vid); - } - else - { - vm->log("LCM", Log::ERROR, "undeploy_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::poweroff_action(const LCMAction& la) -{ - int vid = la.vm_id(); - - poweroff_action(vid, false, la); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::poweroff_hard_action(const LCMAction& la) -{ - int vid = la.vm_id(); - - poweroff_action(vid, true, la); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::poweroff_action(int vid, bool hard, const LCMAction& la) -{ - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - (vm->get_lcm_state() == VirtualMachine::RUNNING || - vm->get_lcm_state() == VirtualMachine::UNKNOWN)) - { - //---------------------------------------------------- - // SHUTDOWN_POWEROFF STATE - //---------------------------------------------------- - - vm->set_state(VirtualMachine::SHUTDOWN_POWEROFF); - - vm->set_resched(false); - - if (hard) - { - vm->set_action(VMActions::POWEROFF_HARD_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::CANCEL,vid); - } - else - { - vm->set_action(VMActions::POWEROFF_ACTION, la.uid(), la.gid(), - la.req_id()); - - vmm->trigger(VMMAction::SHUTDOWN,vid); - } - - vmpool->update_history(vm); - - vmpool->update(vm); - } - else - { - vm->log("LCM", Log::ERROR, "poweroff_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::restore_action(const LCMAction& la) -{ - ostringstream os; - - int vid = la.vm_id(); - - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::SUSPENDED) - { time_t the_time = time(0); - vm->log("LCM", Log::INFO, "Restoring VM"); + VirtualMachine * vm = vmpool->get(vid); - //---------------------------------------------------- - // BOOT STATE (FROM SUSPEND) - //---------------------------------------------------- - vm->set_state(VirtualMachine::ACTIVE); + if ( vm == nullptr ) + { + return; + } - vm->set_state(VirtualMachine::BOOT_SUSPENDED); + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) + { + //---------------------------------------------------- + // SAVE_MIGRATE STATE + //---------------------------------------------------- - vm->set_etime(the_time); + vm->set_state(VirtualMachine::SAVE_MIGRATE); - vm->set_running_etime(the_time); + vm->set_resched(false); - vmpool->update_history(vm); + vm->get_capacity(sr); - vm->cp_history(); + hpool->add_capacity(vm->get_hid(), sr); - vm->set_stime(the_time); + vm->set_stime(the_time); - vm->set_running_stime(the_time); + vm->set_action(vm_action, uid, gid, req_id); - vm->set_action(VMActions::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); + vmpool->update_history(vm); - vmpool->insert_history(vm); + vm->set_previous_action(vm_action, uid, gid, req_id); - vmpool->update(vm); + vmpool->update_previous_history(vm); - //---------------------------------------------------- - - vmm->trigger(VMMAction::RESTORE,vid); - } - else - { - vm->log("LCM", Log::ERROR, "restore_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::restart_action(const LCMAction& la) -{ - int vid = la.vm_id(); - - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if (vm->get_state() == VirtualMachine::ACTIVE && - vm->get_lcm_state() == VirtualMachine::UNKNOWN) - { - vm->set_state(VirtualMachine::BOOT_UNKNOWN); - - vmpool->update(vm); - - vmm->trigger(VMMAction::DEPLOY, vid); - } - else if ( vm->get_state() == VirtualMachine::POWEROFF ) - { - time_t the_time = time(0); - - vm->set_state(VirtualMachine::ACTIVE); - - vm->set_state(VirtualMachine::BOOT_POWEROFF); - - vm->set_etime(the_time); - - vm->set_running_etime(the_time); - - vmpool->update_history(vm); - - vm->cp_history(); - - vm->set_stime(the_time); - - vm->set_running_stime(the_time); - - vm->set_action(VMActions::RESUME_ACTION, la.uid(), la.gid(), la.req_id()); - - vmpool->insert_history(vm); - - vmpool->update(vm); - - vmm->trigger(VMMAction::DEPLOY, vid); - } - else - { - vm->log("LCM", Log::ERROR, "restart_action, VM in a wrong state."); - } - - vm->unlock(); - - return; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void LifeCycleManager::delete_action(const LCMAction& la) -{ - int image_id = -1; - int vid = la.vm_id(); - - VirtualMachine * vm = vmpool->get(vid); - - if ( vm == 0 ) - { - return; - } - - if ( vm->get_state() != VirtualMachine::ACTIVE ) - { - vm->log("LCM", Log::ERROR, "clean_action, VM in a wrong state."); - vm->unlock(); - - return; - } - - switch(vm->get_lcm_state()) - { - case VirtualMachine::CLEANUP_RESUBMIT: - vm->set_state(VirtualMachine::CLEANUP_DELETE); vmpool->update(vm); - case VirtualMachine::CLEANUP_DELETE: - dm->trigger(DMAction::DONE, vid); - break; + //---------------------------------------------------- - default: - clean_up_vm(vm, true, image_id, la); - dm->trigger(DMAction::DONE, vid); - break; - } - - vm->unlock(); - - if ( image_id != -1 ) - { - Image * image = ipool->get(image_id); - - if ( image != 0 ) - { - image->set_state(Image::ERROR); - - ipool->update(image); - - image->unlock(); + switch (vm_action) + { + case VMActions::POFF_MIGRATE_ACTION: + vmm->trigger_shutdown(vid); + break; + case VMActions::POFF_HARD_MIGRATE_ACTION: + vmm->trigger_cancel(vid); + break; + default: + vmm->trigger_save(vid); + break; + } } - } + else if (vm->get_state() == VirtualMachine::POWEROFF || + vm->get_state() == VirtualMachine::SUSPENDED || + (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::UNKNOWN )) + { + //---------------------------------------------------------------------- + // Bypass SAVE_MIGRATE & go to PROLOG_MIGRATE_POWEROFF/SUSPENDED/UNKNOWN + //---------------------------------------------------------------------- + if (vm->get_state() == VirtualMachine::POWEROFF) + { + vm->set_state(VirtualMachine::PROLOG_MIGRATE_POWEROFF); + } + else if (vm->get_state() == VirtualMachine::SUSPENDED) + { + vm->set_state(VirtualMachine::PROLOG_MIGRATE_SUSPEND); + } + else //VirtualMachine::UNKNOWN + { + vm->set_state(VirtualMachine::PROLOG_MIGRATE_UNKNOWN); + + vm->set_previous_action(VMActions::MIGRATE_ACTION, uid, + gid, req_id); + } + + vm->set_previous_running_etime(the_time); + + vm->set_previous_etime(the_time); + + vmpool->update_previous_history(vm); + + vm->set_state(VirtualMachine::ACTIVE); + + vm->set_resched(false); + + if ( !vmm->is_keep_snapshots(vm->get_vmm_mad()) ) + { + vm->delete_snapshots(); + } + + vm->set_action(VMActions::MIGRATE_ACTION, uid, gid, req_id); + + vm->get_capacity(sr); + + hpool->add_capacity(vm->get_hid(), sr); + + if ( vm->get_hid() != vm->get_previous_hid() ) + { + hpool->del_capacity(vm->get_previous_hid(), sr); + } + + vm->set_stime(the_time); + + vm->set_prolog_stime(the_time); + + vmpool->update_history(vm); + + vmpool->update(vm); + + //---------------------------------------------------- + + tm->trigger_prolog_migr(vm); + } + else + { + vm->log("LCM", Log::ERROR, "migrate_action, VM in a wrong state."); + } + + vm->unlock(); + }); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::delete_recreate_action(const LCMAction& la) +void LifeCycleManager::trigger_live_migrate(int vid, const RequestAttributes& ra) { - Template * vm_quotas_snp = 0; + int uid = ra.uid; + int gid = ra.gid; + int req_id = ra.req_id; - vector