diff options
author | Martin Willi <martin@revosec.ch> | 2013-03-19 16:49:07 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-03-19 16:54:20 +0100 |
commit | e2d2b542f1d3278d3e07129ac3ceea342bd63b2f (patch) | |
tree | af1197a7adec203c0509f6bb0d126ccd55a6620f /src | |
parent | 33524f02f90e74631980163e6d58145091d2cab8 (diff) | |
download | strongswan-e2d2b542f1d3278d3e07129ac3ceea342bd63b2f.tar.bz2 strongswan-e2d2b542f1d3278d3e07129ac3ceea342bd63b2f.tar.xz |
Add an option to autobalance a HA cluster automatically
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/plugins/ha/ha_segments.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c index a4ea9ef9a..cab38c63d 100644 --- a/src/libcharon/plugins/ha/ha_segments.c +++ b/src/libcharon/plugins/ha/ha_segments.c @@ -90,6 +90,11 @@ struct private_ha_segments_t { * Timeout for heartbeats received from other node */ int heartbeat_timeout; + + /** + * Interval to check for autobalance, 0 to disable + */ + int autobalance; }; /** @@ -374,6 +379,54 @@ static void start_heartbeat(private_ha_segments_t *this) this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL)); } +/** + * Take a segment if we are handling less than half of segments + */ +static job_requeue_t autobalance(private_ha_segments_t *this) +{ + int i, active = 0; + + this->mutex->lock(this->mutex); + + for (i = 1; i <= this->count; i++) + { + if (this->active & SEGMENTS_BIT(i)) + { + active++; + } + } + if (active < this->count / 2) + { + for (i = 1; i <= this->count; i++) + { + if (!(this->active & SEGMENTS_BIT(i))) + { + DBG1(DBG_CFG, "autobalancing HA (%d/%d active), taking %d", + active, this->count, i); + enable_disable(this, i, TRUE, TRUE); + /* we claim only one in each interval */ + break; + } + } + } + + this->mutex->unlock(this->mutex); + + return JOB_RESCHEDULE(this->autobalance); +} + +/** + * Schedule autobalancing + */ +static void start_autobalance(private_ha_segments_t *this) +{ + DBG1(DBG_CFG, "scheduling HA autobalance every %ds", this->autobalance); + lib->scheduler->schedule_job(lib->scheduler, + (job_t*)callback_job_create_with_prio((callback_job_cb_t)autobalance, + this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL), + this->autobalance); +} + METHOD(ha_segments_t, is_active, bool, private_ha_segments_t *this, u_int segment) { @@ -421,6 +474,8 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, .heartbeat_timeout = lib->settings->get_int(lib->settings, "%s.plugins.ha.heartbeat_timeout", DEFAULT_HEARTBEAT_TIMEOUT, charon->name), + .autobalance = lib->settings->get_int(lib->settings, + "%s.plugins.ha.autobalance", 0, charon->name), ); if (monitor) @@ -430,6 +485,10 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, start_heartbeat(this); start_watchdog(this); } + if (this->autobalance) + { + start_autobalance(this); + } return &this->public; } |