* Timeout for heartbeats received from other node
*/
int heartbeat_timeout;
+
+ /**
+ * Interval to check for autobalance, 0 to disable
+ */
+ int autobalance;
};
/**
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)
{
.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)
start_heartbeat(this);
start_watchdog(this);
}
+ if (this->autobalance)
+ {
+ start_autobalance(this);
+ }
return &this->public;
}