/*------------------------------------------------------------------------- * * 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 #include #include #include #include #include #include #include #include #include #include #include #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; }