summaryrefslogtreecommitdiffstats
path: root/src/providers/data_provider_fo.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-03-05 21:09:37 +0100
committerStephen Gallagher <sgallagh@redhat.com>2012-03-06 15:29:18 -0500
commitb300bad539e9a9ad7f3a88dc91253afff0425cb6 (patch)
tree4fbd463ffcb9c6b898d72f27aa443deea1e2bff4 /src/providers/data_provider_fo.c
parent21f666d6a88dfa9cd7e984c25464dd56fe170598 (diff)
downloadsssd-b300bad539e9a9ad7f3a88dc91253afff0425cb6.tar.gz
sssd-b300bad539e9a9ad7f3a88dc91253afff0425cb6.tar.xz
sssd-b300bad539e9a9ad7f3a88dc91253afff0425cb6.zip
Only do one cycle when resolving a server
https://fedorahosted.org/sssd/ticket/1214
Diffstat (limited to 'src/providers/data_provider_fo.c')
-rw-r--r--src/providers/data_provider_fo.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index 4c2c0b4af..c358e68d1 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -46,6 +46,7 @@ struct be_svc_data {
bool run_callbacks;
struct be_svc_callback *callbacks;
+ struct fo_server *first_resolved;
};
struct be_failover_ctx {
@@ -398,42 +399,43 @@ static void be_resolve_server_done(struct tevent_req *subreq)
switch (ret) {
case EOK:
if (!state->srv) {
- tevent_req_error(req, EFAULT);
- return;
+ ret = EFAULT;
+ goto fail;
}
break;
case ENOENT:
/* all servers have been tried and none
* was found good, go offline */
- tevent_req_error(req, EIO);
- return;
+ ret = EIO;
+ goto fail;
default:
/* mark server as bad and retry */
if (!state->srv) {
- tevent_req_error(req, EFAULT);
- return;
+ ret = EFAULT;
+ goto fail;
}
- DEBUG(6, ("Couldn't resolve server (%s), resolver returned (%d)\n",
- fo_get_server_str_name(state->srv), ret));
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Couldn't resolve server (%s), resolver returned (%d)\n",
+ fo_get_server_str_name(state->srv), ret));
state->attempts++;
if (state->attempts >= 10) {
DEBUG(2, ("Failed to find a server after 10 attempts\n"));
- tevent_req_error(req, EIO);
- return;
+ ret = EIO;
+ goto fail;
}
/* now try next one */
- DEBUG(6, ("Trying with the next one!\n"));
+ DEBUG(SSSDBG_TRACE_LIBS, ("Trying with the next one!\n"));
subreq = fo_resolve_service_send(state, state->ev,
state->ctx->be_fo->resolv,
state->ctx->be_fo->fo_ctx,
state->svc->fo_service);
if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
+ ret = ENOMEM;
+ goto fail;
}
tevent_req_set_callback(subreq, be_resolve_server_done, req);
@@ -441,24 +443,34 @@ static void be_resolve_server_done(struct tevent_req *subreq)
}
/* all fine we got the server */
+ if (state->svc->first_resolved == NULL) {
+ DEBUG(SSSDBG_TRACE_LIBS, ("Saving the first resolved server\n"));
+ state->svc->first_resolved = state->srv;
+ } else if (state->svc->first_resolved == state->srv) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("The fail over cycled through all available servers\n"));
+ ret = ENOENT;
+ goto fail;
+ }
- if (DEBUG_IS_SET(SSSDBG_CONF_SETTINGS) && fo_get_server_name(state->srv)) {
+ if (DEBUG_IS_SET(SSSDBG_FUNC_DATA) && fo_get_server_name(state->srv)) {
struct resolv_hostent *srvaddr;
char ipaddr[128];
srvaddr = fo_get_server_hostent(state->srv);
if (!srvaddr) {
- DEBUG(3, ("FATAL: No hostent available for server (%s)\n",
- fo_get_server_str_name(state->srv)));
- tevent_req_error(req, EFAULT);
- return;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("FATAL: No hostent available for server (%s)\n",
+ fo_get_server_str_name(state->srv)));
+ ret = EFAULT;
+ goto fail;
}
inet_ntop(srvaddr->family, srvaddr->addr_list[0]->ipaddr,
ipaddr, 128);
- DEBUG(4, ("Found address for server %s: [%s] TTL %d\n",
- fo_get_server_str_name(state->srv), ipaddr,
- srvaddr->addr_list[0]->ttl));
+ DEBUG(SSSDBG_FUNC_DATA, ("Found address for server %s: [%s] TTL %d\n",
+ fo_get_server_str_name(state->srv), ipaddr,
+ srvaddr->addr_list[0]->ttl));
}
srv_status_change = fo_get_server_hostname_last_change(state->srv);
@@ -478,6 +490,12 @@ static void be_resolve_server_done(struct tevent_req *subreq)
}
tevent_req_done(req);
+ return;
+
+fail:
+ DEBUG(SSSDBG_TRACE_LIBS, ("Server resolution failed: %d\n", ret));
+ state->svc->first_resolved = NULL;
+ tevent_req_error(req, ret);
}
int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv)
@@ -524,3 +542,33 @@ void reset_fo(struct be_ctx *be_ctx)
fo_reset_services(be_ctx->be_fo->fo_ctx);
}
+void be_fo_set_port_status(struct be_ctx *ctx,
+ struct fo_server *server,
+ enum port_status status)
+{
+ struct be_svc_data *svc;
+ struct fo_service *fsvc;
+
+ fo_set_port_status(server, status);
+
+ fsvc = fo_get_server_service(server);
+ if (!fsvc) {
+ DEBUG(SSSDBG_OP_FAILURE, ("BUG: No service associated with server\n"));
+ return;
+ }
+
+ DLIST_FOR_EACH(svc, ctx->be_fo->svcs) {
+ if (svc->fo_service == fsvc) break;
+ }
+
+ if (!svc) {
+ DEBUG(SSSDBG_OP_FAILURE, ("BUG: Unknown service\n"));
+ return;
+ }
+
+ if (status == PORT_WORKING) {
+ /* We were successful in connecting to the server. Cycle through all
+ * available servers next time */
+ svc->first_resolved = NULL;
+ }
+}