ehlo,

The simple reproducer is to use getent passwd,group with non-existing entry.
Without the patch you will see that "/var/lib/sss/mc/passwd" is opened
twice. Onece with mode "rw" opened by sssd_nss and the 2nd time
with "r-" opened by sssd-client (getpwnam, getpwuid, getgrnam, getgrgid)

LS
>From 3762590d38a2ff4c156185ac54b5d2ab7b8ee284 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lsleb...@redhat.com>
Date: Mon, 8 Aug 2016 13:55:52 +0200
Subject: [PATCH] NSS: Do not check local users with disabled
 local_negative_timeout

sssd_nss can set different negative timeout for local users
and groups. However, checking whether user/group is local
is quite expensive operation. We can avoid such operations
if local_negative_timeout is not set.

This fix improve performance(40%) of lookup non-existing
entries in offline mode and with disabled local_negative_timeout.

  sh$ cat pok.sh
  for i in {1..10000}; do
    getent passwd -s sss temp$i
    getent group -s sss temp$i
  done

  #without patch
  sh $time /bin/bash pok.sh
  real    0m41.534s
  user    0m3.580s
  sys     0m14.202s

  #with patch
  sh $time /bin/bash pok.sh
  real    0m26.686s
  user    0m3.292s
  sys     0m13.165s

Resolves:
https://fedorahosted.org/sssd/ticket/3122
---
 src/responder/common/negcache.c | 45 +++++++++++++++++++++++------------------
 src/tests/cwrap/test_negcache.c | 16 +++++++--------
 2 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 
dfeb0d483e4db34cb2f25e1f82884611a707aabe..e617d2b9ac38d250e92689bb2a277d61d73d0692
 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -143,7 +143,7 @@ done:
 }
 
 static int sss_ncache_set_str(struct sss_nc_ctx *ctx, char *str,
-                              bool permanent, bool is_local)
+                              bool permanent, bool use_local_negative)
 {
     TDB_DATA key;
     TDB_DATA data;
@@ -157,15 +157,12 @@ static int sss_ncache_set_str(struct sss_nc_ctx *ctx, 
char *str,
     if (permanent) {
         timest = talloc_strdup(ctx, "0");
     } else {
-        if (is_local == true && ctx->local_timeout > 0) {
-            timell = (unsigned long long int)time(NULL) + ctx->local_timeout;
+        if (use_local_negative == true && ctx->local_timeout > ctx->timeout) {
+            timell = ctx->local_timeout;
         } else {
-            if (ctx->timeout > 0) {
-                timell = (unsigned long long int)time(NULL) + ctx->timeout;
-            } else {
-                return EOK;
-            }
+            timell = ctx->timeout;
         }
+        timell += (unsigned long long int)time(NULL);
         timest = talloc_asprintf(ctx, "%llu", timell);
     }
     if (!timest) return ENOMEM;
@@ -457,7 +454,7 @@ int sss_ncache_check_cert(struct sss_nc_ctx *ctx, const 
char *cert)
 static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
                                    const char *domain, const char *name)
 {
-    bool is_local;
+    bool use_local_negative = false;
     char *str;
     int ret;
 
@@ -466,8 +463,10 @@ static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, 
bool permanent,
     str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
     if (!str) return ENOMEM;
 
-    is_local = is_user_local_by_name(name);
-    ret = sss_ncache_set_str(ctx, str, permanent, is_local);
+    if (ctx->local_timeout > 0) {
+        use_local_negative = is_user_local_by_name(name);
+    }
+    ret = sss_ncache_set_str(ctx, str, permanent, use_local_negative);
 
     talloc_free(str);
     return ret;
@@ -476,7 +475,7 @@ static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, 
bool permanent,
 static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent,
                                     const char *domain, const char *name)
 {
-    bool is_local;
+    bool use_local_negative = false;
     char *str;
     int ret;
 
@@ -485,8 +484,10 @@ static int sss_ncache_set_group_int(struct sss_nc_ctx 
*ctx, bool permanent,
     str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
     if (!str) return ENOMEM;
 
-    is_local = is_group_local_by_name(name);
-    ret = sss_ncache_set_str(ctx, str, permanent, is_local);
+    if (ctx->local_timeout > 0) {
+        use_local_negative = is_group_local_by_name(name);
+    }
+    ret = sss_ncache_set_str(ctx, str, permanent, use_local_negative);
 
     talloc_free(str);
     return ret;
@@ -550,7 +551,7 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool 
permanent,
 int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent,
                        struct sss_domain_info *dom, uid_t uid)
 {
-    bool is_local;
+    bool use_local_negative = false;
     char *str;
     int ret;
 
@@ -562,8 +563,10 @@ int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool 
permanent,
     }
     if (!str) return ENOMEM;
 
-    is_local = is_user_local_by_uid(uid);
-    ret = sss_ncache_set_str(ctx, str, permanent, is_local);
+    if (ctx->local_timeout > 0) {
+        use_local_negative = is_user_local_by_uid(uid);
+    }
+    ret = sss_ncache_set_str(ctx, str, permanent, use_local_negative);
 
     talloc_free(str);
     return ret;
@@ -572,7 +575,7 @@ int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool 
permanent,
 int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent,
                        struct sss_domain_info *dom, gid_t gid)
 {
-    bool is_local;
+    bool use_local_negative = false;
     char *str;
     int ret;
 
@@ -584,8 +587,10 @@ int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool 
permanent,
     }
     if (!str) return ENOMEM;
 
-    is_local = is_group_local_by_gid(gid);
-    ret = sss_ncache_set_str(ctx, str, permanent, is_local);
+    if (ctx->local_timeout > 0) {
+        use_local_negative = is_group_local_by_gid(gid);
+    }
+    ret = sss_ncache_set_str(ctx, str, permanent, use_local_negative);
 
     talloc_free(str);
     return ret;
diff --git a/src/tests/cwrap/test_negcache.c b/src/tests/cwrap/test_negcache.c
index 
d43ef98ae7aefafdae3819aac527be7ba1d75fb1..e691ccefa427de5d11b165bfcd7cf8a8e888d95c
 100644
--- a/src/tests/cwrap/test_negcache.c
+++ b/src/tests/cwrap/test_negcache.c
@@ -258,7 +258,7 @@ void test_ncache_nocache_user(void **state)
 
     set_users(test_ctx);
 
-    check_users(test_ctx, ENOENT, ENOENT, ENOENT, ENOENT);
+    check_users(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -276,7 +276,7 @@ void test_ncache_local_user(void **state)
 
     set_users(test_ctx);
 
-    check_users(test_ctx, ENOENT, ENOENT, EEXIST, ENOENT);
+    check_users(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -369,7 +369,7 @@ void test_ncache_nocache_uid(void **state)
 
     set_uids(test_ctx);
 
-    check_uids(test_ctx, ENOENT, ENOENT, ENOENT, ENOENT);
+    check_uids(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -387,7 +387,7 @@ void test_ncache_local_uid(void **state)
 
     set_uids(test_ctx);
 
-    check_uids(test_ctx, ENOENT, ENOENT, EEXIST, ENOENT);
+    check_uids(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -480,7 +480,7 @@ void test_ncache_nocache_group(void **state)
 
     set_groups(test_ctx);
 
-    check_groups(test_ctx, ENOENT, ENOENT, ENOENT, ENOENT);
+    check_groups(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -498,7 +498,7 @@ void test_ncache_local_group(void **state)
 
     set_groups(test_ctx);
 
-    check_groups(test_ctx, ENOENT, ENOENT, EEXIST, ENOENT);
+    check_groups(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -591,7 +591,7 @@ void test_ncache_nocache_gid(void **state)
 
     set_gids(test_ctx);
 
-    check_gids(test_ctx, ENOENT, ENOENT, ENOENT, ENOENT);
+    check_gids(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
@@ -609,7 +609,7 @@ void test_ncache_local_gid(void **state)
 
     set_gids(test_ctx);
 
-    check_gids(test_ctx, ENOENT, ENOENT, EEXIST, ENOENT);
+    check_gids(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);
 
     talloc_zfree(test_ctx->ncache);
 }
-- 
2.9.2

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org

Reply via email to