From: Michal 'vorner' Vaner Date: Fri, 3 Feb 2012 13:08:21 +0000 (+0100) Subject: [1596] Handle pid parameter in auth X-Git-Tag: trac2351_base~97^2~32^2~3^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=94ca32cb24762fc41c23631d7183c35f643545e7;p=thirdparty%2Fkea.git [1596] Handle pid parameter in auth --- diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in index 693e813ff4..e202978c6e 100644 --- a/src/bin/auth/auth.spec.pre.in +++ b/src/bin/auth/auth.spec.pre.in @@ -97,7 +97,13 @@ { "command_name": "shutdown", "command_description": "Shut down authoritative DNS server", - "command_args": [] + "command_args": [ + { + "item_name": "pid", + "item_type": "integer", + "item_optional": true + } + ] }, { "command_name": "sendstats", diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h index ad61fd865a..dc0e5120ca 100644 --- a/src/bin/auth/auth_srv.h +++ b/src/bin/auth/auth_srv.h @@ -343,7 +343,7 @@ public: /// /// \param type Type of a counter to get the value of /// - /// \return the value of the counter. + uint64_t getCounter(const AuthCounters::ServerCounterType type) const; /// \brief Get the value of per Opcode counter in the Auth Counters. diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc index 280558d70d..b1cc2eed9e 100644 --- a/src/bin/auth/command.cc +++ b/src/bin/auth/command.cc @@ -12,10 +12,9 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include - -#include -#include +#include +#include +#include #include @@ -27,9 +26,13 @@ #include -#include -#include -#include +#include + +#include +#include + +#include +#include using boost::scoped_ptr; using namespace isc::auth; @@ -104,10 +107,22 @@ public: virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) = 0; }; -// Handle the "shutdown" command. No argument is assumed. +// Handle the "shutdown" command. An optional parameter "pid" is used to +// see if it is really for our instance. class ShutdownCommand : public AuthCommand { public: - virtual void exec(AuthSrv& server, isc::data::ConstElementPtr) { + virtual void exec(AuthSrv& server, isc::data::ConstElementPtr args) { + // Is the pid argument provided? + if (args && args->getType() == + isc::data::Element::map && args->contains("pid")) { + // If it is, we check it is the same as our PID + int pid(args->get("pid")->intValue()); + pid_t my_pid(getpid()); + if (my_pid != pid) { + // It is not for us + return; + } + } server.stop(); } }; diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc index 8a82367aea..d14ff6b5be 100644 --- a/src/bin/auth/tests/command_unittest.cc +++ b/src/bin/auth/tests/command_unittest.cc @@ -14,14 +14,9 @@ #include -#include -#include -#include -#include - -#include - -#include +#include +#include +#include #include #include @@ -33,14 +28,22 @@ #include -#include -#include -#include - #include #include +#include +#include +#include +#include + +#include + +#include + +#include +#include + using namespace std; using namespace isc::dns; using namespace isc::data; @@ -50,7 +53,11 @@ using namespace isc::config; namespace { class AuthCommandTest : public ::testing::Test { protected: - AuthCommandTest() : server(false, xfrout), rcode(-1) { + AuthCommandTest() : + server(false, xfrout), + rcode(-1), + itimer_(server.getIOService()) + { server.setStatisticsSession(&statistics_session); } void checkAnswer(const int expected_code) { @@ -61,9 +68,13 @@ protected: MockXfroutClient xfrout; AuthSrv server; ConstElementPtr result; + // The shutdown command parameter + ConstElementPtr param; int rcode; + isc::asiolink::IntervalTimer itimer_; public: void stopServer(); // need to be public for boost::bind + void dontStopServer(); // need to be public for boost::bind }; TEST_F(AuthCommandTest, unknownCommand) { @@ -92,14 +103,52 @@ TEST_F(AuthCommandTest, sendStatistics) { void AuthCommandTest::stopServer() { - result = execAuthServerCommand(server, "shutdown", ConstElementPtr()); + result = execAuthServerCommand(server, "shutdown", param); parseAnswer(rcode, result); assert(rcode == 0); // make sure the test stops when something is wrong } TEST_F(AuthCommandTest, shutdown) { - isc::asiolink::IntervalTimer itimer(server.getIOService()); - itimer.setup(boost::bind(&AuthCommandTest::stopServer, this), 1); + // Param defaults to empty/null pointer on creation + itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1); + server.getIOService().run(); + EXPECT_EQ(0, rcode); +} + +TEST_F(AuthCommandTest, shutdownCorrectPID) { + // Put the pid parameter there + pid_t pid(getpid()); + ElementPtr param(new isc::data::MapElement()); + param->set("pid", ConstElementPtr(new isc::data::IntElement(pid))); + this->param = param; + // With the correct PID, it should act exactly the same as in case + // of no parameter + itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1); + server.getIOService().run(); + EXPECT_EQ(0, rcode); +} + +// This is like stopServer, but the server should not stop after the +// command, it should be running +void +AuthCommandTest::dontStopServer() { + result = execAuthServerCommand(server, "shutdown", param); + parseAnswer(rcode, result); + EXPECT_EQ(0, rcode); + rcode = -1; + // We run the stopServer now, to really stop the server. + // If it had stopped already, it won't be run and the rcode -1 will + // be left here. + param = ConstElementPtr(); + itimer_.cancel(); + itimer_.setup(boost::bind(&AuthCommandTest::stopServer, this), 1); +} + +TEST_F(AuthCommandTest, shutdownIncorrectPID) { + // The PID = 0 should be taken by init, so we are not init and the + // PID should be different + param = Element::fromJSON("{\"pid\": 0}"); + itimer_.setup(boost::bind(&AuthCommandTest::dontStopServer, this), 1); server.getIOService().run(); EXPECT_EQ(0, rcode); }