The branch, master has been updated via ced27e1 s3:lib: make sure we don't try to send messages to server_id's marked as disconnected via 1f7eac9 s3:lib: remove unused processes_exist() via 9529301 s3:lib: readd the CTDB_CONTROL_CHECK_SRVIDS optimization to serverids_exist() via 18c6757 s3:lib: only loop over the server_ids we need to verify in serverids_exist() via 6c3c25b s3:lib: use server_id_is_disconnected() in serverids_exist() via dc7d0f6 s3:lib: inline processes_exist() into serverids_exist() via 84b5a5c s3:lib: SERVERID_UNIQUE_ID_NOT_TO_VERIFY only means not to verify the 'unique_id' part via 95f3662 lib/util: don't SMB_ASSERT() in process_exists_by_pid() via 0b5e354 s3:lib: implement process_exists() as wrapper of serverid_exists() via 774c284 s3:g_lock: use serverid_exists() with SERVERID_UNIQUE_ID_NOT_TO_VERIFY via 99b134a s3:lib: implement serverid_exists() as wrapper of serverids_exist() via 6145329 s3:lib: remove CTDB_CONTROL_CHECK_SRVIDS optimization in serverids_exist() for now from f83521a lib/param: fix usage of 'write list = +Group'
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit ced27e1c5de491b4bac6c7817e72816ab075ef32 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Aug 21 14:14:40 2012 +0200 s3:lib: make sure we don't try to send messages to server_id's marked as disconnected metze Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Fri Aug 24 15:54:48 CEST 2012 on sn-devel-104 commit 1f7eac907a04361abf89b12ab03284cf57fec0f5 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 13:30:22 2012 +0200 s3:lib: remove unused processes_exist() metze commit 9529301503c043aaf8d3c39d3b0f014aaa0cc123 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Aug 24 09:05:06 2012 +0200 s3:lib: readd the CTDB_CONTROL_CHECK_SRVIDS optimization to serverids_exist() metze commit 18c6757dbb7ee0e6a4be15b0f2a3fec1f94ba518 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Aug 23 09:03:36 2012 +0200 s3:lib: only loop over the server_ids we need to verify in serverids_exist() metze commit 6c3c25b5c1e4981687556b7a8e56c8460d69deb4 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 17:52:56 2012 +0200 s3:lib: use server_id_is_disconnected() in serverids_exist() metze commit dc7d0f688317593ffa58badcc0ed7b10b2047c5e Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 13:28:49 2012 +0200 s3:lib: inline processes_exist() into serverids_exist() metze commit 84b5a5cbcd5e1c9ff984cd37b35a67707ceb430b Author: Stefan Metzmacher <me...@samba.org> Date: Tue Aug 21 12:57:28 2012 +0200 s3:lib: SERVERID_UNIQUE_ID_NOT_TO_VERIFY only means not to verify the 'unique_id' part It doesn't mean the the server_id is always valid. metze commit 95f3662bbd587af24c2ff5411318e9d466412ee9 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 17:52:01 2012 +0200 lib/util: don't SMB_ASSERT() in process_exists_by_pid() Just return false... metze commit 0b5e354080ae1990b1f8acc470bfbad3f92868b8 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 12:36:22 2012 +0200 s3:lib: implement process_exists() as wrapper of serverid_exists() The changes the behavior of process_exists() it checks the pid.unique_id now, if it's not SERVERID_UNIQUE_ID_NOT_TO_VERIFY. metze commit 774c28416bd05c66f398dfbc999cff0e209b3620 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 12:35:29 2012 +0200 s3:g_lock: use serverid_exists() with SERVERID_UNIQUE_ID_NOT_TO_VERIFY metze commit 99b134adbe6b02388665c3b34f00b6723f6a1120 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 12:07:02 2012 +0200 s3:lib: implement serverid_exists() as wrapper of serverids_exist() metze commit 6145329fcd7463279b3c497a7a5db5f4f6bd991e Author: Stefan Metzmacher <me...@samba.org> Date: Wed Aug 22 12:02:43 2012 +0200 s3:lib: remove CTDB_CONTROL_CHECK_SRVIDS optimization in serverids_exist() for now This will be readded... metze ----------------------------------------------------------------------- Summary of changes: lib/util/util.c | 4 +- source3/lib/g_lock.c | 11 ++- source3/lib/messages.c | 4 + source3/lib/serverid.c | 214 +++++++++++++++++++++++++++++++++++++----------- source3/lib/util.c | 86 +------------------- 5 files changed, 184 insertions(+), 135 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/util.c b/lib/util/util.c index 100d3d8..b50d28a 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -286,7 +286,9 @@ _PUBLIC_ bool process_exists_by_pid(pid_t pid) { /* Doing kill with a non-positive pid causes messages to be * sent to places we don't want. */ - SMB_ASSERT(pid > 0); + if (pid <= 0) { + return false; + } return(kill(pid,0) == 0 || errno != ESRCH); } diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 4535b35..fbd9022 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -29,6 +29,7 @@ #include "../lib/util/tevent_ntstatus.h" #include "system/select.h" #include "messages.h" +#include "serverid.h" struct g_lock_ctx { struct db_context *db; @@ -124,8 +125,16 @@ static NTSTATUS g_lock_trylock(struct db_record *rec, struct server_id self, goto done; } if (g_lock_conflicts(type, locks[i].lock_type)) { + struct server_id pid = locks[i].pid; - if (process_exists(locks[i].pid)) { + /* + * As the serverid_exists might recurse into + * the g_lock code, we use + * SERVERID_UNIQUE_ID_NOT_TO_VERIFY to avoid the loop + */ + pid.unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY; + + if (serverid_exists(&pid)) { status = NT_STATUS_LOCK_NOT_GRANTED; goto done; } diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 6a18e4f..cd763e7 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -351,6 +351,10 @@ NTSTATUS messaging_send(struct messaging_context *msg_ctx, struct server_id server, uint32_t msg_type, const DATA_BLOB *data) { + if (server_id_is_disconnected(&server)) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + #ifdef CLUSTER_SUPPORT if (!procid_is_local(&server)) { return msg_ctx->remote->send_fn(msg_ctx, server, diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c index 3c5402e..cb49520 100644 --- a/source3/lib/serverid.c +++ b/source3/lib/serverid.c @@ -251,89 +251,205 @@ static void server_exists_parse(TDB_DATA key, TDB_DATA data, void *priv) bool serverid_exists(const struct server_id *id) { - struct db_context *db; - struct serverid_exists_state state; - struct serverid_key key; - TDB_DATA tdbkey; - NTSTATUS status; - - if (procid_is_me(id)) { - return true; - } + bool result = false; + bool ok = false; - if (!process_exists(*id)) { + ok = serverids_exist(id, 1, &result); + if (!ok) { return false; } - if (id->unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { - return true; - } + return result; +} + +bool serverids_exist(const struct server_id *ids, int num_ids, bool *results) +{ + int *todo_idx = NULL; + struct server_id *todo_ids = NULL; + bool *todo_results = NULL; + int todo_num = 0; + int *remote_idx = NULL; + int remote_num = 0; + int *verify_idx = NULL; + int verify_num = 0; + int t, idx; + bool result = false; + struct db_context *db; db = serverid_db(); if (db == NULL) { return false; } - serverid_fill_key(id, &key); - tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key)); - - state.id = id; - state.exists = false; + todo_idx = talloc_array(talloc_tos(), int, num_ids); + if (todo_idx == NULL) { + goto fail; + } + todo_ids = talloc_array(talloc_tos(), struct server_id, num_ids); + if (todo_ids == NULL) { + goto fail; + } + todo_results = talloc_array(talloc_tos(), bool, num_ids); + if (todo_results == NULL) { + goto fail; + } - status = dbwrap_parse_record(db, tdbkey, server_exists_parse, &state); - if (!NT_STATUS_IS_OK(status)) { - return false; + remote_idx = talloc_array(talloc_tos(), int, num_ids); + if (remote_idx == NULL) { + goto fail; + } + verify_idx = talloc_array(talloc_tos(), int, num_ids); + if (verify_idx == NULL) { + goto fail; } - return state.exists; -} -bool serverids_exist(const struct server_id *ids, int num_ids, bool *results) -{ - struct db_context *db; - int i; + for (idx=0; idx<num_ids; idx++) { + results[idx] = false; + + if (server_id_is_disconnected(&ids[idx])) { + continue; + } + + if (procid_is_me(&ids[idx])) { + results[idx] = true; + continue; + } + + if (procid_is_local(&ids[idx])) { + bool exists = process_exists_by_pid(ids[idx].pid); + + if (!exists) { + continue; + } + + if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { + results[idx] = true; + continue; + } + + verify_idx[verify_num] = idx; + verify_num += 1; + continue; + } + + if (!lp_clustering()) { + continue; + } + + remote_idx[remote_num] = idx; + remote_num += 1; + } #ifdef HAVE_CTDB_CONTROL_CHECK_SRVIDS_DECL - if (lp_clustering()) { - return ctdb_serverids_exist(messaging_ctdbd_connection(), - ids, num_ids, results); + if (remote_num != 0) { + int old_remote_num = remote_num; + + remote_num = 0; + todo_num = 0; + + for (t=0; t<old_remote_num; t++) { + idx = remote_idx[t]; + + if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { + remote_idx[remote_num] = idx; + remote_num += 1; + continue; + } + + todo_idx[todo_num] = idx; + todo_ids[todo_num] = ids[idx]; + todo_results[todo_num] = false; + todo_num += 1; + } + + /* + * Note: this only uses CTDB_CONTROL_CHECK_SRVIDS + * to verify that the server_id still exists, + * which means only the server_id.unique_id and + * server_id.vnn are verified, while server_id.pid + * is not verified at all. + * + * TODO: do we want to verify server_id.pid somehow? + */ + if (!ctdb_serverids_exist(messaging_ctdbd_connection(), + todo_ids, todo_num, todo_results)) + { + goto fail; + } + + for (t=0; t<todo_num; t++) { + idx = todo_idx[t]; + + results[idx] = todo_results[t]; + } } #endif - if (!processes_exist(ids, num_ids, results)) { - return false; - } - db = serverid_db(); - if (db == NULL) { - return false; + if (remote_num != 0) { + todo_num = 0; + + for (t=0; t<remote_num; t++) { + idx = remote_idx[t]; + todo_idx[todo_num] = idx; + todo_ids[todo_num] = ids[idx]; + todo_results[todo_num] = false; + todo_num += 1; + } + +#ifdef CLUSTER_SUPPORT + if (!ctdb_processes_exist(messaging_ctdbd_connection(), + todo_ids, todo_num, + todo_results)) { + goto fail; + } +#endif + + for (t=0; t<todo_num; t++) { + idx = todo_idx[t]; + + if (!todo_results[t]) { + continue; + } + + if (ids[idx].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { + results[idx] = true; + continue; + } + + verify_idx[verify_num] = idx; + verify_num += 1; + } } - for (i=0; i<num_ids; i++) { + for (t=0; t<verify_num; t++) { struct serverid_exists_state state; struct serverid_key key; TDB_DATA tdbkey; NTSTATUS status; - if (ids[i].unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { - results[i] = true; - continue; - } - if (!results[i]) { - continue; - } + idx = verify_idx[t]; - serverid_fill_key(&ids[i], &key); + serverid_fill_key(&ids[idx], &key); tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key)); - state.id = &ids[i]; + state.id = &ids[idx]; state.exists = false; status = dbwrap_parse_record(db, tdbkey, server_exists_parse, &state); if (!NT_STATUS_IS_OK(status)) { - results[i] = false; + results[idx] = false; continue; } - results[i] = state.exists; + results[idx] = state.exists; } - return true; + + result = true; +fail: + TALLOC_FREE(verify_idx); + TALLOC_FREE(remote_idx); + TALLOC_FREE(todo_results); + TALLOC_FREE(todo_ids); + TALLOC_FREE(todo_idx); + return result; } static bool serverid_rec_parse(const struct db_record *rec, diff --git a/source3/lib/util.c b/source3/lib/util.c index 242fb10..5ffce58 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -30,6 +30,7 @@ #include "messages.h" #include <ccan/hash/hash.h> #include "libcli/security/security.h" +#include "serverid.h" #ifdef HAVE_SYS_PRCTL_H #include <sys/prctl.h> @@ -706,92 +707,9 @@ char *automount_lookup(TALLOC_CTX *ctx, const char *user_name) #endif /* WITH_NISPLUS_HOME */ #endif -/**************************************************************************** - Check if a process exists. Does this work on all unixes? -****************************************************************************/ - bool process_exists(const struct server_id pid) { - if (procid_is_me(&pid)) { - return True; - } - - if (procid_is_local(&pid)) { - return (kill(pid.pid,0) == 0 || errno != ESRCH); - } - -#ifdef CLUSTER_SUPPORT - return ctdbd_process_exists(messaging_ctdbd_connection(), - pid.vnn, pid.pid); -#else - return False; -#endif -} - -bool processes_exist(const struct server_id *pids, int num_pids, - bool *results) -{ - struct server_id *remote_pids = NULL; - int *remote_idx = NULL; - bool *remote_results = NULL; - int i, num_remote_pids; - bool result = false; - - remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids); - if (remote_pids == NULL) { - goto fail; - } - remote_idx = talloc_array(talloc_tos(), int, num_pids); - if (remote_idx == NULL) { - goto fail; - } - remote_results = talloc_array(talloc_tos(), bool, num_pids); - if (remote_results == NULL) { - goto fail; - } - - num_remote_pids = 0; - - for (i=0; i<num_pids; i++) { - if (procid_is_me(&pids[i])) { - results[i] = true; - continue; - } - if (procid_is_local(&pids[i])) { - results[i] = ((kill(pids[i].pid,0) == 0) || - (errno != ESRCH)); - continue; - } - - remote_pids[num_remote_pids] = pids[i]; - remote_idx[num_remote_pids] = i; - num_remote_pids += 1; - } - - if (num_remote_pids != 0) { -#ifdef CLUSTER_SUPPORT - if (!ctdb_processes_exist(messaging_ctdbd_connection(), - remote_pids, num_remote_pids, - remote_results)) { - goto fail; - } -#else - for (i=0; i<num_remote_pids; i++) { - remote_results[i] = false; - } -#endif - - for (i=0; i<num_remote_pids; i++) { - results[remote_idx[i]] = remote_results[i]; - } - } - - result = true; -fail: - TALLOC_FREE(remote_results); - TALLOC_FREE(remote_idx); - TALLOC_FREE(remote_pids); - return result; + return serverid_exists(&pid); } /******************************************************************* -- Samba Shared Repository