This commit is contained in:
Petr Písař 2012-06-15 14:30:35 +02:00
parent 87fbf047f5
commit 2167994db4
5 changed files with 8 additions and 291 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ radvd-1.6.tar.gz
/radvd-1.8.3.tar.gz
/radvd-1.8.4.tar.gz
/radvd-1.8.5.tar.gz
/radvd-1.9.tar.gz

View File

@ -1,210 +0,0 @@
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

View File

@ -1,66 +0,0 @@
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

View File

@ -1,7 +1,7 @@
Summary: A Router Advertisement daemon
Name: radvd
Version: 1.8.5
Release: 4%{?dist}
Version: 1.9
Release: 1%{?dist}
# The code includes the advertising clause, so it's GPL-incompatible
License: BSD with advertising
Group: System Environment/Daemons
@ -9,14 +9,6 @@ URL: http://www.litech.org/radvd/
Source0: %{url}dist/%{name}-%{version}.tar.gz
Source1: radvd-tmpfs.conf
Source2: 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
# autotools are needed for Use-libdaemon-for-daemonization and
# Use-pkg-config-to-discover-libdaemon patches
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: byacc
BuildRequires: flex
BuildRequires: flex-static
@ -41,9 +33,6 @@ 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"
@ -100,7 +89,7 @@ getent passwd radvd >/dev/null || \
exit 0
%files
%doc COPYRIGHT README CHANGES INTRO.html TODO
%doc CHANGES COPYRIGHT INTRO.html README TODO
%{_unitdir}/radvd.service
%config(noreplace) %{_sysconfdir}/radvd.conf
%config(noreplace) %{_sysconfdir}/sysconfig/radvd
@ -112,6 +101,9 @@ exit 0
%{_sbindir}/radvdump
%changelog
* Fri Jun 15 2012 Petr Pisar <ppisar@redhat.com> - 1.9-1
- 1.9 bump
* Wed May 23 2012 Petr Pisar <ppisar@redhat.com> - 1.8.5-4
- Start service independently on network state (bug #824205)
- Do not force systemd logging to syslog (bug #824205)

View File

@ -1 +1 @@
bdeca76d976282c306f3c454d6ff1f67 radvd-1.8.5.tar.gz
881627a2dbea4df1152ec6bb7ef6a9e8 radvd-1.9.tar.gz