[PATCH] Speed up user requests while offline

This adds a new boolean option to sss_dp_send_acct_req() called
fast_reply. If we make a request to the backends and we are
currently offline, this option will determine whether we should
immediately return from the cache (acceptable for NSS requests) or
potentially wait for an online check to complete (required for PAM
requests).

If we immediately return from cache, we will still continue processing
in the backend. If it is time to do an online check, it will happen out
of band.


On 11/16/2009 05:44 PM, Simo Sorce wrote:
> On Mon, 2009-11-16 at 16:01 -0500, Stephen Gallagher wrote:
>>
>>
>> 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.
> 
> Uhmm, unfortunately I have to nack this one.
> 
> The problem is that you can't trust what you receive to be authoritative
> for the future.
> For example, between the last call from the nss frontend and the new one
> the backend can have run an enumeration task that have discovered we are
> back online.
> In that case it would probably be advisable to do an online refresh,
> except that you don't know that the backend is actually online because
> last time you got an answer it was offline.
> 
> We should probably always contact the backend and let the backend know
> we want a "quick" answer by adding a parameter in the sbus call.
> 
> If we require a "quick" call and the backend is offline it will
> immediately return back an offline error and then schedule an out of
> band request to try to go online.
> 
> Simo.
> 


-- 
Stephen Gallagher
RHCE 804006346421761

Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
From e2be903f6d582e86728f17219bb8566f64ab1af6 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <[email protected]>
Date: Thu, 19 Nov 2009 16:37:51 -0500
Subject: [PATCH] Speed up user requests while offline

This adds a new boolean option to sss_dp_send_acct_req() called
fast_reply. If we make a request to the backends and we are
currently offline, this option will determine whether we should
immediately return from the cache (acceptable for NSS requests) or
potentially wait for an online check to complete (required for PAM
requests).
---
 server/providers/data_provider_be.c    |  121 ++++++++++++++++++++++----------
 server/responder/common/responder.h    |    3 +-
 server/responder/common/responder_dp.c |   10 ++-
 server/responder/nss/nsssrv_cmd.c      |   22 +++---
 server/responder/pam/pamsrv_cmd.c      |    8 ++-
 5 files changed, 109 insertions(+), 55 deletions(-)

diff --git a/server/providers/data_provider_be.c 
b/server/providers/data_provider_be.c
index d5c2492..dc16906 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -250,36 +250,44 @@ static void acctinfo_callback(struct be_req *req,
     dbus_uint32_t err_min = 0;
     const char *err_msg = NULL;
 
-    err_maj = dp_err_type;
-    err_min = errnum;
-    if (errstr) {
-        err_msg = errstr;
-    } else {
-        err_msg = dp_err_to_string(req, dp_err_type, errnum);
-    }
-    if (!err_msg) {
-        DEBUG(1, ("Failed to set err_msg, Out of memory?\n"));
-        err_msg = "OOM";
-    }
-
     reply = (DBusMessage *)req->pvt;
 
-    dbret = dbus_message_append_args(reply,
-                                     DBUS_TYPE_UINT16, &err_maj,
-                                     DBUS_TYPE_UINT32, &err_min,
-                                     DBUS_TYPE_STRING, &err_msg,
-                                     DBUS_TYPE_INVALID);
-    if (!dbret) {
-        DEBUG(1, ("Failed to generate dbus reply\n"));
-        return;
-    }
+    if (reply) {
+        /* Return a reply if one was requested
+         * There may not be one if this request began
+         * while we were offline
+         */
 
-    dbus_conn = sbus_get_connection(req->becli->conn);
-    dbus_connection_send(dbus_conn, reply, NULL);
-    dbus_message_unref(reply);
+        err_maj = dp_err_type;
+        err_min = errnum;
+        if (errstr) {
+            err_msg = errstr;
+        } else {
+            err_msg = dp_err_to_string(req, dp_err_type, errnum);
+        }
+        if (!err_msg) {
+            DEBUG(1, ("Failed to set err_msg, Out of memory?\n"));
+            err_msg = "OOM";
+        }
 
-    DEBUG(4, ("Request processed. Returned %d,%d,%s\n",
-              err_maj, err_min, err_msg));
+
+        dbret = dbus_message_append_args(reply,
+                                         DBUS_TYPE_UINT16, &err_maj,
+                                         DBUS_TYPE_UINT32, &err_min,
+                                         DBUS_TYPE_STRING, &err_msg,
+                                         DBUS_TYPE_INVALID);
+        if (!dbret) {
+            DEBUG(1, ("Failed to generate dbus reply\n"));
+            return;
+        }
+
+        dbus_conn = sbus_get_connection(req->becli->conn);
+        dbus_connection_send(dbus_conn, reply, NULL);
+        dbus_message_unref(reply);
+
+        DEBUG(4, ("Request processed. Returned %d,%d,%s\n",
+                  err_maj, err_min, err_msg));
+    }
 
     /* finally free the request */
     talloc_free(req);
@@ -294,6 +302,7 @@ static int be_get_account_info(DBusMessage *message, struct 
sbus_connection *con
     DBusError dbus_error;
     dbus_bool_t dbret;
     void *user_data;
+    dbus_bool_t fast_reply;
     uint32_t type;
     char *attrs, *filter;
     int attr_type, filter_type;
@@ -313,6 +322,7 @@ static int be_get_account_info(DBusMessage *message, struct 
sbus_connection *con
     dbus_error_init(&dbus_error);
 
     ret = dbus_message_get_args(message, &dbus_error,
+                                DBUS_TYPE_BOOLEAN, &fast_reply,
                                 DBUS_TYPE_UINT32, &type,
                                 DBUS_TYPE_STRING, &attrs,
                                 DBUS_TYPE_STRING, &filter,
@@ -323,11 +333,44 @@ static int be_get_account_info(DBusMessage *message, 
struct sbus_connection *con
         return EIO;
     }
 
-    DEBUG(4, ("Got request for [%u][%s][%s]\n", type, attrs, filter));
+    DEBUG(4, ("Got request for [%u][%u][%s][%s]\n",
+              fast_reply, type, attrs, filter));
 
     reply = dbus_message_new_method_return(message);
     if (!reply) return ENOMEM;
 
+    /* If we are offline and fast reply was requested
+     * return offline immediately
+     */
+    if (fast_reply) {
+        if (becli->bectx->offstat.offline) {
+            /* Send back an immediate reply */
+            err_maj = DP_ERR_OFFLINE;
+            err_min = EAGAIN;
+            err_msg = "Fast reply - offline";
+
+            dbret = dbus_message_append_args(reply,
+                                             DBUS_TYPE_UINT16, &err_maj,
+                                             DBUS_TYPE_UINT32, &err_min,
+                                             DBUS_TYPE_STRING, &err_msg,
+                                             DBUS_TYPE_INVALID);
+            if (!dbret) return EIO;
+
+            DEBUG(4, ("Request processed. Returned %d,%d,%s\n",
+                      err_maj, err_min, err_msg));
+
+            sbus_conn_send_reply(conn, reply);
+            dbus_message_unref(reply);
+            reply = NULL;
+            /* This reply will be queued and sent
+             * when we reenter the mainloop.
+             *
+             * Continue processing in case we are
+             * going back online.
+             */
+        }
+    }
+
     if (attrs) {
         if (strcmp(attrs, "core") == 0) attr_type = BE_ATTR_CORE;
         else if (strcmp(attrs, "membership") == 0) attr_type = BE_ATTR_MEM;
@@ -409,19 +452,21 @@ done:
         talloc_free(be_req);
     }
 
-    dbret = dbus_message_append_args(reply,
-                                     DBUS_TYPE_UINT16, &err_maj,
-                                     DBUS_TYPE_UINT32, &err_min,
-                                     DBUS_TYPE_STRING, &err_msg,
-                                     DBUS_TYPE_INVALID);
-    if (!dbret) return EIO;
+    if (reply) {
+        dbret = dbus_message_append_args(reply,
+                                         DBUS_TYPE_UINT16, &err_maj,
+                                         DBUS_TYPE_UINT32, &err_min,
+                                         DBUS_TYPE_STRING, &err_msg,
+                                         DBUS_TYPE_INVALID);
+        if (!dbret) return EIO;
 
-    DEBUG(4, ("Request processed. Returned %d,%d,%s\n",
-              err_maj, err_min, err_msg));
+        DEBUG(4, ("Request processed. Returned %d,%d,%s\n",
+                  err_maj, err_min, err_msg));
 
-    /* send reply back */
-    sbus_conn_send_reply(conn, reply);
-    dbus_message_unref(reply);
+        /* send reply back */
+        sbus_conn_send_reply(conn, reply);
+        dbus_message_unref(reply);
+    }
 
     return EOK;
 }
diff --git a/server/responder/common/responder.h 
b/server/responder/common/responder.h
index a597e68..9294f40 100644
--- a/server/responder/common/responder.h
+++ b/server/responder/common/responder.h
@@ -145,7 +145,8 @@ typedef void (*sss_dp_callback_t)(uint16_t err_maj, 
uint32_t err_min,
 
 int sss_dp_send_acct_req(struct resp_ctx *rctx, TALLOC_CTX *callback_memctx,
                          sss_dp_callback_t callback, void *callback_ctx,
-                         int timeout, const char *domain, int type,
+                         int timeout, const char *domain,
+                         bool fast_reply, int type,
                          const char *opt_name, uint32_t opt_id);
 
 #endif /* __SSS_RESPONDER_H__ */
diff --git a/server/responder/common/responder_dp.c 
b/server/responder/common/responder_dp.c
index 943b72c..3337d83 100644
--- a/server/responder/common/responder_dp.c
+++ b/server/responder/common/responder_dp.c
@@ -234,6 +234,7 @@ error:
 static int sss_dp_send_acct_req_create(struct resp_ctx *rctx,
                                        TALLOC_CTX *callback_memctx,
                                        const char *domain,
+                                       bool fast_reply,
                                        uint32_t be_type,
                                        char *filter,
                                        int timeout,
@@ -243,7 +244,8 @@ static int sss_dp_send_acct_req_create(struct resp_ctx 
*rctx,
 
 int sss_dp_send_acct_req(struct resp_ctx *rctx, TALLOC_CTX *callback_memctx,
                          sss_dp_callback_t callback, void *callback_ctx,
-                         int timeout, const char *domain, int type,
+                         int timeout, const char *domain,
+                         bool fast_reply, int type,
                          const char *opt_name, uint32_t opt_id)
 {
     int ret, hret;
@@ -351,8 +353,8 @@ int sss_dp_send_acct_req(struct resp_ctx *rctx, TALLOC_CTX 
*callback_memctx,
          * Create a new request
          */
         ret = sss_dp_send_acct_req_create(rctx, callback_memctx, domain,
-                                          be_type, filter, timeout,
-                                          callback, callback_ctx,
+                                          fast_reply, be_type, filter,
+                                          timeout, callback, callback_ctx,
                                           &sdp_req);
         if (ret != EOK) {
             goto done;
@@ -404,6 +406,7 @@ done:
 static int sss_dp_send_acct_req_create(struct resp_ctx *rctx,
                                        TALLOC_CTX *callback_memctx,
                                        const char *domain,
+                                       bool fast_reply,
                                        uint32_t be_type,
                                        char *filter,
                                        int timeout,
@@ -447,6 +450,7 @@ static int sss_dp_send_acct_req_create(struct resp_ctx 
*rctx,
               domain, be_type, attrs, filter));
 
     dbret = dbus_message_append_args(msg,
+                                     DBUS_TYPE_BOOLEAN, &fast_reply,
                                      DBUS_TYPE_UINT32, &be_type,
                                      DBUS_TYPE_STRING, &attrs,
                                      DBUS_TYPE_STRING, &filter,
diff --git a/server/responder/nss/nsssrv_cmd.c 
b/server/responder/nss/nsssrv_cmd.c
index e4b08cb..37cc9fd 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -359,7 +359,8 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
          */
         ret = sss_dp_send_acct_req(cctx->rctx, NULL, NULL, NULL,
                                    timeout, dctx->domain->name,
-                                   req_type, opt_name, opt_id);
+                                   true, req_type,
+                                   opt_name, opt_id);
         if (ret != EOK) {
             DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
                       ret, strerror(ret)));
@@ -384,7 +385,8 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
 
         ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
                                    callback, dctx, timeout,
-                                   dctx->domain->name, req_type,
+                                   dctx->domain->name,
+                                   true, req_type,
                                    opt_name, opt_id);
         if (ret != EOK) {
             DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
@@ -1133,8 +1135,8 @@ static void nss_cmd_setpwent_callback(void *ptr, int 
status,
             timeout = SSS_CLI_SOCKET_TIMEOUT;
             ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
                                        nss_cmd_setpw_dp_callback, dctx,
-                                       timeout, dom->name, SSS_DP_USER,
-                                       NULL, 0);
+                                       timeout, dom->name, true,
+                                       SSS_DP_USER, NULL, 0);
         } else {
             ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
                                           dctx->domain, &sysdb);
@@ -1280,8 +1282,8 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, 
bool immediate)
         timeout = SSS_CLI_SOCKET_TIMEOUT;
         ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
                                    nss_cmd_setpw_dp_callback, dctx,
-                                   timeout, dom->name, SSS_DP_USER,
-                                   NULL, 0);
+                                   timeout, dom->name, true,
+                                   SSS_DP_USER, NULL, 0);
     } else {
         ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
                                       dctx->domain, &sysdb);
@@ -2458,8 +2460,8 @@ static void nss_cmd_setgrent_callback(void *ptr, int 
status,
             timeout = SSS_CLI_SOCKET_TIMEOUT;
             ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
                                        nss_cmd_setgr_dp_callback, dctx,
-                                       timeout, dom->name, SSS_DP_GROUP,
-                                       NULL, 0);
+                                       timeout, dom->name, true,
+                                       SSS_DP_GROUP, NULL, 0);
         } else {
             ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
                                           dctx->domain, &sysdb);
@@ -2605,8 +2607,8 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, 
bool immediate)
         timeout = SSS_CLI_SOCKET_TIMEOUT;
         ret = sss_dp_send_acct_req(cctx->rctx, cmdctx,
                                    nss_cmd_setgr_dp_callback, dctx,
-                                   timeout, dom->name, SSS_DP_GROUP,
-                                   NULL, 0);
+                                   timeout, dom->name, true,
+                                   SSS_DP_GROUP, NULL, 0);
     } else {
         ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
                                       dctx->domain, &sysdb);
diff --git a/server/responder/pam/pamsrv_cmd.c 
b/server/responder/pam/pamsrv_cmd.c
index 8627d5c..4479926 100644
--- a/server/responder/pam/pamsrv_cmd.c
+++ b/server/responder/pam/pamsrv_cmd.c
@@ -725,7 +725,8 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
 
         ret = sss_dp_send_acct_req(preq->cctx->rctx, preq,
                                    pam_check_user_dp_callback, preq,
-                                   timeout, preq->domain->name, 
SSS_DP_INITGROUPS,
+                                   timeout, preq->domain->name,
+                                   false, SSS_DP_INITGROUPS,
                                    preq->pd->user, 0);
     }
     else {
@@ -840,7 +841,8 @@ static void pam_check_user_callback(void *ptr, int status,
 
         ret = sss_dp_send_acct_req(preq->cctx->rctx, preq,
                                    pam_check_user_dp_callback, preq,
-                                   timeout, preq->domain->name, SSS_DP_USER,
+                                   timeout, preq->domain->name,
+                                   false, SSS_DP_USER,
                                    preq->pd->user, 0);
         if (ret != EOK) {
             DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
@@ -910,7 +912,7 @@ static void pam_check_user_callback(void *ptr, int status,
                                                pam_check_user_dp_callback,
                                                preq, timeout,
                                                preq->domain->name,
-                                               SSS_DP_USER,
+                                               false, SSS_DP_USER,
                                                preq->pd->user, 0);
                 }
                 else {
-- 
1.6.2.5

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
sssd-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to