The branch, v4-5-test has been updated via 416d062 ctdb-daemon: Log when removing stale Unix domain socket via 14313b0 ctdb-daemon: Drop attempt to connect to Unix domain socket via 8866233 ctdb-daemon: Don't try to reopen TDB files via 2ebed56 ctdb-daemon: Bind to Unix domain socket after PID file creation via 81d8f89 ctdb-daemon: Use PID file abstraction via a1a1fe4 ctdb-common: Add routines to manage PID file via aefc593 s3-spoolss: fix winreg_printer_ver_to_qword via a23ff4c nsswitch: Also set h_errnop for nss_wins functions via 568f9fb nsswitch: Add missing arguments to wins gethostbyname* via 62f4e3d s3/smbd: set FILE_ATTRIBUTE_DIRECTORY as necessary via 5bd28ff gencache: Bail out of stabilize if we can not get the allrecord lock from 68302ce ctdb-recovery-helper: Add missing initialisation of ban_credits
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-5-test - Log ----------------------------------------------------------------- commit 416d062225f51edbb5461d90aceb211ded763582 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Sep 22 14:52:55 2016 +1000 ctdb-daemon: Log when removing stale Unix domain socket BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Amitay Isaacs <ami...@samba.org> Autobuild-Date(master): Thu Sep 22 12:28:12 CEST 2016 on sn-devel-144 (cherry picked from commit 0ec01826d32019b06dd10bb9b6ea5232786d5699) Autobuild-User(v4-5-test): Stefan Metzmacher <me...@samba.org> Autobuild-Date(v4-5-test): Thu Oct 13 20:46:42 CEST 2016 on sn-devel-144 commit 14313b0d57edc027d2c3b375071daf4a70e01752 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Sep 22 14:47:02 2016 +1000 ctdb-daemon: Drop attempt to connect to Unix domain socket This was a weak attempt at exclusivity. PID file creation now does that properly. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 8eff9e96037627b1e4adf3ccc8da94ef8f0bad2a) commit 8866233e5d3d4d14d7d1738b14bea2cb92e98652 Author: Martin Schwenke <mar...@meltin.net> Date: Thu Sep 22 14:46:12 2016 +1000 ctdb-daemon: Don't try to reopen TDB files There aren't any open at this stage. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit d719a87fe021b0c704fc4b12ddfc0345fe3af146) commit 2ebed563e42000de8327797b76e446bab70102ad Author: Martin Schwenke <mar...@meltin.net> Date: Thu Sep 22 14:43:58 2016 +1000 ctdb-daemon: Bind to Unix domain socket after PID file creation No use touching the socket if PID file creation fails. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 1e501c77492d25b760c7b10849460ee6490f39dc) commit 81d8f89385fcf1e79a3c9d7b1fbab1cd696a03ee Author: Martin Schwenke <mar...@meltin.net> Date: Thu Sep 22 14:35:03 2016 +1000 ctdb-daemon: Use PID file abstraction BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 5148e02adb7b2ea34da9c826a682c1387773402b) commit a1a1fe45533edaee94923e6cf2978e186e612a14 Author: Amitay Isaacs <ami...@gmail.com> Date: Mon Sep 19 16:30:12 2016 +1000 ctdb-common: Add routines to manage PID file BUG: https://bugzilla.samba.org/show_bug.cgi?id=12287 Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (cherry picked from commit 97b6ac7f662d8de316ed520e038779e79bcdb7bc) commit aefc59359d980ebb7ea4b75219dad0e62ff52ab0 Author: Günther Deschner <g...@samba.org> Date: Mon Sep 12 17:55:37 2016 +0200 s3-spoolss: fix winreg_printer_ver_to_qword Bug: https://bugzilla.samba.org/show_bug.cgi?id=12285 We were reporting the OS minor number as the driver version number in all GetDriver/EnumDriver calls. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> (cherry picked from commit a9a1a16cc8b87a84cdfa049ebd26bf4eac1b3618) commit a23ff4c66c3dd45616da8beb40e4e9eda7f74a7d Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 20 13:26:52 2016 +0200 nsswitch: Also set h_errnop for nss_wins functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=12269 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jim McDonough <j...@samba.org> (cherry picked from commit 382345126c56e26d3dbc319f1c7c1dae3c4fafc9) commit 568f9fb5b0772b744ac9c6092dc7e35720e42cdf Author: Andreas Schneider <a...@samba.org> Date: Mon Sep 19 16:17:11 2016 +0200 nsswitch: Add missing arguments to wins gethostbyname* The errno pointer argument is missing. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12269 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Jim McDonough <j...@samba.org> (cherry picked from commit 124ae4e861f048fe015bff32ace4abff4d3e6c62) commit 62f4e3dda9c5835659d2ba76b83c55a0e6e42db5 Author: Ralph Boehme <s...@samba.org> Date: Wed Sep 14 12:52:48 2016 +0200 s3/smbd: set FILE_ATTRIBUTE_DIRECTORY as necessary Some VFS modules like GPFS will always return success from SMB_VFS_GET_DOS_ATTRIBUTES() but only set a subset of the attributes. It neither sets FILE_ATTRIBUTE_NORMAL nor FILE_ATTRIBUTE_DIRECTORY. We already handle the case that the VFS stack returns with result==0 and then add the FILE_ATTRIBUTE_NORMAL, regardless of the type of the filesystem object. If we want to handle result==0 situation in the SMB_VFS_GET_DOS_ATTRIBUTES() caller, then do it right by either setting FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_DIRECTORY. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12261 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Fri Sep 16 00:34:43 CEST 2016 on sn-devel-144 (cherry picked from commit 2a2ac63975b8ff41ede8e93ef2b33148c89f185f) commit 5bd28ffcf5bb20bc4f3b9c359d99dd2751fe6c93 Author: Volker Lendecke <v...@samba.org> Date: Mon Sep 19 14:29:21 2016 -0700 gencache: Bail out of stabilize if we can not get the allrecord lock Bug: https://bugzilla.samba.org/show_bug.cgi?id=12045 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 Sep 20 04:09:33 CEST 2016 on sn-devel-144 (cherry picked from commit b208499960eefef02d305a3bd59b03a7c2aafcac) ----------------------------------------------------------------------- Summary of changes: ctdb/common/pidfile.c | 143 +++++++++++++++++++ ctdb/common/pidfile.h | 51 +++++++ ctdb/server/ctdb_daemon.c | 66 ++++----- ctdb/tests/cunit/pidfile_test_001.sh | 8 ++ ctdb/tests/src/pidfile_test.c | 241 ++++++++++++++++++++++++++++++++ ctdb/wscript | 4 +- nsswitch/wins.c | 60 ++++++-- source3/lib/gencache.c | 2 +- source3/rpc_client/cli_winreg_spoolss.c | 7 +- source3/smbd/dosmode.c | 6 +- 10 files changed, 533 insertions(+), 55 deletions(-) create mode 100644 ctdb/common/pidfile.c create mode 100644 ctdb/common/pidfile.h create mode 100755 ctdb/tests/cunit/pidfile_test_001.sh create mode 100644 ctdb/tests/src/pidfile_test.c Changeset truncated at 500 lines: diff --git a/ctdb/common/pidfile.c b/ctdb/common/pidfile.c new file mode 100644 index 0000000..b3f29e3 --- /dev/null +++ b/ctdb/common/pidfile.c @@ -0,0 +1,143 @@ +/* + Create and remove pidfile + + Copyright (C) Amitay Isaacs 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "system/filesys.h" + +#include <talloc.h> + +#include "common/pidfile.h" + +struct pidfile_context { + const char *pidfile; + int fd; + pid_t pid; +}; + +static int pidfile_context_destructor(struct pidfile_context *pid_ctx); + +int pidfile_create(TALLOC_CTX *mem_ctx, const char *pidfile, + struct pidfile_context **result) +{ + struct pidfile_context *pid_ctx; + struct flock lck; + char tmp[64]; + int fd, ret = 0; + int len; + ssize_t nwritten; + + pid_ctx = talloc_zero(mem_ctx, struct pidfile_context); + if (pid_ctx == NULL) { + return ENOMEM; + } + + pid_ctx->pidfile = talloc_strdup(pid_ctx, pidfile); + if (pid_ctx->pidfile == NULL) { + ret = ENOMEM; + goto fail; + } + + pid_ctx->pid = getpid(); + + fd = open(pidfile, O_CREAT|O_WRONLY|O_NONBLOCK, 0644); + if (fd == -1) { + ret = errno; + goto fail; + } + + pid_ctx->fd = fd; + + lck = (struct flock) { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + }; + + do { + ret = fcntl(fd, F_SETLK, &lck); + } while ((ret == -1) && (errno == EINTR)); + + if (ret != 0) { + ret = errno; + goto fail; + } + + do { + ret = ftruncate(fd, 0); + } while ((ret == -1) && (errno == EINTR)); + + if (ret == -1) { + ret = EIO; + goto fail_unlink; + } + + len = snprintf(tmp, sizeof(tmp), "%u\n", pid_ctx->pid); + if (len < 0) { + ret = EIO; + goto fail_unlink; + } + + do { + nwritten = write(fd, tmp, len); + } while ((nwritten == -1) && (errno == EINTR)); + + if ((nwritten == -1) || (nwritten != len)) { + ret = EIO; + goto fail_unlink; + } + + talloc_set_destructor(pid_ctx, pidfile_context_destructor); + + *result = pid_ctx; + return 0; + +fail_unlink: + unlink(pidfile); + close(fd); + +fail: + talloc_free(pid_ctx); + return ret; +} + +static int pidfile_context_destructor(struct pidfile_context *pid_ctx) +{ + struct flock lck; + int ret; + + if (getpid() != pid_ctx->pid) { + return 0; + } + + lck = (struct flock) { + .l_type = F_UNLCK, + .l_whence = SEEK_SET, + }; + + (void) unlink(pid_ctx->pidfile); + + do { + ret = fcntl(pid_ctx->fd, F_SETLK, &lck); + } while ((ret == -1) && (errno == EINTR)); + + do { + ret = close(pid_ctx->fd); + } while ((ret == -1) && (errno == EINTR)); + + return 0; +} diff --git a/ctdb/common/pidfile.h b/ctdb/common/pidfile.h new file mode 100644 index 0000000..1450134 --- /dev/null +++ b/ctdb/common/pidfile.h @@ -0,0 +1,51 @@ +/* + Create and remove pidfile + + Copyright (C) Amitay Isaacs 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CTDB_PIDFILE_H__ +#define __CTDB_PIDFILE_H__ + +#include <talloc.h> + +/** + * @file pidfile.h + * + * @brief Routines to manage PID file + */ + +/** + * @brief Abstract struct to store pidfile details + */ +struct pidfile_context; + +/** + * @brief Create a PID file + * + * This creates a PID file, locks it, and writes PID. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] pidfile Path of PID file + * @param[out] result Pidfile context + * @return 0 on success, errno on failure + * + * Freeing the pidfile_context, will delete the pidfile. + */ +int pidfile_create(TALLOC_CTX *mem_ctx, const char *pidfile, + struct pidfile_context **result); + +#endif /* __CTDB_PIDFILE_H__ */ diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index 47e49df..8cd5bba 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -44,6 +44,7 @@ #include "common/system.h" #include "common/common.h" #include "common/logging.h" +#include "common/pidfile.h" struct ctdb_client_pid_list { struct ctdb_client_pid_list *next, *prev; @@ -53,6 +54,7 @@ struct ctdb_client_pid_list { }; const char *ctdbd_pidfile = NULL; +static struct pidfile_context *ctdbd_pidfile_ctx = NULL; static void daemon_incoming_packet(void *, struct ctdb_req_header *); @@ -1005,17 +1007,16 @@ static int ux_socket_bind(struct ctdb_context *ctdb) addr.sun_family = AF_UNIX; strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path)-1); - /* First check if an old ctdbd might be running */ - if (connect(ctdb->daemon.sd, - (struct sockaddr *)&addr, sizeof(addr)) == 0) { - DEBUG(DEBUG_CRIT, - ("Something is already listening on ctdb socket '%s'\n", - ctdb->daemon.name)); - goto failed; - } - /* Remove any old socket */ - unlink(ctdb->daemon.name); + ret = unlink(ctdb->daemon.name); + if (ret == 0) { + DEBUG(DEBUG_WARNING, + ("Removed stale socket %s\n", ctdb->daemon.name)); + } else if (errno != ENOENT) { + DEBUG(DEBUG_ERR, + ("Failed to remove stale socket %s\n", ctdb->daemon.name)); + return -1; + } set_close_on_exec(ctdb->daemon.sd); @@ -1149,32 +1150,21 @@ static void ctdb_tevent_trace(enum tevent_trace_point tp, static void ctdb_remove_pidfile(void) { - /* Only the main ctdbd's PID matches the SID */ - if (ctdbd_pidfile != NULL && getsid(0) == getpid()) { - if (unlink(ctdbd_pidfile) == 0) { - DEBUG(DEBUG_NOTICE, ("Removed PID file %s\n", - ctdbd_pidfile)); - } else { - DEBUG(DEBUG_WARNING, ("Failed to Remove PID file %s\n", - ctdbd_pidfile)); - } - } + TALLOC_FREE(ctdbd_pidfile_ctx); } -static void ctdb_create_pidfile(pid_t pid) +static void ctdb_create_pidfile(TALLOC_CTX *mem_ctx) { if (ctdbd_pidfile != NULL) { - FILE *fp; - - fp = fopen(ctdbd_pidfile, "w"); - if (fp == NULL) { - DEBUG(DEBUG_ALERT, - ("Failed to open PID file %s\n", ctdbd_pidfile)); + int ret = pidfile_create(mem_ctx, ctdbd_pidfile, + &ctdbd_pidfile_ctx); + if (ret != 0) { + DEBUG(DEBUG_ERR, + ("Failed to create PID file %s\n", + ctdbd_pidfile)); exit(11); } - fprintf(fp, "%d\n", pid); - fclose(fp); DEBUG(DEBUG_NOTICE, ("Created PID file %s\n", ctdbd_pidfile)); atexit(ctdb_remove_pidfile); } @@ -1236,19 +1226,10 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork) int res, ret = -1; struct tevent_fd *fde; - /* create a unix domain stream socket to listen to */ - res = ux_socket_bind(ctdb); - if (res!=0) { - DEBUG(DEBUG_ALERT,("Cannot continue. Exiting!\n")); - exit(10); - } - if (do_fork && fork()) { return 0; } - tdb_reopen_all(false); - if (do_fork) { if (setsid() == -1) { ctdb_die(ctdb, "Failed to setsid()\n"); @@ -1265,7 +1246,14 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork) ctdb->ctdbd_pid = getpid(); DEBUG(DEBUG_ERR, ("Starting CTDBD (Version %s) as PID: %u\n", CTDB_VERSION_STRING, ctdb->ctdbd_pid)); - ctdb_create_pidfile(ctdb->ctdbd_pid); + ctdb_create_pidfile(ctdb); + + /* create a unix domain stream socket to listen to */ + res = ux_socket_bind(ctdb); + if (res!=0) { + DEBUG(DEBUG_ALERT,("Cannot continue. Exiting!\n")); + exit(10); + } /* Make sure we log something when the daemon terminates. * This must be the first exit handler to run (so the last to diff --git a/ctdb/tests/cunit/pidfile_test_001.sh b/ctdb/tests/cunit/pidfile_test_001.sh new file mode 100755 index 0000000..620682e --- /dev/null +++ b/ctdb/tests/cunit/pidfile_test_001.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +pidfile=$(mktemp --tmpdir="$TEST_VAR_DIR") + +ok_null +unit_test pidfile_test $pidfile diff --git a/ctdb/tests/src/pidfile_test.c b/ctdb/tests/src/pidfile_test.c new file mode 100644 index 0000000..ad8bf14 --- /dev/null +++ b/ctdb/tests/src/pidfile_test.c @@ -0,0 +1,241 @@ +/* + pidfile tests + + Copyright (C) Amitay Isaacs 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "system/wait.h" + +#include <assert.h> + +#include "common/pidfile.c" + + +/* create pid file, check pid file exists, check pid and remove pid file */ +static void test1(const char *pidfile) +{ + struct pidfile_context *pid_ctx; + int ret; + struct stat st; + FILE *fp; + pid_t pid; + + ret = pidfile_create(NULL, pidfile, &pid_ctx); + assert(ret == 0); + assert(pid_ctx != NULL); + + ret = stat(pidfile, &st); + assert(ret == 0); + assert(S_ISREG(st.st_mode)); + + fp = fopen(pidfile, "r"); + ret = fscanf(fp, "%d", &pid); + assert(ret == 1); + assert(pid == getpid()); + fclose(fp); + + TALLOC_FREE(pid_ctx); + + ret = stat(pidfile, &st); + assert(ret == -1); +} + +/* create pid file in two processes */ +static void test2(const char *pidfile) +{ + struct pidfile_context *pid_ctx; + pid_t pid, pid2; + int fd[2]; + int ret; + size_t nread; + FILE *fp; + struct stat st; + + ret = pipe(fd); + assert(ret == 0); + + pid = fork(); + assert(pid != -1); + + if (pid == 0) { + ssize_t nwritten; + + close(fd[0]); + + ret = pidfile_create(NULL, pidfile, &pid_ctx); + assert(ret == 0); + assert(pid_ctx != NULL); + + nwritten = write(fd[1], &ret, sizeof(ret)); + assert(nwritten == sizeof(ret)); + + sleep(10); + + TALLOC_FREE(pid_ctx); + + nwritten = write(fd[1], &ret, sizeof(ret)); + assert(nwritten == sizeof(ret)); + + exit(1); + } + + close(fd[1]); + + nread = read(fd[0], &ret, sizeof(ret)); + assert(nread == sizeof(ret)); + assert(ret == 0); + + fp = fopen(pidfile, "r"); + assert(fp != NULL); + ret = fscanf(fp, "%d", &pid2); + assert(ret == 1); + assert(pid == pid2); + fclose(fp); + + ret = pidfile_create(NULL, pidfile, &pid_ctx); + assert(ret != 0); + + nread = read(fd[0], &ret, sizeof(ret)); + assert(nread == sizeof(ret)); + assert(ret == 0); + + ret = pidfile_create(NULL, pidfile, &pid_ctx); + assert(ret == 0); + assert(pid_ctx != NULL); + + TALLOC_FREE(pid_ctx); + + ret = stat(pidfile, &st); + assert(ret == -1); +} + +/* create pid file, fork, try to remove pid file in separate process */ +static void test3(const char *pidfile) +{ + struct pidfile_context *pid_ctx; + pid_t pid; + int fd[2]; + int ret; + size_t nread; + struct stat st; + + ret = pidfile_create(NULL, pidfile, &pid_ctx); + assert(ret == 0); + assert(pid_ctx != NULL); + + ret = pipe(fd); + assert(ret == 0); + + pid = fork(); + assert(pid != -1); + + if (pid == 0) { + ssize_t nwritten; + + close(fd[0]); + -- Samba Shared Repository