The branch, master has been updated via 41cfc73 lib: Remove unused serverid.tdb via 6423ca4 lib: Use messaging_send_all instead of message_send_all via 77cccbc lib: Add messaging_send_all via 2fdde4a messaging: Always register CTDB_SRVID_SAMBA_PROCESS via 84fd51b messaging: Remove an unused #define via 2dfabd8 net: Remove "net serverid list" via c9022d5 net: Remove "net serverid wipe" via e8ac34d smbcontrol: Use messaging_dgm_forall via 05647d4 messaging_dgm: Use messaging_dgm_forall in dgm_wipe via 6b5b999 messaging: Add messaging_dgm_forall via fc2f002 messaging: Remove the "n_sent" arg from message_send_all via 2dac8eb messaging_dgm: Protect against fork without reinit from d80b8f2 Revert "selftest: mark samba3.smb2.kernel-oplocks as flapping"
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 41cfc737dfb2c751053a61917458a4a8cdb386b0 Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 5 12:58:09 2017 +0100 lib: Remove unused serverid.tdb Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Dec 5 04:58:26 CET 2017 on sn-devel-144 commit 6423ca4bf293cac5e2f84b1a37bb29b06b5c05ed Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 5 12:54:10 2017 +0100 lib: Use messaging_send_all instead of message_send_all Just a global search&replace Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 77cccbc6f4240926d448dd2e2a76d91ccc783729 Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 5 12:44:01 2017 +0100 lib: Add messaging_send_all This will replace message_send_all. With messaging_dgm_forall we have a local broadcast mechanism, and ctdb can also broadcast everywhere. So there's no need for a separate traverse/send mechanism. There's no good error reporting mechanism for broadcasting, so make this function void. This drops the message_type filtering. I believe that this does not matter in practice, since messaging is a lot cheaper with dgm instead of the old tdb based messaging. If someone presents a use case where this matters, nowadays I'd much rather extend the messaging_dgm lock file format (where the unique id lives right now) with the filter bits. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2fdde4a07a4e7f28cd9cbd0ac9a0bae3fa748522 Author: Volker Lendecke <v...@samba.org> Date: Tue Jul 25 17:10:27 2017 +0200 messaging: Always register CTDB_SRVID_SAMBA_PROCESS This will be used to broadcast to all processes, avoiding the costly traverse of serverid.tdb. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 84fd51ba6103957f64021e6543314bcbe1f389af Author: Volker Lendecke <v...@samba.org> Date: Tue Jul 25 16:24:04 2017 +0200 messaging: Remove an unused #define Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2dfabd85d95fcb2b22112eb86c9dedd356c8590f Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 5 12:09:08 2017 +0100 net: Remove "net serverid list" Traversing a clustered tdb is a pretty expensive operation. If someone really needs this command-line interface, we can re-add it for the local node using messaging_dgm_forall. If someone needs that globally, there's the "onnode all" script that could be used. Alternatively, we could implement an enhanced ping broadcast message also returning a processes unique id. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c9022d594b19051a5600d7e2955c3bd73a2988ea Author: Volker Lendecke <v...@samba.org> Date: Sun Nov 5 12:02:26 2017 +0100 net: Remove "net serverid wipe" This used to be a hygiene command for clustered node startup. In clustered mode, CLEAR_IF_FIRST does not work, records can stay alive by means of recovery. serverid.tdb will soon die, so remove this command. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit e8ac34d3f73b45702459af6ec878f156075520b2 Author: Volker Lendecke <v...@samba.org> Date: Thu Oct 26 17:18:36 2017 +0200 smbcontrol: Use messaging_dgm_forall Doing stacktraces can be done locally only anyway Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 05647d4723321081959dd02a5035419335b38c6e Author: Volker Lendecke <v...@samba.org> Date: Mon Oct 16 21:52:35 2017 +0200 messaging_dgm: Use messaging_dgm_forall in dgm_wipe Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6b5b999d2f324889827223fc3d0ac74a76530092 Author: Volker Lendecke <v...@samba.org> Date: Fri Jul 21 19:03:26 2017 +0200 messaging: Add messaging_dgm_forall This factors out the traversal function from _wipe. It will be used to replace message_send_all soon. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit fc2f0023a0ea521c5bc392db8f635bc3f23f68b8 Author: Volker Lendecke <v...@samba.org> Date: Fri Jul 21 19:08:43 2017 +0200 messaging: Remove the "n_sent" arg from message_send_all The only user of this is an informative message in smbcontrol. I don't think that's worth the effort. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2dac8eb2778802847688ef862f375440d3aa0ff4 Author: Volker Lendecke <v...@samba.org> Date: Sat Nov 25 16:47:24 2017 +0100 messaging_dgm: Protect against fork without reinit In the wake of bug 13150 we've discussed that this could happen even without clustering. This adds code to make sure that whenever messaging is used the pid and the files used match. It's pretty heavy-weight, thus I made it DEVELOPER only. My gut feeling is that the getsockname is cheap, but the stat call might be a bit too expensive. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/include/ctdb_srvids.h | 6 + source3/include/messages.h | 14 +- source3/include/serverid.h | 50 ---- source3/lib/messages.c | 74 ++++++ source3/lib/messages_ctdb.c | 9 + source3/lib/messages_dgm.c | 135 ++++++++++- source3/lib/messages_dgm.h | 2 + source3/lib/serverid.c | 350 ---------------------------- source3/nmbd/nmbd.c | 10 - source3/passdb/pdb_interface.c | 9 +- source3/printing/nt_printing.c | 4 - source3/printing/queue_process.c | 9 +- source3/printing/spoolssd.c | 13 -- source3/rpc_server/epmd.c | 9 - source3/rpc_server/fss/srv_fss_agent.c | 9 +- source3/rpc_server/fssd.c | 9 - source3/rpc_server/lsasd.c | 11 - source3/rpc_server/mdssd.c | 11 - source3/rpc_server/spoolss/srv_spoolss_nt.c | 4 +- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 10 +- source3/smbd/negprot.c | 8 - source3/smbd/process.c | 9 - source3/smbd/scavenger.c | 8 - source3/smbd/server.c | 20 -- source3/smbd/server_exit.c | 8 - source3/smbd/smbd_cleanupd.c | 16 +- source3/smbd/statcache.c | 9 +- source3/torture/vfstest.c | 2 - source3/utils/net_serverid.c | 58 ----- source3/utils/smbcontrol.c | 19 +- source3/winbindd/winbindd.c | 14 -- 31 files changed, 242 insertions(+), 677 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/ctdb_srvids.h b/source3/include/ctdb_srvids.h index 500b506..b51a458 100644 --- a/source3/include/ctdb_srvids.h +++ b/source3/include/ctdb_srvids.h @@ -38,3 +38,9 @@ * locally according to the non-clustered local notify.tdb */ #define CTDB_SRVID_SAMBA_NOTIFY_PROXY 0xFE00000000000001LL + +/* + * SRVID for all processes that come from Samba. Used to be + * MSG_SRVID_SAMBA in the past. Now used for message_send_all. + */ +#define CTDB_SRVID_SAMBA_PROCESS 0xFE00000000000002LL diff --git a/source3/include/messages.h b/source3/include/messages.h index 8d3b1d8..29c394a 100644 --- a/source3/include/messages.h +++ b/source3/include/messages.h @@ -35,18 +35,6 @@ */ #define MSG_FLAG_LOWPRIORITY 0x80000000 - -/* - * ctdb gives us 64-bit server ids for messaging_send. This is done to avoid - * pid clashes and to be able to register for special messages like "all - * smbds". - * - * Normal individual server id's have the upper 32 bits to 0, I picked "1" for - * Samba, other subsystems might use something else. - */ - -#define MSG_SRVID_SAMBA 0x0000000100000000LL - #include "librpc/gen_ndr/server_id.h" #include "lib/util/data_blob.h" #include "system/network.h" @@ -108,6 +96,8 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx, struct server_id server, uint32_t msg_type, const struct iovec *iov, int iovlen, const int *fds, size_t num_fds); +void messaging_send_all(struct messaging_context *msg_ctx, + int msg_type, const void *buf, size_t len); struct tevent_req *messaging_filtered_read_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/source3/include/serverid.h b/source3/include/serverid.h index 749b950..89487cf 100644 --- a/source3/include/serverid.h +++ b/source3/include/serverid.h @@ -21,61 +21,11 @@ #define __SERVERID_H__ #include "replace.h" -#include "lib/dbwrap/dbwrap.h" #include "librpc/gen_ndr/server_id.h" -/* Flags to classify messages - used in message_send_all() */ -/* Sender will filter by flag. */ - -#define FLAG_MSG_GENERAL 0x0001 -#define FLAG_MSG_SMBD 0x0002 -#define FLAG_MSG_NMBD 0x0004 -#define FLAG_MSG_WINBIND 0x0008 -#define FLAG_MSG_PRINT_GENERAL 0x0010 -/* dbwrap messages 4001-4999 */ -#define FLAG_MSG_DBWRAP 0x0020 - -/* - * Register a server with its unique id - */ -bool serverid_register(const struct server_id id, uint32_t msg_flags); - -/* - * De-register a server with its unique id - */ -bool serverid_deregister(const struct server_id id); - /* * Check existence of a server id */ bool serverid_exists(const struct server_id *id); -/* - * Walk the list of server_ids registered - */ -bool serverid_traverse(int (*fn)(struct db_record *rec, - const struct server_id *id, - uint32_t msg_flags, - void *private_data), - void *private_data); - -/* - * Walk the list of server_ids registered read-only - */ -bool serverid_traverse_read(int (*fn)(const struct server_id *id, - uint32_t msg_flags, - void *private_data), - void *private_data); -/* - * Ensure CLEAR_IF_FIRST works fine, to be called from the parent smbd - */ -bool serverid_parent_init(TALLOC_CTX *mem_ctx); - -struct messaging_context; - -bool message_send_all(struct messaging_context *msg_ctx, - int msg_type, - const void *buf, size_t len, - int *n_sent); - #endif diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 01029b2..a0a3f9f 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -60,6 +60,12 @@ #include "lib/messages_ctdb_ref.h" #include "lib/messages_util.h" #include "cluster_support.h" +#include "ctdbd_conn.h" +#include "ctdb_srvids.h" + +#ifdef CLUSTER_SUPPORT +#include "ctdb_protocol.h" +#endif struct messaging_callback { struct messaging_callback *prev, *next; @@ -513,6 +519,7 @@ static NTSTATUS messaging_init_internal(TALLOC_CTX *mem_ctx, } talloc_set_destructor(ctx, messaging_context_destructor); +#ifdef CLUSTER_SUPPORT if (lp_clustering()) { ctx->msg_ctdb_ref = messaging_ctdb_ref( ctx, ctx->event_ctx, @@ -525,6 +532,8 @@ static NTSTATUS messaging_init_internal(TALLOC_CTX *mem_ctx, goto done; } } +#endif + ctx->id.vnn = get_my_vnn(); ctx->names_db = server_id_db_init(ctx, @@ -836,6 +845,71 @@ NTSTATUS messaging_send_iov(struct messaging_context *msg_ctx, return NT_STATUS_OK; } +struct send_all_state { + struct messaging_context *msg_ctx; + int msg_type; + const void *buf; + size_t len; +}; + +static int send_all_fn(pid_t pid, void *private_data) +{ + struct send_all_state *state = private_data; + NTSTATUS status; + + status = messaging_send_buf(state->msg_ctx, pid_to_procid(pid), + state->msg_type, state->buf, state->len); + if (!NT_STATUS_IS_OK(status)) { + DBG_WARNING("messaging_send_buf to %ju failed: %s\n", + (uintmax_t)pid, nt_errstr(status)); + } + + return 0; +} + +void messaging_send_all(struct messaging_context *msg_ctx, + int msg_type, const void *buf, size_t len) +{ + struct send_all_state state = { + .msg_ctx = msg_ctx, .msg_type = msg_type, + .buf = buf, .len = len + }; + int ret; + +#ifdef CLUSTER_SUPPORT + if (lp_clustering()) { + struct ctdbd_connection *conn = messaging_ctdb_connection(); + uint8_t msghdr[MESSAGE_HDR_LENGTH]; + struct iovec iov[] = { + { .iov_base = msghdr, + .iov_len = sizeof(msghdr) }, + { .iov_base = discard_const_p(void, buf), + .iov_len = len } + }; + + message_hdr_put(msghdr, msg_type, messaging_server_id(msg_ctx), + (struct server_id) {0}); + + ret = ctdbd_messaging_send_iov( + conn, CTDB_BROADCAST_CONNECTED, + CTDB_SRVID_SAMBA_PROCESS, + iov, ARRAY_SIZE(iov)); + if (ret != 0) { + DBG_WARNING("ctdbd_messaging_send_iov failed: %s\n", + strerror(ret)); + } + + return; + } +#endif + + ret = messaging_dgm_forall(send_all_fn, &state); + if (ret != 0) { + DBG_WARNING("messaging_dgm_forall failed: %s\n", + strerror(ret)); + } +} + static struct messaging_rec *messaging_rec_dup(TALLOC_CTX *mem_ctx, struct messaging_rec *rec) { diff --git a/source3/lib/messages_ctdb.c b/source3/lib/messages_ctdb.c index a2a7c21..66b9f55 100644 --- a/source3/lib/messages_ctdb.c +++ b/source3/lib/messages_ctdb.c @@ -26,6 +26,7 @@ #include "lib/messages_util.h" #include "ctdbd_conn.h" #include "lib/cluster_support.h" +#include "ctdb_srvids.h" struct messaging_ctdb_context; @@ -111,6 +112,14 @@ int messaging_ctdb_init(const char *sockname, int timeout, uint64_t unique_id, goto fail; } + ret = register_with_ctdbd(ctx->conn, CTDB_SRVID_SAMBA_PROCESS, + messaging_ctdb_recv, ctx); + if (ret != 0) { + DBG_DEBUG("register_with_ctdbd returned %s (%d)\n", + strerror(ret), ret); + goto fail; + } + ret = register_with_ctdbd(ctx->conn, unique_id, NULL, NULL); if (ret != 0) { DBG_DEBUG("register_with_ctdbd returned %s (%d)\n", diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c index 9d87746..b9cddc2 100644 --- a/source3/lib/messages_dgm.c +++ b/source3/lib/messages_dgm.c @@ -1138,6 +1138,88 @@ static int messaging_dgm_context_destructor(struct messaging_dgm_context *c) return 0; } +static void messaging_dgm_validate(struct messaging_dgm_context *ctx) +{ +#ifdef DEVELOPER + pid_t pid = getpid(); + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(addr); + struct sockaddr_un *un_addr; + struct sun_path_buf pathbuf; + struct stat st1, st2; + int ret; + + /* + * Protect against using the wrong messaging context after a + * fork without reinit_after_fork. + */ + + ret = getsockname(ctx->sock, (struct sockaddr *)&addr, &addrlen); + if (ret == -1) { + DBG_ERR("getsockname failed: %s\n", strerror(errno)); + goto fail; + } + if (addr.ss_family != AF_UNIX) { + DBG_ERR("getsockname returned family %d\n", + (int)addr.ss_family); + goto fail; + } + un_addr = (struct sockaddr_un *)&addr; + + ret = snprintf(pathbuf.buf, sizeof(pathbuf.buf), + "%s/%u", ctx->socket_dir.buf, (unsigned)pid); + if (ret < 0) { + DBG_ERR("snprintf failed: %s\n", strerror(errno)); + goto fail; + } + if ((size_t)ret >= sizeof(pathbuf.buf)) { + DBG_ERR("snprintf returned %d chars\n", (int)ret); + goto fail; + } + + if (strcmp(pathbuf.buf, un_addr->sun_path) != 0) { + DBG_ERR("sockname wrong: Expected %s, got %s\n", + pathbuf.buf, un_addr->sun_path); + goto fail; + } + + ret = snprintf(pathbuf.buf, sizeof(pathbuf.buf), + "%s/%u", ctx->lockfile_dir.buf, (unsigned)pid); + if (ret < 0) { + DBG_ERR("snprintf failed: %s\n", strerror(errno)); + goto fail; + } + if ((size_t)ret >= sizeof(pathbuf.buf)) { + DBG_ERR("snprintf returned %d chars\n", (int)ret); + goto fail; + } + + ret = stat(pathbuf.buf, &st1); + if (ret == -1) { + DBG_ERR("stat failed: %s\n", strerror(errno)); + goto fail; + } + ret = fstat(ctx->lockfile_fd, &st2); + if (ret == -1) { + DBG_ERR("fstat failed: %s\n", strerror(errno)); + goto fail; + } + + if ((st1.st_dev != st2.st_dev) || (st1.st_ino != st2.st_ino)) { + DBG_ERR("lockfile differs, expected (%d/%d), got (%d/%d)\n", + (int)st2.st_dev, (int)st2.st_ino, + (int)st1.st_dev, (int)st1.st_ino); + goto fail; + } + + return; +fail: + abort(); +#else + return; +#endif +} + static void messaging_dgm_recv(struct messaging_dgm_context *ctx, struct tevent_context *ev, uint8_t *msg, size_t msg_len, @@ -1162,6 +1244,8 @@ static void messaging_dgm_read_handler(struct tevent_context *ev, uint8_t msgbuf[msgbufsize]; uint8_t buf[MESSAGING_DGM_FRAGMENT_LENGTH]; + messaging_dgm_validate(ctx); + if ((flags & TEVENT_FD_READ) == 0) { return; } @@ -1336,6 +1420,8 @@ int messaging_dgm_send(pid_t pid, return ENOTCONN; } + messaging_dgm_validate(ctx); + ret = messaging_dgm_out_get(ctx, pid, &out); if (ret != 0) { return ret; @@ -1385,6 +1471,8 @@ int messaging_dgm_get_unique(pid_t pid, uint64_t *unique) return EBADF; } + messaging_dgm_validate(ctx); + if (pid == getpid()) { /* * Protect against losing our own lock @@ -1474,18 +1562,46 @@ int messaging_dgm_cleanup(pid_t pid) return 0; } +static int messaging_dgm_wipe_fn(pid_t pid, void *private_data) +{ + pid_t *our_pid = (pid_t *)private_data; + int ret; + + if (pid == *our_pid) { + /* + * fcntl(F_GETLK) will succeed for ourselves, we hold + * that lock ourselves. + */ + return 0; + } + + ret = messaging_dgm_cleanup(pid); + DEBUG(10, ("messaging_dgm_cleanup(%lu) returned %s\n", + (unsigned long)pid, ret ? strerror(ret) : "ok")); + + return 0; +} + int messaging_dgm_wipe(void) { + pid_t pid = getpid(); + messaging_dgm_forall(messaging_dgm_wipe_fn, &pid); + return 0; +} + +int messaging_dgm_forall(int (*fn)(pid_t pid, void *private_data), + void *private_data) +{ struct messaging_dgm_context *ctx = global_dgm_context; DIR *msgdir; struct dirent *dp; - pid_t our_pid = getpid(); - int ret; if (ctx == NULL) { return ENOTCONN; } + messaging_dgm_validate(ctx); + /* * We scan the socket directory and not the lock directory. Otherwise * we would race against messaging_dgm_lockfile_create's open(O_CREAT) @@ -1499,6 +1615,7 @@ int messaging_dgm_wipe(void) while ((dp = readdir(msgdir)) != NULL) { unsigned long pid; + int ret; pid = strtoul(dp->d_name, NULL, 10); if (pid == 0) { @@ -1507,17 +1624,11 @@ int messaging_dgm_wipe(void) */ continue; } - if ((pid_t)pid == our_pid) { - /* - * fcntl(F_GETLK) will succeed for ourselves, we hold - * that lock ourselves. - */ - continue; - } - ret = messaging_dgm_cleanup(pid); - DEBUG(10, ("messaging_dgm_cleanup(%lu) returned %s\n", - pid, ret ? strerror(ret) : "ok")); + ret = fn(pid, private_data); + if (ret != 0) { + break; + } } closedir(msgdir); diff --git a/source3/lib/messages_dgm.h b/source3/lib/messages_dgm.h index ca11db1..7221c72 100644 --- a/source3/lib/messages_dgm.h +++ b/source3/lib/messages_dgm.h @@ -42,6 +42,8 @@ int messaging_dgm_send(pid_t pid, const int *fds, size_t num_fds); int messaging_dgm_cleanup(pid_t pid); int messaging_dgm_wipe(void); +int messaging_dgm_forall(int (*fn)(pid_t pid, void *private_data), + void *private_data); struct messaging_dgm_fde; struct messaging_dgm_fde *messaging_dgm_register_tevent_context( diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c index 7300448..b4125cb 100644 --- a/source3/lib/serverid.c +++ b/source3/lib/serverid.c @@ -18,157 +18,13 @@ */ #include "includes.h" -#include "system/filesys.h" #include "lib/util/server_id.h" #include "serverid.h" -#include "util_tdb.h" -#include "dbwrap/dbwrap.h" -#include "dbwrap/dbwrap_open.h" -#include "lib/tdb_wrap/tdb_wrap.h" #include "lib/param/param.h" #include "ctdbd_conn.h" -#include "messages.h" #include "lib/messages_ctdb.h" #include "lib/messages_dgm.h" -struct serverid_key { - pid_t pid; - uint32_t task_id; - uint32_t vnn; -}; - -struct serverid_data { - uint64_t unique_id; - uint32_t msg_flags; -}; - -static struct db_context *serverid_db(void) -{ - static struct db_context *db; - char *db_path; - - if (db != NULL) { - return db; - } - - db_path = lock_path("serverid.tdb"); - if (db_path == NULL) { -- Samba Shared Repository