static void set_mode(char *modeopt) { if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0) { shutdown_mode = SMART_MODE; sig = SIGTERM; } else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0) { shutdown_mode = FAST_MODE; sig = SIGINT; } else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0) { shutdown_mode = IMMEDIATE_MODE; sig = SIGQUIT; } else { write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt); do_advice(); exit(1); } }
static void set_sig(char *signame) { if (!strcmp(signame, "HUP")) sig = SIGHUP; else if (!strcmp(signame, "INT")) sig = SIGINT; else if (!strcmp(signame, "QUIT")) sig = SIGQUIT; else if (!strcmp(signame, "ABRT")) sig = SIGABRT; /* * probably should NOT provide SIGKILL * * else if (!strcmp(signame,"KILL")) sig = SIGKILL; */ else if (!strcmp(signame, "TERM")) sig = SIGTERM; else if (!strcmp(signame, "USR1")) sig = SIGUSR1; else if (!strcmp(signame, "USR2")) sig = SIGUSR2; else { write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame); do_advice(); exit(1); } }
int main(int argc, char **argv) { static struct option long_options[] = { {"help", no_argument, NULL, '?'}, {"version", no_argument, NULL, 'V'}, {"log", required_argument, NULL, 'l'}, {"mode", required_argument, NULL, 'm'}, {"pgdata", required_argument, NULL, 'D'}, {"silent", no_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"core-files", no_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; int option_index; int c; pgpid_t killproc = 0; #if defined(WIN32) || defined(__CYGWIN__) setvbuf(stderr, NULL, _IONBF, 0); #endif progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl")); /* * save argv[0] so do_start() can look for the postmaster if necessary. we * don't look for postmaster here because in many cases we won't need it. */ argv0 = argv[0]; umask(077); /* support --help and --version even if invoked as root */ if (argc > 1) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { do_help(); exit(0); } else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { puts("pg_ctl (PostgreSQL) " PG_VERSION); exit(0); } } /* * Disallow running as root, to forestall any possible security holes. */ #ifndef WIN32 if (geteuid() == 0) { write_stderr(_("%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the " "(unprivileged) user that will\n" "own the server process.\n"), progname); exit(1); } #endif /* * 'Action' can be before or after args so loop over both. Some * getopt_long() implementations will reorder argv[] to place all flags * first (GNU?), but we don't rely on it. Our /port version doesn't do * that. */ optind = 1; /* process command-line options */ while (optind < argc) { while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:st:U:wW", long_options, &option_index)) != -1) { switch (c) { case 'D': { char *pgdata_D; char *env_var = pg_malloc(strlen(optarg) + 8); pgdata_D = xstrdup(optarg); canonicalize_path(pgdata_D); snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s", pgdata_D); putenv(env_var); /* * We could pass PGDATA just in an environment * variable but we do -D too for clearer postmaster * 'ps' display */ pgdata_opt = pg_malloc(strlen(pgdata_D) + 7); snprintf(pgdata_opt, strlen(pgdata_D) + 7, "-D \"%s\" ", pgdata_D); break; } case 'l': log_file = xstrdup(optarg); break; case 'm': set_mode(optarg); break; case 'N': register_servicename = xstrdup(optarg); break; case 'o': post_opts = xstrdup(optarg); break; case 'p': exec_path = xstrdup(optarg); break; case 'P': register_password = xstrdup(optarg); break; case 's': silent_mode = true; break; case 't': wait_seconds = atoi(optarg); break; case 'U': if (strchr(optarg, '\\')) register_username = xstrdup(optarg); else /* Prepend .\ for local accounts */ { register_username = malloc(strlen(optarg) + 3); if (!register_username) { write_stderr(_("%s: out of memory\n"), progname); exit(1); } strcpy(register_username, ".\\"); strcat(register_username, optarg); } break; case 'w': do_wait = true; wait_set = true; break; case 'W': do_wait = false; wait_set = true; break; case 'c': allow_core_files = true; break; default: /* getopt_long already issued a suitable error message */ do_advice(); exit(1); } } /* Process an action */ if (optind < argc) { if (ctl_command != NO_COMMAND) { write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]); do_advice(); exit(1); } if (strcmp(argv[optind], "init") == 0 || strcmp(argv[optind], "initdb") == 0) ctl_command = INIT_COMMAND; else if (strcmp(argv[optind], "start") == 0) ctl_command = START_COMMAND; else if (strcmp(argv[optind], "stop") == 0) ctl_command = STOP_COMMAND; else if (strcmp(argv[optind], "restart") == 0) ctl_command = RESTART_COMMAND; else if (strcmp(argv[optind], "reload") == 0) ctl_command = RELOAD_COMMAND; else if (strcmp(argv[optind], "status") == 0) ctl_command = STATUS_COMMAND; else if (strcmp(argv[optind], "kill") == 0) { if (argc - optind < 3) { write_stderr(_("%s: missing arguments for kill mode\n"), progname); do_advice(); exit(1); } ctl_command = KILL_COMMAND; set_sig(argv[++optind]); killproc = atol(argv[++optind]); } #if defined(WIN32) || defined(__CYGWIN__) else if (strcmp(argv[optind], "register") == 0) ctl_command = REGISTER_COMMAND; else if (strcmp(argv[optind], "unregister") == 0) ctl_command = UNREGISTER_COMMAND; else if (strcmp(argv[optind], "runservice") == 0) ctl_command = RUN_AS_SERVICE_COMMAND; #endif else { write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]); do_advice(); exit(1); } optind++; } } if (ctl_command == NO_COMMAND) { write_stderr(_("%s: no operation specified\n"), progname); do_advice(); exit(1); } /* Note we put any -D switch into the env var above */ pg_data = getenv("PGDATA"); if (pg_data) { pg_data = xstrdup(pg_data); canonicalize_path(pg_data); } if (pg_data == NULL && ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND) { write_stderr(_("%s: no database directory specified " "and environment variable PGDATA unset\n"), progname); do_advice(); exit(1); } if (!wait_set) { switch (ctl_command) { case RESTART_COMMAND: case START_COMMAND: do_wait = false; break; case STOP_COMMAND: do_wait = true; break; default: break; } } if (ctl_command == RELOAD_COMMAND) { sig = SIGHUP; do_wait = false; } if (pg_data) { snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data); snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data); snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data); snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data); snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data); } switch (ctl_command) { case INIT_COMMAND: do_init(); break; case STATUS_COMMAND: do_status(); break; case START_COMMAND: do_start(); break; case STOP_COMMAND: do_stop(); break; case RESTART_COMMAND: do_restart(); break; case RELOAD_COMMAND: do_reload(); break; case KILL_COMMAND: do_kill(killproc); break; #if defined(WIN32) || defined(__CYGWIN__) case REGISTER_COMMAND: pgwin32_doRegister(); break; case UNREGISTER_COMMAND: pgwin32_doUnregister(); break; case RUN_AS_SERVICE_COMMAND: pgwin32_doRunAsService(); break; #endif default: break; } exit(0); }
int main(int argc, char **argv) { int c; char *nodename = NULL; /* GTM Proxy nodename */ progname = "gtm_ctl"; /* * save argv[0] so do_start() can look for the gtm if necessary. we * don't look for gtm here because in many cases we won't need it. */ argv0 = argv[0]; umask(077); /* support --help and --version even if invoked as root */ if (argc > 1) { if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { do_help(); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("gtm_ctl (Postgres-XC) " PGXC_VERSION); exit(0); } } /* * Disallow running as root, to forestall any possible security holes. */ if (geteuid() == 0) { write_stderr(_("%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the " "(unprivileged) user that will\n" "own the server process.\n"), progname); exit(1); } /* * 'Action' can be before or after args so loop over both. Some * getopt_long() implementations will reorder argv[] to place all flags * first (GNU?), but we don't rely on it. Our /port version doesn't do * that. */ optind = 1; /* process command-line options */ while (optind < argc) { while ((c = getopt(argc, argv, "D:i:l:m:o:p:t:wWZ:C:")) != -1) { switch (c) { case 'D': { char *env_var = pg_malloc(strlen(optarg) + 9); gtmdata_D = xstrdup(optarg); canonicalize_path(gtmdata_D); snprintf(env_var, strlen(optarg) + 9, "GTMDATA=%s", gtmdata_D); putenv(env_var); /* * We could pass GTMDATA just in an environment * variable but we do -D too for clearer gtm * 'ps' display */ gtmdata_opt = (char *) pg_malloc(strlen(gtmdata_D) + 8); snprintf(gtmdata_opt, strlen(gtmdata_D) + 8, "-D \"%s\" ", gtmdata_D); break; } case 'i': nodename = strdup(optarg); break; case 'l': log_file = xstrdup(optarg); break; case 'm': set_mode(optarg); break; case 'o': gtm_opts = xstrdup(optarg); break; case 'p': gtm_path = xstrdup(optarg); canonicalize_path(gtm_path); break; case 't': wait_seconds = atoi(optarg); break; case 'C': control_file = xstrdup(optarg); break; case 'w': do_wait = true; wait_set = true; break; case 'W': do_wait = false; wait_set = true; break; case 'Z': gtm_app = xstrdup(optarg); if (strcmp(gtm_app,"gtm_proxy") != 0 && strcmp(gtm_app,"gtm_standby") != 0 && strcmp(gtm_app,"gtm") != 0) { write_stderr(_("%s: %s launch name set not correct\n"), progname, gtm_app); do_advice(); exit(1); } break; default: /* getopt_long already issued a suitable error message */ do_advice(); exit(1); } } /* Process an action */ if (optind < argc) { if (ctl_command != NO_COMMAND) { write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]); do_advice(); exit(1); } if (strcmp(argv[optind], "start") == 0) ctl_command = START_COMMAND; else if (strcmp(argv[optind], "stop") == 0) ctl_command = STOP_COMMAND; else if (strcmp(argv[optind], "promote") == 0) ctl_command = PROMOTE_COMMAND; else if (strcmp(argv[optind], "restart") == 0) ctl_command = RESTART_COMMAND; else if (strcmp(argv[optind], "status") == 0) ctl_command = STATUS_COMMAND; else if (strcmp(argv[optind], "reconnect") == 0) ctl_command = RECONNECT_COMMAND; else { write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]); do_advice(); exit(1); } optind++; } } /* * Take care of the control file (-C Option) */ if (control_file) { char ctrl_path[MAXPGPATH+1]; char C_opt_path[MAXPGPATH+1]; char bkup_path[MAXPGPATH+1]; FILE *f1, *f2; int c; if (!gtmdata_D) { write_stderr(_("No -D option specified.\n")); exit(1); } if ((strcmp(gtm_app, "gtm") != 0) && (strcmp(gtm_app, "gtm_master") != 0)) { write_stderr(_("-C option is valid only for gtm.\n")); exit(1); } /* If there's already a control file, backup it to *.bak */ trim_last_slash(gtmdata_D); snprintf(ctrl_path, MAXPGPATH, "%s/%s", gtmdata_D, GTM_CONTROL_FILE); if ((f1 = fopen(ctrl_path, "r"))) { snprintf(bkup_path, MAXPGPATH, "%s/%s.bak", gtmdata_D, GTM_CONTROL_FILE); if (!(f2 = fopen(bkup_path, "w"))) { fclose(f1); write_stderr(_("Cannot open backup file, %s/%s.bak, %s\n"), gtmdata_D, GTM_CONTROL_FILE, strerror(errno)); exit(1); } while ((c = getc(f1)) != EOF) putc(c, f2); fclose(f1); fclose(f2); } /* Copy specified control file. */ snprintf(C_opt_path, MAXPGPATH, "%s/%s", gtmdata_D, control_file); if (!(f1 = fopen(ctrl_path, "w"))) { write_stderr(_("Cannot oopen control file, %s, %s\n"), ctrl_path, strerror(errno)); exit(1); } if (!(f2 = fopen(C_opt_path, "r"))) { fclose(f1); write_stderr(_("Cannot open -C option file, %s, %s\n"), C_opt_path, strerror(errno)); exit(1); } while ((c = getc(f2)) != EOF) putc(c, f1); fclose(f1); fclose(f2); } if (ctl_command == NO_COMMAND) { write_stderr(_("%s: no operation specified\n"), progname); do_advice(); exit(1); } gtm_data = getenv("GTMDATA"); if (gtm_data) { gtm_data = xstrdup(gtm_data); canonicalize_path(gtm_data); } if (!gtm_data) { write_stderr("%s: no GTM/GTM Proxy directory specified \n", progname); do_advice(); exit(1); } /* * pid files of gtm and gtm proxy are named differently * -Z option has also to be set for STOP_COMMAND * or gtm_ctl will not be able to find the correct pid_file */ if (!gtm_app) { write_stderr("%s: no launch option not specified\n", progname); do_advice(); exit(1); } if (strcmp(gtm_app,"gtm_proxy") != 0 && strcmp(gtm_app, "gtm_standby") != 0 && strcmp(gtm_app,"gtm") != 0) { write_stderr(_("%s: launch option incorrect\n"), progname); do_advice(); exit(1); } /* Check if GTM Proxy ID is set, this is not necessary when stopping */ if (ctl_command == START_COMMAND || ctl_command == RESTART_COMMAND) { /* Rebuild option string to include Proxy ID */ if (strcmp(gtm_app, "gtm_proxy") == 0) { gtmdata_opt = (char *) pg_realloc(gtmdata_opt, strlen(gtmdata_opt) + 9); if (nodename) sprintf(gtmdata_opt, "%s -i %s ", gtmdata_opt, nodename); else sprintf(gtmdata_opt, "%s ", gtmdata_opt); } } if (!wait_set) { switch (ctl_command) { case RESTART_COMMAND: case START_COMMAND: case PROMOTE_COMMAND: case STATUS_COMMAND: do_wait = false; break; case STOP_COMMAND: do_wait = true; break; default: break; } } /* Build strings for pid file and option file */ if (strcmp(gtm_app,"gtm_proxy") == 0) { snprintf(pid_file, MAXPGPATH, "%s/gtm_proxy.pid", gtm_data); snprintf(gtmopts_file, MAXPGPATH, "%s/gtm_proxy.opts", gtm_data); snprintf(conf_file, MAXPGPATH, "%s/gtm_proxy.conf", gtm_data); } else if (strcmp(gtm_app,"gtm") == 0) { snprintf(pid_file, MAXPGPATH, "%s/gtm.pid", gtm_data); snprintf(gtmopts_file, MAXPGPATH, "%s/gtm.opts", gtm_data); snprintf(conf_file, MAXPGPATH, "%s/gtm.conf", gtm_data); } else if (strcmp(gtm_app,"gtm_standby") == 0) { snprintf(pid_file, MAXPGPATH, "%s/gtm.pid", gtm_data); snprintf(gtmopts_file, MAXPGPATH, "%s/gtm.opts", gtm_data); snprintf(conf_file, MAXPGPATH, "%s/gtm.conf", gtm_data); } if (ctl_command==STATUS_COMMAND) gtm_opts = xstrdup("-c"); switch (ctl_command) { case START_COMMAND: do_start(); break; case STOP_COMMAND: do_stop(); break; case PROMOTE_COMMAND: do_promote(); break; case RESTART_COMMAND: do_restart(); break; case STATUS_COMMAND: do_status(); break; case RECONNECT_COMMAND: do_reconnect(); break; default: break; } exit(0); }