summaryrefslogtreecommitdiffstats
path: root/server/providers/fail_over.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/fail_over.c')
-rw-r--r--server/providers/fail_over.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/server/providers/fail_over.c b/server/providers/fail_over.c
index 5c91bfc6d..9795ccecd 100644
--- a/server/providers/fail_over.c
+++ b/server/providers/fail_over.c
@@ -56,6 +56,7 @@ struct fo_service {
struct fo_ctx *ctx;
char *name;
struct fo_server *active_server;
+ struct fo_server *last_tried_server;
struct fo_server *server_list;
};
@@ -391,21 +392,41 @@ get_first_server_entity(struct fo_service *service, struct fo_server **_server)
server = service->active_server;
if (server != NULL) {
if (service_works(server)) {
- *_server = server;
- return EOK;
+ goto done;
}
service->active_server = NULL;
}
- /* Otherwise iterate through the server list. */
+ /*
+ * Otherwise iterate through the server list.
+ */
+
+ /* First, try servers after the last one we tried. */
+ if (service->last_tried_server != NULL) {
+ DLIST_FOR_EACH(server, service->last_tried_server->next) {
+ if (service_works(server)) {
+ goto done;
+ }
+ }
+ }
+
+ /* If none were found, try at the start. */
DLIST_FOR_EACH(server, service->server_list) {
if (service_works(server)) {
- *_server = server;
- return EOK;
+ goto done;
+ }
+ if (server == service->last_tried_server) {
+ break;
}
}
+ service->last_tried_server = NULL;
return ENOENT;
+
+done:
+ service->last_tried_server = server;
+ *_server = server;
+ return EOK;
}
static int