From 2922fdaaf0ab2178a1701141cc2435af33c10dc8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Jul 2012 15:41:52 -0700 Subject: Move source4/smbd/pidfile into lib/util in preparation for making it in common. --- lib/util/pidfile.c | 131 ++++++++++++++++++++++++++++++++++++++++++++ lib/util/pidfile.h | 26 +++++++++ lib/util/wscript_build | 2 +- source3/include/proto.h | 6 +- source3/lib/pidfile.c | 8 +-- source3/libsmb/clidgram.c | 2 +- source3/nmbd/nmbd.c | 4 +- source3/smbd/server.c | 2 +- source3/smbd/server_exit.c | 2 +- source3/utils/smbcontrol.c | 2 +- source3/web/startstop.c | 6 +- source3/web/statuspage.c | 2 +- source3/winbindd/winbindd.c | 4 +- source4/smbd/pidfile.c | 131 -------------------------------------------- source4/smbd/server.c | 2 +- source4/smbd/wscript_build | 8 +-- 16 files changed, 179 insertions(+), 159 deletions(-) create mode 100644 lib/util/pidfile.c create mode 100644 lib/util/pidfile.h delete mode 100644 source4/smbd/pidfile.c diff --git a/lib/util/pidfile.c b/lib/util/pidfile.c new file mode 100644 index 0000000000..ac8ff8a0c3 --- /dev/null +++ b/lib/util/pidfile.c @@ -0,0 +1,131 @@ +/* this code is broken - there is a race condition with the unlink (tridge) */ + +/* + Unix SMB/CIFS implementation. + pidfile handling + Copyright (C) Andrew Tridgell 1998 + + 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 . +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/util/pidfile.h" + +/** + * @file + * @brief Pid file handling + */ + +/** + * return the pid in a pidfile. return 0 if the process (or pidfile) + * does not exist + */ +pid_t pidfile_pid(const char *piddir, const char *name) +{ + int fd; + char pidstr[20]; + pid_t ret; + char *pidFile; + + if (asprintf(&pidFile, "%s/%s.pid", piddir, name) < 0) { + return 0; + } + + fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644); + + if (fd == -1) { + SAFE_FREE(pidFile); + return 0; + } + + ZERO_STRUCT(pidstr); + + if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) { + goto noproc; + } + + ret = (pid_t)atoi(pidstr); + if (ret <= 0) { + goto noproc; + } + + if (!process_exists_by_pid(ret)) { + goto noproc; + } + + if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) { + /* we could get the lock - it can't be a Samba process */ + goto noproc; + } + + close(fd); + SAFE_FREE(pidFile); + return ret; + + noproc: + close(fd); + unlink(pidFile); + SAFE_FREE(pidFile); + return 0; +} + +/** + * create a pid file in the pid directory. open it and leave it locked + */ +void pidfile_create(const char *piddir, const char *name) +{ + int fd; + char buf[20]; + char *pidFile; + pid_t pid; + + if (asprintf(&pidFile, "%s/%s.pid", piddir, name) < 0) { + DEBUG(0,("ERROR: Out of memory\n")); + exit(1); + } + + pid = pidfile_pid(piddir, name); + if (pid != 0) { + DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", + name, pidFile, (int)pid)); + exit(1); + } + + fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644); + if (fd == -1) { + DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, + strerror(errno))); + exit(1); + } + + smb_set_close_on_exec(fd); + + if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==false) { + DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n", + name, pidFile, strerror(errno))); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) getpid()); + if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { + DEBUG(0,("ERROR: can't write to file %s: %s\n", + pidFile, strerror(errno))); + exit(1); + } + + /* Leave pid file open & locked for the duration... */ + SAFE_FREE(pidFile); +} diff --git a/lib/util/pidfile.h b/lib/util/pidfile.h new file mode 100644 index 0000000000..92a277d820 --- /dev/null +++ b/lib/util/pidfile.h @@ -0,0 +1,26 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jeremy Allison 2012. + + 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 . +*/ + +#ifndef _SAMBA_PIDFILE_H_ +#define _SAMBA_PIDFILE_H_ + +pid_t pidfile_pid(const char *piddir, const char *name); +void pidfile_create(const char *piddir, const char *program_name); + +#endif diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 340cf12cd4..ddaf90ffc2 100755 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -7,7 +7,7 @@ bld.SAMBA_LIBRARY('samba-util', signal.c system.c params.c util.c util_id.c util_net.c util_strlist.c util_paths.c idtree.c debug.c fault.c base64.c util_str.c util_str_common.c substitute.c ms_fnmatch.c - server_id.c dprintf.c parmlist.c bitmap.c''', + server_id.c dprintf.c parmlist.c bitmap.c pidfile.c''', deps='DYNCONFIG', public_deps='talloc execinfo uid_wrapper pthread LIBCRYPTO charset util_setid', public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h xfile.h dlinklist.h samba_util.h string_wrappers.h', diff --git a/source3/include/proto.h b/source3/include/proto.h index 4d99a607e3..b58f9a2945 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -160,9 +160,9 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern, /* The following definitions come from lib/pidfile.c */ -pid_t pidfile_pid(const char *name); -void pidfile_create(const char *program_name); -void pidfile_unlink(void); +pid_t pidfile_pid_s3(const char *name); +void pidfile_create_s3(const char *program_name); +void pidfile_unlink_s3(void); /* The following definitions come from lib/recvfile.c */ diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c index 987ab068e7..1170f876c3 100644 --- a/source3/lib/pidfile.c +++ b/source3/lib/pidfile.c @@ -30,7 +30,7 @@ static char *pidFile_name = NULL; /* return the pid in a pidfile. return 0 if the process (or pidfile) does not exist */ -pid_t pidfile_pid(const char *program_name) +pid_t pidfile_pid_s3(const char *program_name) { int fd; char pidstr[20]; @@ -115,7 +115,7 @@ pid_t pidfile_pid(const char *program_name) } /* create a pid file in the pid directory. open it and leave it locked */ -void pidfile_create(const char *program_name) +void pidfile_create_s3(const char *program_name) { int fd; char buf[20]; @@ -146,7 +146,7 @@ void pidfile_create(const char *program_name) smb_panic("asprintf failed"); } - pid = pidfile_pid(program_name); + pid = pidfile_pid_s3(program_name); if (pid != 0) { DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", name, pidFile_name, (int)pid)); @@ -181,7 +181,7 @@ void pidfile_create(const char *program_name) fcntl(fd, F_SETFD, FD_CLOEXEC); } -void pidfile_unlink(void) +void pidfile_unlink_s3(void) { if (pidFile_name == NULL) { return; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 377219448b..d9de99eb04 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -327,7 +327,7 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->my_mailslot, req)) { return tevent_req_post(req, ev); } - state->nmbd_pid = pidfile_pid("nmbd"); + state->nmbd_pid = pidfile_pid_s3("nmbd"); if (state->nmbd_pid == 0) { DEBUG(3, ("No nmbd found\n")); tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index ebe83a6147..35ed3c0d92 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -70,7 +70,7 @@ static void terminate(struct messaging_context *msg) gencache_stabilize(); serverid_deregister(messaging_server_id(msg)); - pidfile_unlink(); + pidfile_unlink_s3(); exit(0); } @@ -942,7 +942,7 @@ static bool open_sockets(bool isdaemon, int port) mkdir(lp_piddir(), 0755); } - pidfile_create("nmbd"); + pidfile_create_s3("nmbd"); status = reinit_after_fork(msg, nmbd_event_context(), false); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index f7f1d8c715..ee1eafb0dc 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -1285,7 +1285,7 @@ extern void build_options(bool screen); mkdir(lp_piddir(), 0755); if (is_daemon) - pidfile_create("smbd"); + pidfile_create_s3("smbd"); status = reinit_after_fork(msg_ctx, ev_ctx, diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c index 07b8432bff..86a621f551 100644 --- a/source3/smbd/server_exit.c +++ b/source3/smbd/server_exit.c @@ -216,7 +216,7 @@ static void exit_server_common(enum server_exit_reason how, DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { - pidfile_unlink(); + pidfile_unlink_s3(); } gencache_stabilize(); } diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 54e10d8b42..dbbd8049de 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -1365,7 +1365,7 @@ static struct server_id parse_dest(struct messaging_context *msg, /* Look up other destinations in pidfile directory */ - if ((pid = pidfile_pid(dest)) != 0) { + if ((pid = pidfile_pid_s3(dest)) != 0) { return pid_to_procid(pid); } diff --git a/source3/web/startstop.c b/source3/web/startstop.c index e23acf8931..ef2871ccd3 100644 --- a/source3/web/startstop.c +++ b/source3/web/startstop.c @@ -86,7 +86,7 @@ void start_winbindd(void) /* stop smbd */ void stop_smbd(void) { - pid_t pid = pidfile_pid("smbd"); + pid_t pid = pidfile_pid_s3("smbd"); if (geteuid() != 0) return; @@ -98,7 +98,7 @@ void stop_smbd(void) /* stop nmbd */ void stop_nmbd(void) { - pid_t pid = pidfile_pid("nmbd"); + pid_t pid = pidfile_pid_s3("nmbd"); if (geteuid() != 0) return; @@ -110,7 +110,7 @@ void stop_nmbd(void) /* stop winbindd */ void stop_winbindd(void) { - pid_t pid = pidfile_pid("winbindd"); + pid_t pid = pidfile_pid_s3("winbindd"); if (geteuid() != 0) return; diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index 8eac8036d0..d04554901c 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -253,7 +253,7 @@ void status_page(void) TALLOC_CTX *ctx = talloc_stackframe(); const char form_name[] = "status"; - smbd_pid = pid_to_procid(pidfile_pid("smbd")); + smbd_pid = pid_to_procid(pidfile_pid_s3("smbd")); if (!verify_xsrf_token(form_name)) { goto output_page; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index fe6e34b4b9..dfbcf13eb4 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -184,7 +184,7 @@ static void terminate(bool is_parent) if (is_parent) { serverid_deregister(procid_self()); - pidfile_unlink(); + pidfile_unlink_s3(); } exit(0); @@ -1449,7 +1449,7 @@ int main(int argc, char **argv, char **envp) if (!interactive) become_daemon(Fork, no_process_group, log_stdout); - pidfile_create("winbindd"); + pidfile_create_s3("winbindd"); #if HAVE_SETPGID /* diff --git a/source4/smbd/pidfile.c b/source4/smbd/pidfile.c deleted file mode 100644 index 32d3964302..0000000000 --- a/source4/smbd/pidfile.c +++ /dev/null @@ -1,131 +0,0 @@ -/* this code is broken - there is a race condition with the unlink (tridge) */ - -/* - Unix SMB/CIFS implementation. - pidfile handling - Copyright (C) Andrew Tridgell 1998 - - 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 . -*/ - -#include "includes.h" -#include "system/filesys.h" -#include "smbd/pidfile.h" - -/** - * @file - * @brief Pid file handling - */ - -/** - * return the pid in a pidfile. return 0 if the process (or pidfile) - * does not exist - */ -pid_t pidfile_pid(const char *piddir, const char *name) -{ - int fd; - char pidstr[20]; - pid_t ret; - char *pidFile; - - if (asprintf(&pidFile, "%s/%s.pid", piddir, name) < 0) { - return 0; - } - - fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644); - - if (fd == -1) { - SAFE_FREE(pidFile); - return 0; - } - - ZERO_STRUCT(pidstr); - - if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) { - goto noproc; - } - - ret = (pid_t)atoi(pidstr); - if (ret <= 0) { - goto noproc; - } - - if (!process_exists_by_pid(ret)) { - goto noproc; - } - - if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) { - /* we could get the lock - it can't be a Samba process */ - goto noproc; - } - - close(fd); - SAFE_FREE(pidFile); - return ret; - - noproc: - close(fd); - unlink(pidFile); - SAFE_FREE(pidFile); - return 0; -} - -/** - * create a pid file in the pid directory. open it and leave it locked - */ -void pidfile_create(const char *piddir, const char *name) -{ - int fd; - char buf[20]; - char *pidFile; - pid_t pid; - - if (asprintf(&pidFile, "%s/%s.pid", piddir, name) < 0) { - DEBUG(0,("ERROR: Out of memory\n")); - exit(1); - } - - pid = pidfile_pid(piddir, name); - if (pid != 0) { - DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", - name, pidFile, (int)pid)); - exit(1); - } - - fd = open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644); - if (fd == -1) { - DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, - strerror(errno))); - exit(1); - } - - smb_set_close_on_exec(fd); - - if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==false) { - DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n", - name, pidFile, strerror(errno))); - exit(1); - } - - memset(buf, 0, sizeof(buf)); - slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) getpid()); - if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) { - DEBUG(0,("ERROR: can't write to file %s: %s\n", - pidFile, strerror(errno))); - exit(1); - } - - /* Leave pid file open & locked for the duration... */ - SAFE_FREE(pidFile); -} diff --git a/source4/smbd/server.c b/source4/smbd/server.c index 21560f981f..a6ebcd65d8 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -34,7 +34,7 @@ #include "libcli/auth/schannel.h" #include "smbd/process_model.h" #include "param/secrets.h" -#include "smbd/pidfile.h" +#include "lib/util/pidfile.h" #include "param/param.h" #include "dsdb/samdb/samdb.h" #include "auth/session.h" diff --git a/source4/smbd/wscript_build b/source4/smbd/wscript_build index 97877fc54b..bfa13121f2 100644 --- a/source4/smbd/wscript_build +++ b/source4/smbd/wscript_build @@ -9,12 +9,6 @@ bld.SAMBA_LIBRARY('service', ) -bld.SAMBA_SUBSYSTEM('PIDFILE', - source='pidfile.c', - deps='talloc', - autoproto='pidfile.h' - ) - bld.SAMBA_LIBRARY('process_model', source='process_model.c', autoproto='process_model_proto.h', @@ -27,7 +21,7 @@ bld.SAMBA_BINARY('samba', source='server.c', manpages='samba.8', subsystem_name='service', - deps='''events process_model service samba-hostconfig samba-util POPT_SAMBA PIDFILE + deps='''events process_model service samba-hostconfig samba-util POPT_SAMBA popt gensec registry ntptr ntvfs share cluster COMMON_SCHANNEL SECRETS''', pyembed=True, install_path='${SBINDIR}', -- cgit