diff options
-rw-r--r-- | src/providers/data_provider_be.c | 119 | ||||
-rw-r--r-- | src/providers/data_provider_fo.c | 5 | ||||
-rw-r--r-- | src/providers/dp_backend.h | 3 | ||||
-rw-r--r-- | src/providers/fail_over.c | 17 | ||||
-rw-r--r-- | src/providers/fail_over.h | 1 | ||||
-rw-r--r-- | src/providers/proxy/proxy_init.c | 3 |
6 files changed, 143 insertions, 5 deletions
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index e094c65b0..98c3f392e 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -173,10 +173,9 @@ void be_mark_offline(struct be_ctx *ctx) be_run_offline_cb(ctx); } -void be_reset_offline(struct be_ctx *ctx) +static void be_reset_offline(struct be_ctx *ctx) { - DEBUG(8, ("Going back online!\n")); - + ctx->offstat.went_offline = 0; ctx->offstat.offline = false; be_run_online_cb(ctx); } @@ -728,6 +727,114 @@ static int client_registration(DBusMessage *message, return EOK; } +static errno_t be_file_check_online_request(struct be_req *req) +{ + int ret; + + req->be_ctx->offstat.went_offline = time(NULL); + reset_fo(req->be_ctx); + + ret = be_file_request(req->be_ctx, + req->be_ctx->bet_info[BET_ID].bet_ops->check_online, req); + if (ret != EOK) { + DEBUG(1, ("be_file_request failed.\n")); + } + + return ret; +} + +static void check_online_callback(struct be_req *req, int dp_err_type, + int errnum, const char *errstr) +{ + int ret; + + DEBUG(4, ("Backend returned: (%d, %d, %s) [%s]\n", + dp_err_type, errnum, errstr?errstr:"<NULL>", + dp_pam_err_to_string(req, dp_err_type, errnum))); + + req->be_ctx->check_online_ref_count--; + + if (dp_err_type != DP_ERR_OK && req->be_ctx->check_online_ref_count > 0) { + ret = be_file_check_online_request(req); + if (ret != EOK) { + DEBUG(1, ("be_file_check_online_request failed.\n")); + goto done; + } + return; + } + +done: + req->be_ctx->check_online_ref_count = 0; + if (dp_err_type != DP_ERR_OFFLINE) { + if (dp_err_type != DP_ERR_OK) { + reset_fo(req->be_ctx); + } + be_reset_offline(req->be_ctx); + } + + talloc_free(req); + + return; +} + +static void check_if_online(struct be_ctx *ctx) +{ + int ret; + struct be_req *be_req = NULL; + + if (ctx->offstat.offline == false) { + DEBUG(8, ("Backend is already online, nothing to do.\n")); + return; + } + + /* Make sure nobody tries to go online while we are checking */ + ctx->offstat.went_offline = time(NULL); + + DEBUG(8, ("Trying to go back online!\n")); + + ctx->check_online_ref_count++; + + if (ctx->check_online_ref_count != 1) { + DEBUG(8, ("There is an online check already running.\n")); + return; + } + + if (ctx->bet_info[BET_ID].bet_ops->check_online == NULL) { + DEBUG(8, ("ID providers does not provide a check_online method.\n")); + goto failed; + } + + be_req = talloc_zero(ctx, struct be_req); + if (be_req == NULL) { + DEBUG(1, ("talloc_zero failed.\n")); + goto failed; + } + + be_req->be_ctx = ctx; + be_req->fn = check_online_callback; + + ret = be_file_check_online_request(be_req); + if (ret != EOK) { + DEBUG(1, ("be_file_check_online_request failed.\n")); + goto failed; + } + + return; + +failed: + ctx->check_online_ref_count--; + DEBUG(1, ("Failed to run a check_online test.\n")); + + talloc_free(be_req); + + if (ctx->check_online_ref_count == 0) { + reset_fo(ctx); + be_reset_offline(ctx); + } + + return; +} + static void init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) @@ -1228,7 +1335,11 @@ int main(int argc, const char *argv[]) static int data_provider_res_init(DBusMessage *message, struct sbus_connection *conn) { + struct be_ctx *be_ctx; + be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); + resolv_reread_configuration(); + check_if_online(be_ctx); return monitor_common_res_init(message, conn); } @@ -1247,6 +1358,6 @@ static int data_provider_reset_offline(DBusMessage *message, { struct be_ctx *be_ctx; be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); - be_reset_offline(be_ctx); + check_if_online(be_ctx); return monitor_common_pong(message, conn); } diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c index 8617cd236..0b4b24349 100644 --- a/src/providers/data_provider_fo.c +++ b/src/providers/data_provider_fo.c @@ -512,3 +512,8 @@ int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx, return EOK; } +void reset_fo(struct be_ctx *be_ctx) +{ + fo_reset_services(be_ctx->be_fo->fo_ctx); +} + diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index e11b3b6c7..3d5e40bae 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -111,6 +111,8 @@ struct be_ctx { struct loaded_be loaded_be[BET_MAX]; struct bet_info bet_info[BET_MAX]; + + size_t check_online_ref_count; }; struct bet_ops { @@ -193,4 +195,5 @@ void be_fo_try_next_server(struct be_ctx *ctx, const char *service_name); int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx, const char *service_name); +void reset_fo(struct be_ctx *be_ctx); #endif /* __DP_BACKEND_H___ */ diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c index 9b818d0c4..858d6ba6a 100644 --- a/src/providers/fail_over.c +++ b/src/providers/fail_over.c @@ -1329,3 +1329,20 @@ fo_get_server_hostent(struct fo_server *server) } return server->common->hostent; } + +void fo_reset_services(struct fo_ctx *fo_ctx) +{ + struct fo_service *service; + struct fo_server *server; + + DLIST_FOR_EACH(service, fo_ctx->service_list) { + DLIST_FOR_EACH(server, service->server_list) { + fo_set_server_status(server, SERVER_NAME_NOT_RESOLVED); + fo_set_port_status(server, PORT_NEUTRAL); + if (server->srv_data != NULL) { + set_srv_data_status(server->srv_data, SRV_NOT_RESOLVED); + } + } + } +} + diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h index f1a071da9..dce02dc60 100644 --- a/src/providers/fail_over.h +++ b/src/providers/fail_over.h @@ -172,4 +172,5 @@ struct hostent *fo_get_server_hostent(struct fo_server *server); int fo_is_srv_lookup(struct fo_server *s); +void fo_reset_services(struct fo_ctx *fo_ctx); #endif /* !__FAIL_OVER_H__ */ diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c index de1904c79..0993feed0 100644 --- a/src/providers/proxy/proxy_init.c +++ b/src/providers/proxy/proxy_init.c @@ -54,7 +54,8 @@ static void proxy_auth_shutdown(struct be_req *req) struct bet_ops proxy_id_ops = { .handler = proxy_get_account_info, - .finalize = proxy_shutdown + .finalize = proxy_shutdown, + .check_online = NULL }; struct bet_ops proxy_auth_ops = { |