/* * Init gtm master ----------------------------------------------------------------- */ static cmd_t * prepare_initGtmMaster(void) { cmd_t *cmdInitGtmMaster, *cmdGtmConf, *cmdGxid; char date[MAXTOKEN+1]; FILE *f; char **fileList = NULL; /* Kill current gtm, bild work directory and run initgtm */ cmdInitGtmMaster = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmdInitGtmMaster), MAXLINE, "killall -u %s -9 gtm; rm -rf %s; mkdir -p %s;initgtm -Z gtm -D %s", sval(VAR_pgxcUser), sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir)); /* Then prepare gtm.conf file */ /* Prepare local Stdin */ appendCmdEl(cmdInitGtmMaster, (cmdGtmConf = initCmd(sval(VAR_gtmMasterServer)))); if ((f = prepareLocalStdin(newFilename(cmdGtmConf->localStdin), MAXPATH, NULL)) == NULL) { cleanCmd(cmdInitGtmMaster); return(NULL); } fprintf(f, "#===============================================\n" "# Added at initialization, %s\n" "listen_addresses = '*'\n", timeStampString(date, MAXTOKEN)); if (!is_none(sval(VAR_gtmExtraConfig))) AddMember(fileList, sval(VAR_gtmExtraConfig)); if (!is_none(sval(VAR_gtmMasterSpecificExtraConfig))) AddMember(fileList, sval(VAR_gtmMasterSpecificExtraConfig)); appendFiles(f, fileList); CleanArray(fileList); fprintf(f, "port = %s\n" "nodename = '%s'\n" "startup = ACT\n" "# End of addition\n", sval(VAR_gtmMasterPort), sval(VAR_gtmName)); fclose(f); /* other options */ snprintf(newCommand(cmdGtmConf), MAXLINE, "cat >> %s/gtm.conf", sval(VAR_gtmMasterDir)); /* Setup GTM with appropriate GXID value */ appendCmdEl(cmdGtmConf, (cmdGxid = initCmd(sval(VAR_gtmMasterServer)))); snprintf(newCommand(cmdGxid), MAXLINE, "(gtm -x 2000 -D %s &); sleep 1; gtm_ctl stop -Z gtm -D %s", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir)); return cmdInitGtmMaster; }
/* * Assumes Gtm Slave is configured. * Caller should check this. */ static cmd_t * prepare_initGtmSlave(void) { char date[MAXTOKEN+1]; cmd_t *cmdInitGtm, *cmdGtmConf; FILE *f; char **fileList = NULL; if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer))) { elog(ERROR, "ERROR: GTM slave is not configured.\n"); return(NULL); } /* Kill current gtm, build work directory and run initgtm */ cmdInitGtm = initCmd(sval(VAR_gtmSlaveServer)); snprintf(newCommand(cmdInitGtm), MAXLINE, "killall -u %s -9 gtm; rm -rf %s; mkdir -p %s; initgtm -Z gtm -D %s", sval(VAR_pgxcUser), sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir)); /* Prepare gtm.conf file */ /* Prepare local Stdin */ appendCmdEl(cmdInitGtm, (cmdGtmConf = initCmd(sval(VAR_gtmSlaveServer)))); snprintf(newCommand(cmdGtmConf), MAXLINE, "cat >> %s/gtm.conf", sval(VAR_gtmSlaveDir)); if ((f = prepareLocalStdin(newFilename(cmdGtmConf->localStdin), MAXPATH, NULL)) == NULL) { cleanCmd(cmdInitGtm); return(NULL); } fprintf(f, "#===============================================\n" "# Added at initialization, %s\n" "listen_addresses = '*'\n", timeStampString(date, MAXPATH+1)); if (!is_none(sval(VAR_gtmExtraConfig))) AddMember(fileList, sval(VAR_gtmExtraConfig)); if (!is_none(sval(VAR_gtmMasterSpecificExtraConfig))) AddMember(fileList, sval(VAR_gtmMasterSpecificExtraConfig)); appendFiles(f, fileList); CleanArray(fileList); fprintf(f, "port = %s\n" "nodename = '%s'\n" "startup = STANDBY\n" "active_host = '%s'\n" "active_port = %d\n" "# End of addition\n", sval(VAR_gtmSlavePort), sval(VAR_gtmName), sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))); fclose(f); return (cmdInitGtm); }
/* * Reconnect to the current GTM master -------------------------------------------------- * * When failed over, the current Master must have been updated. * Remember to update gtm_proxy configuration file so that it * connects to the new master at the next start. * Please note that we assume GTM has already been failed over. * First argument is gtm_proxy nodename */ static cmd_t * prepare_reconnectGtmProxy(char *nodeName) { cmd_t *cmdGtmCtl, *cmdGtmProxyConf; int idx; FILE *f; char date[MAXTOKEN+1]; if ((idx = gtmProxyIdx(nodeName)) < 0) { elog(ERROR, "ERROR: Specified name %s is not GTM Proxy\n", nodeName); return(NULL); } /* gtm_ctl reconnect */ cmdGtmCtl = initCmd(aval(VAR_gtmProxyServers)[idx]); snprintf(newCommand(cmdGtmCtl), MAXLINE, "gtm_ctl reconnect -Z gtm_proxy -D %s -o \\\"-s %s -t %s\\\"", aval(VAR_gtmProxyDirs)[idx], sval(VAR_gtmMasterServer), sval(VAR_gtmMasterPort)); /* gtm_proxy.conf */ appendCmdEl(cmdGtmCtl, (cmdGtmProxyConf = initCmd(aval(VAR_gtmProxyServers)[idx]))); if ((f = prepareLocalStdin(newFilename(cmdGtmProxyConf->localStdin), MAXPATH, NULL)) == NULL) { cleanCmd(cmdGtmCtl); return(NULL); } fprintf(f, "#===================================================\n" "# Updated due to GTM Proxy reconnect\n" "# %s\n" "gtm_host = '%s'\n" "gtm_port = %s\n" "#----End of reconfiguration -------------------------\n", timeStampString(date, MAXTOKEN), sval(VAR_gtmMasterServer), sval(VAR_gtmMasterPort)); fclose(f); snprintf(newCommand(cmdGtmProxyConf), MAXLINE, "cat >> %s/gtm_proxy.conf", aval(VAR_gtmProxyDirs)[idx]); return(cmdGtmCtl); }
/* * Stop gtm master --------------------------------------------------------- */ static cmd_t * prepare_stopGtmMaster(void) { cmd_t *cmdGtmCtl; cmdGtmCtl = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmdGtmCtl), MAXLINE, "gtm_ctl stop -Z gtm -D %s", sval(VAR_gtmMasterDir)); return(cmdGtmCtl); }
/* * Clean gtm master resources -- directory and socket -------------------------- */ cmd_t * prepare_cleanGtmMaster(void) { cmd_t *cmd; /* Remote work dir and clean the socket */ cmd = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmd), MAXLINE, "rm -rf %s; mkdir -p %s; chmod 0700 %s;rm -f /tmp/.s.*%d*", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), atoi(VAR_gtmMasterPort)); return cmd; }
/* * Start gtm master ----------------------------------------------------- */ static cmd_t * prepare_startGtmMaster(void) { cmd_t *cmdGtmCtl; cmdGtmCtl = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmdGtmCtl), MAXLINE, "gtm_ctl stop -Z gtm -D %s;" "rm -f %s/register.node;" "gtm_ctl start -Z gtm -D %s", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir)); return cmdGtmCtl; }
/* * Null will be retruend if gtm slave is not configured. * Be careful. If you configure gtm slave and gtm master on a same server, * bott slave amd master process will be killed. */ cmd_t * prepare_cleanGtmSlave(void) { cmd_t *cmd; if (!isVarYes(VAR_gtmSlave) || is_none(VAR_gtmSlaveServer)) return(NULL); cmd = initCmd(sval(VAR_gtmSlaveServer)); snprintf(newCommand(cmd), MAXLINE, "rm -rf %s; mkdir -p %s; chmod 0700 %s;rm -f /tmp/.s.*%d*", sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), sval(VAR_gtmMasterDir), atoi(VAR_gtmSlavePort)); return cmd; }
// executes command int executeCmd(struct cmd *command, short *abor, int fd, struct state *cstate, struct config *configuration) { // loads the pointer to the apropriate function initCmd(command, all_commands, (sizeof (all_commands) / sizeof (all_commands[0]))); // calls it if (command->func) command->func(command->params, abor, fd, cstate, configuration); else { printf("%s\n", "Unknown command!"); respond(fd, 5, 0, 2, "Command not implemented.\n"); } return (0); }
/* * Cleanup -- nodeName must be valid. Instead, NULL will bereturned. */ cmd_t * prepare_cleanGtmProxy(char *nodeName) { cmd_t *cmd; int idx; if ((idx = gtmProxyIdx(nodeName)) < 0) return NULL; cmd = initCmd(aval(VAR_gtmProxyServers)[idx]); snprintf(newCommand(cmd), MAXLINE, "rm -rf %s; mkdir -p %s; chmod 0700 %s;rm -f /tmp/.s.*%d*", aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx], atoi(aval(VAR_gtmProxyPorts)[idx])); return cmd; }
/* * Stop gtm slave --------------------------------------------------------------- */ static cmd_t * prepare_stopGtmSlave(void) { cmd_t *cmdGtmCtl; if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer))) { elog(ERROR, "ERROR: GTM slave is not configured.\n"); return(NULL); } cmdGtmCtl = initCmd(sval(VAR_gtmSlaveServer)); snprintf(newCommand(cmdGtmCtl), MAXLINE, "gtm_ctl stop -Z gtm -D %s", sval(VAR_gtmSlaveDir)); return(cmdGtmCtl); }
/* * Stop gtm proxy ------------------------------------------------------------- */ static cmd_t * prepare_stopGtmProxy(char *nodeName) { cmd_t *cmd; int idx; if ((idx = gtmProxyIdx(nodeName)) < 0) { elog(ERROR, "ERROR: Specified name %s is not GTM Proxy\n", nodeName); return NULL; } cmd = initCmd(aval(VAR_gtmProxyServers)[idx]); snprintf(newCommand(cmd), MAXLINE, "gtm_ctl stop -Z gtm_proxy -D %s", aval(VAR_gtmProxyDirs)[idx]); return(cmd); }
/* * Kill gtm master ----------------------------------------------------- * * You should not kill gtm master in this way. This may discard the latest * gtm status. This is just in case. You must try to stop gtm master * gracefully. */ static cmd_t * prepare_killGtmMaster(void) { cmd_t *cmdKill; pid_t gtmPid; if (is_none(sval(VAR_gtmMasterServer))) return(NULL); cmdKill = initCmd(sval(VAR_gtmMasterServer)); gtmPid = get_gtm_pid(sval(VAR_gtmMasterServer), sval(VAR_gtmMasterDir)); if (gtmPid > 0) snprintf(newCommand(cmdKill), MAXLINE, "kill -9 %d; rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", gtmPid, atoi(sval(VAR_gtmMasterPort)), sval(VAR_gtmMasterDir)); else snprintf(newCommand(cmdKill), MAXLINE, "killall -u %s -9 gtm; rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", sval(VAR_pgxcUser), atoi(sval(VAR_gtmMasterPort)), sval(VAR_gtmMasterDir)); return(cmdKill); }
/* * Kill gtm slave -------------------------------------------------------- * * GTM slave has no significant informaion to carry over. But it is a good * habit to stop gtm slave gracefully with stop command. */ static cmd_t * prepare_killGtmSlave(void) { cmd_t *cmdKill; pid_t gtmPid; if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer))) { elog(ERROR, "ERROR: GTM slave is not configured.\n"); return(NULL); } cmdKill = initCmd(sval(VAR_gtmSlaveServer)); gtmPid = get_gtm_pid(sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir)); if (gtmPid > 0) snprintf(newCommand(cmdKill), MAXLINE, "kill -9 %d; rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", gtmPid, atoi(sval(VAR_gtmSlavePort)), sval(VAR_gtmSlaveDir)); else snprintf(newCommand(cmdKill), MAXLINE, "killall -u %s -9 gtm; rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", sval(VAR_pgxcUser), atoi(sval(VAR_gtmSlavePort)), sval(VAR_gtmSlaveDir)); return(cmdKill); }
/* * Kill gtm proxy ------------------------------------------------------------------- * * Although gtm proxy does not have significant resources to carry over to the next * run, it is a good habit to stop gtm proxy with stop command gracefully. */ static cmd_t * prepare_killGtmProxy(char *nodeName) { cmd_t *cmd; int idx; pid_t gtmPxyPid; if ((idx = gtmProxyIdx(nodeName)) < 0) { elog(ERROR, "ERROR: Specified name %s is not GTM Proxy\n", nodeName); return NULL; } cmd = initCmd(aval(VAR_gtmProxyServers)[idx]); gtmPxyPid = get_gtmProxy_pid(aval(VAR_gtmProxyServers)[idx], aval(VAR_gtmProxyDirs)[idx]); if (gtmPxyPid > 0) snprintf(newCommand(cmd), MAXLINE, "kill -9 %d; rm -rf /tmp/.s.'*'%d'*' %s/gtm_proxy.pid", gtmPxyPid, atoi(aval(VAR_gtmProxyPorts)[idx]), aval(VAR_gtmProxyDirs)[idx]); else snprintf(newCommand(cmd), MAXLINE, "killall -u %s -9 gtm; rm -rf /tmp/.s.'*'%d'*' %s/gtm_proxy.pid", sval(VAR_pgxcUser), atoi(aval(VAR_gtmProxyPorts)[idx]), aval(VAR_gtmProxyDirs)[idx]); return(cmd); }
/* * Does not check if node name is valid. */ static cmd_t * prepare_initGtmProxy(char *nodeName) { cmd_t *cmdInitGtm, *cmdGtmProxyConf; int idx; FILE *f; char timestamp[MAXTOKEN+1]; char **fileList = NULL; if ((idx = gtmProxyIdx(nodeName)) < 0) { elog(ERROR, "ERROR: Specified name %s is not GTM Proxy configuration.\n", nodeName); return NULL; } /* Build directory and run initgtm */ cmdInitGtm = initCmd(aval(VAR_gtmProxyServers)[idx]); snprintf(newCommand(cmdInitGtm), MAXLINE, "killall -u %s -9 gtm_proxy;" "rm -rf %s;" "mkdir -p %s;" "initgtm -Z gtm_proxy -D %s", sval(VAR_pgxcUser), aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx]); /* Configure gtm_proxy.conf */ appendCmdEl(cmdInitGtm, (cmdGtmProxyConf = initCmd(aval(VAR_gtmProxyServers)[idx]))); if ((f = prepareLocalStdin(newFilename(cmdGtmProxyConf->localStdin), MAXPATH, NULL)) == NULL) { cleanCmd(cmdInitGtm); return NULL; } fprintf(f, "#===========================\n" "# Added at initialization, %s\n" "listen_addresses = '*'\n" "worker_threads = 1\n" "gtm_connect_retry_interval = 1\n", timeStampString(timestamp, MAXTOKEN));; if (!is_none(sval(VAR_gtmPxyExtraConfig))) AddMember(fileList, sval(VAR_gtmPxyExtraConfig)); if (!is_none(aval(VAR_gtmPxySpecificExtraConfig)[idx])) AddMember(fileList, aval(VAR_gtmPxySpecificExtraConfig)[idx]); appendFiles(f, fileList); CleanArray(fileList); fprintf(f, "nodename = '%s'\n" "port = %s\n" "gtm_host = '%s'\n" "gtm_port = %s\n" "# End of addition\n", aval(VAR_gtmProxyNames)[idx], aval(VAR_gtmProxyPorts)[idx], sval(VAR_gtmMasterServer), sval(VAR_gtmMasterPort)); fclose(f); snprintf(newCommand(cmdGtmProxyConf), MAXLINE, "cat >> %s/gtm_proxy.conf", aval(VAR_gtmProxyDirs)[idx]); return(cmdInitGtm); }