/*------------------------------------------------------------------------- * * gtm_cmd.c * * GTM command module of Postgres-XC configuration and operation tool. * * Copyright (c) 2013 Postgres-XC Development Group * *------------------------------------------------------------------------- */ /* * This module provides various gtm-related pgxc_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 "monitor.h" static char date[MAXTOKEN+1]; /* ====================================================================================== * * GTM Staff * * ======================================================================================= */ /* * Init gtm master ----------------------------------------------------------------- */ cmd_t *prepare_initGtmMaster(bool stop) { cmd_t *cmdInitGtmMaster, *cmdGtmConf, *cmdGxid; char date[MAXTOKEN+1]; FILE *f; char **fileList = NULL; char remoteDirCheck[MAXPATH * 2 + 128]; remoteDirCheck[0] = '\0'; if (!forceInit) { sprintf(remoteDirCheck, "if [ '$(ls -A %s 2> /dev/null)' ]; then echo 'ERROR: " "target directory (%s) exists and not empty. " "Skip GTM initilialization'; exit; fi;", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir) ); } /* Kill current gtm, bild work directory and run initgtm */ cmdInitGtmMaster = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmdInitGtmMaster), MAXLINE, "%s" "[ -f %s/gtm.pid ] && gtm_ctl -D %s -m immediate -Z gtm stop;" "rm -rf %s;" "mkdir -p %s;" "PGXC_CTL_SILENT=1 initgtm -Z gtm -D %s", remoteDirCheck, sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir), 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)))); if (stop) snprintf(newCommand(cmdGxid), MAXLINE, "(gtm -x 2000 -D %s &); sleep 1; gtm_ctl stop -Z gtm -D %s", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir)); else snprintf(newCommand(cmdGxid), MAXLINE, "(gtm -x 2000 -D %s &); sleep 1;", sval(VAR_gtmMasterDir)); return cmdInitGtmMaster; } int init_gtm_master(bool stop) { int rc = 0; cmdList_t *cmdList; cmd_t *cmd; elog(INFO, "Initialize GTM master\n"); if (is_none(sval(VAR_gtmMasterServer))) { elog(INFO, "No GTM master specified, exiting!\n"); return rc; } cmdList = initCmdList(); /* Kill current gtm, build work directory and run initgtm */ if ((cmd = prepare_initGtmMaster(stop))) addCmd(cmdList, cmd); rc = doCmdList(cmdList); cleanCmdList(cmdList); elog(INFO, "Done.\n"); return(rc); } /* * Add gtm master * */ int add_gtmMaster(char *name, char *host, int port, char *dir) { char port_s[MAXTOKEN+1]; char date[MAXTOKEN+1]; FILE *f; int rc; if (is_none(name)) { elog(ERROR, "ERROR: Cannot add gtm master with the name \"none\".\n"); return 1; } if (is_none(host)) { elog(ERROR, "ERROR: Cannot add gtm master with the name \"none\".\n"); return 1; } if (is_none(dir)) { elog(ERROR, "ERROR: Cannot add gtm master with the directory \"none\".\n"); return 1; } if (checkSpecificResourceConflict(name, host, port, dir, TRUE)) { elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n", name, host, port, dir); return 1; } assign_sval(VAR_gtmName, Strdup(name)); assign_sval(VAR_gtmMasterServer, Strdup(host)); snprintf(port_s, MAXTOKEN, "%d", port); assign_sval(VAR_gtmMasterPort, Strdup(port_s)); assign_sval(VAR_gtmMasterDir, Strdup(dir)); makeServerList(); if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM master addition\n" "# %s\n", timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_gtmName); fprintSval(f, VAR_gtmMasterServer); fprintSval(f, VAR_gtmMasterPort); fprintSval(f, VAR_gtmMasterDir); fprintf(f, "%s","#----End of reconfiguration -------------------------\n"); fclose(f); backup_configuration(); if ((rc = init_gtm_master(false)) != 0) return rc; return(start_gtm_master()); } /* * Add gtm slave: to be used after all the configuration is done. * * This function only maintains internal configuration, updte configuration file, * and make backup if configured. You should run init_gtm_slave and stat_gtm_slave * separately. */ int add_gtmSlave(char *name, char *host, int port, char *dir) { char port_s[MAXTOKEN+1]; char date[MAXTOKEN+1]; FILE *f; int rc; if (isVarYes(VAR_gtmSlave)) { elog(ERROR, "ERROR: GTM slave is already configured.\n"); return 1; } if (is_none(name)) { elog(ERROR, "ERROR: Cannot add gtm slave with the name \"none\".\n"); return 1; } if (is_none(host)) { elog(ERROR, "ERROR: Cannot add gtm slave with the name \"none\".\n"); return 1; } if (is_none(dir)) { elog(ERROR, "ERROR: Cannot add gtm slave with the directory \"none\".\n"); return 1; } if (checkSpecificResourceConflict(name, host, port, dir, FALSE)) { elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n", name, host, port, dir); return 1; } assign_sval(VAR_gtmSlave, Strdup("y")); assign_sval(VAR_gtmSlaveName, Strdup(name)); assign_sval(VAR_gtmSlaveServer, Strdup(host)); snprintf(port_s, MAXTOKEN, "%d", port); assign_sval(VAR_gtmSlavePort, Strdup(port_s)); assign_sval(VAR_gtmSlaveDir, Strdup(dir)); makeServerList(); if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM slave addition\n" "# %s\n", timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_gtmSlave); fprintSval(f, VAR_gtmSlaveName); fprintSval(f, VAR_gtmSlaveServer); fprintSval(f, VAR_gtmSlavePort); fprintSval(f, VAR_gtmSlaveDir); fprintf(f, "%s","#----End of reconfiguration -------------------------\n"); fclose(f); backup_configuration(); if ((rc = init_gtm_slave()) != 0) return rc; return(start_gtm_slave()); } int remove_gtmMaster(bool clean_opt) { FILE *f; /* Check if gtm_slave is configured */ if (!sval(VAR_gtmMasterServer) || is_none(sval(VAR_gtmMasterServer))) { elog(ERROR, "ERROR: GTM master is not configured.\n"); return 1; } /* Check if gtm_master is running and stop if yes */ if (do_gtm_ping(sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))) == 0) stop_gtm_master(); elog(NOTICE, "Removing gtm master.\n"); /* Clean */ if (clean_opt) clean_gtm_master(); /* Reconfigure */ reset_var(VAR_gtmName); assign_sval(VAR_gtmName, Strdup("none")); reset_var(VAR_gtmMasterServer); assign_sval(VAR_gtmMasterServer, Strdup("none")); reset_var(VAR_gtmMasterPort); assign_sval(VAR_gtmMasterPort, Strdup("-1")); reset_var(VAR_gtmMasterDir); assign_sval(VAR_gtmMasterDir, Strdup("none")); /* Write the configuration file and bakup it */ if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM master removal\n" "# %s\n", timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_gtmName); fprintSval(f, VAR_gtmMasterServer); fprintSval(f, VAR_gtmMasterPort); fprintSval(f, VAR_gtmMasterDir); fprintf(f, "%s", "#----End of reconfiguration -------------------------\n"); fclose(f); backup_configuration(); elog(NOTICE, "Done.\n"); return 0; } int remove_gtmSlave(bool clean_opt) { FILE *f; /* Check if gtm_slave is configured */ if (!isVarYes(VAR_gtmSlave) || !sval(VAR_gtmSlaveServer) || is_none(sval(VAR_gtmSlaveServer))) { elog(ERROR, "ERROR: GTM slave is not configured.\n"); return 1; } /* Check if gtm_slave is not running */ if (!do_gtm_ping(sval(VAR_gtmSlaveServer), atoi(sval(VAR_gtmSlavePort)))) { elog(ERROR, "ERROR: GTM slave is now running. Cannot remove it.\n"); return 1; } elog(NOTICE, "Removing gtm slave.\n"); /* Clean */ if (clean_opt) clean_gtm_slave(); /* Reconfigure */ reset_var(VAR_gtmSlave); assign_sval(VAR_gtmSlave, Strdup("n")); reset_var(VAR_gtmSlaveName); assign_sval(VAR_gtmSlaveName, Strdup("none")); reset_var(VAR_gtmSlaveServer); assign_sval(VAR_gtmSlaveServer, Strdup("none")); reset_var(VAR_gtmSlavePort); assign_sval(VAR_gtmSlavePort, Strdup("-1")); reset_var(VAR_gtmSlaveDir); assign_sval(VAR_gtmSlaveDir, Strdup("none")); /* Write the configuration file and bakup it */ if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM slave removal\n" "# %s\n", timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_gtmSlave); fprintSval(f, VAR_gtmSlaveServer); fprintSval(f, VAR_gtmSlavePort); fprintSval(f, VAR_gtmSlaveDir); fprintf(f, "%s", "#----End of reconfiguration -------------------------\n"); fclose(f); backup_configuration(); elog(NOTICE, "Done.\n"); return 0; } /* * Init gtm slave ------------------------------------------------------------- */ /* * Assumes Gtm Slave is configured. * Caller should check this. */ 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, "[ -f %s/gtm.pid ] && gtm_ctl -D %s -m immediate -Z gtm stop;" "rm -rf %s;" "mkdir -p %s;" "PGXC_CTL_SILENT=1 initgtm -Z gtm -D %s", sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), 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_gtmSlaveName), sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))); fclose(f); return (cmdInitGtm); } int init_gtm_slave(void) { cmdList_t *cmdList; cmd_t *cmdInitGtm; int rc; elog(INFO, "Initialize GTM slave\n"); cmdList = initCmdList(); if ((cmdInitGtm = prepare_initGtmSlave())) { addCmd(cmdList, cmdInitGtm); /* Do all the commands and clean */ rc = doCmdList(cmdList); cleanCmdList(cmdList); elog(INFO, "Done.\n"); return(rc); } return 1; } /* * Start gtm master ----------------------------------------------------- */ cmd_t *prepare_startGtmMaster(void) { cmd_t *cmdGtmCtl; cmdGtmCtl = initCmd(sval(VAR_gtmMasterServer)); snprintf(newCommand(cmdGtmCtl), MAXLINE, "[ -f %s/gtm.pid ] && 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), sval(VAR_gtmMasterDir)); return cmdGtmCtl; } int start_gtm_master(void) { cmdList_t *cmdList; int rc = 0; elog(INFO, "Start GTM master\n"); if (is_none(sval(VAR_gtmMasterServer))) { elog(INFO, "No GTM master specified, cannot start. Exiting!\n"); return rc; } cmdList = initCmdList(); addCmd(cmdList, prepare_startGtmMaster()); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } /* * Start gtm slave ---------------------------------------------------- */ cmd_t *prepare_startGtmSlave(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, "[ -f %s/gtm.pid ] && gtm_ctl stop -Z gtm -D %s;" "rm -rf %s/register.node;" "gtm_ctl start -Z gtm -D %s", sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir), sval(VAR_gtmSlaveDir)); return (cmdGtmCtl); } int start_gtm_slave(void) { cmdList_t *cmdList; cmd_t *cmd; int rc; elog(INFO, "Start GTM slave"); cmdList = initCmdList(); if ((cmd = prepare_startGtmSlave())) { addCmd(cmdList, cmd); rc = doCmdList(cmdList); cleanCmdList(cmdList); elog(INFO, "Done.\n"); return(rc); } return 1; } /* * Stop gtm master --------------------------------------------------------- */ 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); } int stop_gtm_master(void) { cmdList_t *cmdList; int rc; elog(INFO, "Stop GTM master\n"); cmdList = initCmdList(); addCmd(cmdList, prepare_stopGtmMaster()); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } /* * Stop gtm slave --------------------------------------------------------------- */ 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); } int stop_gtm_slave(void) { cmdList_t *cmdList; cmd_t *cmd; int rc; elog(INFO, "Stop GTM slave\n"); cmdList = initCmdList(); if ((cmd = prepare_stopGtmSlave())) { addCmd(cmdList, cmd); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } return 1; } /* * 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. */ cmd_t *prepare_killGtmMaster(void) { cmd_t *cmdKill; pid_t gtmPid; 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 { elog(WARNING, "WARNING: pid for gtm master was not found. Remove socket only.\n"); snprintf(newCommand(cmdKill), MAXLINE, "rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", atoi(sval(VAR_gtmMasterPort)), sval(VAR_gtmMasterDir)); } return(cmdKill); } int kill_gtm_master(void) { cmdList_t *cmdList; cmd_t *cmd_killGtmMaster; int rc; elog(INFO, "Kill GTM master\n"); cmdList = initCmdList(); if ((cmd_killGtmMaster = prepare_killGtmMaster())) { addCmd(cmdList, cmd_killGtmMaster); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } return 1; } /* * 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. */ 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 { elog(WARNING, "WARNING: pid for gtm slave was not found. Remove socket only.\n"); snprintf(newCommand(cmdKill), MAXLINE, "rm -rf /tmp/.s.'*'%d'*' %s/gtm.pid", atoi(sval(VAR_gtmSlavePort)), sval(VAR_gtmSlaveDir)); } return(cmdKill); } int kill_gtm_slave(void) { cmdList_t *cmdList; cmd_t *cmdKill; int rc; elog(INFO, "Kill GTM slave\n"); cmdList = initCmdList(); if ((cmdKill = prepare_killGtmSlave())) { addCmd(cmdList, cmdKill); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } else return 1; } /* * Failover the gtm ------------------------------------------------------ */ int failover_gtm(void) { char date[MAXTOKEN+1]; char *stdIn; int rc; FILE *f; elog(INFO, "Failover gtm\n"); if (!isVarYes(VAR_gtmSlave) || (sval(VAR_gtmSlaveServer) == NULL) || is_none(sval(VAR_gtmSlaveServer))) { elog(ERROR, "ERROR: GTM slave is not configured. Cannot failover.\n"); return(1); } if (do_gtm_ping(sval(VAR_gtmSlaveServer), atoi(sval(VAR_gtmSlavePort))) != 0) { elog(ERROR, "ERROR: GTM slave is not running\n"); return(1); } /* Promote the slave */ elog(NOTICE, "Running \"gtm_ctl promote -Z gtm -D %s\"\n", sval(VAR_gtmSlaveDir)); rc = doImmediate(sval(VAR_gtmSlaveServer), NULL, "gtm_ctl promote -Z gtm -D %s", sval(VAR_gtmSlaveDir)); if (WEXITSTATUS(rc) != 0) { elog(ERROR, "ERROR: could not promote gtm (host:%s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir)); return 1; } /* Configure promoted gtm */ if ((f = prepareLocalStdin(newFilename(stdIn), MAXPATH, NULL)) == NULL) return(1); fprintf(f, "#===================================================\n" "# Updated due to GTM failover\n" "# %s\n" "startup = ACT\n" "#----End of reconfiguration -------------------------\n", timeStampString(date, MAXTOKEN+1)); fclose(f); elog(NOTICE, "Updating gtm.conf at %s:%s\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir)); rc = doImmediate(sval(VAR_gtmSlaveServer), stdIn, "cat >> %s/gtm.conf", sval(VAR_gtmSlaveDir)); if (WEXITSTATUS(rc) != 0) { elog(ERROR, "ERROR: could not update gtm.conf (host: %s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir)); return 1; } /* Update and backup configuration file */ if ((f = prepareLocalStdin(stdIn, MAXPATH, NULL)) == NULL) return(1); fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM failover\n" "# %s\n" "gtmMasterServer=%s\n" "gtmMasterPort=%s\n" "gtmMasterDir=%s\n" "gtmSlave=n\n" "gtmSlaveServer=none\n" "gtmSlavePort=0\n" "gtmSlaveDir=none\n" "#----End of reconfiguration -------------------------\n", timeStampString(date, MAXTOKEN+1), sval(VAR_gtmSlaveServer), sval(VAR_gtmSlavePort), sval(VAR_gtmSlaveDir)); fclose(f); rc = doImmediate(NULL, stdIn, "cat >> %s", pgxc_ctl_config_path); if (WEXITSTATUS(rc) != 0) { elog(ERROR, "ERROR: could not update gtm.conf (host: %s, dir:%s)\n", sval(VAR_gtmSlaveServer), sval(VAR_gtmSlaveDir)); return 1; } freeAndReset(stdIn); backup_configuration(); /* Reconfigure myself */ assign_val(VAR_gtmMasterServer, VAR_gtmSlaveServer); reset_var(VAR_gtmSlaveServer); assign_val(VAR_gtmMasterPort, VAR_gtmSlavePort); reset_var(VAR_gtmSlavePort); assign_val(VAR_gtmMasterDir, VAR_gtmSlaveDir); reset_var(VAR_gtmSlaveDir); assign_sval(VAR_gtmSlaveServer, "none"); assign_sval(VAR_gtmSlavePort, "0"); assign_sval(VAR_gtmSlaveDir, "none"); assign_sval(VAR_gtmSlave, "n"); return 0; } /* * 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; } int clean_gtm_master(void) { cmdList_t *cmdList; int rc; elog(INFO, "Clearing gtm master directory and socket.\n"); cmdList = initCmdList(); addCmd(cmdList, prepare_cleanGtmMaster()); rc = doCmdList(cmdList); cleanCmdList(cmdList); return(rc); } /* * Clean gtm master resources -- direcotry and socket -------------------------- */ /* * 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; } int clean_gtm_slave(void) { cmdList_t *cmdList; int rc; elog(NOTICE, "Clearing gtm slave resources.\n"); if (!isVarYes(VAR_gtmSlave) || is_none(VAR_gtmSlaveServer)) { elog(ERROR, "ERROR: gtm slave is not configured.\n"); return 1; } cmdList = initCmdList(); addCmd(cmdList, prepare_cleanGtmSlave()); rc = doCmdList(cmdList); cleanCmdList(cmdList); elog(NOTICE, "Done.\n"); return(rc); } /* * ================================================================================== * * Gtm Proxy Staff * * ================================================================================== */ /* * Add gtm proxy: to be used after all the configuration is done. * * This function only maintains internal configuration, updte configuration file, * and make backup if configured. You should run init and start it separately. */ int add_gtmProxy(char *name, char *host, int port, char *dir) { char port_s[MAXTOKEN+1]; char date[MAXTOKEN+1]; FILE *f; char **nodelist = NULL; int rc; if (is_none(host)) { elog(ERROR, "ERROR: Cannot add gtm proxy with the name \"none\".\n"); return 1; } if (is_none(dir)) { elog(ERROR, "ERROR: Cannot add gtm proxy with the directory \"none\".\n"); return 1; } if (checkSpecificResourceConflict(name, host, port, dir, TRUE)) { elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n", name, host, port, dir); return 1; } if (!isVarYes(VAR_gtmProxy)) { assign_sval(VAR_gtmProxy, Strdup("y")); reset_var(VAR_gtmProxyNames); reset_var(VAR_gtmProxyServers); reset_var(VAR_gtmProxyPorts); reset_var(VAR_gtmProxyDirs); reset_var(VAR_gtmPxySpecificExtraConfig); reset_var(VAR_gtmPxyExtraConfig); } add_val(find_var(VAR_gtmProxyNames), Strdup(name)); add_val(find_var(VAR_gtmProxyServers), Strdup(host)); snprintf(port_s, MAXTOKEN, "%d", port); add_val(find_var(VAR_gtmProxyPorts), Strdup(port_s)); add_val(find_var(VAR_gtmProxyDirs), Strdup(dir)); add_val(find_var(VAR_gtmPxySpecificExtraConfig), Strdup("none")); makeServerList(); if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM proxy (%s) addition\n" "# %s\n", name, timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_gtmProxy); fprintAval(f, VAR_gtmProxyNames); fprintAval(f, VAR_gtmProxyServers); fprintAval(f, VAR_gtmProxyPorts); fprintAval(f, VAR_gtmProxyDirs); fprintAval(f, VAR_gtmPxySpecificExtraConfig); fprintf(f, "%s", "#----End of reconfiguration -------------------------\n"); fclose(f); AddMember(nodelist, name); init_gtm_proxy(nodelist); rc = start_gtm_proxy(nodelist); CleanArray(nodelist); return rc; } int remove_gtmProxy(char *name, bool clean_opt) { FILE *f; int idx; /* Check if gtm proxy exists */ if ((idx = gtmProxyIdx(name)) < 0) { elog(ERROR, "ERROR: %s is not a gtm proxy.\n", name); return 1; } /* Check if it is in use */ if (ifExists(VAR_coordMasterServers, aval(VAR_gtmProxyServers)[idx]) || ifExists(VAR_coordSlaveServers, aval(VAR_gtmProxyServers)[idx]) || ifExists(VAR_datanodeMasterServers, aval(VAR_gtmProxyServers)[idx]) || ifExists(VAR_datanodeSlaveServers, aval(VAR_gtmProxyServers)[idx])) { elog(ERROR, "ERROR: GTM Proxy %s is in use\n", name); return 1; } elog(NOTICE, "NOTICE: removing gtm_proxy %s\n", name); /* Clean */ if (clean_opt) { char **nodelist = NULL; elog(NOTICE, "NOTICE: cleaning target resources.\n"); AddMember(nodelist, name); clean_gtm_proxy(nodelist); CleanArray(nodelist); } /* Reconfigure */ var_assign(&aval(VAR_gtmProxyNames)[idx], Strdup("none")); var_assign(&aval(VAR_gtmProxyServers)[idx], Strdup("none")); var_assign(&aval(VAR_gtmProxyPorts)[idx], Strdup("-1")); var_assign(&aval(VAR_gtmProxyDirs)[idx], Strdup("none")); handle_no_slaves(); makeServerList(); /* Update configuration file and backup it */ if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) { /* Should it be panic? */ elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); return 1; } fprintf(f, "#===================================================\n" "# pgxc configuration file updated due to GTM proxy addition\n" "# %s\n" "%s=%s\n" /* gtmProxy */ "%s=( %s )\n" /* gtmProxyNames */ "%s=( %s )\n" /* gtmProxyServers */ "%s=( %s )\n" /* gtmProxyPorts */ "%s=( %s )\n" /* gtmProxyDirs */ "#----End of reconfiguration -------------------------\n", timeStampString(date, MAXTOKEN+1), VAR_gtmProxy, sval(VAR_gtmProxy), VAR_gtmProxyNames, listValue(VAR_gtmProxyNames), VAR_gtmProxyServers, listValue(VAR_gtmProxyServers), VAR_gtmProxyPorts, listValue(VAR_gtmProxyPorts), VAR_gtmProxyDirs, listValue(VAR_gtmProxyDirs)); fclose(f); backup_configuration(); elog(NOTICE, "Done.\n"); return 0; } /* * Does not check if node name is valid. */ cmd_t *prepare_initGtmProxy(char *nodeName) { cmd_t *cmdInitGtm, *cmdGtmProxyConf; int idx; FILE *f; char timestamp[MAXTOKEN+1]; char **fileList = NULL; char remoteDirCheck[MAXPATH * 2 + 128]; if ((idx = gtmProxyIdx(nodeName)) < 0) { elog(ERROR, "ERROR: Specified name %s is not GTM Proxy configuration.\n", nodeName); return NULL; } remoteDirCheck[0] = '\0'; if (!forceInit) { sprintf(remoteDirCheck, "if [ '$(ls -A %s 2> /dev/null)' ]; then echo 'ERROR: " "target directory (%s) exists and not empty. " "Skip GTM proxy initilialization'; exit; fi;", aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx]); } /* Build directory and run initgtm */ cmdInitGtm = initCmd(aval(VAR_gtmProxyServers)[idx]); snprintf(newCommand(cmdInitGtm), MAXLINE, "%s" "[ -f %s/gtm_proxy.pid ] && gtm_ctl -D %s -m immediate -Z gtm_proxy stop;" "rm -rf %s;" "mkdir -p %s;" "PGXC_CTL_SILENT=1 initgtm -Z gtm_proxy -D %s", remoteDirCheck, aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx], 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" "nodename = '%s'\n" "listen_addresses = '*'\n", timeStampString(timestamp, MAXTOKEN), aval(VAR_gtmProxyNames)[idx]); fprintf(f, "port = %s\n" "gtm_host = '%s'\n" "gtm_port = %s\n" "worker_threads = 1\n" "gtm_connect_retry_interval = 1\n" "# End of addition\n", aval(VAR_gtmProxyPorts)[idx], sval(VAR_gtmMasterServer), sval(VAR_gtmMasterPort)); if (!is_none(sval(VAR_gtmPxyExtraConfig))) AddMember(fileList, sval(VAR_gtmPxyExtraConfig)); if (!is_none(sval(VAR_gtmPxySpecificExtraConfig))) AddMember(fileList, sval(VAR_gtmPxySpecificExtraConfig)); appendFiles(f, fileList); CleanArray(fileList); fclose(f); snprintf(newCommand(cmdGtmProxyConf), MAXLINE, "cat >> %s/gtm_proxy.conf", aval(VAR_gtmProxyDirs)[idx]); return(cmdInitGtm); } /* * Initialize gtm proxy ------------------------------------------------------- */ int init_gtm_proxy(char **nodeList) { char **actualNodeList; int ii; int rc; cmdList_t *cmdList; cmd_t *cmdInitGtmPxy; if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "ERROR: GTM Proxy is not configured.\n"); return 1; } actualNodeList = makeActualNodeList(nodeList); /* Init and run initgtm */ cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { elog(NOTICE, "Initializing gtm proxy %s.\n", actualNodeList[ii]); if ((cmdInitGtmPxy = prepare_initGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmdInitGtmPxy); else elog(WARNING, "WARNING: %s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); elog(NOTICE, "Done.\n"); return(rc); } int init_gtm_proxy_all(void) { elog(NOTICE, "Initialize all the gtm proxies.\n"); if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "ERROR: GTM Proxy is not configured.\n"); return(1); } return(init_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * Start gtm proxy ----------------------------------------------------------- */ cmd_t *prepare_startGtmProxy(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, "[ -f %s/gtm_proxy.pid ] && gtm_ctl -D %s -m immediate -Z gtm_proxy stop;" "gtm_ctl start -Z gtm_proxy -D %s", aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx], aval(VAR_gtmProxyDirs)[idx]); return(cmd); } int start_gtm_proxy(char **nodeList) { char **actualNodeList; int ii; int rc; cmdList_t *cmdList; if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "ERROR: GTM Proxy is not configured.\n"); return(1); } actualNodeList = makeActualNodeList(nodeList); /* Init and run initgtm */ cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { cmd_t *cmd; elog(NOTICE, "Starting gtm proxy %s.\n", actualNodeList[ii]); if ((cmd = prepare_startGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmd); else elog(WARNING, "WARNING: %s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); elog(NOTICE, "Done.\n"); return(rc); } int start_gtm_proxy_all(void) { elog(NOTICE, "Starting all the gtm proxies.\n"); return(start_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * Stop gtm proxy ------------------------------------------------------------- */ 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); } int stop_gtm_proxy(char **nodeList) { char **actualNodeList; int ii; int rc; cmdList_t *cmdList; if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "ERROR: GTM Proxy is not configured.\n"); return(1); } actualNodeList = makeActualNodeList(nodeList); /* Init and run initgtm */ cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { cmd_t *cmd; elog(NOTICE, "Stopping gtm proxy %s.\n", actualNodeList[ii]); if ((cmd = prepare_stopGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmd); else elog(WARNING, "WARNING: %s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); elog(NOTICE, "Done.\n"); return(rc); } int stop_gtm_proxy_all(void) { elog(NOTICE, "Stopping all the gtm proxies.\n"); return(stop_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * 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. */ 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 { elog(WARNING, "WARNING: pid for gtm proxy \"%s\" was not found. Remove socket only.\n", nodeName); snprintf(newCommand(cmd), MAXLINE, "rm -rf /tmp/.s.'*'%d'*' %s/gtm_proxy.pid", atoi(aval(VAR_gtmProxyPorts)[idx]), aval(VAR_gtmProxyDirs)[idx]); } return(cmd); } int kill_gtm_proxy(char **nodeList) { char **actualNodeList; int ii; int rc; cmdList_t *cmdList; if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "ERROR: GTM Proxy is not configured.\n"); return(1); } actualNodeList = makeActualNodeList(nodeList); /* Init and run initgtm */ cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { cmd_t *cmd; elog(NOTICE, "Killing process of gtm proxy %s.\n", actualNodeList[ii]); if ((cmd = prepare_killGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmd); else elog(WARNING, "WARNING: %s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); return(rc); } int kill_gtm_proxy_all(void) { elog(NOTICE, "Killing all the gtm proxy processes.\n"); return(kill_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * 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 */ 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); } int reconnect_gtm_proxy(char **nodeList) { char **actualNodeList; int ii; int rc; cmdList_t *cmdList; if (!isVarYes(VAR_gtmProxy)) { elog(ERROR, "GTM Proxy is not configured.\n"); return(1); } actualNodeList = makeActualNodeList(nodeList); /* Init and run initgtm */ cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { cmd_t *cmd; elog(NOTICE, "Reconnecting gtm proxy %s.\n", actualNodeList[ii]); if((cmd = prepare_reconnectGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmd); else elog(WARNING, "WARNING: %s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); elog(NOTICE, "Done.\n"); return(rc); } int reconnect_gtm_proxy_all(void) { elog(NOTICE, "Reconnecting all the gtm proxies to the new one.\n"); return(reconnect_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * 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; } int clean_gtm_proxy(char **nodeList) { char **actualNodeList; cmdList_t *cmdList; cmd_t *cmd; int ii; int rc; actualNodeList = makeActualNodeList(nodeList); cmdList = initCmdList(); for (ii = 0; actualNodeList[ii]; ii++) { elog(NOTICE, "Clearing resources for gtm_proxy %s.\n", actualNodeList[ii]); if ((cmd = prepare_cleanGtmProxy(actualNodeList[ii]))) addCmd(cmdList, cmd); else elog(WARNING, "%s is not a gtm proxy.\n", actualNodeList[ii]); } rc = doCmdList(cmdList); cleanCmdList(cmdList); CleanArray(actualNodeList); elog(NOTICE, "Done.\n"); return(rc); } int clean_gtm_proxy_all(void) { elog(NOTICE, "Clearing all the gtm_proxy resources.\n"); return(clean_gtm_proxy(aval(VAR_gtmProxyNames))); } /* * configuration -------------------------------------------------------------------- */ int show_config_gtmMaster(int flag, char *hostname) { char lineBuf[MAXLINE+1]; char editBuf[MAXPATH+1]; lineBuf[0] = 0; if (flag) strncat(lineBuf, "GTM Master: ", MAXLINE); if (hostname) { snprintf(editBuf, MAXPATH, "host: %s", hostname); strncat(lineBuf, editBuf, MAXLINE); } if (flag || hostname) strncat(lineBuf, "\n", MAXLINE); lockLogFile(); if (lineBuf[0]) elog(NOTICE, "%s", lineBuf); print_simple_node_info(sval(VAR_gtmName), sval(VAR_gtmMasterPort), sval(VAR_gtmMasterDir), sval(VAR_gtmExtraConfig), sval(VAR_gtmMasterSpecificExtraConfig)); unlockLogFile(); return 0; } int show_config_gtmSlave(int flag, char *hostname) { char lineBuf[MAXLINE+1]; char editBuf[MAXPATH+1]; if (!isVarYes(VAR_gtmSlave) || is_none(VAR_gtmSlaveServer)) { elog(ERROR, "ERROR: gtm slave is not configured.\n"); return 0; } lineBuf[0] = 0; if (flag) strncat(lineBuf, "GTM Slave: ", MAXLINE); if (hostname) { snprintf(editBuf, MAXPATH, "host: %s", hostname); strncat(lineBuf, editBuf, MAXLINE); } if (flag || hostname) strncat(lineBuf, "\n", MAXLINE); lockLogFile(); elog(NOTICE, "%s", lineBuf); print_simple_node_info(sval(VAR_gtmSlaveName), sval(VAR_gtmSlavePort), sval(VAR_gtmSlaveDir), sval(VAR_gtmExtraConfig), sval(VAR_gtmSlaveSpecificExtraConfig)); unlockLogFile(); return 0; } int show_config_gtmProxies(char **nameList) { int ii; lockLogFile(); for(ii = 0; nameList[ii]; ii++) show_config_gtmProxy(TRUE, ii, aval(VAR_gtmProxyServers)[ii]); unlockLogFile(); return 0; } int show_config_gtmProxy(int flag, int idx, char *hostname) { char lineBuf[MAXLINE+1]; char editBuf[MAXPATH+1]; lineBuf[0] = 0; if (flag) strncat(lineBuf, "GTM Proxy: ", MAXLINE); if (hostname) { snprintf(editBuf, MAXPATH, "host: %s", hostname); strncat(lineBuf, editBuf, MAXLINE); } if (flag || hostname) strncat(lineBuf, "\n", MAXLINE); lockLogFile(); if (lineBuf[0]) elog(NOTICE, "%s", lineBuf); print_simple_node_info(aval(VAR_gtmProxyNames)[idx], aval(VAR_gtmProxyPorts)[idx], aval(VAR_gtmProxyDirs)[idx], sval(VAR_gtmPxyExtraConfig), aval(VAR_gtmPxySpecificExtraConfig)[idx]); unlockLogFile(); return 0; }