4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Daemon non-inline non-template implementation */
30 #include <sys/types.h>
41 #include <boost/algorithm/string/predicate.hpp>
42 #include <boost/algorithm/string/trim.hpp>
43 #include <boost/format.hpp>
44 #include "../Exception.hh"
45 #include "../membind.hh"
46 #include "../Backtrace.hh"
47 #include "../signalnames.hh"
52 //#include "Daemon.mpp"
54 ///////////////////////////////cc.p////////////////////////////////////////
56 #define LIBC_CALL(fn, args) if (fn args < 0) \
57 SENF_THROW_SYSTEM_EXCEPTION(#fn "()")
59 #define LIBC_CALL_RV(var, fn, args) \
60 int var (fn args); if (var < 0) SENF_THROW_SYSTEM_EXCEPTION(#fn "()")
62 ///////////////////////////////////////////////////////////////////////////
65 prefix_ senf::Daemon::~Daemon()
67 if (pidfileCreated_) {
69 LIBC_CALL( ::unlink, (pidfile_.c_str()) );
70 } catch (Exception e) {
71 // e << "; could not unlink " << pidfile_.c_str();
77 prefix_ void senf::Daemon::daemonize(bool v)
82 prefix_ bool senf::Daemon::daemon()
87 prefix_ int senf::Daemon::argc()
92 prefix_ char const ** senf::Daemon::argv()
100 bool operator()(std::string const & str) const {
101 return str == "--no-daemon"
102 || boost::starts_with(str, std::string("--pid-file="))
103 || boost::starts_with(str, std::string("--console-log="));
108 prefix_ void senf::Daemon::removeDaemonArgs()
110 char const ** last (std::remove_if(argv_+1, argv_+argc_, IsDaemonOpt()));
112 argc_ = last - argv_;
115 prefix_ void senf::Daemon::consoleLog(std::string const & path, StdStream which)
118 case StdOut : stdoutLog_ = path; break;
119 case StdErr : stderrLog_ = path; break;
120 case Both : stdoutLog_ = path; stderrLog_ = path; break;
125 prefix_ void senf::Daemon::openLog()
128 if (! stdoutLog_.empty()) {
129 fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666);
131 SENF_THROW_SYSTEM_EXCEPTION("")
132 << " Could not open \"" << stdoutLog_ << "\" for redirecting stdout.";
135 if (! stderrLog_.empty()) {
136 if (stderrLog_ == stdoutLog_) {
139 SENF_THROW_SYSTEM_EXCEPTION("::dup()");
142 fd = ::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666);
144 SENF_THROW_SYSTEM_EXCEPTION("")
145 << " Could not open \"" << stderrLog_ << "\" for redirecting stderr.";
151 prefix_ void senf::Daemon::logReopen()
153 if (! stdoutLog_.empty()) {
154 int fd (::open(stdoutLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666));
157 if (::dup2(fd, 1) < 0)
159 if (stderrLog_ == stdoutLog_) {
160 if (::dup2(fd, 2) < 0)
165 if (! stderrLog_.empty()) {
166 int fd (::open(stderrLog_.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0666));
169 if (::dup2(fd, 2) < 0)
176 (senf::log::CRITICAL)
177 ("log-file reopen failed: (" << errno << ") " << ::strerror(errno)) );
180 prefix_ void senf::Daemon::pidFile(std::string const & f)
186 bool signaled (false);
192 prefix_ void senf::Daemon::detach()
194 if (daemonize_ && ! detached_) {
196 // To ensure all data is written to the console log file in the correct order, we suspend
197 // execution here until the parent process tells us to continue via SIGUSR1: We block
198 // SIGUSR1 and install our own signal handler saving the old handler and signal mask. Then
199 // we close stdin/stderr which will send a HUP condition to the parent process. We wait for
200 // SIGUSR1 and reinstall the old signal mask and action.
203 ::sigemptyset(&usrsig);
204 LIBC_CALL( ::sigaddset, (&usrsig, SIGUSR1) );
205 LIBC_CALL( ::sigprocmask, (SIG_BLOCK, &usrsig, &oldsig) );
206 struct ::sigaction oldact;
207 struct ::sigaction usract;
208 ::memset(&usract, 0, sizeof(usract));
209 usract.sa_handler = &waitusr;
210 LIBC_CALL( ::sigaction, (SIGUSR1, &usract, &oldact) );
211 ::sigset_t waitsig (oldsig);
212 LIBC_CALL( ::sigdelset, (&waitsig, SIGUSR1) );
214 LIBC_CALL_RV( nul, ::open, ("/dev/null", O_WRONLY) );
215 LIBC_CALL( ::dup2, (stdout_ == -1 ? nul : stdout_, 1) );
216 LIBC_CALL( ::dup2, (stderr_ == -1 ? nul : stderr_, 2) );
217 LIBC_CALL( ::close, (nul) );
221 ::sigsuspend(&waitsig);
223 SENF_THROW_SYSTEM_EXCEPTION("::sigsuspend()");
226 LIBC_CALL( ::sigaction, (SIGUSR1, &oldact, 0) );
227 LIBC_CALL( ::sigprocmask, (SIG_SETMASK, &oldsig, 0) );
234 /* Purposely *not* derived from std::exception */
235 struct DaemonExitException {
236 DaemonExitException(unsigned c) : code(c) {}
241 prefix_ void senf::Daemon::exit(unsigned code)
243 throw DaemonExitException(code);
246 prefix_ int senf::Daemon::start(int argc, char const ** argv)
258 installSighandlers();
259 if (! pidfile_.empty()) {
261 pidfileCreated_ = true;
263 std::cerr << "PID file '" << pidfile_
264 << "' creation failed. Daemon running ?" << std::endl;
271 catch (DaemonExitException & e) {
277 catch (std::exception & e) {
278 std::cerr << "\n*** Fatal exception: " << e.what() << "\n" << std::endl;
282 std::cerr << "\n*** Fatal exception: (unknown)" << "\n" << std::endl;
291 prefix_ senf::Daemon & senf::Daemon::instance()
293 BOOST_ASSERT( instance_ );
297 ////////////////////////////////////////
300 prefix_ senf::Daemon::Daemon()
301 : argc_(0), argv_(0), daemonize_(true), stdout_(-1), stderr_(-1), pidfile_(""),
302 pidfileCreated_(false), detached_(false)
304 BOOST_ASSERT( ! instance_ );
308 senf::Daemon * senf::Daemon::instance_ (0);
310 ////////////////////////////////////////
313 prefix_ void senf::Daemon::configure()
315 // int i (not unsigned) since argc_ is int ...
316 for (int i (1); i<argc_; ++i) {
317 if (argv_[i] == std::string("--no-daemon"))
319 else if (boost::starts_with(argv_[i], std::string("--console-log="))) {
320 std::string arg (std::string(argv_[i]), 14u);
321 std::string::size_type komma (arg.find(','));
322 if (komma == std::string::npos) {
324 if (arg == std::string("none")) consoleLog("");
325 else if (!arg.empty()) consoleLog(arg);
327 std::string arg1 (arg,0,komma);
328 std::string arg2 (arg,komma+1);
331 if (arg1 == std::string("none")) consoleLog("",StdOut);
332 else if (! arg1.empty() ) consoleLog(arg1, StdOut);
333 if (arg2 == std::string("none")) consoleLog("",StdErr);
334 else if (! arg2.empty() ) consoleLog(arg2, StdErr);
337 else if (boost::starts_with(argv_[i], std::string("--pid-file=")))
338 pidFile(std::string(std::string(argv_[i]), 11u));
342 prefix_ void senf::Daemon::main()
349 prefix_ void senf::Daemon::init()
352 prefix_ void senf::Daemon::run()
355 prefix_ void senf::Daemon::fork()
360 LIBC_CALL_RV( nul, ::open, ("/dev/null", O_RDONLY) );
361 LIBC_CALL( ::dup2, (nul, 0) );
362 LIBC_CALL( ::close, (nul) );
363 LIBC_CALL( ::pipe, (coutpipe) );
364 LIBC_CALL( ::pipe, (cerrpipe) );
366 // We need to block the SIGCHLD signal here so we don't miss it, if the child
370 ::sigemptyset(&cldsig);
371 LIBC_CALL( ::sigaddset, (&cldsig, SIGCHLD) );
372 LIBC_CALL( ::sigprocmask, (SIG_BLOCK, &cldsig, &oldsig) );
374 if (! senf::scheduler::empty() ) {
378 "Scheduler not empty before fork(). THIS MUST NOT HAPPEN.\n"
379 "The scheduler will be reinitialized by the fork() and lose all registrations.\n\n";
380 senf::scheduler::detail::EventManager::instance().listEvents(std::cerr);
382 "\n*** WARNING ***\n"
386 LIBC_CALL_RV( pid, ::fork, () );
391 LIBC_CALL( ::dup2, (coutpipe[1],1) );
392 LIBC_CALL( ::dup2, (cerrpipe[1],2) );
393 LIBC_CALL( ::close, (coutpipe[0]) );
394 LIBC_CALL( ::close, (coutpipe[1]) );
395 LIBC_CALL( ::close, (cerrpipe[0]) );
396 LIBC_CALL( ::close, (cerrpipe[1]) );
397 LIBC_CALL( ::setsid, () );
398 LIBC_CALL( ::sigprocmask, (SIG_SETMASK, &oldsig, 0) );
400 senf::scheduler::restart();
404 // Ouch ... ensure, the daemon watcher does not remove the pidfile ...
407 LIBC_CALL( ::close, (coutpipe[1]) );
408 LIBC_CALL( ::close, (cerrpipe[1]) );
410 senf::scheduler::restart();
412 detail::DaemonWatcher watcher (pid, coutpipe[0], cerrpipe[0], stdout_, stderr_);
418 prefix_ bool senf::Daemon::pidfileCreate()
420 // Create temporary file pidfile_.hostname.pid and hard-link it to pidfile_ If the hardlink
421 // fails, the pidfile exists. If the link count of the temporary file is not 2 after this, there
422 // was some race condition, probably over NFS.
424 std::string tempname;
425 boost::format linkErrorFormat(" Could not link \"%1%\" to \"%2%\".");
428 char hostname[HOST_NAME_MAX+1];
429 LIBC_CALL( ::gethostname, (hostname, HOST_NAME_MAX+1) );
430 hostname[HOST_NAME_MAX] = 0;
431 std::stringstream tempname_s;
432 tempname_s << pidfile_ << "." << hostname << "." << ::getpid();
433 tempname = tempname_s.str();
438 std::ofstream pidf (tempname.c_str());
440 SENF_THROW_SYSTEM_EXCEPTION("")
441 << " Could not open pidfile \"" << tempname << "\" for output.";
442 pidf << ::getpid() << std::endl;
444 SENF_THROW_SYSTEM_EXCEPTION("")
445 << " Could not write to pidfile \"" << tempname << "\".";
448 if (::link(tempname.c_str(), pidfile_.c_str()) < 0) {
450 SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % pidfile_ % tempname;
454 LIBC_CALL( ::stat, (tempname.c_str(), &s) );
455 LIBC_CALL( ::unlink, (tempname.c_str()) );
456 return s.st_nlink == 2;
459 // pidfile exists. Check, whether the pid in the pidfile still exists.
462 std::ifstream pidf (pidfile_.c_str());
463 if ( ! (pidf >> old_pid)
465 || ::kill(old_pid, 0) >= 0
466 || errno == EPERM ) {
467 LIBC_CALL( ::unlink, (tempname.c_str()) );
472 // If we reach this point, the pid file exists but the process mentioned within the
473 // pid file does *not* exists. We assume, the pid file to be stale.
475 // I hope, the following procedure is without race condition: We remove our generated
476 // temporary pid file and recreate it as hard-link to the old pid file. Now we check, that
477 // the hard-link count of this file is 2. If it is not, we terminate, since someone else
478 // must have already created his hardlink. We then truncate the file and write our pid.
480 LIBC_CALL( ::unlink, (tempname.c_str() ));
481 if (::link(pidfile_.c_str(), tempname.c_str()) < 0) {
483 SENF_THROW_SYSTEM_EXCEPTION("") << linkErrorFormat % tempname % pidfile_;
484 // Hmm ... the pidfile mysteriously disappeared ... try again.
490 LIBC_CALL( ::stat, (tempname.c_str(), &s) );
491 if (s.st_nlink != 2) {
492 LIBC_CALL( ::unlink, (tempname.c_str()) );
498 std::ofstream pidf (tempname.c_str());
499 pidf << ::getpid() << std::endl;
502 LIBC_CALL( ::unlink, (tempname.c_str()) );
512 void fatalSignalsHandler(int sig, ::siginfo_t * info, void * arg)
514 // ::ucontext_t * ucontext = static_cast<ucontext_t*>(arg);
515 std::cerr << "\n" << "Signal " << senf::signalName(sig) << '(' << sig << ')'
519 std::cerr << "Invalid memory access at " << info->si_addr << "\n";
521 static void * entries[SENF_DEBUG_BACKTRACE_NUMCALLERS];
522 unsigned nEntries( ::backtrace(entries, SENF_DEBUG_BACKTRACE_NUMCALLERS) );
524 // Hack the callers address into the backtrace
525 // entries[1] = reinterpret_cast<void *>(ucontext->uc_mcontext.gregs[REG_EIP]);
527 std::cerr << "Backtrace:\n";
528 senf::formatBacktrace(std::cerr, entries, nEntries);
529 std::cerr << "-- \n";
531 if (sig != SIGUSR2) {
532 ::signal(sig, SIG_DFL);
533 ::kill(::getpid(), sig);
542 void sighupHandler(int sig)
544 senf::Daemon::instance().logReopen();
548 prefix_ void senf::Daemon::installSighandlers()
550 struct ::sigaction sa;
552 ::sigemptyset(&sa.sa_mask);
553 sa.sa_handler = &sighupHandler;
554 sa.sa_flags = SA_RESTART;
556 ::sigaction(SIGHUP, &sa, NULL);
558 sa.sa_handler = SIG_IGN;
559 ::sigaction(SIGPIPE, &sa, NULL);
562 sa.sa_sigaction = &fatalSignalsHandler;
563 sa.sa_flags = SA_RESTART | SA_SIGINFO;
565 ::sigaction(SIGILL, &sa, NULL);
566 ::sigaction(SIGTRAP, &sa, NULL);
567 ::sigaction(SIGABRT, &sa, NULL);
568 ::sigaction(SIGFPE, &sa, NULL);
569 ::sigaction(SIGBUS, &sa, NULL);
570 ::sigaction(SIGSEGV, &sa, NULL);
571 ::sigaction(SIGSTKFLT, &sa, NULL);
572 ::sigaction(SIGSYS, &sa, NULL);
573 ::sigaction(SIGUSR2, &sa, NULL);
577 ///////////////////////////////////////////////////////////////////////////
578 // senf::detail::DaemonWatcher
580 prefix_ senf::detail::DaemonWatcher::DaemonWatcher(int pid, int coutpipe, int cerrpipe,
581 int stdout, int stderr)
582 : childPid_(pid), coutpipe_(coutpipe), cerrpipe_(cerrpipe), stdout_(stdout),
583 stderr_(stderr), sigChld_(false),
584 cldSignal_ (SIGCHLD, senf::membind(&DaemonWatcher::sigChld, this)),
585 timer_ ("senf::detail::DaemonWatcher::childOk", senf::membind(&DaemonWatcher::childOk, this)),
586 coutForwarder_(coutpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 1)),
587 cerrForwarder_(cerrpipe_, boost::bind(&DaemonWatcher::pipeClosed, this, 2))
589 coutForwarder_.addTarget(1);
591 coutForwarder_.addTarget(stdout_);
592 cerrForwarder_.addTarget(2);
594 cerrForwarder_.addTarget(stderr_);
597 prefix_ void senf::detail::DaemonWatcher::run()
599 scheduler::process();
602 ////////////////////////////////////////
605 prefix_ void senf::detail::DaemonWatcher::pipeClosed(int id)
608 case 1 : coutpipe_ = -1; break;
609 case 2 : cerrpipe_ = -1; break;
612 if (coutpipe_ == -1 && cerrpipe_ == -1) {
614 childDied(); // does not return
615 if (::kill(childPid_, SIGUSR1) < 0 && errno != ESRCH)
616 SENF_THROW_SYSTEM_EXCEPTION("::kill()");
617 timer_.timeout(scheduler::eventTime() + ClockService::seconds(1));
621 prefix_ void senf::detail::DaemonWatcher::sigChld(siginfo_t const &)
624 if (coutpipe_ == -1 && cerrpipe_ == -1)
625 childDied(); // does not return
628 prefix_ void senf::detail::DaemonWatcher::childDied()
631 if (::waitpid(childPid_,&status,0) < 0) SENF_THROW_SYSTEM_EXCEPTION("::waitpid()");
632 if (WIFSIGNALED(status)) {
633 ::signal(WTERMSIG(status),SIG_DFL);
634 ::kill(::getpid(), WTERMSIG(status));
635 // should not be reached
638 if (WEXITSTATUS(status) == 0)
640 ::_exit(WEXITSTATUS(status));
643 prefix_ void senf::detail::DaemonWatcher::childOk()
645 scheduler::terminate();
648 ///////////////////////////////////////////////////////////////////////////
649 // senf::detail::DaemonWatcher::Forwarder
651 prefix_ senf::detail::DaemonWatcher::Forwarder::Forwarder(int src, Callback cb)
652 : src_(src), cb_(cb),
653 readevent_("senf::detail::DaemonWatcher::Forwarder::readevent", senf::membind(&Forwarder::readData, this),
654 src_, scheduler::FdEvent::EV_READ)
657 prefix_ senf::detail::DaemonWatcher::Forwarder::~Forwarder()
659 targets_.clear_and_destroy(DestroyDelete());
662 prefix_ void senf::detail::DaemonWatcher::Forwarder::addTarget(int fd)
664 targets_.push_back(*(new Target(*this, fd)));
667 prefix_ void senf::detail::DaemonWatcher::Forwarder::readData(int event)
673 n = ::read(src_,buf,1024);
676 SENF_THROW_SYSTEM_EXCEPTION("::read()");
686 readevent_.disable();
690 if (targets_.empty())
693 for (Targets::iterator i (targets_.begin()); i != targets_.end(); ++i)
694 if (i->offset >= buffer_.size())
695 i->writeevent.enable();
697 buffer_.insert(buffer_.end(), buf, buf+n);
700 prefix_ void senf::detail::DaemonWatcher::Forwarder::writeData(int event, Target * target)
702 if (event != scheduler::FdEvent::EV_WRITE) {
703 // Broken pipe while writing data ? Not much, we can do here, we just drop the data
704 targets_.erase_and_destroy(Targets::current(*target),DestroyDelete());
705 if (targets_.empty() && src_ == -1)
711 int n (buffer_.size() - target->offset > 1024 ? 1024 : buffer_.size() - target->offset);
712 std::copy(buffer_.begin() + target->offset, buffer_.begin() + target->offset + n, buf);
714 int w (::write(target->fd, buf, n));
716 if (errno != EINTR) SENF_THROW_SYSTEM_EXCEPTION("::write()");
721 n = std::min_element(
722 targets_.begin(), targets_.end(),
723 boost::bind(&Target::offset, _1) < boost::bind(&Target::offset, _2))->offset;
725 buffer_.erase(buffer_.begin(), buffer_.begin()+n);
727 for (Targets::iterator i (targets_.begin()); i != targets_.end(); ++i)
730 if (target->offset >= buffer_.size())
731 target->writeevent.disable();
732 if (src_ == -1 && (buffer_.empty() || targets_.empty()))
739 ///////////////////////////////cc.e////////////////////////////////////////
741 //#include "Daemon.mpp"
747 // comment-column: 40
748 // c-file-style: "senf"
749 // indent-tabs-mode: nil
750 // ispell-local-dictionary: "american"
751 // compile-command: "scons -u test"