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;
}
}
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)