From 5834af4d9916fb6b7e3c15c46d1fac56183d5f74 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Sep 2017 22:02:25 +0100 Subject: [PATCH] Wait for housekeeping to finish before bbstored exits Should fix random test failures due to housekeeping process realising that the master has asked it to terminate, and logging that it has, after the master has already died and the test finished, confusing the test runner with its extra output. Should also help make the occasionally-reported housekeeping crashes more obvious and easier to debug. (cherry picked from commit 0100d3185abf10b17ff7727f2c0f2d8fb6b724d4) --- lib/bbstored/BBStoreDHousekeeping.cpp | 8 ++++++ lib/bbstored/BackupStoreDaemon.cpp | 37 ++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/bbstored/BBStoreDHousekeeping.cpp b/lib/bbstored/BBStoreDHousekeeping.cpp index 230b3a680..130a5b8a0 100644 --- a/lib/bbstored/BBStoreDHousekeeping.cpp +++ b/lib/bbstored/BBStoreDHousekeeping.cpp @@ -217,6 +217,14 @@ bool BackupStoreDaemon::CheckForInterProcessMsg(int AccountNum, int MaximumWaitT return false; } + // First, check to see if it's EOF -- this means something has gone wrong, and the housekeeping should terminate. + if(mInterProcessComms.IsEOF()) + { + BOX_INFO("Housekeeping process was hungup by main daemon, terminating"); + SetTerminateWanted(); + return true; + } + // Get a line, and process the message std::string line; diff --git a/lib/bbstored/BackupStoreDaemon.cpp b/lib/bbstored/BackupStoreDaemon.cpp index aad2d0157..daa9f6235 100644 --- a/lib/bbstored/BackupStoreDaemon.cpp +++ b/lib/bbstored/BackupStoreDaemon.cpp @@ -171,6 +171,7 @@ void BackupStoreDaemon::Run() mExtendedLogging = false; const Configuration &config(GetConfiguration()); mExtendedLogging = config.GetKeyValueBool("ExtendedLogging"); + int housekeeping_pid; // Fork off housekeeping daemon -- must only do this the first // time Run() is called. Housekeeping runs synchronously on Win32 @@ -190,7 +191,8 @@ void BackupStoreDaemon::Run() int whichSocket = 0; // Fork - switch(::fork()) + housekeeping_pid = ::fork(); + switch(housekeeping_pid) { case -1: { @@ -261,6 +263,39 @@ void BackupStoreDaemon::Run() if(IsTerminateWanted()) { mInterProcessCommsSocket.Write("t\n", 2); + +#ifndef WIN32 // waitpid() only works with fork(), and thus not on Windows + // Wait for housekeeping to finish, and report its status, otherwise it + // can remain running and write to the console after the main process has + // died, which can confuse the tests. + int child_state; + if(waitpid(housekeeping_pid, &child_state, 0) == -1) + { + BOX_LOG_SYS_ERROR("Failed to wait for housekeeping child process " + "to finish"); + } + else if(WIFEXITED(child_state)) + { + if(WEXITSTATUS(child_state) == 0) + { + BOX_TRACE("Housekeeping child process exited normally"); + } + else + { + BOX_ERROR("Housekeeping child process exited with " + "status " << WEXITSTATUS(child_state)); + } + } + else if(WIFSIGNALED(child_state)) + { + BOX_ERROR("Housekeeping child process terminated with signal " << + WTERMSIG(child_state)); + } + else + { + BOX_ERROR("Housekeeping child process terminated in unexpected manner"); + } +#endif // !WIN32 } } }