]> granicus.if.org Git - pgbouncer/commitdiff
actively kill databases removed from config
authorMarko Kreen <markokr@gmail.com>
Fri, 11 Jan 2008 21:23:18 +0000 (21:23 +0000)
committerMarko Kreen <markokr@gmail.com>
Fri, 11 Jan 2008 21:23:18 +0000 (21:23 +0000)
include/bouncer.h
src/janitor.c
src/loader.c
src/main.c

index 2678d6fb5dd056a9f6f03f67e8c04adb1956ab8d..81fcfe661a7cb24553017e38d42685d4ba21c4cd 100644 (file)
@@ -201,6 +201,7 @@ struct PgDatabase {
        char                    name[MAX_DBNAME];
 
        unsigned                db_paused:1;
+       unsigned                db_dead:1;
 
        /* key/val pairs (without user) for startup msg to be sent to server */
        uint8_t                 startup_params[256];
index 4c4d100d8a39709115cc46a4e565a2647f427498..a596313c1326a41ad353579db9d2739afece73a6 100644 (file)
@@ -511,16 +511,55 @@ void janitor_setup(void)
        safe_evtimer_add(&full_maint_ev, &full_maint_period);
 }
 
+static void kill_pool(PgPool *pool)
+{
+       const char *reason = "database removed";
+
+       close_client_list(&pool->active_client_list, reason);
+       close_client_list(&pool->waiting_client_list, reason);
+       close_client_list(&pool->cancel_req_list, reason);
+
+       close_server_list(&pool->active_server_list, reason);
+       close_server_list(&pool->idle_server_list, reason);
+       close_server_list(&pool->used_server_list, reason);
+       close_server_list(&pool->tested_server_list, reason);
+       close_server_list(&pool->new_server_list, reason);
+
+       list_del(&pool->map_head);
+       statlist_remove(&pool->head, &pool_list);
+       free(pool);
+}
+
+static void kill_database(PgDatabase *db)
+{
+       PgPool *pool;
+       List *item, *tmp;
+
+       log_warning("dropping database '%s' as it does not exist anymore", db->name);
+
+       statlist_for_each_safe(item, &pool_list, tmp) {
+               pool = container_of(item, PgPool, head);
+               if (pool->db == db)
+                       kill_pool(pool);
+       }
+       if (db->forced_user)
+               free(db->forced_user);
+       statlist_remove(&db->head, &database_list);
+       free(db);
+}
+
 /* as [pgbouncer] section can be loaded after databases,
    there's need for review */
 void config_postprocess(void)
 {
-       List *item;
+       List *item, *tmp;
        PgDatabase *db;
 
-       statlist_for_each(item, &database_list) {
+       statlist_for_each_safe(item, &database_list, tmp) {
                db = container_of(item, PgDatabase, head);
-               if (db->pool_size < 0)
+               if (db->db_dead)
+                       kill_database(db);
+               else if (db->pool_size < 0)
                        db->pool_size = cf_default_pool_size;
        }
 }
index e57ccab759984a05087369a6fb66d2022fa66f45..5ff6acf3158f857227cc20a10969f25054f71592 100644 (file)
@@ -234,6 +234,9 @@ void parse_database(char *name, char *connstr)
                return;
        }
 
+       /* tag the db as alive */
+       db->db_dead = 0;
+
        /* if updating old db, check if anything changed */
        if (db->dbname) {
                bool changed = false;
index 9d1c3f75666a1057930970f52edcefeac701082e..828d5e5a8119dda7933fbb6ac2429ab1b8325d04 100644 (file)
@@ -223,18 +223,39 @@ static bool set_auth(ConfElem *elem, const char *val, PgSocket *console)
        return true;
 }
 
+static void set_dbs_dead(bool flag)
+{
+       List *item;
+       PgDatabase *db;
+
+       statlist_for_each(item, &database_list) {
+               db = container_of(item, PgDatabase, head);
+               if (strcmp(db->name, "pgbouncer") == 0)
+                       continue;
+               db->db_dead = flag;
+       }
+}
+
 /* config loading, tries to be tolerant to errors */
 void load_config(bool reload)
 {
-       /* actual loading */
-       iniparser(cf_config_file, bouncer_config, reload);
+       bool ok;
 
-       /* load users if needed */
-       if (cf_auth_type >= AUTH_TRUST)
-               load_auth_file(cf_auth_file);
+       set_dbs_dead(true);
 
-       /* reset pool_size */
-       config_postprocess();
+       /* actual loading */
+       ok = iniparser(cf_config_file, bouncer_config, reload);
+       if (ok) {
+               /* load users if needed */
+               if (cf_auth_type >= AUTH_TRUST)
+                       load_auth_file(cf_auth_file);
+
+               /* reset pool_size, kill dbs */
+               config_postprocess();
+       } else {
+               /* if ini file missing, dont kill anybody */
+               set_dbs_dead(false);
+       }
 
        /* reopen logfile */
        if (reload)