On 08/13/2012 11:13 AM, Jakub Hrozek wrote:
On Fri, Aug 10, 2012 at 07:12:38PM +0200, Jakub Hrozek wrote:
On Fri, Aug 10, 2012 at 07:09:13PM +0200, Jakub Hrozek wrote:
On Fri, Aug 10, 2012 at 05:13:48PM +0200, Michal Zidek wrote:
This should fix the duplicate detection. Patch is attached. Please
review with caution, i was in hurry.

https://fedorahosted.org/sssd/ticket/1472

Thanks
Michal
I think the general approach with compare function is good, but it
should be a property of the fo_service. I don't think there is any
scenario where we'd like to treat two servers with same user_data
contents as the same.
^^^ Sorry, this should have read "two servers from the same service".
You also need to amend the testsuite as well when changing the fo_
interface, otherwise the test suite doesn't work:

   CC     src/resolv/fail_over_tests-async_resolv.o
src/tests/fail_over-tests.c: In function ‘test_fo_resolve_service’:
src/tests/fail_over-tests.c:233:5: warning: passing argument 5 of 
‘fo_add_server’ makes pointer from integer without a cast [enabled by default]
In file included from ./src/providers/dp_backend.h:26:0,
                  from ./src/providers/ldap/sdap.h:25,
                  from ./src/tests/common.h:31,
                  from src/tests/fail_over-tests.c:35:
./src/providers/fail_over.h:120:5: note: expected ‘int (*)(void *, void *)’ but 
argument is of type ‘int’
src/tests/fail_over-tests.c:233:5: error: too few arguments to function 
‘fo_add_server’

Ok. I rewrote it, so the user_data_cmp is now part of fo_service.
If it is set to NULL, user_data is not used as part of duplicity detection.
Also testsuite is now updated.

New patch is attached.

Thanks
Michal
>From abeafd14c684dd7d4fa61c2bdf05eb2451f332df Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzi...@redhat.com>
Date: Mon, 13 Aug 2012 16:37:13 +0200
Subject: [PATCH] Duplicate detection in fail over did not work.

https://fedorahosted.org/sssd/ticket/1472
---
 src/providers/ad/ad_common.c     |  3 ++-
 src/providers/data_provider_fo.c |  6 ++++--
 src/providers/dp_backend.h       |  3 ++-
 src/providers/fail_over.c        | 30 +++++++++++++++++++++++++++---
 src/providers/fail_over.h        |  1 +
 src/providers/ipa/ipa_common.c   |  2 +-
 src/providers/krb5/krb5_common.c |  2 +-
 src/providers/ldap/ldap_common.c |  2 +-
 src/tests/fail_over-tests.c      | 10 +++++-----
 9 files changed, 44 insertions(+), 15 deletions(-)

diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 800ef13..5473d6a 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -240,7 +240,8 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
         goto done;
     }
 
-    ret = be_fo_add_service(bectx, AD_SERVICE_NAME);
+    ret = be_fo_add_service(bectx, AD_SERVICE_NAME,
+                            (int (*)(void*, void*)) strcmp);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to create failover service!\n"));
         goto done;
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index 1c03e31..d005e92 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -168,7 +168,8 @@ static struct be_svc_data *be_fo_find_svc_data(struct be_ctx *ctx,
     return 0;
 }
 
-int be_fo_add_service(struct be_ctx *ctx, const char *service_name)
+int be_fo_add_service(struct be_ctx *ctx, const char *service_name,
+                      int (*user_data_cmp)(void*, void*))
 {
     struct fo_service *service;
     struct be_svc_data *svc;
@@ -185,7 +186,8 @@ int be_fo_add_service(struct be_ctx *ctx, const char *service_name)
 
     /* if not in the be service list, try to create new one */
 
-    ret = fo_new_service(ctx->be_fo->fo_ctx, service_name, &service);
+    ret = fo_new_service(ctx->be_fo->fo_ctx, service_name, user_data_cmp,
+                         &service);
     if (ret != EOK && ret != EEXIST) {
         DEBUG(1, ("Failed to create failover service!\n"));
         return ret;
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 4d079c0..7c2101e 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -218,7 +218,8 @@ typedef void (be_svc_callback_fn_t)(void *, struct fo_server *);
 
 int be_init_failover(struct be_ctx *ctx);
 int be_fo_is_srv_identifier(const char *server);
-int be_fo_add_service(struct be_ctx *ctx, const char *service_name);
+int be_fo_add_service(struct be_ctx *ctx, const char *service_name,
+                      int (*user_data_cmp) (void*, void*));
 int be_fo_service_add_callback(TALLOC_CTX *memctx,
                                struct be_ctx *ctx, const char *service_name,
                                be_svc_callback_fn_t *fn, void *private_data);
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index facc990..c861d0f 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -66,6 +66,12 @@ struct fo_service {
     struct fo_server *active_server;
     struct fo_server *last_tried_server;
     struct fo_server *server_list;
+
+    /* Function pointed by user_data_cmp returns 0 if user_data is equal
+     * or nonzero value if not. Set to NULL if no user data comparison
+     * is needed in fail over duplicate servers detection.
+     */
+    int (*user_data_cmp)(void*, void*);
 };
 
 struct fo_server {
@@ -393,6 +399,7 @@ service_destructor(struct fo_service *service)
 
 int
 fo_new_service(struct fo_ctx *ctx, const char *name,
+               int (*user_data_cmp)(void*, void*),
                struct fo_service **_service)
 {
     struct fo_service *service;
@@ -420,6 +427,8 @@ fo_new_service(struct fo_ctx *ctx, const char *name,
         return ENOMEM;
     }
 
+    service->user_data_cmp = user_data_cmp;
+
     service->ctx = ctx;
     DLIST_ADD(ctx->service_list, service);
 
@@ -520,8 +529,14 @@ fo_add_srv_server(struct fo_service *service, const char *srv,
                               service->name, proto));
 
     DLIST_FOR_EACH(server, service->server_list) {
-        if (server->user_data != user_data)
-            continue;
+        /* Compare user data only if user_data_cmp and both arguments
+         * are not NULL.
+         */
+        if (server->service->user_data_cmp) {
+            if (server->service->user_data_cmp(server->user_data, user_data)) {
+                continue;
+            }
+        }
 
         if (fo_is_srv_lookup(server)) {
             if (((discovery_domain == NULL &&
@@ -629,10 +644,19 @@ static bool fo_server_match(struct fo_server *server,
                            int port,
                            void *user_data)
 {
-    if (server->port != port || server->user_data != user_data) {
+    if (server->port != port) {
         return false;
     }
 
+    /* Compare user data only if user_data_cmp and both arguments
+     * are not NULL.
+     */
+    if (server->service->user_data_cmp && server->user_data && user_data) {
+        if (server->service->user_data_cmp(server->user_data, user_data)) {
+            return false;
+        }
+    }
+
     if (name == NULL && server->common == NULL) {
         return true;
     }
diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h
index b69e8a5..449c125 100644
--- a/src/providers/fail_over.h
+++ b/src/providers/fail_over.h
@@ -96,6 +96,7 @@ struct fo_ctx *fo_context_init(TALLOC_CTX *mem_ctx,
  */
 int fo_new_service(struct fo_ctx *ctx,
                    const char *name,
+                   int (*user_data_cmp)(void*, void*),
                    struct fo_service **_service);
 
 /*
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index bf62fcb..1c619a8 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -893,7 +893,7 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
-    ret = be_fo_add_service(ctx, "IPA");
+    ret = be_fo_add_service(ctx, "IPA", (int (*)(void*, void*)) strcmp);
     if (ret != EOK) {
         DEBUG(1, ("Failed to create failover service!\n"));
         goto done;
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index 98a2f7d..f4c0097 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -600,7 +600,7 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
-    ret = be_fo_add_service(ctx, service_name);
+    ret = be_fo_add_service(ctx, service_name, (int (*)(void*, void*)) strcmp);
     if (ret != EOK) {
         DEBUG(1, ("Failed to create failover service!\n"));
         goto done;
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 570ec97..1fa3129 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -1218,7 +1218,7 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
-    ret = be_fo_add_service(ctx, service_name);
+    ret = be_fo_add_service(ctx, service_name, (int (*)(void*, void*)) strcmp);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to create failover service!\n"));
         goto done;
diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c
index 6f4843c..3a7c4ae 100644
--- a/src/tests/fail_over-tests.c
+++ b/src/tests/fail_over-tests.c
@@ -114,11 +114,11 @@ START_TEST(test_fo_new_service)
         sprintf(buf, "service_%d", i);
 
         check_leaks_push(ctx);
-        ret = fo_new_service(ctx->fo_ctx, buf, &services[i]);
+        ret = fo_new_service(ctx->fo_ctx, buf, NULL, &services[i]);
         fail_if(ret != EOK);
     }
 
-    ret = fo_new_service(ctx->fo_ctx, "service_3", &service);
+    ret = fo_new_service(ctx->fo_ctx, "service_3", NULL, &service);
     fail_if(ret != EEXIST);
 
     for (i = 9; i >= 0; i--) {
@@ -223,11 +223,11 @@ START_TEST(test_fo_resolve_service)
     fail_if(ctx == NULL);
 
     /* Add service. */
-    fail_if(fo_new_service(ctx->fo_ctx, "http", &service[0]) != EOK);
+    fail_if(fo_new_service(ctx->fo_ctx, "http", NULL, &service[0]) != EOK);
 
-    fail_if(fo_new_service(ctx->fo_ctx, "ldap", &service[1]) != EOK);
+    fail_if(fo_new_service(ctx->fo_ctx, "ldap", NULL, &service[1]) != EOK);
 
-    fail_if(fo_new_service(ctx->fo_ctx, "ntp", &service[2]) != EOK);
+    fail_if(fo_new_service(ctx->fo_ctx, "ntp", NULL, &service[2]) != EOK);
 
     /* Add servers. */
     fail_if(fo_add_server(service[0], "localhost", 20, NULL, true) != EOK);
-- 
1.7.11.2

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

Reply via email to