xorp

task.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 
00021 #ifndef __RTRMGR_TASK_HH__
00022 #define __RTRMGR_TASK_HH__
00023 
00024 
00025 
00026 
00027 #include "libxorp/bug_catcher.hh"
00028 #include "libxorp/run_command.hh"
00029 #include "libxorp/status_codes.h"
00030 
00031 #include "libxipc/xrl_router.hh"
00032 
00033 #include "unexpanded_program.hh"
00034 #include "unexpanded_xrl.hh"
00035 
00036 
00037 class MasterConfigTree;
00038 class ModuleCommand;
00039 class ModuleManager;
00040 class Task;
00041 class TaskManager;
00042 class XorpClient;
00043 
00044 class Validation {
00045 public:
00046     typedef XorpCallback1<void, bool>::RefPtr CallBack;
00047 
00048     Validation(const string& module_name, bool verbose)
00049     : _module_name(module_name), _verbose(verbose) {};
00050     virtual ~Validation() {};
00051 
00052     virtual void validate(RunShellCommand::ExecId exec_id, CallBack cb) = 0;
00053 
00054 protected:
00055     const string    _module_name;
00056     RunShellCommand::ExecId _exec_id;
00057     bool        _verbose;    // Set to true if output is verbose
00058 };
00059 
00060 class DelayValidation : public Validation {
00061 public:
00062     DelayValidation(const string& module_name, EventLoop& eventloop,
00063             uint32_t ms, bool verbose);
00064 
00065     void validate(RunShellCommand::ExecId exec_id, CallBack cb);
00066 
00067 private:
00068     void timer_expired();
00069 
00070     EventLoop&  _eventloop;
00071     CallBack    _cb;
00072     uint32_t    _delay_in_ms;
00073     XorpTimer   _timer;
00074 };
00075 
00076 class XrlStatusValidation : public Validation {
00077 public:
00078     XrlStatusValidation(const string& module_name, const XrlAction& xrl_action,
00079             TaskManager& taskmgr);
00080     virtual ~XrlStatusValidation() {
00081     eventloop().remove_timer(_retry_timer);
00082     // TODO:  Should remove callbacks pointing to this as well,
00083     // but that is a whole other problem...
00084     }
00085 
00086     void validate(RunShellCommand::ExecId exec_id, CallBack cb);
00087 
00088 protected:
00089     void dummy_response();
00090     virtual void xrl_done(const XrlError& e, XrlArgs* xrl_args);
00091     virtual void handle_status_response(ProcessStatus status,
00092                     const string& reason) = 0;
00093     EventLoop& eventloop();
00094 
00095     const XrlAction&    _xrl_action;
00096     TaskManager&    _task_manager;
00097     CallBack        _cb;
00098     XorpTimer       _retry_timer;
00099     uint32_t        _retries;
00100 };
00101 
00102 class ProgramStatusValidation : public Validation {
00103 public:
00104     ProgramStatusValidation(const string& module_name,
00105                 const ProgramAction& program_action,
00106                 TaskManager& taskmgr);
00107     virtual ~ProgramStatusValidation();
00108 
00109     void validate(RunShellCommand::ExecId exec_id, CallBack cb);
00110 
00111 protected:
00112     virtual void handle_status_response(bool success,
00113                     const string& stdout_output,
00114                     const string& stderr_output) = 0;
00115     EventLoop& eventloop();
00116 
00117     const ProgramAction& _program_action;
00118     TaskManager&    _task_manager;
00119     CallBack        _cb;
00120 
00121 private:
00122     void stdout_cb(RunShellCommand* run_command, const string& output);
00123     void stderr_cb(RunShellCommand* run_command, const string& output);
00124     void done_cb(RunShellCommand* run_command, bool success,
00125          const string& error_msg);
00126     void execute_done(bool success);
00127 
00128     RunShellCommand*    _run_command;
00129     string      _command_stdout;
00130     string      _command_stderr;
00131     XorpTimer       _delay_timer;
00132 };
00133 
00134 class XrlStatusStartupValidation : public XrlStatusValidation {
00135 public:
00136     XrlStatusStartupValidation(const string& module_name,
00137                    const XrlAction& xrl_action,
00138                    TaskManager& taskmgr);
00139 
00140 private:
00141     void handle_status_response(ProcessStatus status, const string& reason);
00142 };
00143 
00144 class ProgramStatusStartupValidation : public ProgramStatusValidation {
00145 public:
00146     ProgramStatusStartupValidation(const string& module_name,
00147                    const ProgramAction& program_action,
00148                    TaskManager& taskmgr);
00149 
00150 private:
00151     void handle_status_response(bool success,
00152                 const string& stdout_output,
00153                 const string& stderr_output);
00154 };
00155 
00156 class XrlStatusReadyValidation : public XrlStatusValidation {
00157 public:
00158     XrlStatusReadyValidation(const string& module_name,
00159                  const XrlAction& xrl_action,
00160                  TaskManager& taskmgr);
00161 
00162 private:
00163     void handle_status_response(ProcessStatus status, const string& reason);
00164 };
00165 
00166 class ProgramStatusReadyValidation : public ProgramStatusValidation {
00167 public:
00168     ProgramStatusReadyValidation(const string& module_name,
00169                  const ProgramAction& program_action,
00170                  TaskManager& taskmgr);
00171 
00172 private:
00173     void handle_status_response(bool success,
00174                 const string& stdout_output,
00175                 const string& stderr_output);
00176 };
00177 
00178 class XrlStatusConfigMeValidation : public XrlStatusValidation {
00179 public:
00180     XrlStatusConfigMeValidation(const string& module_name,
00181                 const XrlAction& xrl_action,
00182                 TaskManager& taskmgr);
00183 
00184 private:
00185     void handle_status_response(ProcessStatus status, const string& reason);
00186 };
00187 
00188 class ProgramStatusConfigMeValidation : public ProgramStatusValidation {
00189 public:
00190     ProgramStatusConfigMeValidation(const string& module_name,
00191                     const ProgramAction& program_action,
00192                     TaskManager& taskmgr);
00193 
00194 private:
00195     void handle_status_response(bool success,
00196                 const string& stdout_output,
00197                 const string& stderr_output);
00198 };
00199 
00200 class XrlStatusShutdownValidation : public XrlStatusValidation {
00201 public:
00202     XrlStatusShutdownValidation(const string& module_name,
00203                 const XrlAction& xrl_action,
00204                 TaskManager& taskmgr);
00205 
00206 private:
00207     void xrl_done(const XrlError& e, XrlArgs* xrl_args);
00208     void handle_status_response(ProcessStatus status, const string& reason);
00209 };
00210 
00211 class ProgramStatusShutdownValidation : public ProgramStatusValidation {
00212 public:
00213     ProgramStatusShutdownValidation(const string& module_name,
00214                     const ProgramAction& program_action,
00215                     TaskManager& taskmgr);
00216 
00217 private:
00218     void handle_status_response(bool success,
00219                 const string& stdout_output,
00220                 const string& stderr_output);
00221 };
00222 
00223 class Startup {
00224 public:
00225     typedef XorpCallback1<void, bool>::RefPtr CallBack;
00226     Startup(const string& module_name, bool verbose);
00227     virtual ~Startup() {}
00228 
00229     virtual void startup(const RunShellCommand::ExecId& exec_id,
00230              CallBack cb) = 0;
00231 
00232 protected:
00233     const string _module_name;
00234     bool    _verbose;    // Set to true if output is verbose
00235 };
00236 
00237 class XrlStartup : public Startup {
00238 public:
00239     XrlStartup(const string& module_name, const XrlAction& xrl_action,
00240            TaskManager& taskmgr);
00241     virtual ~XrlStartup() {}
00242 
00243     void startup(const RunShellCommand::ExecId& exec_id, CallBack cb);
00244     EventLoop& eventloop() const;
00245 
00246 private:
00247     void dummy_response();
00248     void startup_done(const XrlError& err, XrlArgs* xrl_args);
00249 
00250     const XrlAction&    _xrl_action;
00251     TaskManager&    _task_manager;
00252     CallBack        _cb;
00253     XorpTimer       _dummy_timer;
00254 };
00255 
00256 class ProgramStartup : public Startup {
00257 public:
00258     ProgramStartup(const string& module_name,
00259            const ProgramAction& program_action,
00260            TaskManager& taskmgr);
00261     virtual ~ProgramStartup();
00262 
00263     void startup(const RunShellCommand::ExecId& exec_id, CallBack cb);
00264     EventLoop& eventloop() const;
00265 
00266 private:
00267     void stdout_cb(RunShellCommand* run_command, const string& output);
00268     void stderr_cb(RunShellCommand* run_command, const string& output);
00269     void done_cb(RunShellCommand* run_command, bool success,
00270          const string& error_msg);
00271     void execute_done(bool success);
00272 
00273     const ProgramAction& _program_action;
00274     TaskManager&    _task_manager;
00275     CallBack        _cb;
00276 
00277     RunShellCommand*    _run_command;
00278     string      _command_stdout;
00279     string      _command_stderr;
00280     XorpTimer       _delay_timer;
00281 };
00282 
00283 class Shutdown {
00284 public:
00285     typedef XorpCallback1<void, bool>::RefPtr CallBack;
00286     Shutdown(const string& module_name, bool verbose);
00287     virtual ~Shutdown() {}
00288 
00289     virtual void shutdown(const RunShellCommand::ExecId& exec_id,
00290               CallBack cb) = 0;
00291 
00292 protected:
00293     const string _module_name;
00294     bool    _verbose;    // Set to true if output is verbose
00295 };
00296 
00297 class XrlShutdown : public Shutdown {
00298 public:
00299     XrlShutdown(const string& module_name, const XrlAction& xrl_action,
00300         TaskManager& taskmgr);
00301     virtual ~XrlShutdown() {}
00302 
00303     void shutdown(const RunShellCommand::ExecId& exec_id, CallBack cb);
00304     EventLoop& eventloop() const;
00305 
00306 private:
00307     void dummy_response();
00308     void shutdown_done(const XrlError& err, XrlArgs* xrl_args);
00309 
00310     const XrlAction&    _xrl_action;
00311     TaskManager&    _task_manager;
00312     CallBack        _cb;
00313     XorpTimer       _dummy_timer;
00314 };
00315 
00316 class ProgramShutdown : public Shutdown {
00317 public:
00318     ProgramShutdown(const string& module_name,
00319             const ProgramAction& program_action,
00320             TaskManager& taskmgr);
00321     virtual ~ProgramShutdown();
00322 
00323     void shutdown(const RunShellCommand::ExecId& exec_id, CallBack cb);
00324     EventLoop& eventloop() const;
00325 
00326 private:
00327     void stdout_cb(RunShellCommand* run_command, const string& output);
00328     void stderr_cb(RunShellCommand* run_command, const string& output);
00329     void done_cb(RunShellCommand* run_command, bool success,
00330          const string& error_msg);
00331     void execute_done(bool success);
00332 
00333     const ProgramAction& _program_action;
00334     TaskManager&    _task_manager;
00335     CallBack        _cb;
00336 
00337     RunShellCommand*    _run_command;
00338     string      _command_stdout;
00339     string      _command_stderr;
00340     XorpTimer       _delay_timer;
00341 };
00342 
00343 class TaskBaseItem {
00344 public:
00345     TaskBaseItem(Task& task) : _task(task) {}
00346     TaskBaseItem(const TaskBaseItem& them) : _task(them._task) {}
00347     virtual ~TaskBaseItem() {}
00348 
00349     virtual bool execute(string& errmsg) = 0;
00350     virtual void unschedule() = 0;
00351 
00352     Task& task() { return (_task); }
00353 
00354 private:
00355     Task&   _task;
00356 };
00357 
00358 class TaskXrlItem : public TaskBaseItem {
00359 public:
00360     TaskXrlItem(const UnexpandedXrl& uxrl, const XrlRouter::XrlCallback& cb,
00361         Task& task,
00362         uint32_t xrl_resend_count = TaskXrlItem::DEFAULT_RESEND_COUNT,
00363         int xrl_resend_delay_ms = TaskXrlItem::DEFAULT_RESEND_DELAY_MS);
00364     TaskXrlItem(const TaskXrlItem& them);
00365 
00366     bool execute(string& errmsg);
00367     void execute_done(const XrlError& err, XrlArgs* xrl_args);
00368     void resend();
00369     void unschedule();
00370 
00371 private:
00372     static const uint32_t   DEFAULT_RESEND_COUNT;
00373     static const int        DEFAULT_RESEND_DELAY_MS;
00374 
00375     UnexpandedXrl       _unexpanded_xrl;
00376     XrlRouter::XrlCallback  _xrl_callback;
00377     uint32_t            _xrl_resend_count_limit;
00378     uint32_t            _xrl_resend_count;
00379     int             _xrl_resend_delay_ms;
00380     XorpTimer           _xrl_resend_timer;
00381     bool            _verbose;   // Set to true if output is verbose
00382 };
00383 
00384 class TaskProgramItem : public TaskBaseItem {
00385 public:
00386     typedef XorpCallback4<void, bool, const string&, const string&, bool>::RefPtr ProgramCallback;
00387 
00388     TaskProgramItem(const UnexpandedProgram&        program,
00389             TaskProgramItem::ProgramCallback    program_cb,
00390             Task&               task);
00391     TaskProgramItem(const TaskProgramItem& them);
00392     ~TaskProgramItem();
00393 
00394     bool execute(string& errmsg);
00395     void execute_done(bool success);
00396     void unschedule();
00397 
00398 private:
00399     void stdout_cb(RunShellCommand* run_command, const string& output);
00400     void stderr_cb(RunShellCommand* run_command, const string& output);
00401     void done_cb(RunShellCommand* run_command, bool success,
00402          const string& error_msg);
00403 
00404     UnexpandedProgram       _unexpanded_program;
00405     RunShellCommand*        _run_command;
00406     string          _command_stdout;
00407     string          _command_stderr;
00408     TaskProgramItem::ProgramCallback _program_cb;
00409     XorpTimer           _delay_timer;
00410     bool            _verbose;   // Set to true if output is verbose
00411 };
00412 
00413 class Task {
00414 public:
00415     typedef XorpCallback2<void, bool, const string&>::RefPtr CallBack;
00416 
00417     Task(const string& name, TaskManager& taskmgr);
00418     ~Task();
00419 
00420     void start_module(const string& mod_name, Validation* startup_validation,
00421               Validation* config_validation, Startup* startup);
00422     void shutdown_module(const string& mod_name, Validation* validation,
00423              Shutdown* shutdown);
00424     void add_xrl(const UnexpandedXrl& xrl, XrlRouter::XrlCallback& cb);
00425     void add_program(const UnexpandedProgram&       program,
00426              TaskProgramItem::ProgramCallback   program_cb);
00427     void set_ready_validation(Validation* validation);
00428     Validation* ready_validation() const { return _ready_validation; }
00429     bool will_shutdown_module() const { return _stop_module; }
00430     void run(CallBack cb);
00431     void item_done(bool success, bool fatal, const string& errmsg); 
00432     bool do_exec() const;
00433     bool is_verification() const;
00434     XorpClient& xorp_client() const;
00435 
00442     const RunShellCommand::ExecId& exec_id() const { return _exec_id; }
00443 
00449     void set_exec_id(const RunShellCommand::ExecId& v) { _exec_id = v; }
00450 
00451     const string& name() const { return _name; }
00452     EventLoop& eventloop() const;
00453 
00454     bool verbose() const { return _verbose; }
00455 
00456 protected:
00457     void step1_start();
00458     void step1_done(bool success);
00459 
00460     void step2_wait();
00461     void step2_done(bool success);
00462 
00463     void step2_2_wait();
00464     void step2_2_done(bool success);
00465 
00466     void step2_3_wait();
00467     void step2_3_done(bool success);
00468 
00469     void step3_config();
00470     void step3_done(bool success);
00471 
00472     void step4_wait();
00473     void step4_done(bool success);
00474 
00475     void step5_stop();
00476     void step5_done(bool success);
00477 
00478     void step6_wait();
00479     void step6_done(bool success);
00480 
00481     void step7_wait();
00482     void step7_kill();
00483 
00484     void step8_report();
00485     void task_fail(const string& errmsg, bool fatal);
00486 
00487 private:
00488     string  _name;      // The name of the task
00489     TaskManager& _taskmgr;
00490     string  _module_name;   // The name of the module to start and stop
00491     bool    _start_module;
00492     bool    _stop_module;
00493     Validation* _startup_validation; // The validation mechanism for the
00494                                      // module startup
00495     Validation* _config_validation;  // The validation mechanism for the
00496                      // module configuration
00497     Validation* _ready_validation; // The validation mechanism for the module 
00498                                    // reconfiguration
00499     Validation* _shutdown_validation;  // The validation mechanism for the 
00500                                        // module shutdown
00501     Startup*    _startup_method;
00502     Shutdown*   _shutdown_method;
00503     list<TaskBaseItem *> _task_items;
00504     bool    _config_done;   // True if we changed the module's config
00505     CallBack    _task_complete_cb; // The task completion callback
00506     XorpTimer   _wait_timer;
00507     RunShellCommand::ExecId _exec_id;
00508     bool    _verbose;    // Set to true if output is verbose
00509 };
00510 
00511 class TaskManager : public BugCatcher {
00512     typedef XorpCallback2<void, bool, string>::RefPtr CallBack;
00513 
00514 public:
00515     TaskManager(MasterConfigTree& config_tree, 
00516         ModuleManager& mmgr,
00517         XorpClient& xclient, bool global_do_exec,
00518         bool verbose);
00519     ~TaskManager();
00520 
00521     void set_do_exec(bool do_exec, bool is_verification);
00522     void reset();
00523     int add_module(const ModuleCommand& mod_cmd, string& error_msg);
00524     void add_xrl(const string& module_name, const UnexpandedXrl& xrl, 
00525          XrlRouter::XrlCallback& cb);
00526     void add_program(const string&          module_name,
00527              const UnexpandedProgram&       program,
00528              TaskProgramItem::ProgramCallback   program_cb);
00529     void shutdown_module(const string& module_name);
00530     void run(CallBack cb);
00531     XorpClient& xorp_client() const { return _xorp_client; }
00532     ModuleManager& module_manager() const { return _module_manager; }
00533     MasterConfigTree& config_tree() const { return _config_tree; }
00534     bool do_exec() const { return _current_do_exec; }
00535     bool is_verification() const { return _is_verification; }
00536     bool verbose() const { return _verbose; }
00537     EventLoop& eventloop() const;
00538 
00549     void kill_process(const string& module_name);
00550 
00557     const RunShellCommand::ExecId& exec_id() const { return _exec_id; }
00558 
00564     void set_exec_id(const RunShellCommand::ExecId& v) { _exec_id = v; }
00565 
00566 
00567 private:
00568     void reorder_tasks();
00569     void run_task();
00570     void task_done(bool success, const string& errmsg);
00571     void fail_tasklist_initialization(const string& errmsg);
00572     Task& find_task(const string& module_name);
00573     void null_callback();
00574 
00575     MasterConfigTree&   _config_tree;
00576     ModuleManager&  _module_manager;
00577     XorpClient&     _xorp_client;
00578     bool        _global_do_exec; // Set to false if we're never going
00579                     // to execute anything because we're
00580                     // in a debug mode
00581     bool        _current_do_exec;
00582     bool        _is_verification; // Set to true if current execution
00583                       // is for verification purpose
00584     bool        _verbose;   // Set to true if output is verbose
00585 
00586     // _tasks provides fast access to a Task by name
00587     map<string, Task*> _tasks;
00588 
00589     // _tasklist maintains the execution order
00590     list<Task*> _tasklist;
00591 
00592     // _shutdown_order maintains the shutdown ordering
00593     list<Task*> _shutdown_order;
00594 
00595     map<string, const ModuleCommand*> _module_commands;
00596 
00597     RunShellCommand::ExecId _exec_id;
00598 
00599     CallBack _completion_cb;
00600 };
00601 
00602 #endif // __RTRMGR_TASK_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations