openGauss-server/contrib/pgxc_ctl/do_command.cpp

2119 lines
74 KiB
C++

/*-------------------------------------------------------------------------
*
* do_command.c
*
* Main command module of Postgres-XC configuration and operation tool.
*
* Copyright (c) 2013 Postgres-XC Development Group
*
*-------------------------------------------------------------------------
*/
/*
* This file provides a frontend module to pgxc_ctl operation.
*/
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <setjmp.h>
#include <string.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "pgxc_ctl.h"
#include "do_command.h"
#include "variables.h"
#include "varnames.h"
#include "pgxc_ctl_log.h"
#include "config.h"
#include "do_shell.h"
#include "utils.h"
#include "gtm_cmd.h"
#include "coord_cmd.h"
#include "datanode_cmd.h"
#include "gtm_util.h"
#include "monitor.h"
extern char* pgxc_ctl_conf_prototype[];
#define Exit(c) exit(myWEXITSTATUS(c))
#define GetToken() (line = get_word(line, &token))
#define TestToken(word) ((token != NULL) && (strcasecmp(token, word) == 0))
#define testToken(word) ((token != NULL) && (strcmp(token, word) == 0))
static void kill_something(char* token);
static void do_deploy(char* line);
static void deploy_xc(char** hostlist);
static void show_config_something(char* nodeName);
static void show_config_something_multi(char** nodeList);
extern void show_config_hostList(char** hostList);
static void show_config_host(char* hostname);
static void show_basicConfig(void);
static void show_config_servers(char** hostList);
static void do_clean_command(char* line);
static void do_start_command(char* line);
static void start_all(void);
static void do_stop_command(char* line);
static void stop_all(char* immediate);
static int show_Resource(char* datanodeName, char* databasename, char* username);
static void do_echo_command(char* line)
{
printf("do_echo_command\n");
}
static void do_prepareConfFile(char* Path)
{
char* path = NULL;
FILE* conf = NULL;
int ii;
if (Path)
path = Path;
else {
if (find_var(VAR_configFile) && sval(VAR_configFile))
path = sval(VAR_configFile);
else {
elog(ERROR, "ERROR: Configuration file path was not specified.\n");
return;
}
}
conf = fopen(path, "w");
if (conf == NULL) {
elog(ERROR, "ERROR: Could not open the configuration file \"%s\", %s.\n", path, strerror(errno));
return;
}
for (ii = 0; pgxc_ctl_conf_prototype[ii]; ii++) {
fprintf(conf, "%s\n", pgxc_ctl_conf_prototype[ii]);
}
fclose(conf);
return;
}
/*
* Deploy pgxc binaries
*/
static void do_deploy(char* line)
{
char* token = NULL;
char** hostlist = NULL;
if (GetToken() == NULL) {
elog(ERROR, "ERROR: Please specify option for deploy command.\n");
return;
}
if (TestToken("all")) {
elog(NOTICE, "Deploying Postgres-XC materials to all the target servers.\n");
deploy_xc(aval(VAR_allServers));
} else {
elog(NOTICE, "Deploying Postgres-XC materials.\n");
/*
* Please note that the following code does not check if the specified nost
* appears in the configuration file.
* We should deploy xc binary to the target not in the current configuraiton
* to add gtm slave, gtm_proxy, coordinator/datanode master/slave online.
*/
do {
AddMember(hostlist, token);
} while (GetToken());
deploy_xc(hostlist);
CleanArray(hostlist);
}
}
static void deploy_xc(char** hostlist)
{
char tarFile[MAXPATH + 1];
cmdList_t* cmdList = NULL;
int ii;
/* Build tarball --> need to do foreground */
elog(NOTICE, "Prepare tarball to deploy ... \n");
snprintf(tarFile, MAXPATH, "%d.tgz", getpid());
doImmediate(NULL,
NULL,
"tar czCf %s %s/%s bin include lib share",
sval(VAR_pgxcInstallDir),
sval(VAR_localTmpDir),
tarFile);
/* Backgroud jobs */
cmdList = initCmdList();
/* Build install dir */
for (ii = 0; hostlist[ii]; ii++) {
cmd_t* cmd = NULL;
cmd_t* cmdScp = NULL;
cmd_t* cmdTarExtract = NULL;
elog(NOTICE, "Deploying to the server %s.\n", hostlist[ii]);
/* Build target directory */
addCmd(cmdList, (cmd = initCmd(hostlist[ii])));
snprintf(newCommand(cmd),
MAXLINE,
"rm -rf %s/bin %s/include %s/lib %s/share; mkdir -p %s",
sval(VAR_pgxcInstallDir),
sval(VAR_pgxcInstallDir),
sval(VAR_pgxcInstallDir),
sval(VAR_pgxcInstallDir),
sval(VAR_pgxcInstallDir));
/* SCP tarball */
appendCmdEl(cmd, (cmdScp = initCmd(NULL)));
snprintf(newCommand(cmdScp),
MAXLINE,
"scp %s/%s %s@%s:%s",
sval(VAR_localTmpDir),
tarFile,
sval(VAR_pgxcUser),
hostlist[ii],
sval(VAR_tmpDir));
/* Extract Tarball and remove it */
appendCmdEl(cmd, (cmdTarExtract = initCmd(hostlist[ii])));
snprintf(newCommand(cmdTarExtract),
MAXLINE,
"tar xzCf %s %s/%s; rm %s/%s",
sval(VAR_pgxcInstallDir),
sval(VAR_tmpDir),
tarFile,
sval(VAR_tmpDir),
tarFile);
}
doCmdList(cmdList);
cleanCmdList(cmdList);
doImmediate(NULL, NULL, "rm -f %s/%s", sval(VAR_tmpDir), tarFile);
elog(NOTICE, "Deployment done.\n");
}
static void do_set(char* line)
{
char* token = NULL;
char* varname = NULL;
pgxc_ctl_var* var = NULL;
if (GetToken() == NULL) {
elog(ERROR, "ERROR: No variable name was given\n");
return;
}
varname = Strdup(token);
var = confirm_var(varname);
reset_value(var);
while (GetToken()) {
add_val(var, token);
}
print_var(varname);
log_var(varname);
return;
}
/*
* Failover command ... failover gtm
* failover coordinator nodename
* failover datanode nodename
* failover nodename
*/
static void do_failover_command(char* line)
{
char* token = NULL;
int idx;
if (GetToken() == NULL) {
elog(ERROR, "ERROR: Please specify failover command option.\n");
return;
} else if (TestToken("gtm")) {
if (isVarYes(VAR_gtmSlave) && !is_none(sval(VAR_gtmSlaveServer)))
failover_gtm();
else
elog(ERROR, "ERROR: no gtm slave is configured.\n");
return;
} else if (TestToken("coordinator")) {
if (!isVarYes(VAR_coordSlave))
elog(ERROR, "ERROR: coordinator slave is not configured.\n");
else if (!GetToken())
elog(ERROR, "ERROR: please specify failover coordinator command option.\n");
else {
char** nodeList = NULL;
do {
if ((idx = coordIdx(token)) < 0)
elog(ERROR, "ERROR: %s is not a coordinator\n", token);
else if (is_none(aval(VAR_coordSlaveServers)[idx]))
elog(ERROR, "ERROR: slave for the coordinator %s is not configured.\n", token);
else
AddMember(nodeList, token);
} while (GetToken());
if (nodeList)
failover_coordinator(nodeList);
CleanArray(nodeList);
}
return;
} else if (TestToken("datanode")) {
if (!isVarYes(VAR_datanodeSlave))
elog(ERROR, "ERROR: datanode slave is not configired.\n");
else if (!GetToken())
elog(ERROR, "ERROR: please specify failover datanode command option.\n");
else {
char** nodeList = NULL;
do {
if ((idx = datanodeIdx(token)) < 0)
elog(ERROR, "ERROR: %s is not a datanode.\n", token);
else if (is_none(aval(VAR_datanodeSlaveServers)[idx]))
elog(ERROR, "ERROR: slave for the datanode %s is not configured,\n", token);
else
AddMember(nodeList, token);
} while (GetToken());
if (nodeList)
failover_datanode(nodeList);
CleanArray(nodeList);
}
} else
elog(ERROR, "ERROR: invalid failover command option %s.\n", token);
}
/*
* Reconnect command ... reconnect gtm_proxy [all | nodename ... ]
*/
static void do_reconnect_command(char* line)
{
char* token = NULL;
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specifiy option to reconnect command.\n");
else if (TestToken("gtm_proxy")) {
if (!isVarYes(VAR_gtmProxy))
elog(ERROR, "ERROR: gtm proxy is not configured.\n");
else if ((GetToken() == NULL) || TestToken("all"))
reconnect_gtm_proxy_all();
else {
char** nodeList = NULL;
int idx;
do {
if ((idx = gtmProxyIdx(token)) < 0)
elog(ERROR, "ERROR: %s is not gtm_proxy.\n", token);
else
AddMember(nodeList, token);
} while (GetToken());
if (nodeList)
reconnect_gtm_proxy(nodeList);
CleanArray(nodeList);
}
} else
elog(ERROR, "ERROR: invalid option %s for reconnect command.\n", token);
return;
}
/*
* Kill command ... kill nodename, kill all,
* kill gtm [master|slave|all],
* kill gtm_proxy [nodename|all] ...
* kill coordinator [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
* kill datanode [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
*/
static void do_kill_command(char* line)
{
char* token = NULL;
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specifiy option to kill command\n");
else if (TestToken("gtm")) {
if ((GetToken() == NULL) || TestToken("all")) {
kill_gtm_master();
if (isVarYes(VAR_gtmSlave))
kill_gtm_slave();
} else if (TestToken("master"))
kill_gtm_master();
else if (TestToken("slave")) {
if (isVarYes(VAR_gtmSlave))
kill_gtm_slave();
else
elog(ERROR, "ERROR: GTM slave is not configured.\n");
} else
elog(ERROR, "ERROR: input value \"%s\" is invalid.\n", token);
return;
} else if (TestToken("gtm_proxy")) {
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify additonal option to kill gtm_proxies\n");
else if (TestToken("all"))
kill_gtm_proxy(aval(VAR_gtmProxyNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_gtm_proxy(nodeList);
clean_array(nodeList);
}
return;
} else if (TestToken("coordinator")) {
if ((GetToken() == NULL) || TestToken("all")) {
kill_coordinator_master(aval(VAR_coordNames));
if (isVarYes(VAR_coordSlave))
kill_coordinator_slave(aval(VAR_coordNames));
}
if (TestToken("master")) {
if ((GetToken() == NULL) || (TestToken("all")))
kill_coordinator_master(aval(VAR_coordNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_coordinator_master(nodeList);
clean_array(nodeList);
}
} else if (TestToken("slave")) {
if ((GetToken() == NULL) || (TestToken("all")))
kill_coordinator_slave(aval(VAR_coordNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_coordinator_slave(nodeList);
clean_array(nodeList);
}
} else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
kill_coordinator_slave(nodeList);
clean_array(nodeList);
}
return;
} else if (TestToken("datanode")) {
if ((GetToken() == NULL) || (TestToken("all"))) {
kill_datanode_master(aval(VAR_datanodeNames));
if (isVarYes(VAR_datanodeSlave))
kill_datanode_slave(aval(VAR_coordNames));
} else if (TestToken("master")) {
if ((GetToken() == NULL) || (TestToken("all")))
kill_datanode_master(aval(VAR_datanodeNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_datanode_master(nodeList);
clean_array(nodeList);
}
} else if (TestToken("slave")) {
if ((GetToken() == NULL) || (TestToken("all")))
kill_datanode_slave(aval(VAR_datanodeNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_datanode_slave(nodeList);
clean_array(nodeList);
}
} else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
kill_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
kill_datanode_slave(nodeList);
clean_array(nodeList);
}
} else if (TestToken("all")) {
if (isVarYes(VAR_datanodeSlave))
kill_datanode_slave(aval(VAR_datanodeNames));
kill_datanode_master(aval(VAR_datanodeNames));
if (isVarYes(VAR_coordSlave))
kill_coordinator_slave(aval(VAR_coordNames));
kill_coordinator_master(aval(VAR_coordNames));
if (isVarYes(VAR_gtmProxy))
kill_gtm_proxy(aval(VAR_gtmProxyNames));
if (isVarYes(VAR_gtmSlave))
kill_gtm_slave();
kill_gtm_master();
} else {
do {
kill_something(token);
} while (GetToken());
}
return;
}
static void init_all(void)
{
init_gtm_master();
start_gtm_master();
if (isVarYes(VAR_gtmSlave)) {
init_gtm_slave();
start_gtm_slave();
}
if (isVarYes(VAR_gtmProxy)) {
init_gtm_proxy_all();
start_gtm_proxy_all();
}
init_coordinator_master_all();
start_coordinator_master_all();
if (isVarYes(VAR_coordSlave)) {
init_coordinator_slave_all();
start_coordinator_slave_all();
}
init_datanode_master_all();
start_datanode_master_all();
if (isVarYes(VAR_datanodeSlave)) {
init_datanode_slave_all();
start_datanode_slave_all();
}
configure_nodes_all();
}
/*
* Init command ... init all
* init gtm [master|slave|all],
* init gtm_proxy [all| nodename ...]
* init coordinator [all | master [all | nodename ... ]| slave [all | nodename ... ]| nodename ... ]
* init datanode [all | master [all | nodename ...] | slave [all | nodename ... ] | nodename ... ]
*/
static void do_init_command(char* line)
{
char* token = NULL;
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify option to init command.\n");
else if (TestToken("all"))
init_all();
else if (TestToken("gtm")) {
if (!GetToken() || (TestToken("all"))) {
init_gtm_master();
if (isVarYes(VAR_gtmSlave))
init_gtm_slave();
} else if (TestToken("master"))
init_gtm_master();
else if (TestToken("slave"))
init_gtm_slave();
else
elog(ERROR, "ERROR: please specify master, slave or all for init gs_gtm command.\n");
} else if (TestToken("gtm_proxy"))
if (!GetToken() || TestToken("all"))
init_gtm_proxy_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
init_gtm_proxy(nodeList);
clean_array(nodeList);
}
else if (TestToken("coordinator"))
if (!GetToken() || TestToken("all")) {
init_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
init_coordinator_slave_all();
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
init_coordinator_master_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
init_coordinator_master(nodeList);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
init_coordinator_slave_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do {
AddMember(nodeList, token);
} while (GetToken());
init_coordinator_slave(nodeList);
clean_array(nodeList);
}
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
init_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
init_coordinator_slave(nodeList);
clean_array(nodeList);
}
else if (TestToken("datanode"))
if (!GetToken() || TestToken("all")) {
init_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
init_datanode_slave_all();
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
init_datanode_master_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
init_datanode_master(nodeList);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
init_datanode_slave_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
init_datanode_slave(nodeList);
clean_array(nodeList);
}
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
init_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
init_datanode_slave(nodeList);
}
else
elog(ERROR, "ERROR: invalid option for init command.\n");
return;
}
/*
* Start command ... start nodename, start all,
* start gtm [master|slave|all],
* start gtm_proxy [nodename|all] ...
* start coordinator [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
* start datanode [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
*/
static void start_all(void)
{
start_gtm_master();
if (isVarYes(VAR_gtmSlave))
start_gtm_slave();
if (isVarYes(VAR_gtmProxy))
start_gtm_proxy_all();
start_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
start_coordinator_slave_all();
start_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
start_datanode_slave_all();
}
static void do_start_command(char* line)
{
char* token = NULL;
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify option to start command.\n");
else if (TestToken("all"))
start_all();
else if (TestToken("gtm")) {
if (!GetToken() || (TestToken("all"))) {
start_gtm_master();
if (isVarYes(VAR_gtmSlave))
start_gtm_slave();
} else if (TestToken("master"))
start_gtm_master();
else if (TestToken("slave"))
start_gtm_slave();
else
elog(ERROR, "ERROR: please specify master, slave or all for start gs_gtm command.\n");
} else if (TestToken("gtm_proxy"))
if (!GetToken() || TestToken("all"))
start_gtm_proxy_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
start_gtm_proxy(nodeList);
clean_array(nodeList);
}
else if (TestToken("coordinator"))
if (!GetToken() || TestToken("all")) {
start_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
start_coordinator_slave_all();
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
start_coordinator_master_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
start_coordinator_master(nodeList);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
start_coordinator_slave_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
start_coordinator_slave(nodeList);
clean_array(nodeList);
}
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
start_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
start_coordinator_slave(nodeList);
clean_array(nodeList);
}
else if (TestToken("datanode"))
if (!GetToken() || TestToken("all")) {
start_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
start_datanode_slave_all();
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
start_datanode_master_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
start_datanode_master(nodeList);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
start_datanode_slave_all();
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
start_datanode_slave(nodeList);
clean_array(nodeList);
}
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
start_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
start_datanode_slave(nodeList);
}
else
elog(ERROR, "ERROR: invalid option for start command.\n");
return;
}
/*
* Stop command ... stop nodename, start all,
* stop gtm [master|slave|all],
* stop gtm_proxy [nodename|all] ...
* stop coordinator [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
* stop datanode [nodename ... |master [all | nodenames ... ] | slave [all | nodenames ... ] |all]
*
* Can insert -m immediate option at any place.
*/
static void stop_all(char* immediate)
{
if (isVarYes(VAR_coordSlave))
stop_coordinator_slave_all(immediate);
stop_coordinator_master_all(immediate);
if (isVarYes(VAR_datanodeSlave))
stop_datanode_slave_all(immediate);
stop_datanode_master_all(immediate);
if (isVarYes(VAR_gtmProxy))
stop_gtm_proxy_all();
if (isVarYes(VAR_gtmSlave))
stop_gtm_slave();
stop_gtm_master();
}
#define GetAndSet(var, msg) \
do { \
if (!GetToken()) { \
elog(ERROR, msg); \
return; \
} \
var = Strdup(token); \
} while (0)
/*
* Add command
*/
static void do_add_command(char* line)
{
char* token = NULL;
char* name = NULL;
char* host = NULL;
char* port = NULL;
char* pooler = NULL;
char* dir = NULL;
char* archDir = NULL;
if (!GetToken()) {
elog(ERROR, "ERROR: Specify options for add command.\n");
return;
}
if (TestToken("gtm")) {
/*
* add gtm slave name host port dir
*/
if (!GetToken()) {
elog(ERROR, "ERROR: Specify option for add gs_gtm command.\n");
return;
}
if (!TestToken("slave")) {
elog(ERROR, "ERROR: you can specify only slave to add gs_gtm command. %s is invalid.\n", token);
return;
}
GetAndSet(name, "ERROR: please specify the name of gtm slave\n");
GetAndSet(host, "ERROR: please specify the host name for gtm slave\n");
GetAndSet(port, "ERROR: please specify the port number for gtm slave\n");
GetAndSet(dir, "ERROR: please specify the working director for gtm slave\n");
add_gtmSlave(name, host, atoi(port), dir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(port);
freeAndReset(dir);
} else if (TestToken("gtm_proxy")) {
/*
* Add gtm_proxy name host port dir
*/
GetAndSet(name, "ERROR: please specify the name of gtm_proxy\n");
GetAndSet(host, "ERROR: please specify the host name for gtm_proxy\n");
GetAndSet(port, "ERROR: please specify the port number for gtm_proxy\n");
GetAndSet(dir, "ERROR: please specify the working director for gtm_proxy\n");
add_gtmProxy(name, host, atoi(port), dir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(port);
freeAndReset(dir);
} else if (TestToken("coordinator")) {
/*
* Add coordinator master name host port pooler dir
* Add coordinator slave name host dir
*/
if (!GetToken() || (!TestToken("master") && !TestToken("slave"))) {
elog(ERROR, "ERROR: please speify master or slave.\n");
return;
}
if (TestToken("master")) {
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
GetAndSet(host, "ERROR: please specify the host for the coordinator masetr\n");
GetAndSet(port, "ERROR: please specify the port number for the coordinator master\n");
GetAndSet(pooler, "ERROR: please specify the pooler port number for the coordinator master.\n");
GetAndSet(dir, "ERROR: please specify the working director for the coordinator master\n");
add_coordinatorMaster(name, host, atoi(port), atoi(pooler), dir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(port);
freeAndReset(pooler);
freeAndReset(dir);
} else {
GetAndSet(name, "ERROR: please specify the name of the coordinator slave\n");
GetAndSet(host, "ERROR: please specify the host for the coordinator slave\n");
GetAndSet(dir, "ERROR: please specify the working director for coordinator slave\n");
GetAndSet(archDir, "ERROR: please specify WAL archive directory for coordinator slave\n");
add_coordinatorSlave(name, host, dir, archDir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(dir);
}
} else if (TestToken("datanode")) {
if (!GetToken() || (!TestToken("master") && !TestToken("slave"))) {
elog(ERROR, "ERROR: please speify master or slave.\n");
return;
}
if (TestToken("master")) {
GetAndSet(name, "ERROR: please specify the name of the datanode master\n");
GetAndSet(host, "ERROR: please specify the host for the datanode masetr\n");
GetAndSet(port, "ERROR: please specify the port number for the datanode master\n");
GetAndSet(dir, "ERROR: please specify the working director for the datanode master\n");
add_datanodeMaster(name, host, atoi(port), dir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(port);
freeAndReset(dir);
} else {
GetAndSet(name, "ERROR: please specify the name of the datanode slave\n");
GetAndSet(host, "ERROR: please specify the host for the datanode slave\n");
GetAndSet(dir, "ERROR: please specify the working director for datanode slave\n");
GetAndSet(archDir, "ERROR: please specify WAL archive directory for datanode slave\n");
add_datanodeSlave(name, host, dir, archDir);
freeAndReset(name);
freeAndReset(host);
freeAndReset(dir);
}
}
return;
}
static void do_remove_command(char* line)
{
char* token = NULL;
char* name = NULL;
bool clean_opt = FALSE;
if (!GetToken()) {
elog(ERROR, "ERROR: Please specify gtm, gtm_master, coordinator or datanode after add command.\n");
return;
}
if (TestToken("gtm")) {
if (!GetToken() || !TestToken("slave")) {
elog(ERROR, "ERROR: Please speciy slave to add gs_gtm command\n");
return;
}
if (GetToken() && TestToken("clean"))
clean_opt = TRUE;
remove_gtmSlave(clean_opt);
} else if (TestToken("gtm_proxy")) {
GetAndSet(name, "ERROR: please specify gtm proxy name to remove.\n");
if (TestToken("clean")) {
clean_opt = TRUE;
freeAndReset(name);
GetAndSet(name, "ERROR: please specify gtm proxy name to remove.\n");
}
remove_gtmProxy(name, clean_opt);
freeAndReset(name);
} else if (TestToken("coordinator")) {
if (!GetToken() || (!TestToken("master") && !TestToken("slave"))) {
elog(ERROR, "ERROR: please speify master or slave.\n");
return;
}
if (TestToken("master")) {
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
if (TestToken("clean")) {
clean_opt = TRUE;
freeAndReset(name);
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
}
remove_coordinatorMaster(name, clean_opt);
freeAndReset(name);
} else {
GetAndSet(name, "ERROR: please specify the name of the coordinator slave\n");
if (TestToken("clean")) {
clean_opt = TRUE;
freeAndReset(name);
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
}
remove_coordinatorSlave(name, clean_opt);
freeAndReset(name);
}
} else if (TestToken("datanode")) {
if (!GetToken() || (!TestToken("master") && !TestToken("slave"))) {
elog(ERROR, "ERROR: please speify master or slave.\n");
return;
}
if (TestToken("master")) {
GetAndSet(name, "ERROR: please specify the name of the datanode master\n");
if (TestToken("clean")) {
clean_opt = TRUE;
freeAndReset(name);
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
}
remove_datanodeMaster(name, clean_opt);
freeAndReset(name);
} else {
GetAndSet(name, "ERROR: please specify the name of the datanode slave\n");
if (TestToken("clean")) {
clean_opt = TRUE;
freeAndReset(name);
GetAndSet(name, "ERROR: please specify the name of the coordinator master\n");
}
remove_datanodeSlave(name, clean_opt);
freeAndReset(name);
}
} else
elog(ERROR, "ERROR:Add command argument %s is invalid.\n", token);
return;
}
static char* m_Option;
static char* handle_m_option(char* line, char** m_option)
{
char* token = NULL;
freeAndReset(m_Option);
if (GetToken() == NULL)
return (line);
else if (TestToken("immediate"))
m_Option = Strdup("immediate");
else if (TestToken("fast"))
m_Option = Strdup("fast");
else if (TestToken("smart"))
m_Option = Strdup("smart");
else
elog(ERROR, "ERROR: specify smart, fast or immediate for -m option value.\n");
return (line);
}
static void do_stop_command(char* line)
{
char* token = NULL;
freeAndReset(m_Option);
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify option to stop command.\n");
else if (testToken("-m")) {
line = handle_m_option(line, &m_Option);
GetToken();
}
if (TestToken("all")) {
if (GetToken() && TestToken("-m"))
handle_m_option(line, &m_Option);
stop_all(m_Option);
} else if (TestToken("gtm")) {
if (m_Option)
elog(WARNING, "-m option is not available with gs_gtm. Ignoring.\n");
if (!GetToken() || (TestToken("all"))) {
stop_gtm_master();
if (isVarYes(VAR_gtmSlave))
stop_gtm_slave();
} else if (TestToken("master"))
stop_gtm_master();
else if (TestToken("slave"))
stop_gtm_slave();
else
elog(ERROR, "ERROR: please specify master, slave or all for stop gs_gtm command.\n");
} else if (TestToken("gtm_proxy")) {
if (m_Option)
elog(WARNING, "-m option is not available with gtm_prxy. Ignoring.\n");
if (!GetToken() || TestToken("all"))
stop_gtm_proxy_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
stop_gtm_proxy(nodeList);
clean_array(nodeList);
}
} else if (TestToken("coordinator"))
if (!GetToken() || TestToken("all")) {
stop_coordinator_master_all(m_Option);
if (isVarYes(VAR_coordSlave))
stop_coordinator_slave_all(m_Option);
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
stop_coordinator_master_all(m_Option);
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
stop_coordinator_master(nodeList, m_Option);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
stop_coordinator_slave_all(m_Option);
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
stop_coordinator_slave(nodeList, m_Option);
clean_array(nodeList);
}
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
stop_coordinator_master(nodeList, m_Option);
if (isVarYes(VAR_coordSlave))
stop_coordinator_slave(nodeList, m_Option);
clean_array(nodeList);
}
else if (TestToken("datanode"))
if (!GetToken() || TestToken("all")) {
stop_datanode_master_all(m_Option);
if (isVarYes(VAR_datanodeSlave))
stop_datanode_slave_all(m_Option);
} else if (TestToken("master"))
if (!GetToken() || TestToken("all"))
stop_datanode_master_all(m_Option);
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
stop_datanode_master(nodeList, m_Option);
clean_array(nodeList);
}
else if (TestToken("slave"))
if (!GetToken() || TestToken("all"))
stop_datanode_slave_all(m_Option);
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
stop_datanode_slave(nodeList, m_Option);
clean_array(nodeList);
}
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
stop_datanode_master(nodeList, m_Option);
if (isVarYes(VAR_datanodeSlave))
stop_datanode_slave(nodeList, m_Option);
}
else
elog(ERROR, "ERROR: invalid option for stop command.\n");
return;
}
/*
* Test staff
*/
static void do_test(char* line)
{
char* token = NULL;
int logLevel;
int printLevel;
logLevel = setLogMsgLevel(DEBUG3);
printLevel = setPrintMsgLevel(DEBUG3);
GetToken();
if (TestToken("ssh")) {
cmdList_t* cmdList = NULL;
cmd_t* cmd = NULL;
GetToken();
cmdList = initCmdList();
cmd = Malloc0(sizeof(cmd_t));
cmd->host = Strdup(token);
cmd->command = Strdup(line);
cmd->localStdin = NULL;
addCmd(cmdList, cmd);
elog(INFO, "INFO: Testing ssh %s \"%s\"\n", token, line);
doCmdList(cmdList);
cleanCmdList(cmdList);
} else if (TestToken("ssh-stdin")) {
cmdList_t* cmdList = NULL;
cmd_t* cmd = NULL;
cmdList = initCmdList();
cmd = Malloc0(sizeof(cmd_t));
GetToken();
cmd->host = Strdup(token);
GetToken();
cmd->localStdin = Strdup(token);
cmd->command = Strdup(line);
addCmd(cmdList, cmd);
elog(INFO, "Testing ssh %s \"%s\" < %s\n", cmd->host, cmd->command, cmd->localStdin);
doCmdList(cmdList);
cleanCmdList(cmdList);
} else if (TestToken("local")) {
cmdList_t* cmdList = NULL;
cmd_t* cmd = NULL;
cmdList = initCmdList();
addCmd(cmdList, (cmd = initCmd(NULL)));
cmd->command = Strdup(line);
elog(INFO, "Testing local, \"%s\"\n", cmd->command);
doCmdList(cmdList);
cleanCmdList(cmdList);
} else if (TestToken("local-stdin")) {
cmdList_t* cmdList = NULL;
cmd_t* cmd = NULL;
cmdList = initCmdList();
addCmd(cmdList, (cmd = initCmd(NULL)));
GetToken();
cmd->localStdin = Strdup(token);
cmd->command = Strdup(line);
elog(INFO, "Testing local-stdin, \"%s\"\n", cmd->command);
doCmdList(cmdList);
cleanCmdList(cmdList);
}
setLogMsgLevel(logLevel);
setPrintMsgLevel(printLevel);
}
/* ==================================================================
*
* Staff specified by "node name", not node type
*
* ==================================================================
*/
static void kill_something(char* nodeName)
{
char* nodeList[2];
nodeList[1] = NULL;
switch (getNodeType(nodeName)) {
case NodeType_UNDEF:
elog(ERROR, "ERROR: Could not find name \"%s\" in any node type.\n", nodeName);
return;
case NodeType_GTM:
elog(ERROR, "ERROR: Issue kill gtm command to kill gtm master/slave\n");
return;
case NodeType_GTM_PROXY:
nodeList[0] = nodeName;
kill_gtm_proxy(nodeList);
return;
case NodeType_COORDINATOR:
nodeList[0] = nodeName;
kill_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
kill_coordinator_slave(nodeList);
return;
case NodeType_DATANODE:
nodeList[0] = nodeName;
kill_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
kill_datanode_slave(nodeList);
return;
default:
elog(ERROR, "ERROR: internal error. Should not come here!\n");
return;
}
}
static void show_config_something_multi(char** nodeList)
{
int ii;
for (ii = 0; nodeList[ii]; ii++)
show_config_something(nodeList[ii]);
}
static void show_config_something(char* nodeName)
{
int idx;
switch (getNodeType(nodeName)) {
case NodeType_UNDEF:
elog(ERROR, "ERROR: Could not find name \"%s\" in any node type.\n", nodeName);
return;
case NodeType_GTM:
show_config_gtmMaster(TRUE, sval(VAR_gtmMasterServer));
if (isVarYes(VAR_gtmSlave))
show_config_gtmSlave(TRUE, sval(VAR_gtmSlaveServer));
return;
case NodeType_GTM_PROXY:
idx = gtmProxyIdx(nodeName);
show_config_gtmProxy(TRUE, idx, aval(VAR_gtmProxyServers)[idx]);
return;
case NodeType_COORDINATOR:
idx = coordIdx(nodeName);
show_config_coordMaster(TRUE, idx, aval(VAR_coordMasterServers)[idx]);
if (isVarYes(VAR_coordSlave))
show_config_coordSlave(TRUE, idx, aval(VAR_coordSlaveServers)[idx]);
return;
case NodeType_DATANODE:
idx = datanodeIdx(nodeName);
show_config_datanodeMaster(TRUE, idx, aval(VAR_datanodeMasterServers)[idx]);
if (isVarYes(VAR_datanodeSlave))
show_config_datanodeSlave(TRUE, idx, aval(VAR_datanodeSlaveServers)[idx]);
return;
case NodeType_SERVER: {
char* hostList[2];
hostList[0] = nodeName;
hostList[1] = NULL;
show_config_servers(hostList);
return;
}
default:
elog(ERROR, "ERROR: internal error. Should not come here!\n");
return;
}
}
/* ========================================================================================
*
* Configuration staff
*
* ========================================================================================
*/
static void show_config_servers(char** hostList)
{
int ii;
for (ii = 0; hostList[ii]; ii++)
if (!is_none(hostList[ii]))
show_config_host(hostList[ii]);
return;
}
/*
* show {config|configuration} [all | name .... | gtm [master|slave|all] | gtm_proxy [all | name ...] |
* coordinator [all | master | slave | name ... ] |
* host name .... ]
* With no option, will print common configuartion parameters and exit.
*
*/
static void show_basicConfig(void)
{
elog(NOTICE, "========= Postgres-XC configuration Common Info ========================\n");
elog(NOTICE, "=== Overall ===\n");
elog(NOTICE, "Postgres-XC owner: %s\n", sval(VAR_pgxcOwner));
elog(NOTICE, "Postgres-XC user: %s\n", sval(VAR_pgxcUser));
elog(NOTICE, "Postgres-XC install directory: %s\n", sval(VAR_pgxcInstallDir));
elog(NOTICE, "pgxc_ctl home: %s\n", pgxc_ctl_home);
elog(NOTICE, "pgxc_ctl configuration file: %s\n", pgxc_ctl_config_path);
elog(NOTICE, "pgxc_ctl tmpDir: %s\n", sval(VAR_tmpDir));
elog(NOTICE, "pgxc_ctl localTempDir: %s\n", sval(VAR_localTmpDir));
elog(NOTICE, "pgxc_ctl log file: %s\n", logFileName);
elog(NOTICE, "pgxc_ctl configBackup: %s\n", isVarYes(VAR_configBackup) ? "y" : "n");
elog(NOTICE, "pgxc_ctl configBackupHost: %s\n", isVarYes(VAR_configBackup) ? sval(VAR_configBackupHost) : "none");
elog(NOTICE, "pgxc_ctl configBackupFile: %s\n", isVarYes(VAR_configBackup) ? sval(VAR_configBackupFile) : "none");
elog(NOTICE, "========= Postgres-XC configuration End Common Info ===================\n");
}
static void show_configuration(char* line)
{
char* token = NULL;
GetToken();
if (line == NULL)
elog(ERROR, "ERROR: No configuration option is specified. Retruning.\n");
else if (TestToken("basic"))
show_basicConfig();
else if (TestToken("all")) {
show_basicConfig();
show_config_servers(aval(VAR_allServers));
} else if (TestToken("basic")) {
show_basicConfig();
} else if (TestToken("host")) {
char** hostList = Malloc0(sizeof(char*));
do {
AddMember(hostList, token);
} while (GetToken());
if (hostList[0])
show_config_servers(hostList);
clean_array(hostList);
} else if (TestToken("gtm")) {
if ((GetToken() == NULL) || (TestToken("all"))) {
show_config_gtmMaster(TRUE, sval(VAR_gtmMasterServer));
if (isVarYes(VAR_gtmSlave))
show_config_gtmSlave(TRUE, sval(VAR_gtmSlaveServer));
} else if (TestToken("master"))
show_config_gtmMaster(TRUE, sval(VAR_gtmMasterServer));
else if (TestToken("slave")) {
if (isVarYes(VAR_gtmSlave))
show_config_gtmSlave(TRUE, sval(VAR_gtmSlaveServer));
else
elog(NOTICE, "NOTICE: gtm slave is not configured.\n");
} else
elog(ERROR, "ERROR: invalid option %s for 'show config gs_gtm' command.\n", token);
} else if (TestToken("gtm_proxy")) {
if (!isVarYes(VAR_gtmProxy)) {
elog(ERROR, "ERROR: gtm proxies are not configured.\n");
} else if ((GetToken() == NULL) || (TestToken("all")))
show_config_gtmProxies(aval(VAR_gtmProxyNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do {
int idx;
idx = gtmProxyIdx(token);
if (idx < 0)
elog(ERROR, "ERROR: Specified name %s is not GTM Proxy.\n", token);
else
AddMember(nodeList, token);
} while (GetToken());
show_config_gtmProxies(nodeList);
clean_array(nodeList);
}
} else if (TestToken("coordinator")) {
if ((GetToken() == NULL) || (TestToken("all")))
show_config_coordMasterSlaveMulti(aval(VAR_coordNames));
else if (TestToken("master")) {
if (GetToken() == NULL)
show_config_coordMasterMulti(aval(VAR_coordNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
show_config_coordMasterMulti(nodeList);
clean_array(nodeList);
}
} else if (TestToken("slave")) {
if (!isVarYes(VAR_coordSlave))
elog(ERROR, "ERROR: Coordinator slave is not configured.\n");
else if (GetToken() == NULL)
show_config_coordMasterMulti(aval(VAR_coordNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
show_config_coordMasterMulti(nodeList);
clean_array(nodeList);
}
} else
elog(ERROR, "ERROR: Invalid option %s for 'show config coordinator' command.\n", token);
} else if (TestToken("datanode")) {
if ((GetToken() == NULL) || (TestToken("all")))
show_config_datanodeMasterSlaveMulti(aval(VAR_datanodeNames));
else if (TestToken("master")) {
if (GetToken() == NULL)
show_config_datanodeMasterMulti(aval(VAR_datanodeNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
show_config_datanodeMasterMulti(nodeList);
clean_array(nodeList);
}
} else if (TestToken("slave")) {
if (!isVarYes(VAR_datanodeSlave))
elog(ERROR, "ERROR: Datanode slave is not configured.\n");
else if (GetToken() == NULL)
show_config_datanodeMasterMulti(aval(VAR_datanodeNames));
else {
char** nodeList = Malloc0(sizeof(char*));
do
AddMember(nodeList, token);
while (GetToken());
show_config_datanodeMasterMulti(nodeList);
clean_array(nodeList);
}
} else
elog(ERROR, "ERROR: Invalid option %s for 'show config datanode' command.\n", token);
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
show_config_something_multi(nodeList);
clean_array(nodeList);
}
return;
}
void print_simple_node_info(char* nodeName, char* port, char* dir, char* extraConfig, char* specificExtraConfig)
{
elog(NOTICE,
" Nodename: '%s', port: %s, dir: '%s'"
" ExtraConfig: '%s', Specific Extra Config: '%s'\n",
nodeName,
port,
dir,
extraConfig,
specificExtraConfig);
}
static void show_config_host(char* hostname)
{
int ii;
lockLogFile();
elog(NOTICE, "====== Server: %s =======\n", hostname);
/* GTM Master */
if (strcmp(hostname, sval(VAR_gtmMasterServer)) == 0)
show_config_gtmMaster(TRUE, NULL);
/* GTM Slave */
if (isVarYes(VAR_gtmSlave) && (strcmp(sval(VAR_gtmSlaveServer), hostname) == 0))
show_config_gtmSlave(TRUE, NULL);
/* GTM Proxy */
if (isVarYes(VAR_gtmProxy))
for (ii = 0; aval(VAR_gtmProxyServers)[ii]; ii++)
if (strcmp(aval(VAR_gtmProxyServers)[ii], hostname) == 0)
show_config_gtmProxy(TRUE, ii, NULL);
/* Coordinator Master */
for (ii = 0; aval(VAR_coordMasterServers)[ii]; ii++)
if (strcmp(aval(VAR_coordMasterServers)[ii], hostname) == 0)
show_config_coordMaster(TRUE, ii, NULL);
/* Coordinator Slave */
if (isVarYes(VAR_coordSlave))
for (ii = 0; aval(VAR_coordSlaveServers)[ii]; ii++)
if (strcmp(aval(VAR_coordSlaveServers)[ii], hostname) == 0)
show_config_coordSlave(TRUE, ii, NULL);
/* Datanode Master */
for (ii = 0; aval(VAR_datanodeMasterServers)[ii]; ii++)
if (strcmp(aval(VAR_datanodeMasterServers)[ii], hostname) == 0)
show_config_datanodeMaster(TRUE, ii, NULL);
/* Datanode Slave */
if (isVarYes(VAR_datanodeSlave))
for (ii = 0; aval(VAR_datanodeSlaveServers)[ii]; ii++)
if (strcmp(aval(VAR_datanodeSlaveServers)[ii], hostname) == 0)
show_config_datanodeSlave(TRUE, ii, NULL);
unlockLogFile();
}
void show_config_hostList(char** hostList)
{
int ii;
for (ii = 0; hostList[ii]; ii++)
show_config_host(hostList[ii]);
}
/*
* Clean command
*
* clean {all |
* gtm [ all | master | slave ] |
* gtm_proxy [ all | nodename ... ]
* coordinator [[all | master | slave ] [nodename ... ]] |
* datanode [ [all | master | slave] [nodename ... ]}
*/
static void do_clean_command(char* line)
{
char* token = NULL;
cmdList_t* cmdList = NULL;
GetToken();
if (token == NULL) {
elog(ERROR, "ERROR: Please specify options for clean command.\n");
return;
}
if (TestToken("all")) {
elog(INFO, "Cleaning all the directories and sockets.\n");
clean_gtm_master();
if (isVarYes(VAR_gtmSlave))
clean_gtm_slave();
if (isVarYes(VAR_gtmProxy))
clean_gtm_proxy_all();
clean_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
clean_coordinator_slave_all();
clean_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
clean_datanode_slave_all();
} else if (TestToken("gtm")) {
GetToken();
if ((token == NULL) || TestToken("all")) {
elog(INFO, "Cleaning GTM slave/master directories and sockets.\n");
clean_gtm_master();
if (isVarYes(VAR_gtmSlave))
clean_gtm_slave();
} else if (TestToken("master")) {
clean_gtm_master();
} else if (TestToken("slave")) {
if (isVarYes(VAR_gtmSlave))
clean_gtm_slave();
else
elog(ERROR, "ERROR: gtm slave is not configured.\n");
} else
elog(ERROR, "ERROR: invalid clean command option %s.\n", token);
} else if (TestToken("gtm_proxy")) {
elog(INFO, "Cleaning specified gtm_proxy.\n");
GetToken();
if (!isVarYes(VAR_gtmProxy))
elog(ERROR, "ERROR: gtm proxy is not configured.\n");
else if ((token == NULL) || TestToken("all"))
clean_gtm_proxy_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_gtm_proxy(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("coordinator")) {
GetToken();
if (token == NULL) {
elog(INFO, "Clearing coordinator master and slave.\n");
clean_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
clean_coordinator_slave_all();
} else if (TestToken("all")) {
elog(INFO, "Clearing coordinator master and slave.\n");
GetToken();
if (token == NULL) {
clean_coordinator_master_all();
if (isVarYes(VAR_coordSlave))
clean_coordinator_slave_all();
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
clean_coordinator_slave(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("master")) {
elog(INFO, "Cleaning specified coordinator master.\n");
GetToken();
if (token == NULL)
clean_coordinator_master_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_coordinator_master(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("slave")) {
elog(INFO, "Cleaning specified coordinator slave.\n");
if (!isVarYes(VAR_coordSlave)) {
elog(ERROR, "ERROR: Coordinator slave is not configured.\n");
return;
}
GetToken();
if (token == NULL)
clean_coordinator_slave_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_coordinator_slave(nodeList);
CleanArray(nodeList);
}
} else {
char** nodeList = NULL;
elog(INFO, "Cleaning specified coordinator.\n");
do
AddMember(nodeList, token);
while (GetToken());
clean_coordinator_master(nodeList);
if (isVarYes(VAR_coordSlave))
clean_coordinator_slave(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("datanode")) {
GetToken();
if (token == NULL) {
elog(INFO, "Cleaning all the datanodes.\n");
clean_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
clean_datanode_slave_all();
} else if (TestToken("all")) {
GetToken();
if (token == NULL) {
elog(INFO, "Cleaning all the datanodes.\n");
clean_datanode_master_all();
if (isVarYes(VAR_datanodeSlave))
clean_datanode_slave_all();
} else {
char** nodeList = NULL;
elog(INFO, "Cleaning specified datanodes\n");
do
AddMember(nodeList, token);
while (GetToken());
clean_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
clean_datanode_slave(nodeList);
}
} else if (TestToken("master")) {
GetToken();
if (token == NULL) {
elog(INFO, "Cleaning all the datanode masters.\n");
clean_datanode_master_all();
} else {
char** nodeList = NULL;
elog(INFO, "Cleaning specified datanode masters.\n");
do
AddMember(nodeList, token);
while (GetToken());
clean_datanode_master(nodeList);
CleanArray(nodeList);
}
} else if (TestToken("slave")) {
elog(INFO, "Cleaning specified datanode slaves.\n");
if (!isVarYes(VAR_datanodeSlave)) {
elog(ERROR, "ERROR: Datanode slave is not configured.\n");
return;
}
GetToken();
if (token == NULL)
clean_datanode_slave_all();
else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_datanode_slave(nodeList);
CleanArray(nodeList);
}
} else {
char** nodeList = NULL;
do
AddMember(nodeList, token);
while (GetToken());
clean_datanode_master(nodeList);
if (isVarYes(VAR_datanodeSlave))
clean_datanode_slave(nodeList);
CleanArray(nodeList);
}
} else {
elog(INFO, "Cleaning specifieid nodes.\n");
do {
switch (getNodeType(token)) {
case NodeType_UNDEF:
elog(ERROR, "ERROR: %s is not found, skipping\n", token);
continue;
case NodeType_GTM:
elog(INFO, "Cleaning GTM.\n");
if (cmdList == NULL)
cmdList = initCmdList();
addCmd(cmdList, prepare_cleanGtmMaster());
if (isVarYes(VAR_gtmSlave))
addCmd(cmdList, prepare_cleanGtmSlave());
continue;
case NodeType_GTM_PROXY:
elog(INFO, "Cleaning GTM proxy %s.\n", token);
if (cmdList == NULL)
cmdList = initCmdList();
addCmd(cmdList, prepare_cleanGtmProxy(token));
continue;
case NodeType_COORDINATOR:
elog(INFO, "Cleaning coordinator %s\n", token);
if (cmdList == NULL)
cmdList = initCmdList();
addCmd(cmdList, prepare_cleanCoordinatorMaster(token));
if (isVarYes(VAR_coordSlave))
addCmd(cmdList, prepare_cleanCoordinatorSlave(token));
continue;
case NodeType_DATANODE:
elog(INFO, "Cleaning datanode %s\n", token);
if (cmdList == NULL)
cmdList = initCmdList();
addCmd(cmdList, prepare_cleanDatanodeMaster(token));
if (isVarYes(VAR_coordSlave))
addCmd(cmdList, prepare_cleanDatanodeSlave(token));
continue;
case NodeType_SERVER:
elog(ERROR, "ERROR: clearing host is not supported yet. Skipping\n");
continue;
default:
elog(ERROR, "ERROR: internal error.\n");
continue;
}
} while (GetToken());
if (cmdList) {
int rc;
rc = doCmdList(cmdList);
cleanCmdList(cmdList);
elog(INFO, "Done.\n");
}
return;
}
}
static void do_configure_command(char* line)
{
char* token = NULL;
char** nodeList = NULL;
if (!GetToken() || TestToken("all")) {
configure_nodes(aval(VAR_coordNames));
} else {
do
AddMember(nodeList, token);
while (GetToken());
configure_nodes(nodeList);
CleanArray(nodeList);
}
}
static int selectCoordinator(void)
{
int sz = arraySizeName(VAR_coordNames);
int i;
for (;;) {
i = rand() % sz;
if (is_none(aval(VAR_coordMasterServers)[i]))
continue;
else
return i;
}
return -1;
}
static int show_Resource(char* datanodeName, char* databasename, char* username)
{
int cdIdx = selectCoordinator();
int dnIdx = datanodeIdx(datanodeName);
FILE* f = NULL;
char queryFname[MAXPATH + 1];
elog(NOTICE,
"NOTICE: showing tables in the datanode '%s', database %s, user %s\n",
datanodeName,
databasename ? databasename : "NULL",
username ? username : "NULL");
if (dnIdx < 0) {
elog(ERROR, "ERROR: %s is not a datanode.\n", datanodeName);
return 1;
}
createLocalFileName(GENERAL, queryFname, MAXPATH);
if ((f = fopen(queryFname, "w")) == NULL) {
elog(ERROR, "ERROR: Could not create temporary file %s, %s\n", queryFname, strerror(errno));
return 1;
}
fprintf(f,
"SELECT pg_class.relname relation,\n"
" CASE\n"
" WHEN pclocatortype = 'H' THEN 'Hash'\n"
" WHEN pclocatortype = 'M' THEN 'Modulo'\n"
" WHEN pclocatortype = 'N' THEN 'Round Robin'\n"
" WHEN pclocatortype = 'R' THEN 'Replicate'\n"
" ELSE 'Unknown'\n"
" END AS distribution,\n"
" pg_attribute.attname attname,\n"
" pgxc_node.node_name nodename\n"
" FROM pg_class, pgxc_class, pg_attribute, pgxc_node\n"
" WHERE pg_class.oid = pgxc_class.pcrelid\n"
" and pg_class.oid = pg_attribute.attrelid\n"
" and pgxc_class.pcattnum = pg_attribute.attnum\n"
" and pgxc_node.node_name = '%s'\n"
" and pgxc_node.oid = ANY (pgxc_class.nodeoids)\n"
" UNION\n"
" SELECT pg_class.relname relation,\n"
" CASE\n"
" WHEN pclocatortype = 'H' THEN 'Hash'\n"
" WHEN pclocatortype = 'M' THEN 'Modulo'\n"
" WHEN pclocatortype = 'N' THEN 'Round Robin'\n"
" WHEN pclocatortype = 'R' THEN 'Replicate'\n"
" ELSE 'Unknown'\n"
" END AS distribution,\n"
" '- none -' attname,\n"
" pgxc_node.node_name nodename\n"
" FROM pg_class, pgxc_class, pg_attribute, pgxc_node\n"
" WHERE pg_class.oid = pgxc_class.pcrelid\n"
" and pg_class.oid = pg_attribute.attrelid\n"
" and pgxc_class.pcattnum = 0\n"
" and pgxc_node.node_name = '%s'\n"
" and pgxc_node.oid = ANY (pgxc_class.nodeoids)\n"
" ;\n",
datanodeName,
datanodeName);
fclose(f);
if (databasename == NULL)
doImmediateRaw("gsql -p %d -h %s --quiet -f %s",
atoi(aval(VAR_coordPorts)[cdIdx]),
aval(VAR_coordMasterServers)[cdIdx],
queryFname);
else if (username == NULL)
doImmediateRaw("gsql -p %d -h %s --quiet -f %s -d %s",
atoi(aval(VAR_coordPorts)[cdIdx]),
aval(VAR_coordMasterServers)[cdIdx],
queryFname,
databasename);
else
doImmediateRaw("gsql -p %d -h %s --quiet -f %s -d %s -U %s",
atoi(aval(VAR_coordPorts)[cdIdx]),
aval(VAR_coordMasterServers)[cdIdx],
queryFname,
databasename,
username);
doImmediateRaw("rm -f %s", queryFname);
return 0;
}
/*
* =======================================================================================
*
* Loop of main command processor
*
* ======================================================================================
*/
void do_command(FILE* inf, FILE* outf)
{
int istty = ((inf == stdin) && isatty(fileno(stdin)));
int interactive = ((inf == stdin) && (outf == stdout));
char* wkline = NULL;
char buf[MAXLINE + 1];
int rc;
for (;;) {
if (wkline)
free(wkline);
if (istty) {
wkline = readline(sval(VAR_xc_prompt));
if (wkline == NULL) {
wkline = Strdup("q\n");
putchar('\n');
} else
add_history(wkline);
strncpy(buf, wkline, MAXLINE);
} else {
if (interactive)
fputs(sval(VAR_xc_prompt), stdout);
if (fgets(buf, MAXLINE + 1, inf) == NULL)
break;
}
trimNl(buf);
writeLogOnly("PGXC %s\n", buf);
rc = do_singleLine(buf, wkline);
freeAndReset(wkline);
if (rc) /* "q" command was found */
return;
}
}
/*
* ---------------------------------------------------------------------------
*
* Single line command processor
*
* -----------------------------------------------------------------------------
*/
int do_singleLine(char* buf, char* wkline)
{
char* token = NULL;
char* line = buf;
GetToken();
/*
* Parsecommand
*/
if (!token)
return 0;
if (TestToken("q") || TestToken("quit") || TestToken("exit"))
/* Exit command */
return 1;
else if (TestToken("echo")) {
do_echo_command(line);
return 0;
} else if (TestToken("deploy")) {
do_deploy(line);
return 0;
} else if (TestToken("prepare")) {
if (GetToken() == NULL)
do_prepareConfFile(NULL);
if (!TestToken("config"))
do_prepareConfFile(token);
else if (GetToken() == NULL)
do_prepareConfFile(NULL);
else
do_prepareConfFile(token);
return 0;
} else if (TestToken("kill")) {
do_kill_command(line);
return 0;
} else if (TestToken("init")) {
do_init_command(line);
return 0;
} else if (TestToken("start")) {
do_start_command(line);
return 0;
} else if (TestToken("stop")) {
do_stop_command(line);
return 0;
} else if (TestToken("monitor")) {
do_monitor_command(line);
return 0;
} else if (TestToken("failover")) {
do_failover_command(line);
return 0;
} else if (TestToken("reconnect")) {
do_reconnect_command(line);
return 0;
} else if (TestToken("add")) {
do_add_command(line);
return 0;
} else if (TestToken("remove")) {
do_remove_command(line);
return 0;
}
/*
* Show commnand ... show [variable | var] varname ...
* show [variable | var] all
* show config[uration] ....
*/
else if (TestToken("show")) {
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify what to show\n");
else {
if (TestToken("variable") || TestToken("var")) {
/* Variable */
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify variable name to print\n");
else if (TestToken("all"))
print_vars();
else
while (line) {
print_var(token);
GetToken();
}
} else if (TestToken("configuration") || TestToken("config") || TestToken("configure"))
/* Configuration */
show_configuration(line);
else if (TestToken("resource")) {
if ((GetToken() == NULL) || !TestToken("datanode"))
elog(ERROR, "ERROR: please specify datanode for show resource command.\n");
else {
char* datanodeName = NULL;
char* dbname = NULL;
char* username = NULL;
if (GetToken() == NULL)
elog(ERROR, "ERROR: please specify datanode name\n");
else {
datanodeName = Strdup(token);
if (GetToken()) {
dbname = Strdup(token);
if (GetToken())
username = Strdup(token);
}
show_Resource(datanodeName, dbname, username);
Free(datanodeName);
Free(dbname);
Free(username);
}
}
} else
elog(ERROR, "ERROR: Cannot show %s now, sorry.\n", token);
}
return 0;
}
/*
* Log command log variable varname ...
* log variable all
* log msg artitrary_message_to_the_end_of_the_line
*/
else if (TestToken("log")) {
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify what to log\n");
else {
if (TestToken("variable") || TestToken("var")) {
if (GetToken() == NULL)
elog(ERROR, "ERROR: Please specify variable name to log\n");
else if (TestToken("all"))
print_vars();
else
while (line) {
print_var(token);
GetToken();
}
fflush(logFile);
} else if (TestToken("msg") || TestToken("message"))
writeLogOnly("USERLOG: \"%s\"\n", line);
else
elog(ERROR, "ERROR: Cannot log %s in this version.\n", token);
}
return 0;
} else if (TestToken("deploy")) {
do_deploy(line);
return 0;
} else if (TestToken("configure")) {
do_configure_command(line);
return 0;
} else if (testToken("Psql")) {
int idx;
char* cmdLine = NULL;
cmdLine = Strdup(line);
if (GetToken() && TestToken("-")) {
if (!GetToken())
elog(ERROR, "ERROR: Please specify coordinator name after '-'.\n");
else if ((idx = coordIdx(token)) < 0)
elog(ERROR, "ERROR: Specified node %s is not a coordinator.\n", token);
else
doImmediateRaw(
"gsql -p %d -h %s %s", atoi(aval(VAR_coordPorts)[idx]), aval(VAR_coordMasterServers)[idx], line);
} else {
idx = selectCoordinator();
elog(INFO, "Selected %s.\n", aval(VAR_coordNames)[idx]);
doImmediateRaw(
"gsql -p %d -h %s %s", atoi(aval(VAR_coordPorts)[idx]), aval(VAR_coordMasterServers)[idx], cmdLine);
}
Free(cmdLine);
return 0;
} else if (testToken("Createdb")) {
int idx;
char* cmdLine = NULL;
cmdLine = Strdup(line);
if (GetToken() && TestToken("-")) {
if (!GetToken())
elog(ERROR, "ERROR: Please specify coordinator name after '-'.\n");
else if ((idx = coordIdx(token)) < 0)
elog(ERROR, "ERROR: Specified node %s is not a coordinator.\n", token);
else
doImmediateRaw("createdb -p %d -h %s %s",
atoi(aval(VAR_coordPorts)[idx]),
aval(VAR_coordMasterServers)[idx],
line);
} else {
idx = selectCoordinator();
elog(INFO, "Selected %s.\n", aval(VAR_coordNames)[idx]);
doImmediateRaw(
"createdb -p %d -h %s %s", atoi(aval(VAR_coordPorts)[idx]), aval(VAR_coordMasterServers)[idx], cmdLine);
}
Free(cmdLine);
return 0;
} else if (testToken("Createuser")) {
int idx;
char* cmdLine = NULL;
cmdLine = Strdup(line);
if (GetToken() && TestToken("-")) {
if (!GetToken())
elog(ERROR, "ERROR: Please specify coordinator name after '-'.\n");
else if ((idx = coordIdx(token)) < 0)
elog(ERROR, "ERROR: Specified node %s is not a coordinator.\n", token);
else
doImmediateRaw("createuser -p %d -h %s %s",
atoi(aval(VAR_coordPorts)[idx]),
aval(VAR_coordMasterServers)[idx],
line);
} else {
idx = selectCoordinator();
elog(INFO, "Selected %s.\n", aval(VAR_coordNames)[idx]);
doImmediateRaw("createuser -p %d -h %s %s",
atoi(aval(VAR_coordPorts)[idx]),
aval(VAR_coordMasterServers)[idx],
cmdLine);
}
Free(cmdLine);
return 0;
} else if (TestToken("unregister")) {
/*
* unregiseter [-n myname] -Z nodetype nodename
*/
unregisterFromGtm(line);
return 0;
} else if (TestToken("test")) {
do_test(line);
return 0;
} else if (TestToken("set")) {
do_set(line);
return 0;
}
/*
* Clean command
*
* clean [all |
* gtm [ all | master | slave ] |
* gtm_proxy [ all | nodename ... ]
* coordinator [[all | master | slave ] [nodename ... ]] |
* datanode [ [all | master | slave] [nodename ... ]
*/
else if (TestToken("clean")) {
do_clean_command(line);
} else if (TestToken("cd")) {
/*
* CD command
*/
if (GetToken() == NULL)
Chdir(pgxc_ctl_home, FALSE);
else
Chdir(token, FALSE);
return 0;
} else if (TestToken("ssh")) {
doImmediateRaw("%s", wkline);
} else {
doImmediateRaw("%s", wkline);
return 0;
}
return 0;
}