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
|
||||
Name: radvd
|
||||
Version: 1.8.5
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
# The code includes the advertising clause, so it's GPL-incompatible
|
||||
License: BSD with advertising
|
||||
Group: System Environment/Daemons
|
||||
@ -9,12 +9,23 @@ URL: http://www.litech.org/radvd/
|
||||
Source: %{url}dist/%{name}-%{version}.tar.gz
|
||||
Source2: radvd-tmpfs.conf
|
||||
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(preun): systemd-units
|
||||
Requires(post): systemd-units
|
||||
Requires(pre): shadow-utils
|
||||
BuildRequires: systemd-units
|
||||
BuildRequires: flex, flex-static, byacc
|
||||
|
||||
%description
|
||||
radvd is the router advertisement daemon for IPv6. It listens to router
|
||||
@ -29,6 +40,9 @@ services.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch0 -p1 -b .libdaemon
|
||||
%patch1 -p1 -b .pkgconfig
|
||||
autoreconf -is
|
||||
for F in CHANGES; do
|
||||
iconv -f iso-8859-1 -t utf-8 < "$F" > "${F}.new"
|
||||
touch -r "$F" "${F}.new"
|
||||
@ -97,6 +111,9 @@ exit 0
|
||||
%{_sbindir}/radvdump
|
||||
|
||||
%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
|
||||
- Clean up spec file
|
||||
- Remove System V init support
|
||||
|
Loading…
Reference in New Issue
Block a user