Kaynağa Gözat

ZOOKEEPER-2282: C Client: chroot not stripped in asynchronous callbacks

This is related to ZOOKEEPER-1027, which adjusted the result of `create` calls to account for the chroot path.  It did not, however, correct the problem for asynchronous calls:

    $ cli_st $ENSEMBLE_HOSTS/rt-46444

    create /x/fred
    Creating [/x/fred] node (mode: 0)
    [/x/fred]: rc = 0
            name = /rt-46444/x/fred

    create2 /x/wilma
    Creating [/x/wilma] node (mode: 0)
    [/x/wilma]: rc = 0
            name = /rt-46444/x/wilma
            ctime = Wed Aug 28 18:14:16 2019
            czxid=1f00000041
            mtime=Wed Aug 28 18:14:16 2019
            mzxid=1f00000041
            version=0	aversion=0
            ephemeralOwner = 0

(It turns out that there was already a ticket, with a patch, for this issue.  I am mentioning Andrew Grasso as a co-author.  This commit also avoids the test failure, however.)

Co-authored-by: Andrew Grasso <andrew-grassousers.noreply.github.com>

Author: Damien Diederen <dd@crosstwine.com>

Reviewers: eolivelli@apache.org, andor@apache.org

Closes #1066 from ztzg/ZOOKEEPER-2282-c-client-async-chroot-paths
Damien Diederen 5 yıl önce
ebeveyn
işleme
1e7fae31af

+ 8 - 2
zookeeper-client/zookeeper-client-c/src/zookeeper.c

@@ -2716,9 +2716,12 @@ static void deserialize_response(zhandle_t *zh, int type, int xid, int failed, i
             cptr->c.string_result(rc, 0, cptr->data);
         } else {
             struct CreateResponse res;
+            const char *client_path;
             memset(&res, 0, sizeof(res));
             deserialize_CreateResponse(ia, "reply", &res);
-            cptr->c.string_result(rc, res.path, cptr->data);
+            client_path = sub_string(zh, res.path);
+            cptr->c.string_result(rc, client_path, cptr->data);
+            free_duplicate_path(client_path, res.path);
             deallocate_CreateResponse(&res);
         }
         break;
@@ -2729,8 +2732,11 @@ static void deserialize_response(zhandle_t *zh, int type, int xid, int failed, i
             cptr->c.string_stat_result(rc, 0, 0, cptr->data);
         } else {
             struct Create2Response res;
+            const char *client_path;
             deserialize_Create2Response(ia, "reply", &res);
-            cptr->c.string_stat_result(rc, res.path, &res.stat, cptr->data);
+            client_path = sub_string(zh, res.path);
+            cptr->c.string_stat_result(rc, client_path, &res.stat, cptr->data);
+            free_duplicate_path(client_path, res.path);
             deallocate_Create2Response(&res);
         }
         break;

+ 10 - 0
zookeeper-client/zookeeper-client-c/tests/TestClient.cc

@@ -450,6 +450,10 @@ public:
 
     static void create_completion_fn(int rc, const char* value, const void *data) {
         CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        if (data) {
+            const char *expected_value = (const char *)data;
+            CPPUNIT_ASSERT_EQUAL(string(expected_value), string(value));
+        }
         count++;
     }
 
@@ -991,6 +995,12 @@ public:
         rc = zoo_create(zk_ch, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, path_buffer, path_buffer_len);
         CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
         CPPUNIT_ASSERT_EQUAL(string(path), string(path_buffer));
+
+        const char* path2282 = "/zookeeper2282";
+        rc = zoo_acreate(zk_ch, path2282, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
+                         create_completion_fn, path2282);
+        waitForCreateCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
     }
 
     // Test creating normal handle via zookeeper_init then explicitly setting callback