From 429efcb600be42e9e17f349f0e1310664f9274f2 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 16 Nov 2009 15:56:39 -0500 Subject: [PATCH] Speed up NSS responses while offline When offline, we check at regular intervals to see if the backend has come back online. This means that every n seconds (the online check interval), NSS requests may lag as we attempt to go out to the remote server and update the cache. With this patch, we will now always return the cached data while we are offline and queue up an out-of-band cache refresh to determine whether the data provider is back online. --- server/confdb/confdb.h | 1 + server/responder/common/responder.h | 3 +++ server/responder/common/responder_common.c | 12 ++++++++++++ server/responder/common/responder_dp.c | 12 +++++++++++- server/responder/nss/nsssrv_cmd.c | 28 ++++++++++------------------ 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h index b5cf12c..a296823 100644 --- a/server/confdb/confdb.h +++ b/server/confdb/confdb.h @@ -124,6 +124,7 @@ struct sss_domain_info { bool cache_credentials; bool legacy_passwords; bool force_lowercase; + bool offline; struct sss_domain_info *next; }; diff --git a/server/responder/common/responder.h b/server/responder/common/responder.h index a597e68..ea0ae9b 100644 --- a/server/responder/common/responder.h +++ b/server/responder/common/responder.h @@ -130,6 +130,9 @@ int sss_parse_name(TALLOC_CTX *memctx, int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, struct be_conn **_conn); +struct sss_domain_info *sss_get_dom(struct sss_domain_info *doms, + const char *domain); + /* responder_cmd.c */ int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds); void sss_cmd_done(struct cli_ctx *cctx, void *freectx); diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c index 37bbcb3..fa997da 100644 --- a/server/responder/common/responder_common.c +++ b/server/responder/common/responder_common.c @@ -587,3 +587,15 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, return EOK; } +struct sss_domain_info *sss_get_dom(struct sss_domain_info *doms, + const char *domain) +{ + struct sss_domain_info *dom; + + for (dom = doms; dom; dom = dom->next) { + if (strcasecmp(dom->name, domain) == 0) break; + } + if (!dom) DEBUG(2, ("Unknown domain [%s]!\n", domain)); + + return dom; +} diff --git a/server/responder/common/responder_dp.c b/server/responder/common/responder_dp.c index 943b72c..8afba70 100644 --- a/server/responder/common/responder_dp.c +++ b/server/responder/common/responder_dp.c @@ -50,6 +50,7 @@ struct sss_dp_req { struct tevent_timer *tev; struct sss_dp_callback *cb_list; + struct sss_domain_info *domain; dbus_uint16_t err_maj; dbus_uint32_t err_min; @@ -204,6 +205,15 @@ static void sss_dp_send_acct_callback(DBusPendingCall *pending, void *ptr) talloc_strdup(sdp_req, "Failed to get reply from Data Provider"); } + sdp_req->domain->offline = true; + } + else { + if (sdp_req->err_maj == DP_ERR_OK) { + sdp_req->domain->offline = false; + } + else { + sdp_req->domain->offline = true; + } } /* Check whether we need to issue any callbacks */ @@ -476,6 +486,7 @@ static int sss_dp_send_acct_req_create(struct resp_ctx *rctx, } sdp_req->ev = rctx->ev; sdp_req->pending_reply = pending_reply; + sdp_req->domain = sss_get_dom(rctx->domains, domain); if (callback) { cb = talloc_zero(callback_memctx, struct sss_dp_callback); @@ -586,4 +597,3 @@ done: return err; } - diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c index b2a2035..34eb989 100644 --- a/server/responder/nss/nsssrv_cmd.c +++ b/server/responder/nss/nsssrv_cmd.c @@ -86,19 +86,6 @@ static int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err) return ret; \ } while(0) -static struct sss_domain_info *nss_get_dom(struct sss_domain_info *doms, - const char *domain) -{ - struct sss_domain_info *dom; - - for (dom = doms; dom; dom = dom->next) { - if (strcasecmp(dom->name, domain) == 0) break; - } - if (!dom) DEBUG(2, ("Unknown domain [%s]!\n", domain)); - - return dom; -} - static int fill_empty(struct sss_packet *packet) { uint8_t *body; @@ -333,15 +320,15 @@ static errno_t check_cache(struct nss_dom_ctx *dctx, opt_name)); off_band_update = true; } - else { + else { /* Cache is still valid. Just return it. */ return EOK; } } } - if (off_band_update) { + if (off_band_update || dctx->domain->offline) { timeout = SSS_CLI_SOCKET_TIMEOUT/2; @@ -349,6 +336,11 @@ static errno_t check_cache(struct nss_dom_ctx *dctx, * This was an out-of-band update. We'll return EOK * so the calling function can return the cached entry * immediately. + * + * We will also attempt an out-of-band cache update if + * the domain is offline. The data provider will + * ignore the request if it is too soon to attempt a + * reconnection. */ ret = sss_dp_send_acct_req(cctx->rctx, NULL, NULL, NULL, timeout, dctx->domain->name, @@ -652,7 +644,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx) cmdctx->name, domname?domname:"")); if (domname) { - dctx->domain = nss_get_dom(cctx->rctx->domains, domname); + dctx->domain = sss_get_dom(cctx->rctx->domains, domname); if (!dctx->domain) { ret = ENOENT; goto done; @@ -1986,7 +1978,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx) cmdctx->name, domname?domname:"")); if (domname) { - dctx->domain = nss_get_dom(cctx->rctx->domains, domname); + dctx->domain = sss_get_dom(cctx->rctx->domains, domname); if (!dctx->domain) { ret = ENOENT; goto done; @@ -3166,7 +3158,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx) cmdctx->name, domname ? : "")); if (domname) { - dctx->domain = nss_get_dom(cctx->rctx->domains, domname); + dctx->domain = sss_get_dom(cctx->rctx->domains, domname); if (!dctx->domain) { ret = ENOENT; goto done; -- 1.6.2.5