Source: ../../rtrmgr/task.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// Copyright (c) 2001-2005 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.

// $XORP: xorp/rtrmgr/task.hh,v 1.30 2005/03/25 02:54:38 pavlin Exp $

#ifndef __RTRMGR_TASK_HH__
#define __RTRMGR_TASK_HH__


#include <map>
#include <vector>

#include "libxorp/status_codes.h"

#include "libxipc/xrl_router.hh"

#include "unexpanded_xrl.hh"


class MasterConfigTree;
class ModuleCommand;
class ModuleManager;
class Task;
class TaskManager;
class XorpClient;

class Validation {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;

    Validation(const string& module_name, bool verbose)
	: _module_name(module_name), _verbose(verbose) {};
    virtual ~Validation() {};

    virtual void validate(CallBack cb) = 0;

protected:
    const string _module_name;
    bool	_verbose;	 // Set to true if output is verbose
};

class DelayValidation : public Validation {
public:
    DelayValidation(const string& module_name, EventLoop& eventloop,
		    uint32_t ms, bool verbose);

    void validate(CallBack cb);

private:
    void timer_expired();

    EventLoop&	_eventloop;
    CallBack	_cb;
    uint32_t	_delay_in_ms;
    XorpTimer	_timer;
};

class XrlStatusValidation : public Validation {
public:
    XrlStatusValidation(const string& module_name, const XrlAction& xrl_action,
			TaskManager& taskmgr);
    virtual ~XrlStatusValidation() {}

    void validate(CallBack cb);

protected:
    void dummy_response();
    virtual void xrl_done(const XrlError& e, XrlArgs* xrl_args);
    virtual void handle_status_response(ProcessStatus status,
					const string& reason) = 0;
    EventLoop& eventloop();

    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_retry_timer;
    uint32_t		_retries;
};

class StatusStartupValidation : public XrlStatusValidation {
public:
    StatusStartupValidation(const string& module_name,
			    const XrlAction& xrl_action,
			    TaskManager& taskmgr);

private:
    void handle_status_response(ProcessStatus status, const string& reason);
};

class StatusReadyValidation : public XrlStatusValidation {
public:
    StatusReadyValidation(const string& module_name,
			  const XrlAction& xrl_action,
			  TaskManager& taskmgr);

private:
    void handle_status_response(ProcessStatus status, const string& reason);
};

class StatusConfigMeValidation : public XrlStatusValidation {
public:
    StatusConfigMeValidation(const string& module_name,
			     const XrlAction& xrl_action,
			     TaskManager& taskmgr);

private:
    void handle_status_response(ProcessStatus status, const string& reason);
};

class StatusShutdownValidation : public XrlStatusValidation {
public:
    StatusShutdownValidation(const string& module_name,
			     const XrlAction& xrl_action,
			     TaskManager& taskmgr);

private:
    void xrl_done(const XrlError& e, XrlArgs* xrl_args);
    void handle_status_response(ProcessStatus status, const string& reason);
};

class Startup {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;
    Startup(const string& module_name, bool verbose);
    virtual ~Startup() {}

    virtual void startup(CallBack cb) = 0;

protected:
    const string _module_name;
    bool	_verbose;	 // Set to true if output is verbose
};

class XrlStartup : public Startup {
public:
    XrlStartup(const string& module_name, const XrlAction& xrl_action,
	       TaskManager& taskmgr);
    virtual ~XrlStartup() {}

    void startup(CallBack cb);
    EventLoop& eventloop() const;

private:
    void dummy_response();
    void startup_done(const XrlError& err, XrlArgs* xrl_args);

    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_dummy_timer;
};

class Shutdown {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;
    Shutdown(const string& module_name, bool verbose);
    virtual ~Shutdown() {}

    virtual void shutdown(CallBack cb) = 0;

protected:
    const string _module_name;
    bool	_verbose;	 // Set to true if output is verbose
};

class XrlShutdown : public Shutdown {
public:
    XrlShutdown(const string& module_name, const XrlAction& xrl_action,
		TaskManager& taskmgr);
    virtual ~XrlShutdown() {}

    void shutdown(CallBack cb);
    EventLoop& eventloop() const;

private:
    void dummy_response();
    void shutdown_done(const XrlError& err, XrlArgs* xrl_args);

    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_dummy_timer;
};

class TaskXrlItem {
public:
    TaskXrlItem(const UnexpandedXrl& uxrl, const XrlRouter::XrlCallback& cb,
		Task& task,
		uint32_t xrl_resend_count = TaskXrlItem::DEFAULT_RESEND_COUNT,
		int xrl_resend_delay_ms = TaskXrlItem::DEFAULT_RESEND_DELAY_MS);
    TaskXrlItem::TaskXrlItem(const TaskXrlItem& them);

    bool execute(string& errmsg);
    void execute_done(const XrlError& err, XrlArgs* xrl_args);
    void resend();
    void unschedule();

private:
    static const uint32_t	DEFAULT_RESEND_COUNT;
    static const int		DEFAULT_RESEND_DELAY_MS;

    UnexpandedXrl		_unexpanded_xrl;
    XrlRouter::XrlCallback	_xrl_callback;
    Task&			_task;
    uint32_t			_xrl_resend_count_limit;
    uint32_t			_xrl_resend_count;
    int				_xrl_resend_delay_ms;
    XorpTimer			_xrl_resend_timer;
    bool			_verbose;   // Set to true if output is verbose
};

class Task {
public:
    typedef XorpCallback2<void, bool, string>::RefPtr CallBack;

    Task(const string& name, TaskManager& taskmgr);
    ~Task();

    void start_module(const string& mod_name, Validation* startup_validation,
		      Validation* config_validation, Startup* startup);
    void shutdown_module(const string& mod_name, Validation* validation,
			 Shutdown* shutdown);
    void add_xrl(const UnexpandedXrl& xrl, XrlRouter::XrlCallback& cb);
    void set_ready_validation(Validation* validation);
    Validation* ready_validation() const { return _ready_validation; }
    bool will_shutdown_module() const { return _stop_module; }
    void run(CallBack cb);
    void xrl_done(bool success, bool fatal, string errmsg); 
    bool do_exec() const;
    XorpClient& xorp_client() const;

    const string& name() const { return _name; }
    EventLoop& eventloop() const;

    bool verbose() const { return _verbose; }

protected:
    void step1_start();
    void step1_done(bool success);

    void step2_wait();
    void step2_done(bool success);

    void step2_2_wait();
    void step2_2_done(bool success);

    void step2_3_wait();
    void step2_3_done(bool success);

    void step3_config();
    void step3_done(bool success);

    void step4_wait();
    void step4_done(bool success);

    void step5_stop();
    void step5_done(bool success);

    void step6_wait();
    void step6_done(bool success);

    void step7_wait();
    void step7_kill();

    void step8_report();
    void task_fail(string errmsg, bool fatal);

private:
    string	_name;		// The name of the task
    TaskManager& _taskmgr;
    string	_module_name;	// The name of the module to start and stop
    bool	_start_module;
    bool	_stop_module;
    Validation*	_startup_validation; // The validation mechanism for the
                                     // module startup
    Validation* _config_validation;  // The validation mechanism for the
				     // module configuration
    Validation*	_ready_validation; // The validation mechanism for the module 
                                   // reconfiguration
    Validation*	_shutdown_validation;  // The validation mechanism for the 
                                       // module shutdown
    Startup*	_startup_method;
    Shutdown*	_shutdown_method;
    list<TaskXrlItem> _xrls;
    bool	_config_done;	// True if we changed the module's config
    CallBack	_task_complete_cb; // The task completion callback
    XorpTimer	_wait_timer;
    bool	_verbose;	 // Set to true if output is verbose
};

class TaskManager {
    typedef XorpCallback2<void, bool, string>::RefPtr CallBack;

public:
    TaskManager::TaskManager(MasterConfigTree& config_tree, 
			     ModuleManager& mmgr,
			     XorpClient& xclient, bool global_do_exec,
			     bool verbose);
    ~TaskManager();

    void set_do_exec(bool do_exec);
    void reset();
    int add_module(const ModuleCommand& mod_cmd);
    void add_xrl(const string& module_name, const UnexpandedXrl& xrl, 
		 XrlRouter::XrlCallback& cb);
    void shutdown_module(const string& module_name);
    void run(CallBack cb);
    XorpClient& xorp_client() const { return _xorp_client; }
    ModuleManager& module_manager() const { return _module_manager; }
    MasterConfigTree& config_tree() const { return _config_tree; }
    bool do_exec() const { return _current_do_exec; }
    bool verbose() const { return _verbose; }
    EventLoop& eventloop() const;

    /**
     * @short kill_process is used to kill a fatally wounded process
     *
     * kill_process is used to kill a fatally wounded process. This
     * does not politely ask the process to die, because if we get
     * here we can't communicate with the process using XRLs, so we
     * just kill it outright.
     * 
     * @param module_name the module name of the process to be killed.  
     */
    void kill_process(const string& module_name);

    /**
     * @short shell_execute is used to start external processes.
     *
     * shell_execute is used to start external processes, running them
     * in a shell.  It is NOT used to start regular XORP processes,
     * but rather for background maintenance tasks.
     *
     * @param userid the UID of the user to run the task as.
     * @param argv the command and arguements to run
     * @param callback callback to call when the child process terminates
     */
    int shell_execute(uid_t userid, const vector<string>& argv, 
		      TaskManager::CallBack cb);

private:
    void reorder_tasks();
    void run_task();
    void task_done(bool success, string errmsg);
    void fail_tasklist_initialization(const string& errmsg);
    Task& find_task(const string& module_name);
    void null_callback();

    MasterConfigTree&   _config_tree;
    ModuleManager&	_module_manager;
    XorpClient&		_xorp_client;
    bool		_global_do_exec; // Set to false if we're never going
					// to execute anything because we're
					// in a debug mode
    bool		_current_do_exec;
    bool		_verbose;	// Set to true if output is verbose

    // _tasks provides fast access to a Task by name
    map<string, Task*> _tasks;

    // _tasklist maintains the execution order
    list<Task*> _tasklist;

    // _shutdown_order maintains the shutdown ordering
    list<Task*> _shutdown_order;

    map<string, const ModuleCommand*> _module_commands;

    CallBack _completion_cb;
};

#endif // __RTRMGR_TASK_HH__

Generated by: pavlin on possum.icir.org on Wed Apr 13 21:53:23 2005, using kdoc $.