pgpool2.git / summary / log / commit / refs

commit    74fdfacf7adbdbee1abf5b5c9338dd5cdae02242
Author:   Nozomi Anzai <anzai@sraoss.co.jp>
Date:     Fri May 10 05:20:28 2013 +0000

    Add a function "pgpool_pgctl()" which enebles to execute pg_ctl stop/restart/reload
    (except for start) by SQL.
    
    $ psql sales -c "select pgpool_pgctl('reload', 'fast')";
     pgpool_pgctl
    --------------
     t
    (1 row)
    
    This function always ignores the actual result and returns 't',
    so the user can't know if pg_ctl succeeded or failed.
    To use this we have to set the custom variable for security
    which limits the users to execute pg_ctl who has the permission of data directory.


sql/pgpool-recovery/pgpool-recovery.c | 56 ++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/sql/pgpool-recovery/pgpool-recovery.c b/sql/pgpool-recovery/pgpool-recovery.c index 4f47e2c26..85c1e9ace 100644 --- a/sql/pgpool-recovery/pgpool-recovery.c +++ b/sql/pgpool-recovery/pgpool-recovery.c @@ -29,9 +29,13 @@ #include "catalog/namespace.h" #include "utils/syscache.h" #include "utils/builtins.h" /* PostgreSQL 8.4 needs this for textout */ +<<<<<<< HEAD +#include "utils/guc.h" +======= #if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 90300) #include "access/htup_details.h" /* PostgreSQL 9.3 or later needs this */ #endif +>>>>>>> 641ef2ff314d2a9336a37bb29cae686fb3849346 #define REMOTE_START_FILE "pgpool_remote_start" @@ -43,16 +47,19 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(pgpool_recovery); PG_FUNCTION_INFO_V1(pgpool_remote_start); +PG_FUNCTION_INFO_V1(pgpool_pgctl); PG_FUNCTION_INFO_V1(pgpool_switch_xlog); extern Datum pgpool_recovery(PG_FUNCTION_ARGS); extern Datum pgpool_remote_start(PG_FUNCTION_ARGS); +extern Datum pgpool_pgctl(PG_FUNCTION_ARGS); extern Datum pgpool_switch_xlog(PG_FUNCTION_ARGS); static char recovery_script[1024]; +static char command_text[1024]; static Oid get_function_oid(const char *funcname, const char *argtype, const char *nspname); - +char *Log_line_prefix = NULL; Datum pgpool_recovery(PG_FUNCTION_ARGS) { @@ -120,6 +127,52 @@ pgpool_remote_start(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } +Datum +pgpool_pgctl(PG_FUNCTION_ARGS) +{ + int r; + char *action = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(0)))); + char *stop_mode = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(1)))); + char *pg_ctl; + char *data_directory; + + if (!superuser()) +#ifdef ERRCODE_INSUFFICIENT_PRIVILEGE + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to use pgpool_pgctl function")))); +#else + elog(ERROR, "must be superuser to use pgpool_pgctl function"); +#endif + + pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL); + data_directory = GetConfigOptionByName("data_directory", NULL); + + if (strcmp(stop_mode, "") != 0) + { + snprintf(command_text, sizeof(command_text), + "%s %s -D %s -m %s 2>/dev/null 1>/dev/null < /dev/null &", + pg_ctl, action, data_directory, stop_mode); + + } else { + snprintf(command_text, sizeof(command_text), + "%s %s -D %s 2>/dev/null 1>/dev/null < /dev/null &", + pg_ctl, action, data_directory); + } + + elog(DEBUG1, "command_text: %s", command_text); + r = system(command_text); + + if (strcmp(action, "reload") == 0 && r != 0) + { + elog(ERROR, "pgpool_pgctl failed"); + } + + PG_RETURN_BOOL(true); +} + /* * pgpool_switch_log is the same as pg_switch_xlog except that * it wait till archiving is completed. @@ -227,3 +280,4 @@ get_function_oid(const char *funcname, const char *argtype, const char *nspname) #endif return 0; } + [parent: 641ef2ff314d]