* Copyright (c) 2021 Huawei Technologies Co.,Ltd.
*
* CM is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* ctl_distribute.h
*
*
* IDENTIFICATION
* include/cm/cm_ctl/ctl_common.h
*
* -------------------------------------------------------------------------
*/
#ifndef CTL_COMMON_H
#define CTL_COMMON_H
#include "cjson/cJSON.h"
#include "cm/cm_msg.h"
#include "cm/cm_misc.h"
#include "cm/cm_defs.h"
#include "cm_ddb_adapter.h"
#include "cm_cipher.h"
#include "ctl_global_params.h"
#include "cm_json_config.h"
#include "ctl_res.h"
#define DEFAULT_WAIT 60
#define DYNAMIC_PRIMARY 0
#define DYNAMIC_STANDBY 1
#define RELOAD_WAIT_TIME 60
#define MAX_COMMAND_LEN 2048
#define ETCD_BIN_NAME "etcd"
#ifndef ENABLE_MULTIPLE_NODES
#define ITRAN_BIN_NAME "ltran"
#endif
#define CM_CTL_BIN_NAME "cm_ctl"
* ssh connect does not exit automatically when the network is fault,
* this will cause cm_ctl hang for several hours,
* so we should add the following timeout options for ssh
*/
#define SSH_CONNECT_TIMEOUT "5"
#define SSH_CONNECT_ATTEMPTS "3"
#define SSH_SERVER_ALIVE_INTERVAL "15"
#define SSH_SERVER_ALIVE_COUNT_MAX "3"
#define PSSH_TIMEOUT_OPTION \
" -t 60 -O ConnectTimeout=" SSH_CONNECT_TIMEOUT " -O ConnectionAttempts=" SSH_CONNECT_ATTEMPTS \
" -O ServerAliveInterval=" SSH_SERVER_ALIVE_INTERVAL " -O ServerAliveCountMax=" SSH_SERVER_ALIVE_COUNT_MAX " "
const int OPTION_POS = 2;
const int EXEC_DDC_CMD_TIMEOUT = 60;
const int PARALLELISM_MIN = 0;
const int PARALLELISM_MAX = 16;
const int SHARED_STORAGE_MODE_TIMEOUT = 120;
const int CTL_RECV_CYCLE = 200000;
#define FINISH_CONNECTION(conn, ret) \
do { \
CMPQfinish(conn); \
(conn) = NULL; \
return ret; \
} while (0)
#define FINISH_CONNECTION_WITHOUT_EXITCODE(conn) \
do { \
CMPQfinish(conn); \
(conn) = NULL; \
} while (0)
typedef enum {
NO_COMMAND = 0,
RESTART_COMMAND,
START_COMMAND,
STOP_COMMAND,
CM_SWITCHOVER_COMMAND,
CM_BUILD_COMMAND,
CM_REMOVE_COMMAND,
CM_QUERY_COMMAND,
CM_SET_COMMAND,
CM_GET_COMMAND,
CM_STARTCM_COMMAND,
CM_STOPCM_COMMAND,
CM_SYNC_COMMAND,
CM_VIEW_COMMAND,
CM_CHECK_COMMAND,
CM_SETMODE_COMMAND,
CM_HOTPATCH_COMMAND,
CM_DISABLE_COMMAND,
CM_FINISHREDO_COMMAND,
CM_DCF_SETRUNMODE_COMMAND,
CM_DCF_CHANGEROLE_COMMAND,
CM_DCF_CHANGEMEMBER_COMMAND,
CM_RELOAD_COMMAND,
CM_LIST_COMMAND,
CM_ENCRYPT_COMMAND,
CM_SWITCH_COMMAND,
CM_RES_COMMAND,
CM_SHOW_COMMAND,
CM_PAUSE_COMMAND,
CM_RESUME_COMMAND,
CM_RACK_COMMAND
} CtlCommand;
typedef enum {
UNKNOWN_NODE = 0,
FAILED_NODE = 1,
ONLINE_NODE = 2,
STOPPING_NODE = 3,
NORMAL_NODE = 4,
UNINSTALL_NODE = 127,
DISCONNECT_NODE = 255
} ErrCode;
typedef enum {
PSSH_SUCCESS = 0,
PSSH_TIMEOUT = 4,
COMMAND_TIMEOUT = 5,
} ExitCode;
typedef enum GucCommandSt {
UNKNOWN_COMMAND = 0,
SET_CONF_COMMAND,
RELOAD_CONF_COMMAND,
LIST_CONF_COMMAND
} GucCommand;
typedef enum NodeTypeEn {
NODE_TYPE_UNDEF = 0,
NODE_TYPE_AGENT,
NODE_TYPE_SERVER,
} NodeType;
typedef struct CommonOptionSt {
uint32 nodeId;
char *dataPath;
} CommonOption;
typedef struct SwitchoverOptionSt {
bool switchoverAll;
bool switchoverFull;
bool switchoverFast;
} SwitchoverOption;
typedef struct GucOptionSt {
GucCommand gucCommand;
NodeType nodeType;
KeyMode keyMod;
char *parameter;
char *value;
bool needDoGuc;
} GucOption;
typedef struct BuildOptionSt {
bool isNeedCmsBuild;
int parallel;
int doFullBuild;
} BuildOption;
typedef struct SwitchOptionSt {
char *ddbType;
bool isCommit;
bool isRollback;
} SwitchOption;
typedef struct DcfOptionSt {
char *role;
int group;
int priority;
} DcfOption;
typedef struct CtlOptionSt {
CommonOption comm;
GucOption guc;
BuildOption build;
SwitchoverOption switchover;
SwitchOption switchOption;
DcfOption dcfOption;
ResOption resOpt;
} CtlOption;
extern bool g_isRestop;
extern DdbConn *g_sess;
extern TlsAuthPath g_tlsPath;
extern bool g_isPauseArbitration;
extern bool g_enableWalRecord;
extern bool g_wormUsageQuery;
extern int g_wormUsage;
status_t do_start(void);
int DoStop(void);
int do_query(void);
int do_global_barrier_query(void);
int DoKickOutStatQuery(void);
int DoSwitchover(const CtlOption *ctx);
int do_finish_redo(void);
#ifdef ENABLE_MULTIPLE_NODES
void do_logic_cluster_restart(void);
#endif
int do_set(void);
int do_get(void);
int do_check(void);
int DoBuild(const CtlOption *ctx);
void set_mode(const char* modeopt);
int do_disable_cn();
int do_hotpatch(const char* command, const char* path);
int do_setmode();
void DoAdvice(void);
int DoSetRunMode(void);
int DoChangeMember(const CtlOption *ctx);
int DoReload();
int DoChangeRole(const CtlOption *ctx);
int CheckInstanceStatus(const char* processName, const char* cmdLine);
void DoDccCmd(int argc, char **argv);
int DoGuc(CtlOption *ctx);
int DoEncrypt(const CtlOption *ctx);
int DoSwitch(const CtlOption *ctx);
int DoShowCommand();
int DoRack();
void stop_etcd_cluster(void);
int stop_check_node(uint32 node_id_check);
void stop_etcd_node(uint32 nodeid);
void stop_instance(uint32 nodeid, const char *datapath);
void start_instance(uint32 nodeid, const char* datapath);
void* pg_malloc(size_t size);
uint32 get_node_index(uint32 node_id);
bool isMajority(const char* cm_arbitration_mode);
bool isMinority(const char* cm_arbitration_mode);
int FindInstanceIdAndType(uint32 node, const char* dataPath, uint32* instanceId, int* instanceType);
int ssh_exec(const staticNodeConfig* node, const char* cmd, int32 logLevel = ERROR);
int SshExec(const staticNodeConfig* node, const char* cmd);
int RunEtcdCmd(const char* command, uint32 nodeIndex);
void do_conn_cmserver(bool queryCmserver, uint32 nodeIndex, bool queryEtcd = false, struct cm_conn **curConn = NULL);
int cm_client_flush_msg(struct cm_conn* conn);
int cm_client_send_msg(struct cm_conn* conn, char msgtype, const char* s, size_t len);
char* recv_cm_server_cmd(struct cm_conn* conn);
void init_hosts();
bool is_node_stopping(uint32 checkNode, uint32 currentNode, const char *manualStartFile, const char *resultFile,
const char *mppEnvSeperateFile);
char* xstrdup(const char* s);
void CheckDnNodeStatusById(uint32 node_id_check, int* result, uint32 dnIndex);
void CheckGtmNodeStatusById(uint32 node_id_check, int* result);
void CheckCnNodeStatusById(uint32 node_id_check, int* result);
int checkStaticConfigExist(uint32 nodeIndex);
status_t SendKVToCms(const char *key, const char *value, const char *threadName);
int cmctl_getenv(const char* env_var, char* output_env_value, uint32 env_value_len);
time_t get_start_time();
time_t check_with_end_time(const time_t start_time);
void exec_system_ssh(uint32 remote_nodeid, const char *cmd, int *result, const char *resultPath,
const char *mppEnvSeperateFile);
void exec_system(const char *cmd, int *result, const char *resultPath);
int runCmdByNodeId(const char* command, uint32 nodeid);
int caculate_default_timeout(CtlCommand cmd);
int CheckClusterRunningStatus();
int CheckSingleClusterRunningStatus();
extern bool backup_process_query;
int GetDatanodeRelationInfo(uint32 nodeId, const char *cmData, cm_to_ctl_get_datanode_relation_ack *getInstanceMsg);
void InstanceInformationRecord(uint32 nodeIndex, const cm_to_ctl_instance_status* cmToCtlInstanceStatusPtr);
status_t ServerDdbInit(void);
void FreeDdbInfo(void);
bool CheckDdbHealth(void);
bool IsCmsPrimary(const staticNodeConfig *node);
void InitCtlOptionParams(CtlOption *ctx);
status_t CheckGucSetParameter(const CtlOption *ctx);
status_t ExeGucCommand(const GucOption *gucCtx);
status_t ProcessInLocalInstance(const GucOption *gucCtx);
status_t CheckConfigFileStatus(struct stat statBuf, struct stat tmpBuf);
void SetServerSocketWithEtcdInfo(ServerSocket *server, staticNodeConfig *node);
status_t ProcessClusterGucOption(CtlOption *ctx);
status_t KillAllCms(bool isNeedKillPrimaryCms);
uint32 *GetCmsNodeIndex(void);
status_t CheckGucOptionValidate(const GucOption &gucCtx);
void GetUpgradeVersionFromCmaConfig();
bool SetOfflineNode(uint32 nodeIndex, struct cm_conn *con);
void ReleaseConn(struct cm_conn *con);
bool IsCmSharedStorageMode();
void CtlGetCmJsonConf();
int DoRhbPrint();
int DoPause();
int DoResume();
bool CheckTrustAndNet();
bool IsTimeOut(const cmTime_t *lastTime, const char *str);
void RemoveStartingFile();
void getPauseStatus();
void getWalrecordMode();
uint32 GetLockOwnerInstanceId();
status_t CheckDynamicRelationCount(uint32 relationCount, size_t *roleGroupsBytesOut);
#endif