The branch, v4-6-test has been updated via 06e8eec s3: VFS: Catia: Ensure path name is also converted. via c9b3e8f ctdb-tests: Add some extra tests for "ctdb nodestatus" via 0089a4c ctdb-tools: "ctdb nodestatus" should only display header for "all" via 3c596dc ctdb-tools: Stop "ctdb nodestatus" from always showing all nodes via 5906140 ctdb-readonly: Avoid a tight loop waiting for revoke to complete via 049484b Revert "ctdb-readonly: Avoid a tight loop waiting for revoke to complete" from 96b8f72 VERSION: Bump version up to 4.6.5.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-6-test - Log ----------------------------------------------------------------- commit 06e8eec8392ce80b000d8f22c019b05b691fddf8 Author: Jeremy Allison <j...@samba.org> Date: Wed May 24 11:45:35 2017 -0700 s3: VFS: Catia: Ensure path name is also converted. https://bugzilla.samba.org/show_bug.cgi?id=12804 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> (cherry picked from commit fda1e701af804db81dcb3844921e9a327563bc5c) Autobuild-User(v4-6-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-6-test): Tue May 30 16:36:35 CEST 2017 on sn-devel-144 commit c9b3e8f6fee8b1ca5de2164c4f838eeaf3d6c652 Author: Martin Schwenke <mar...@meltin.net> Date: Wed May 24 20:21:55 2017 +1000 ctdb-tests: Add some extra tests for "ctdb nodestatus" BUG: https://bugzilla.samba.org/show_bug.cgi?id=12802 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Fri May 26 05:24:34 CEST 2017 on sn-devel-144 (cherry picked from commit ade535371b86294c12ca3f7eb98d8ef7ecd29caa) commit 0089a4c4399964c97e10b9f17ac35648bb0627b1 Author: Martin Schwenke <mar...@meltin.net> Date: Wed May 24 20:27:58 2017 +1000 ctdb-tools: "ctdb nodestatus" should only display header for "all" The "Number of nodes:" header should only be displayed when "all" is specified. This is how the command behaved in Samba <= 4.4. Printing the number of nodes is not helpful and is rather confusing in the default case where only the status of the current node is printed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12802 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 1d10c8e9e637619b754b4a273d3c714fbca7d503) commit 3c596dc4b98c5b391a34322e0d585ed3b4e7711b Author: Martin Schwenke <mar...@meltin.net> Date: Wed May 24 20:24:54 2017 +1000 ctdb-tools: Stop "ctdb nodestatus" from always showing all nodes Exit code should only reflect current or specified nodes too. Drop an unwanted call to get_nodemap() that overwrites the previously calculated node map. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12802 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit a600d467e2842ab05e429c5a67be5b222ddd1c12) commit 5906140fb1f0ba1154f8754eaa3a7f6d51ef4823 Author: Amitay Isaacs <ami...@gmail.com> Date: Thu May 18 11:50:09 2017 +1000 ctdb-readonly: Avoid a tight loop waiting for revoke to complete BUG: https://bugzilla.samba.org/show_bug.cgi?id=12697 During revoking readonly delegations, if one of the nodes disappears, then there is no point re-trying revoking readonly delegation immedately. The database needs to be recovered before the revoke operation can succeed. However, if the revoke is successful, then all the write requests need to be processed immediately before the read-only requests. This avoids starving write requests, in case there are read-only requests coming from other nodes. In deferred_call_destructor, the result of revoke is not available and deferred calls cannot be correctly ordered. To correctly order the deferred calls, process them in revokechild_destructor where the result of revoke is known. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (cherry picked from commit f5f05a644dadc0b1858c99c5f1f5af1ef80f3a28) commit 049484b65587fee2049487ceffb8c802fc0d4e37 Author: Amitay Isaacs <ami...@gmail.com> Date: Thu May 18 10:15:01 2017 +1000 Revert "ctdb-readonly: Avoid a tight loop waiting for revoke to complete" BUG: https://bugzilla.samba.org/show_bug.cgi?id=12697 This reverts commit ad758cb869ac83534993caa212abc9fe9905ec68. This is an incomplete fix and introduces a regression. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (cherry picked from commit a50b25d0ebbe731a766f8d2ce1924b34d6041668) ----------------------------------------------------------------------- Summary of changes: ctdb/server/ctdb_call.c | 93 ++++++++++++++-------- ...db.nodestatus.001.sh => ctdb.nodestatus.003.sh} | 12 +-- ...db.nodestatus.001.sh => ctdb.nodestatus.004.sh} | 13 +-- ctdb/tests/tool/ctdb.nodestatus.005.sh | 28 +++++++ ctdb/tests/tool/ctdb.nodestatus.006.sh | 40 ++++++++++ ctdb/tools/ctdb.c | 29 ++++--- source3/modules/vfs_catia.c | 41 ++++++++-- 7 files changed, 187 insertions(+), 69 deletions(-) copy ctdb/tests/tool/{ctdb.nodestatus.001.sh => ctdb.nodestatus.003.sh} (73%) copy ctdb/tests/tool/{ctdb.nodestatus.001.sh => ctdb.nodestatus.004.sh} (64%) create mode 100755 ctdb/tests/tool/ctdb.nodestatus.005.sh create mode 100755 ctdb/tests/tool/ctdb.nodestatus.006.sh Changeset truncated at 500 lines: diff --git a/ctdb/server/ctdb_call.c b/ctdb/server/ctdb_call.c index 8ce3928..b3bc9cf 100644 --- a/ctdb/server/ctdb_call.c +++ b/ctdb/server/ctdb_call.c @@ -1562,6 +1562,7 @@ void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode) struct revokechild_deferred_call { + struct revokechild_deferred_call *prev, *next; struct ctdb_context *ctdb; struct ctdb_req_header *hdr; deferred_requeue_fn fn; @@ -1577,50 +1578,31 @@ struct revokechild_handle { int fd[2]; pid_t child; TDB_DATA key; -}; - -struct revokechild_requeue_handle { - struct ctdb_context *ctdb; - struct ctdb_req_header *hdr; - deferred_requeue_fn fn; - void *ctx; + struct revokechild_deferred_call *deferred_call_list; }; static void deferred_call_requeue(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { - struct revokechild_requeue_handle *requeue_handle = talloc_get_type(private_data, struct revokechild_requeue_handle); - - requeue_handle->fn(requeue_handle->ctx, requeue_handle->hdr); - talloc_free(requeue_handle); -} + struct revokechild_deferred_call *dlist = talloc_get_type_abort( + private_data, struct revokechild_deferred_call); -static int deferred_call_destructor(struct revokechild_deferred_call *deferred_call) -{ - struct ctdb_context *ctdb = deferred_call->ctdb; - struct revokechild_requeue_handle *requeue_handle = talloc(ctdb, struct revokechild_requeue_handle); - - requeue_handle->ctdb = ctdb; - requeue_handle->hdr = deferred_call->hdr; - requeue_handle->fn = deferred_call->fn; - requeue_handle->ctx = deferred_call->ctx; - talloc_steal(requeue_handle, requeue_handle->hdr); - - /* Always delay revoke requests. Either wait for the read/write - * operation to complete, or if revoking failed wait for recovery to - * complete - */ - tevent_add_timer(ctdb->ev, requeue_handle, - timeval_current_ofs(1, 0), - deferred_call_requeue, requeue_handle); + while (dlist != NULL) { + struct revokechild_deferred_call *dcall = dlist; - return 0; + DLIST_REMOVE(dlist, dcall); + dcall->fn(dcall->ctx, dcall->hdr); + talloc_free(dcall); + } } static int revokechild_destructor(struct revokechild_handle *rc) { + struct revokechild_deferred_call *now_list = NULL; + struct revokechild_deferred_call *delay_list = NULL; + if (rc->fde != NULL) { talloc_free(rc->fde); } @@ -1634,6 +1616,48 @@ static int revokechild_destructor(struct revokechild_handle *rc) ctdb_kill(rc->ctdb, rc->child, SIGKILL); DLIST_REMOVE(rc->ctdb_db->revokechild_active, rc); + + while (rc->deferred_call_list != NULL) { + struct revokechild_deferred_call *dcall; + + dcall = rc->deferred_call_list; + DLIST_REMOVE(rc->deferred_call_list, dcall); + + /* If revoke is successful, then first process all the calls + * that need write access, and delay readonly requests by 1 + * second grace. + * + * If revoke is unsuccessful, most likely because of node + * failure, delay all the pending requests, so database can + * be recovered. + */ + + if (rc->status == 0) { + struct ctdb_req_call_old *c; + + c = (struct ctdb_req_call_old *)dcall->hdr; + if (c->flags & CTDB_WANT_READONLY) { + DLIST_ADD(delay_list, dcall); + } else { + DLIST_ADD(now_list, dcall); + } + } else { + DLIST_ADD(delay_list, dcall); + } + } + + if (now_list != NULL) { + tevent_add_timer(rc->ctdb->ev, rc->ctdb_db, + tevent_timeval_current_ofs(0, 0), + deferred_call_requeue, now_list); + } + + if (delay_list != NULL) { + tevent_add_timer(rc->ctdb->ev, rc->ctdb_db, + tevent_timeval_current_ofs(1, 0), + deferred_call_requeue, delay_list); + } + return 0; } @@ -1911,19 +1935,18 @@ int ctdb_add_revoke_deferred_call(struct ctdb_context *ctdb, struct ctdb_db_cont return -1; } - deferred_call = talloc(rc, struct revokechild_deferred_call); + deferred_call = talloc(ctdb_db, struct revokechild_deferred_call); if (deferred_call == NULL) { DEBUG(DEBUG_ERR,("Failed to allocate deferred call structure for revoking record\n")); return -1; } deferred_call->ctdb = ctdb; - deferred_call->hdr = hdr; + deferred_call->hdr = talloc_steal(deferred_call, hdr); deferred_call->fn = fn; deferred_call->ctx = call_context; - talloc_set_destructor(deferred_call, deferred_call_destructor); - talloc_steal(deferred_call, hdr); + DLIST_ADD(rc->deferred_call_list, deferred_call); return 0; } diff --git a/ctdb/tests/tool/ctdb.nodestatus.001.sh b/ctdb/tests/tool/ctdb.nodestatus.003.sh similarity index 73% copy from ctdb/tests/tool/ctdb.nodestatus.001.sh copy to ctdb/tests/tool/ctdb.nodestatus.003.sh index 2217afc..5912e65 100755 --- a/ctdb/tests/tool/ctdb.nodestatus.001.sh +++ b/ctdb/tests/tool/ctdb.nodestatus.003.sh @@ -2,11 +2,11 @@ . "${TEST_SCRIPTS_DIR}/unit.sh" -define_test "all, 3 nodes, all OK" +define_test "all, 3 nodes, 1 unhealthy" setup_ctdbd <<EOF NODEMAP -0 192.168.20.41 0x0 +0 192.168.20.41 0x2 1 192.168.20.42 0x0 2 192.168.20.43 0x0 CURRENT RECMASTER @@ -16,17 +16,17 @@ IFACES :eth1:1:4: EOF -required_result 0 <<EOF +required_result 2 <<EOF Number of nodes:3 -pnn:0 192.168.20.41 OK +pnn:0 192.168.20.41 UNHEALTHY pnn:1 192.168.20.42 OK pnn:2 192.168.20.43 OK (THIS NODE) EOF simple_test all -required_result 0 <<EOF +required_result 2 <<EOF |Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode| -|0|192.168.20.41|0|0|0|0|0|0|0|N| +|0|192.168.20.41|0|0|0|1|0|0|0|N| |1|192.168.20.42|0|0|0|0|0|0|0|N| |2|192.168.20.43|0|0|0|0|0|0|0|Y| EOF diff --git a/ctdb/tests/tool/ctdb.nodestatus.001.sh b/ctdb/tests/tool/ctdb.nodestatus.004.sh similarity index 64% copy from ctdb/tests/tool/ctdb.nodestatus.001.sh copy to ctdb/tests/tool/ctdb.nodestatus.004.sh index 2217afc..01ccd51 100755 --- a/ctdb/tests/tool/ctdb.nodestatus.001.sh +++ b/ctdb/tests/tool/ctdb.nodestatus.004.sh @@ -2,11 +2,11 @@ . "${TEST_SCRIPTS_DIR}/unit.sh" -define_test "all, 3 nodes, all OK" +define_test "current, 3 nodes, node 0 unhealthy" setup_ctdbd <<EOF NODEMAP -0 192.168.20.41 0x0 +0 192.168.20.41 0x2 1 192.168.20.42 0x0 2 192.168.20.43 0x0 CURRENT RECMASTER @@ -17,17 +17,12 @@ IFACES EOF required_result 0 <<EOF -Number of nodes:3 -pnn:0 192.168.20.41 OK -pnn:1 192.168.20.42 OK pnn:2 192.168.20.43 OK (THIS NODE) EOF -simple_test all +simple_test required_result 0 <<EOF |Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode| -|0|192.168.20.41|0|0|0|0|0|0|0|N| -|1|192.168.20.42|0|0|0|0|0|0|0|N| |2|192.168.20.43|0|0|0|0|0|0|0|Y| EOF -simple_test -X all +simple_test -X diff --git a/ctdb/tests/tool/ctdb.nodestatus.005.sh b/ctdb/tests/tool/ctdb.nodestatus.005.sh new file mode 100755 index 0000000..0cd24ba --- /dev/null +++ b/ctdb/tests/tool/ctdb.nodestatus.005.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "current, 3 nodes, node 0 unhealthy, query node 0" + +setup_ctdbd <<EOF +NODEMAP +0 192.168.20.41 0x2 +1 192.168.20.42 0x0 +2 192.168.20.43 0x0 CURRENT RECMASTER + +IFACES +:Name:LinkStatus:References: +:eth2:1:2: +:eth1:1:4: +EOF + +required_result 2 <<EOF +pnn:0 192.168.20.41 UNHEALTHY +EOF +simple_test 0 + +required_result 2 <<EOF +|Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode| +|0|192.168.20.41|0|0|0|1|0|0|0|N| +EOF +simple_test -X 0 diff --git a/ctdb/tests/tool/ctdb.nodestatus.006.sh b/ctdb/tests/tool/ctdb.nodestatus.006.sh new file mode 100755 index 0000000..ec189fc --- /dev/null +++ b/ctdb/tests/tool/ctdb.nodestatus.006.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "current, 3 nodes, node 0 disabled+stopped, various queries" + +setup_ctdbd <<EOF +NODEMAP +0 192.168.20.41 0x24 +1 192.168.20.42 0x0 +2 192.168.20.43 0x0 CURRENT RECMASTER + +IFACES +:Name:LinkStatus:References: +:eth2:1:2: +:eth1:1:4: +EOF + +required_result 36 <<EOF +pnn:0 192.168.20.41 DISABLED|STOPPED|INACTIVE +EOF +simple_test 0 + +required_result 36 <<EOF +|Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode| +|0|192.168.20.41|0|0|1|0|1|1|0|N| +EOF +simple_test -X 0 + +required_result 36 <<EOF +pnn:0 192.168.20.41 DISABLED|STOPPED|INACTIVE +pnn:1 192.168.20.42 OK +EOF +simple_test 0,1 + +required_result 0 <<EOF +pnn:1 192.168.20.42 OK +pnn:2 192.168.20.43 OK (THIS NODE) +EOF +simple_test 1,2 diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 050906c..93e4802 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -802,7 +802,8 @@ static void print_nodemap_machine(TALLOC_CTX *mem_ctx, } static void print_nodemap(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, - struct ctdb_node_map *nodemap, uint32_t mypnn) + struct ctdb_node_map *nodemap, uint32_t mypnn, + bool print_header) { struct ctdb_node_and_flags *node; int num_deleted_nodes = 0; @@ -814,11 +815,14 @@ static void print_nodemap(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, } } - if (num_deleted_nodes == 0) { - printf("Number of nodes:%d\n", nodemap->num); - } else { - printf("Number of nodes:%d (including %d deleted nodes)\n", - nodemap->num, num_deleted_nodes); + if (print_header) { + if (num_deleted_nodes == 0) { + printf("Number of nodes:%d\n", nodemap->num); + } else { + printf("Number of nodes:%d " + "(including %d deleted nodes)\n", + nodemap->num, num_deleted_nodes); + } } for (i=0; i<nodemap->num; i++) { @@ -844,7 +848,7 @@ static void print_status(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, { int i; - print_nodemap(mem_ctx, ctdb, nodemap, mypnn); + print_nodemap(mem_ctx, ctdb, nodemap, mypnn, true); if (vnnmap->generation == INVALID_GENERATION) { printf("Generation:INVALID\n"); @@ -5650,6 +5654,7 @@ static int control_nodestatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, const char *nodestring = NULL; struct ctdb_node_map *nodemap; int ret, i; + bool print_hdr = false; if (argc > 1) { usage("nodestatus"); @@ -5657,21 +5662,19 @@ static int control_nodestatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, if (argc == 1) { nodestring = argv[0]; + if (strcmp(nodestring, "all") == 0) { + print_hdr = true; + } } if (! parse_nodestring(mem_ctx, ctdb, nodestring, &nodemap)) { return 1; } - nodemap = get_nodemap(ctdb, false); - if (nodemap == NULL) { - return 1; - } - if (options.machinereadable) { print_nodemap_machine(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn); } else { - print_nodemap(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn); + print_nodemap(mem_ctx, ctdb, nodemap, ctdb->cmd_pnn, print_hdr); } ret = 0; diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 0ee7c36..c6d8f58 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -1316,19 +1316,29 @@ catia_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size) { char *mapped_name = NULL; + char *mapped_ea_name = NULL; NTSTATUS status; ssize_t ret; status = catia_string_replace_allocate(handle->conn, - name, &mapped_name, vfs_translate_to_unix); + path, &mapped_name, vfs_translate_to_unix); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } + status = catia_string_replace_allocate(handle->conn, + name, &mapped_ea_name, vfs_translate_to_unix); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(mapped_name); + errno = map_errno_from_nt_status(status); + return -1; + } - ret = SMB_VFS_NEXT_GETXATTR(handle, path, mapped_name, value, size); + ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_name, + mapped_ea_name, value, size); TALLOC_FREE(mapped_name); + TALLOC_FREE(mapped_ea_name); return ret; } @@ -1360,19 +1370,28 @@ catia_removexattr(vfs_handle_struct *handle, const char *path, const char *name) { char *mapped_name = NULL; + char *mapped_ea_name = NULL; NTSTATUS status; ssize_t ret; status = catia_string_replace_allocate(handle->conn, - name, &mapped_name, vfs_translate_to_unix); + path, &mapped_name, vfs_translate_to_unix); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } + status = catia_string_replace_allocate(handle->conn, + name, &mapped_ea_name, vfs_translate_to_unix); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(mapped_name); + errno = map_errno_from_nt_status(status); + return -1; + } - ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, mapped_name); + ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_name, mapped_ea_name); TALLOC_FREE(mapped_name); + TALLOC_FREE(mapped_ea_name); return ret; } @@ -1383,19 +1402,29 @@ catia_setxattr(vfs_handle_struct *handle, const char *path, int flags) { char *mapped_name = NULL; + char *mapped_ea_name = NULL; NTSTATUS status; ssize_t ret; status = catia_string_replace_allocate(handle->conn, - name, &mapped_name, vfs_translate_to_unix); + path, &mapped_name, vfs_translate_to_unix); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } + status = catia_string_replace_allocate(handle->conn, + name, &mapped_ea_name, vfs_translate_to_unix); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(mapped_name); + errno = map_errno_from_nt_status(status); + return -1; + } - ret = SMB_VFS_NEXT_SETXATTR(handle, path, mapped_name, value, size, flags); + ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_name, mapped_ea_name, + value, size, flags); TALLOC_FREE(mapped_name); + TALLOC_FREE(mapped_ea_name); return ret; } -- Samba Shared Repository