Line data Source code
1 : /* 2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef __AGENT_OPER_INSTANCE_MANAGER_H__ 6 : #define __AGENT_OPER_INSTANCE_MANAGER_H__ 7 : 8 : #include <boost/uuid/uuid.hpp> 9 : #include "cmn/agent_signal.h" 10 : #include "db/db_table.h" 11 : #include "oper/service_instance.h" 12 : #include "oper/instance_manager_adapter.h" 13 : 14 : class Agent; 15 : class DB; 16 : class InstanceState; 17 : class InstanceTask; 18 : class InstanceTaskQueue; 19 : 20 : extern SandeshTraceBufferPtr InstanceManagerTraceBuf; 21 : #define INSTANCE_MANAGER_TRACE(obj, ...) \ 22 : do { \ 23 : InstanceManager##obj::TraceMsg(InstanceManagerTraceBuf, __FILE__, __LINE__, __VA_ARGS__);\ 24 : } while (false) 25 : 26 : /* 27 : * Starts and stops network namespaces corresponding to service-instances. 28 : * 29 : * In order to prevent concurrency issues between the signal hanlder leveraged 30 : * by this class and the db::task context specific methods are protected by 31 : * a mutex. 32 : */ 33 : class InstanceManager { 34 : public: 35 : enum CmdType { 36 : Start = 1, 37 : Stop 38 : }; 39 : 40 : enum ChldEventType { 41 : OnErrorEvent, 42 : OnTaskTimeoutEvent, 43 : OnExitEvent 44 : }; 45 : 46 : struct InstanceManagerChildEvent { 47 2 : InstanceManagerChildEvent() 48 2 : : type(0) 49 2 : , task(NULL) 50 2 : , errors() 51 2 : , error_val(0) 52 2 : , task_queue(NULL) 53 2 : {} 54 : 55 : int type; 56 : 57 : /* 58 : * OnError variables 59 : */ 60 : InstanceTask *task; 61 : std::string errors; 62 : int error_val; 63 : 64 : /* 65 : * OnTimeout 66 : */ 67 : InstanceTaskQueue *task_queue; 68 : }; 69 : 70 : static const int kTimeoutDefault = 30; 71 : static const int kWorkersDefault = 1; 72 : static const int kReattemptsDefault = 2; 73 : 74 : InstanceManager(Agent *); 75 : ~InstanceManager(); 76 : 77 : void Initialize(DB *database, const std::string &netns_cmd, 78 : const std::string &docker_cmd, const int netns_workers, 79 : const int netns_timeout); 80 : void Terminate(); 81 : bool DequeueEvent(InstanceManagerChildEvent event); 82 : 83 : InstanceState *GetState(ServiceInstance *) const; 84 : bool StaleTimeout(); 85 : void SetStaleTimerInterval(int minutes); 86 1 : int StaleTimerInterval() { return stale_timer_interval_;} 87 : void SetNamespaceStorePath(std::string path); 88 : void SetNetNSCmd(const std::string &netns_cmd); 89 : 90 : private: 91 : friend class InstanceManagerTest; 92 : class NamespaceStaleCleaner; 93 : 94 : void RegisterSigHandler(); 95 : void InitSigHandler(AgentSignal *signal); 96 : 97 : InstanceManagerAdapter* FindApplicableAdapter(const ServiceInstance::Properties &props); 98 : void StartServiceInstance(ServiceInstance *svc_instance, 99 : InstanceState *state, bool update); 100 : void StopServiceInstance(ServiceInstance *svc_instance, 101 : InstanceState *state); 102 : 103 : void StopStaleNetNS(ServiceInstance::Properties &props); 104 : 105 : void OnError(InstanceTask *task, const std::string errors); 106 : void OnExit(InstanceTask *task, const boost::system::error_code &ec); 107 : void RegisterSvcInstance(InstanceTask *task, 108 : ServiceInstance *svc_instance); 109 : void UnregisterSvcInstance(ServiceInstance *svc_instance); 110 : ServiceInstance *UnregisterSvcInstance(InstanceTask *task); 111 : ServiceInstance *GetSvcInstance(InstanceTask *task) const; 112 : 113 : InstanceTaskQueue *GetTaskQueue(const std::string &str); 114 : void Enqueue(InstanceTask *task, const boost::uuids::uuid &uuid); 115 : void ScheduleNextTask(InstanceTaskQueue *task_queue); 116 : bool StartTask(InstanceTaskQueue *task_queue, InstanceTask *task); 117 : 118 : InstanceState *GetState(InstanceTask* task) const; 119 : void SetState(ServiceInstance *svc_instance, InstanceState *state); 120 : void ClearState(ServiceInstance *svc_instance); 121 : bool DeleteState(ServiceInstance *svc_instance); 122 : void UpdateStateStatusType(InstanceManagerChildEvent event); 123 : 124 : void SetLastCmdType(ServiceInstance *svc_instance, int last_cmd_type); 125 : int GetLastCmdType(ServiceInstance *svc_instance) const; 126 : void ClearLastCmdType(ServiceInstance *svc_instance); 127 : 128 : void OnTaskTimeout(InstanceTaskQueue *task_queue); 129 : 130 : void OnErrorEventHandler(InstanceManagerChildEvent event); 131 : void OnExitEventHandler(InstanceManagerChildEvent event); 132 : void OnTaskTimeoutEventHandler(InstanceManagerChildEvent event); 133 : 134 : /* 135 : * Clear all the state entries. Used only at process shutdown. 136 : */ 137 : void StateClear(); 138 : 139 : /* 140 : * Event observer for changes in the "db.service-instance.0" table. 141 : */ 142 : void EventObserver(DBTablePartBase *db_part, DBEntryBase *entry); 143 : 144 : DBTableBase::ListenerId si_listener_; 145 : std::string netns_cmd_; 146 : int netns_timeout_; 147 : int netns_reattempts_; 148 : WorkQueue<InstanceManagerChildEvent> work_queue_; 149 : 150 : std::vector<InstanceTaskQueue *> task_queues_; 151 : typedef std::map<InstanceTask *, ServiceInstance *> TaskSvcMap; 152 : TaskSvcMap task_svc_instances_; 153 : std::map<std::string, int> last_cmd_types_; 154 : std::string loadbalancer_config_path_; 155 : std::string namespace_store_path_; 156 : int stale_timer_interval_; 157 : Timer *stale_timer_; 158 : std::unique_ptr<NamespaceStaleCleaner> stale_cleaner_; 159 : Agent *agent_; 160 : 161 : std::vector<InstanceManagerAdapter *> adapters_; 162 : 163 : DISALLOW_COPY_AND_ASSIGN(InstanceManager); 164 : }; 165 : 166 : class InstanceState : public DBState { 167 : 168 : public: 169 : enum StatusType { 170 : Starting = 1, 171 : Started, 172 : Stopping, 173 : Stopped, 174 : Error, 175 : Timeout, 176 : Reattempt 177 : }; 178 : 179 : InstanceState(); 180 : 181 0 : void set_pid(const pid_t &pid) { 182 0 : pid_ = pid; 183 0 : } 184 0 : pid_t pid() const { 185 0 : return pid_; 186 : } 187 : 188 0 : void set_status(const int status) { 189 0 : status_ = status; 190 0 : } 191 0 : pid_t status() const { 192 0 : return status_; 193 : } 194 : 195 0 : void set_errors(const std::string &errors) { 196 0 : errors_.append(errors); 197 0 : } 198 : 199 0 : void reset_errors() { 200 0 : errors_.clear(); 201 0 : } 202 : 203 0 : std::string errors() const { 204 0 : return errors_; 205 : } 206 : 207 0 : void set_cmd(const std::string &cmd) { 208 0 : cmd_ = cmd; 209 0 : } 210 0 : std::string cmd() const { 211 0 : return cmd_; 212 : } 213 : 214 0 : void set_properties(const ServiceInstance::Properties &properties) { 215 0 : properties_ = properties; 216 0 : } 217 0 : const ServiceInstance::Properties &properties() const { 218 0 : return properties_; 219 : } 220 : 221 0 : void set_status_type(const int status) { 222 0 : status_type_ = status; 223 0 : } 224 0 : int status_type() const { 225 0 : return status_type_; 226 : } 227 : 228 0 : int tasks_running() const { 229 0 : return tasks_running_; 230 : } 231 : 232 0 : int incr_tasks_running() { 233 0 : return ++tasks_running_; 234 : } 235 : 236 0 : int decr_tasks_running() { 237 0 : tasks_running_--; 238 0 : assert(!(tasks_running_ < 0)); 239 0 : return tasks_running_; 240 : } 241 : 242 : 243 : void Clear(); 244 : 245 : private: 246 : pid_t pid_; 247 : int status_; 248 : std::string errors_; 249 : std::string cmd_; 250 : int status_type_; 251 : int tasks_running_; 252 : 253 : ServiceInstance::Properties properties_; 254 : 255 : boost::system::error_code ec_; 256 : }; 257 : 258 : #endif