]> granicus.if.org Git - pgbouncer/commitdiff
Add KILL command to pause a db and terminate all connections.
authorMichael Tharp <gxti@partiallystapled.com>
Fri, 18 Mar 2011 14:45:31 +0000 (10:45 -0400)
committerMichael Tharp <gxti@partiallystapled.com>
Fri, 18 Mar 2011 14:45:31 +0000 (10:45 -0400)
include/janitor.h
src/admin.c
src/janitor.c

index e0e1dc888a467c69afec718f5ff156cde0fc317b..eaa813aa2b148286508e513bb74953560c31aa46 100644 (file)
@@ -21,4 +21,5 @@ void config_postprocess(void);
 void resume_all(void);
 void per_loop_maint(void);
 bool suspend_socket(PgSocket *sk, bool force)  _MUSTCHECK;
+void kill_pool(PgPool *pool);
 
index 0125de7c46c6e3b705fb21bb2b659533260344ac..349802055fda95f0666a700cf51e0c22514d22f8 100644 (file)
@@ -911,6 +911,45 @@ static bool admin_cmd_pause(PgSocket *admin, const char *arg)
        return true;
 }
 
+/* Command: KILL */
+static bool admin_cmd_kill(PgSocket *admin, const char *arg)
+{
+       struct List *item, *tmp;
+       PgDatabase *db;
+       PgPool *pool;
+
+       if (!admin->admin_user)
+               return admin_error(admin, "admin access needed");
+
+       if (cf_pause_mode)
+               return admin_error(admin, "already suspended/paused");
+
+       if (!arg[0])
+               return admin_error(admin, "a database is required");
+
+       log_info("KILL '%s' command issued", arg);
+       db = find_database(arg);
+       if (db == NULL) {
+               db = register_auto_database(arg);
+               if (db == NULL) {
+                       return admin_error(admin, "no such database: %s", arg);
+               } else {
+                       slog_info(admin, "registered new auto-database for KILL: %s", arg);
+               }
+       }
+       if (db == admin->pool->db)
+               return admin_error(admin, "cannot kill admin db: %s", arg);
+
+       db->db_paused = 1;
+       statlist_for_each_safe(item, &pool_list, tmp) {
+               pool = container_of(item, PgPool, head);
+               if (pool->db == db)
+                       kill_pool(pool);
+       }
+
+       return admin_ready(admin, "KILL");
+}
+
 /* extract substring from regex group */
 static void copy_arg(const char *src, regmatch_t *glist,
                     int gnum, char *dst, unsigned dstmax)
@@ -1015,6 +1054,7 @@ static bool admin_cmd_show(PgSocket *admin, const char *arg)
 }
 
 static struct cmd_lookup cmd_list [] = {
+       {"kill", admin_cmd_kill},
        {"pause", admin_cmd_pause},
        {"reload", admin_cmd_reload},
        {"resume", admin_cmd_resume},
index bed166d9b37f3bd9db903311e799b140c644b6a7..350d3d45118a138a03b58aa065749f2918af4e17 100644 (file)
@@ -564,7 +564,7 @@ void janitor_setup(void)
        safe_evtimer_add(&full_maint_ev, &full_maint_period);
 }
 
-static void kill_pool(PgPool *pool)
+void kill_pool(PgPool *pool)
 {
        const char *reason = "database removed";