Store PID before daemonizing
This commit is contained in:
parent
cca9be20b1
commit
8e9d1c3480
210
radvd-1.8.5-Use-libdaemon-for-daemonization.patch
Normal file
210
radvd-1.8.5-Use-libdaemon-for-daemonization.patch
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
From 9c0bb4965a916955bfec1c7702e25beb46157a5f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||||
|
Date: Thu, 5 Apr 2012 15:24:22 +0200
|
||||||
|
Subject: [PATCH] Use libdaemon for daemonization
|
||||||
|
|
||||||
|
The libc daemon(3) function suffers from race bewtween exiting parent
|
||||||
|
and saving PID into a file.
|
||||||
|
|
||||||
|
Using libdaemon library one can avoid this race and can simplify PID
|
||||||
|
file manipulation.
|
||||||
|
|
||||||
|
The only difference against older implementation is, the PID file will
|
||||||
|
be inspected, created, and removed only if daemonization is requested.
|
||||||
|
---
|
||||||
|
configure.ac | 6 +++
|
||||||
|
radvd.c | 109 +++++++++++++++++++++++++--------------------------------
|
||||||
|
2 files changed, 54 insertions(+), 61 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 0a6fe0d..2e001bf 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -137,9 +137,15 @@ AC_CHECK_LIB(c, inet_ntop,,
|
||||||
|
# prevent caching
|
||||||
|
unset ac_cv_lib_inet6_inet_ntop
|
||||||
|
|
||||||
|
+AC_CHECK_LIB([daemon], [daemon_fork], ,
|
||||||
|
+ AC_MSG_ERROR([Could not use libdaemon library])
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS( \
|
||||||
|
+ libdaemon/dfork.h \
|
||||||
|
+ libdaemon/dpid.h \
|
||||||
|
getopt.h \
|
||||||
|
ifaddrs.h \
|
||||||
|
machine/limits.h \
|
||||||
|
diff --git a/radvd.c b/radvd.c
|
||||||
|
index 111c21c..ec37157 100644
|
||||||
|
--- a/radvd.c
|
||||||
|
+++ b/radvd.c
|
||||||
|
@@ -23,6 +23,8 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
+#include <libdaemon/dfork.h>
|
||||||
|
+#include <libdaemon/dpid.h>
|
||||||
|
|
||||||
|
struct Interface *IfaceList = NULL;
|
||||||
|
|
||||||
|
@@ -72,6 +74,7 @@ char usage_str[] =
|
||||||
|
extern FILE *yyin;
|
||||||
|
|
||||||
|
char *conf_file = NULL;
|
||||||
|
+char *pidfile = NULL;
|
||||||
|
char *pname;
|
||||||
|
int sock = -1;
|
||||||
|
|
||||||
|
@@ -93,15 +96,14 @@ void usage(void);
|
||||||
|
int drop_root_privileges(const char *);
|
||||||
|
int readin_config(char *);
|
||||||
|
int check_conffile_perm(const char *, const char *);
|
||||||
|
-pid_t strtopid(char const * pidstr);
|
||||||
|
-void write_pid_file(char const *);
|
||||||
|
+const char *get_pidfile(void);
|
||||||
|
void main_loop(void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int c, log_method;
|
||||||
|
- char *logfile, *pidfile;
|
||||||
|
+ char *logfile;
|
||||||
|
int facility;
|
||||||
|
char *username = NULL;
|
||||||
|
char *chrootdir = NULL;
|
||||||
|
@@ -110,6 +112,7 @@ main(int argc, char *argv[])
|
||||||
|
#ifdef HAVE_GETOPT_LONG
|
||||||
|
int opt_idx;
|
||||||
|
#endif
|
||||||
|
+ pid_t pid;
|
||||||
|
|
||||||
|
pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0];
|
||||||
|
|
||||||
|
@@ -290,16 +293,45 @@ main(int argc, char *argv[])
|
||||||
|
* lets fork now...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (get_debuglevel() == 0) {
|
||||||
|
+ if (get_debuglevel() > 0) {
|
||||||
|
+ daemonize = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (daemonize) {
|
||||||
|
- /* Detach from controlling terminal */
|
||||||
|
- if (daemon(0, 0) < 0)
|
||||||
|
- perror("daemon");
|
||||||
|
+ if (daemonize) {
|
||||||
|
+ if (daemon_retval_init()) {
|
||||||
|
+ flog(LOG_ERR, "Could not initialize daemon IPC.");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pid = daemon_fork();
|
||||||
|
+ if (-1 == pid) {
|
||||||
|
+ flog(LOG_ERR, "Could not fork: %s", strerror(errno));
|
||||||
|
+ daemon_retval_done();
|
||||||
|
+ exit(1);
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- write_pid_file(pidfile);
|
||||||
|
+ if (0 < pid) {
|
||||||
|
+ if (daemon_retval_wait(0)) {
|
||||||
|
+ flog(LOG_ERR, "Could not daemonize.");
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ exit(0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ daemon_pid_file_proc = get_pidfile;
|
||||||
|
+ if (daemon_pid_file_is_running() >= 0) {
|
||||||
|
+ flog(LOG_ERR, "radvd already running, terminating.");
|
||||||
|
+ daemon_retval_send(1);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ if (daemon_pid_file_create()) {
|
||||||
|
+ flog(LOG_ERR, "Cannot create radvd PID file, terminating: %s",
|
||||||
|
+ strerror(errno));
|
||||||
|
+ daemon_retval_send(2);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ daemon_retval_send(0);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* config signal handlers
|
||||||
|
@@ -314,62 +346,17 @@ main(int argc, char *argv[])
|
||||||
|
main_loop();
|
||||||
|
flog(LOG_INFO, "sending stop adverts", pidfile);
|
||||||
|
stop_adverts();
|
||||||
|
- flog(LOG_INFO, "removing %s", pidfile);
|
||||||
|
- unlink(pidfile);
|
||||||
|
+ if (daemonize) {
|
||||||
|
+ flog(LOG_INFO, "removing %s", pidfile);
|
||||||
|
+ unlink(pidfile);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-pid_t strtopid(char const * pidstr)
|
||||||
|
-{
|
||||||
|
- return atol(pidstr);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void write_pid_file(char const * pidfile)
|
||||||
|
-{
|
||||||
|
- int fd, ret;
|
||||||
|
- char pidstr[32];
|
||||||
|
-
|
||||||
|
- if ((fd = open(pidfile, O_RDONLY, 0)) > 0)
|
||||||
|
- {
|
||||||
|
- ret = read(fd, pidstr, sizeof(pidstr) - 1);
|
||||||
|
- if (ret < 0)
|
||||||
|
- {
|
||||||
|
- flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno));
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
- if (ret > 0) {
|
||||||
|
- pid_t pid;
|
||||||
|
- pidstr[ret] = '\0';
|
||||||
|
- pid = strtopid(pidstr);
|
||||||
|
- if (pid > 0 && !kill(pid, 0)) {
|
||||||
|
- flog(LOG_ERR, "radvd already running, terminating.");
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- close(fd);
|
||||||
|
- fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644);
|
||||||
|
- }
|
||||||
|
- else /* FIXME: not atomic if pidfile is on an NFS mounted volume */
|
||||||
|
- fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644);
|
||||||
|
-
|
||||||
|
- if (fd < 0)
|
||||||
|
- {
|
||||||
|
- flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno));
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid());
|
||||||
|
-
|
||||||
|
- ret = write(fd, pidstr, strlen(pidstr));
|
||||||
|
- if (ret != strlen(pidstr))
|
||||||
|
- {
|
||||||
|
- flog(LOG_ERR, "cannot write radvd pid file, terminating: %s", strerror(errno));
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- close(fd);
|
||||||
|
+const char *get_pidfile(void) {
|
||||||
|
+ return pidfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_loop(void)
|
||||||
|
--
|
||||||
|
1.7.7.6
|
||||||
|
|
66
radvd-1.8.5-Use-pkg-config-to-discover-libdaemon.patch
Normal file
66
radvd-1.8.5-Use-pkg-config-to-discover-libdaemon.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From 1cda2ef33f505be34e690d1b7a1e5eac632819af Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||||
|
Date: Wed, 11 Apr 2012 13:52:24 +0200
|
||||||
|
Subject: [PATCH] Use pkg-config to discover libdaemon
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile.am | 6 +++++-
|
||||||
|
README | 2 ++
|
||||||
|
configure.ac | 6 +-----
|
||||||
|
3 files changed, 8 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 4b76a97..04b834b 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -59,8 +59,12 @@ EXTRA_radvd_SOURCES = \
|
||||||
|
netlink.h \
|
||||||
|
privsep-linux.c
|
||||||
|
|
||||||
|
+radvd_CPPFLAGS = \
|
||||||
|
+ @DAEMON_CFLAGS@
|
||||||
|
+
|
||||||
|
radvd_LDADD = \
|
||||||
|
- @CONDITIONAL_SOURCES@
|
||||||
|
+ @CONDITIONAL_SOURCES@ \
|
||||||
|
+ @DAEMON_LIBS@
|
||||||
|
|
||||||
|
radvd_DEPENDENCIES = \
|
||||||
|
@CONDITIONAL_SOURCES@
|
||||||
|
diff --git a/README b/README
|
||||||
|
index 5192c52..efa3154 100644
|
||||||
|
--- a/README
|
||||||
|
+++ b/README
|
||||||
|
@@ -2,6 +2,8 @@
|
||||||
|
Installation:
|
||||||
|
=============
|
||||||
|
|
||||||
|
+Install 'pkg-config' and 'libdaemon'.
|
||||||
|
+
|
||||||
|
Run configure, e.g.
|
||||||
|
|
||||||
|
./configure --prefix=/usr/local --sysconfdir=/etc --mandir=/usr/share/man
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index b3f0a19..3ab6667 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -137,15 +137,11 @@ AC_CHECK_LIB(c, inet_ntop,,
|
||||||
|
# prevent caching
|
||||||
|
unset ac_cv_lib_inet6_inet_ntop
|
||||||
|
|
||||||
|
-AC_CHECK_LIB([daemon], [daemon_fork], ,
|
||||||
|
- AC_MSG_ERROR([Could not use libdaemon library])
|
||||||
|
-)
|
||||||
|
+PKG_CHECK_MODULES([DAEMON], libdaemon)
|
||||||
|
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS( \
|
||||||
|
- libdaemon/dfork.h \
|
||||||
|
- libdaemon/dpid.h \
|
||||||
|
getopt.h \
|
||||||
|
ifaddrs.h \
|
||||||
|
machine/limits.h \
|
||||||
|
--
|
||||||
|
1.7.7.6
|
||||||
|
|
23
radvd.spec
23
radvd.spec
@ -1,7 +1,7 @@
|
|||||||
Summary: A Router Advertisement daemon
|
Summary: A Router Advertisement daemon
|
||||||
Name: radvd
|
Name: radvd
|
||||||
Version: 1.8.5
|
Version: 1.8.5
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
# The code includes the advertising clause, so it's GPL-incompatible
|
# The code includes the advertising clause, so it's GPL-incompatible
|
||||||
License: BSD with advertising
|
License: BSD with advertising
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
@ -9,12 +9,23 @@ URL: http://www.litech.org/radvd/
|
|||||||
Source: %{url}dist/%{name}-%{version}.tar.gz
|
Source: %{url}dist/%{name}-%{version}.tar.gz
|
||||||
Source2: radvd-tmpfs.conf
|
Source2: radvd-tmpfs.conf
|
||||||
Source3: radvd.service
|
Source3: radvd.service
|
||||||
|
# Bug #811997, fixed in upstream after 1.8.5
|
||||||
|
Patch0: radvd-1.8.5-Use-libdaemon-for-daemonization.patch
|
||||||
|
# Bug #811997, fixed in upstream after 1.8.5
|
||||||
|
Patch1: radvd-1.8.5-Use-pkg-config-to-discover-libdaemon.patch
|
||||||
|
# autoconf needed for Use-libdaemon-for-daemonization and
|
||||||
|
# Use-pkg-config-to-discover-libdaemon patches
|
||||||
|
BuildRequires: autoconf
|
||||||
|
BuildRequires: byacc
|
||||||
|
BuildRequires: flex
|
||||||
|
BuildRequires: flex-static
|
||||||
|
BuildRequires: libdaemon-devel
|
||||||
|
BuildRequires: pkgconfig
|
||||||
|
BuildRequires: systemd-units
|
||||||
Requires(postun): systemd-units
|
Requires(postun): systemd-units
|
||||||
Requires(preun): systemd-units
|
Requires(preun): systemd-units
|
||||||
Requires(post): systemd-units
|
Requires(post): systemd-units
|
||||||
Requires(pre): shadow-utils
|
Requires(pre): shadow-utils
|
||||||
BuildRequires: systemd-units
|
|
||||||
BuildRequires: flex, flex-static, byacc
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
radvd is the router advertisement daemon for IPv6. It listens to router
|
radvd is the router advertisement daemon for IPv6. It listens to router
|
||||||
@ -29,6 +40,9 @@ services.
|
|||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
%patch0 -p1 -b .libdaemon
|
||||||
|
%patch1 -p1 -b .pkgconfig
|
||||||
|
autoreconf -is
|
||||||
for F in CHANGES; do
|
for F in CHANGES; do
|
||||||
iconv -f iso-8859-1 -t utf-8 < "$F" > "${F}.new"
|
iconv -f iso-8859-1 -t utf-8 < "$F" > "${F}.new"
|
||||||
touch -r "$F" "${F}.new"
|
touch -r "$F" "${F}.new"
|
||||||
@ -97,6 +111,9 @@ exit 0
|
|||||||
%{_sbindir}/radvdump
|
%{_sbindir}/radvdump
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Apr 12 2012 Petr Pisar <ppisar@redhat.com> - 1.8.5-3
|
||||||
|
- Store PID before daemonizing (bug #811997)
|
||||||
|
|
||||||
* Tue Apr 03 2012 Petr Pisar <ppisar@redhat.com> - 1.8.5-2
|
* Tue Apr 03 2012 Petr Pisar <ppisar@redhat.com> - 1.8.5-2
|
||||||
- Clean up spec file
|
- Clean up spec file
|
||||||
- Remove System V init support
|
- Remove System V init support
|
||||||
|
Loading…
Reference in New Issue
Block a user