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]