CPCD.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifndef CPCD_HPP
  14. #define CPCD_HPP
  15. #include <Vector.hpp>
  16. #include <Properties.hpp>
  17. #include <NdbOut.hpp>
  18. #include <NdbThread.h>
  19. #include <NdbCondition.h>
  20. #include <BaseString.hpp>
  21. /* XXX Need to figure out how to do this for non-Unix systems */
  22. #define CPCD_DEFAULT_WORK_DIR "/var/run/ndb_cpcd"
  23. #define CPCD_DEFAULT_PROC_FILE     "ndb_cpcd.conf"
  24. #define CPCD_DEFAULT_TCP_PORT 1234
  25. #define CPCD_DEFAULT_POLLING_INTERVAL 5 /* seconds */
  26. #define CPCD_DEFAULT_CONFIG_FILE        "/etc/ndb_cpcd.conf"
  27. enum ProcessStatus {
  28.   STOPPED  = 0,
  29.   STARTING = 1,
  30.   RUNNING  = 2,
  31.   STOPPING = 3
  32. };
  33. enum ProcessType {
  34.   PERMANENT = 0,
  35.   TEMPORARY = 1
  36. };
  37. struct CPCEvent {
  38.   enum EventType {
  39.     ET_USER_CONNECT,
  40.     ET_USER_DISCONNECT,
  41.     
  42.     ET_PROC_USER_DEFINE,    // Defined proc
  43.     ET_PROC_USER_UNDEFINE,  // Undefined proc
  44.     ET_PROC_USER_START,     // Proc ordered to start
  45.     ET_PROC_USER_STOP,      // Proc ordered to stop
  46.     ET_PROC_STATE_RUNNING,  // exec returned(?) ok 
  47.     ET_PROC_STATE_STOPPED   // detected that proc is ! running
  48.   };
  49.   int m_proc;
  50.   time_t m_time;
  51.   EventType m_type;
  52. };
  53. struct EventSubscriber {
  54.   virtual void report(const CPCEvent &) = 0;
  55. };
  56. /**
  57.  *  @brief Error codes for CPCD requests
  58.  */
  59. enum RequestStatusCode {
  60.   OK = 0,            ///< Everything OK
  61.   Error = 1,      ///< Generic error
  62.   AlreadyExists = 2, ///< Entry already exists in list
  63.   NotExists = 3,     ///< Entry does not exist in list
  64.   AlreadyStopped = 4
  65. };
  66. /**
  67.  *  @class CPCD
  68.  *  @brief Manages processes, letting them be controlled with a TCP connection.
  69.  *
  70.  *  The class implementing the Cluster Process Control Daemon
  71.  */
  72. class CPCD {
  73. public:
  74.   /** @brief Describes the status of a client request */
  75.   class RequestStatus {
  76.   public:
  77.     /** @brief Constructs an empty RequestStatus */
  78.     RequestStatus() { m_status = OK; m_errorstring[0] = ''; };
  79.     /** @brief Sets an errorcode and a printable message */
  80.     void err(enum RequestStatusCode, const char *);
  81.     /** @brief Returns the error message */
  82.     char *getErrMsg() { return m_errorstring; };
  83.     /** @brief Returns the error code */
  84.     enum RequestStatusCode getStatus() { return m_status; };
  85.   private:
  86.     enum RequestStatusCode m_status;
  87.     char m_errorstring[256];
  88.   };
  89.   /**
  90.    *  @brief Manages a process
  91.    */
  92.   class Process {
  93.     int m_pid;
  94.   public:
  95.     /** 
  96.      * @brief Constructs and empty Process
  97.      */
  98.     Process(const Properties & props, class CPCD *cpcd);
  99.     /**
  100.      *  @brief Monitors the process
  101.      *
  102.      *  The process is started or stopped as needed.
  103.      */
  104.     void monitor();
  105.     /**
  106.      *  @brief Checks if the process is running or not
  107.      *
  108.      *  @return 
  109.      *          - true if the process is running,
  110.      *          - false if the process is not running
  111.      */
  112.     bool isRunning();
  113.     /** @brief Starts the process */
  114.     int start();
  115.     /** @brief Stops the process */
  116.     void stop();      
  117.     /** 
  118.      *  @brief Reads the pid from stable storage
  119.      *
  120.      *  @return The pid number
  121.      */
  122.     int readPid();
  123.     /** 
  124.      *  @brief Writes the pid from stable storage
  125.      *
  126.      *  @return 
  127.      *          - 0 if successful
  128.                 - -1 and sets errno if an error occured
  129.      */
  130.     int writePid(int pid);
  131.     /**
  132.      *  @brief Prints a textual description of the process on a file
  133.      */
  134.     void print(FILE *);
  135.     /** Id number of the Process.
  136.      *
  137.      *  @note This is not the same as a pid. This number is used in the
  138.      *        protocol, and will not be changed if a processes is restarted.
  139.      */
  140.     int m_id;
  141.     /** @brief The name shown to the user */
  142.     BaseString m_name;  
  143.     /** @brief Used to group a number of processes */
  144.     BaseString m_group;
  145.     /** @brief Environment variables
  146.      *
  147.      *  Environmentvariables to add for the process.
  148.      *
  149.      *  @note
  150.      *       - The environment cpcd started with is preserved
  151.      *       - There is no way to delete variables
  152.      */
  153.     BaseString m_env;
  154.     /** @brief Path to the binary to run */
  155.     BaseString m_path;
  156.     /** @brief Arguments to the process.
  157.      *
  158.      *  @note 
  159.      *        - This includes argv[0].
  160.      *        - If no argv[0] is given, argv[0] will be set to m_path.
  161.      */
  162.     BaseString m_args;
  163.     /** 
  164.      * @brief Type of process
  165.      *
  166.      *  Either set to "interactive" or "permanent".
  167.      */
  168.     BaseString m_type;
  169.     ProcessType m_processType;
  170.     
  171.     /** 
  172.      *  @brief Working directory
  173.      *
  174.      * Working directory the process will start in.
  175.      */
  176.     BaseString m_cwd;
  177.     /**
  178.      *  @brief Owner of the process.
  179.      *
  180.      *  @note This will not affect the process' uid or gid;
  181.      *        it is only used for managemental purposes.
  182.      *  @see m_runas
  183.      */
  184.     BaseString m_owner;
  185.     /**
  186.      * @bried Run as
  187.      * @note This affects uid
  188.      * @see m_owner
  189.      */
  190.     BaseString m_runas;
  191.     /**
  192.      * @brief redirection for stdin
  193.      */
  194.     BaseString m_stdin;
  195.     /**
  196.      * @brief redirection for stdout
  197.      */
  198.     BaseString m_stdout;
  199.     /**
  200.      * @brief redirection for stderr
  201.      */
  202.     BaseString m_stderr;
  203.     /** @brief Status of the process */
  204.     enum ProcessStatus m_status;
  205.     /**
  206.      * @brief ulimits for process
  207.      * @desc Format c:unlimited d:0 ...
  208.      */
  209.     BaseString m_ulimit;
  210.     /**
  211.      * @brief shutdown options
  212.      */
  213.     BaseString m_shutdown_options;
  214.   private:
  215.     class CPCD *m_cpcd;
  216.     void do_exec();
  217.   };
  218.   /**
  219.    *  @brief Starts and stops processes as needed
  220.    *
  221.    *  At a specified interval (default 5 seconds) calls the monitor function
  222.    *  of all the processes in the CPCDs list, causing the to start or
  223.    *  stop, depending on the configuration.
  224.    */
  225.   class Monitor {
  226.   public:
  227.     /** Creates a new CPCD::Monitor object, connected to the specified
  228.      * CPCD.
  229.      *  A new thread will be created, which will poll the processes of
  230.      *  the CPCD at the specifed interval.
  231.      */
  232.     Monitor(CPCD *cpcd, int poll = CPCD_DEFAULT_POLLING_INTERVAL);
  233.     /** Stops the monitor, but does not stop the processes */
  234.     ~Monitor();
  235.     /** Runs the monitor thread. */
  236.     void run();
  237.     /** Signals configuration changes to the monitor thread, causing it to
  238.      *  do the check without waiting for the timeout */
  239.     void signal();
  240.   private:
  241.     class CPCD *m_cpcd;
  242.     struct NdbThread *m_monitorThread;
  243.     bool m_monitorThreadQuitFlag;
  244.     struct NdbCondition *m_changeCondition;
  245.     NdbMutex *m_changeMutex;
  246.     int m_pollingInterval; /* seconds */
  247.   };
  248.   /** @brief Constructs a CPCD object */
  249.   CPCD();
  250.   /** 
  251.    * @brief Destroys a CPCD object, 
  252.    * but does not stop the processes it manages 
  253.    */
  254.   ~CPCD();
  255.   /** Adds a Process to the CPCDs list of managed Processes.
  256.    *
  257.    *  @note The process will not be started until it is explicitly
  258.    *        marked as running with CPCD::startProcess().
  259.    *
  260.    *  @return 
  261.    *          - true if the addition was successful,
  262.    *          - false if not
  263.    *          - RequestStatus will be filled in with a suitable error
  264.    *            if an error occured.
  265.    */
  266.   bool defineProcess(RequestStatus *rs, Process * arg);
  267.   /** Removes a Process from the CPCD.
  268.    *
  269.    *  @note A Process that is running cannot be removed.
  270.    *
  271.    *  @return
  272.    *          - true if the removal was successful,
  273.    *          - false if not
  274.    *          - The RequestStatus will be filled in with a suitable error
  275.    *            if an error occured.
  276.    */
  277.   bool undefineProcess(RequestStatus *rs, int id);
  278.   /** Marks a Process for starting.
  279.    *
  280.    *  @note The fact that a process has started does not mean it will actually
  281.    *        start properly. This command only makes sure the CPCD will
  282.    *        try to start it.
  283.    *
  284.    *  @return 
  285.    *          - true if the marking was successful
  286.    *          - false if not
  287.    *          - RequestStatus will be filled in with a suitable error
  288.    *            if an error occured.
  289.    */
  290.   bool startProcess(RequestStatus *rs, int id);
  291.   /** Marks a Process for stopping.
  292.    *
  293.    *  @return 
  294.    *          - true if the marking was successful
  295.    *          - false if not
  296.    *          - The RequestStatus will be filled in with a suitable error
  297.    *            if an error occured.
  298.    */
  299.   bool stopProcess(RequestStatus *rs, int id);
  300.   
  301.   /** Generates a list of processes, and sends them to the CPCD client */
  302.   bool listProcesses(RequestStatus *rs, MutexVector<const char *> &);
  303.   /** Set to true while the CPCD is reading the configuration file */
  304.   bool loadingProcessList;
  305.   /** Saves the list of Processes and their status to the configuration file.
  306.    *  Called whenever the configuration is changed.
  307.    */
  308.   bool saveProcessList();
  309.   /** Loads the list of Processes and their status from the configuration
  310.    *  file.
  311.    *  @note This function should only be called when the CPCD is starting,
  312.    *        calling it at other times will cause unspecified behaviour.
  313.    */
  314.   bool loadProcessList();
  315.   /** Returns the list of processes */
  316.   MutexVector<Process *> *getProcessList();
  317.   /** The list of processes. Should not be used directly */
  318.   MutexVector<Process *> m_processes;
  319.   /** Register event subscriber */
  320.   void do_register(EventSubscriber * sub);
  321.   EventSubscriber* do_unregister(EventSubscriber * sub);
  322.   
  323. private:
  324.   friend class Process;  
  325.   bool notifyChanges();
  326.   int findUniqueId();
  327.   BaseString m_procfile;
  328.   Monitor *m_monitor;
  329.   
  330.   void report(int id, CPCEvent::EventType);
  331.   MutexVector<EventSubscriber *> m_subscribers;
  332. };
  333. #endif