One very minor comment, instead of the busy wait we may check if e.g. inotify can be used for daemons and implement a "wrapper" for easier use? /BR HansN
-----Original Message----- From: Anders Widell [mailto:anders.wid...@ericsson.com] Sent: den 22 september 2016 13:17 To: mahesh.va...@oracle.com Cc: opensaf-devel@lists.sourceforge.net Subject: [devel] [PATCH 1 of 1] dtm: Convert transport monitor script to a daemon [#2035] configure.ac | 3 +- opensaf.spec.in | 4 +- osaf/services/infrastructure/dtms/Makefile.am | 3 +- osaf/services/infrastructure/dtms/scripts/Makefile.am | 3 +- osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor.in | 82 ------- osaf/services/infrastructure/dtms/scripts/osaf-transport.in | 45 ++- osaf/services/infrastructure/dtms/transport/Makefile.am | 41 +++ osaf/services/infrastructure/dtms/transport/main.cc | 52 ++++ osaf/services/infrastructure/dtms/transport/tests/Makefile.am | 45 ++++ osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.cc | 34 +++ osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.h | 23 ++ osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.cc | 26 ++ osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h | 38 +++ osaf/services/infrastructure/dtms/transport/tests/transport_monitor_test.cc | 109 ++++++++++ osaf/services/infrastructure/dtms/transport/transport_monitor.cc | 95 ++++++++ osaf/services/infrastructure/dtms/transport/transport_monitor.h | 92 ++++++++ osaf/services/infrastructure/nid/scripts/opensafd.in | 6 +- 17 files changed, 593 insertions(+), 108 deletions(-) Convert the osaf-transport-monitor shell script into a daemon called osaftransportd. The functionality of this new daemon is (should be) exactly the same as the functionality of the shell script that it replaces. diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -784,10 +784,11 @@ AC_CONFIG_FILES([ osaf/services/infrastructure/Makefile osaf/services/infrastructure/dtms/Makefile osaf/services/infrastructure/dtms/dtm/Makefile + osaf/services/infrastructure/dtms/transport/Makefile + osaf/services/infrastructure/dtms/transport/tests/Makefile osaf/services/infrastructure/dtms/scripts/Makefile osaf/services/infrastructure/dtms/scripts/osaf-dtm osaf/services/infrastructure/dtms/scripts/osaf-transport - osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor osaf/services/infrastructure/dtms/config/Makefile osaf/services/infrastructure/dtms/include/Makefile osaf/services/infrastructure/fm/Makefile diff --git a/opensaf.spec.in b/opensaf.spec.in --- a/opensaf.spec.in +++ b/opensaf.spec.in @@ -1384,9 +1384,9 @@ fi %{_pkglibdir}/osaffmd %{_pkgclcclidir}/osaf-fmd %{_pkglibdir}/osafdtmd +%{_pkglibdir}/osaftransportd %{_pkgclcclidir}/osaf-dtm %{_pkgclcclidir}/osaf-transport -%{_pkgclcclidir}/osaf-transport-monitor %{_bindir}/rdegetrole %if %is_immxml %{_pkgimmxml_svcdir}/common_pl_template.xml @@ -1406,9 +1406,9 @@ fi %config(noreplace) %{_pkgsysconfdir}/nodeinit.conf.payload %config(noreplace) %{_pkgsysconfdir}/dtmd.conf %{_pkglibdir}/osafdtmd +%{_pkglibdir}/osaftransportd %{_pkgclcclidir}/osaf-dtm %{_pkgclcclidir}/osaf-transport -%{_pkgclcclidir}/osaf-transport-monitor %files libs %defattr(-,root,root) diff --git a/osaf/services/infrastructure/dtms/Makefile.am b/osaf/services/infrastructure/dtms/Makefile.am --- a/osaf/services/infrastructure/dtms/Makefile.am +++ b/osaf/services/infrastructure/dtms/Makefile.am @@ -18,5 +18,4 @@ include $(top_srcdir)/Makefile.common MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = config dtm include scripts - +SUBDIRS = config dtm transport include scripts diff --git a/osaf/services/infrastructure/dtms/scripts/Makefile.am b/osaf/services/infrastructure/dtms/scripts/Makefile.am --- a/osaf/services/infrastructure/dtms/scripts/Makefile.am +++ b/osaf/services/infrastructure/dtms/scripts/Makefile.am @@ -20,5 +20,4 @@ MAINTAINERCLEANFILES = Makefile.in nodist_pkgclccli_SCRIPTS = \ $(top_builddir)/osaf/services/infrastructure/dtms/scripts/osaf-dtm \ - $(top_builddir)/osaf/services/infrastructure/dtms/scripts/osaf-transport \ - $(top_builddir)/osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor + +$(top_builddir)/osaf/services/infrastructure/dtms/scripts/osaf-transpor +t diff --git a/osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor.in b/osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor.in deleted file mode 100644 --- a/osaf/services/infrastructure/dtms/scripts/osaf-transport-monitor.in +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh -# -# (C) Copyright 2010 The OpenSAF Foundation -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed -# under the GNU Lesser General Public License Version 2.1, February 1999. -# The complete license can be accessed from the following location: -# http://opensource.org/licenses/lgpl-license.php -# See the Copying file included with the OpenSAF distribution for full -# licensing terms. -# -# Author(s): Oracle -# - -osafdirfile=@sysconfdir@/@PACKAGE_NAME@/osafdir.conf - -# Source LSB functions library -. /lib/lsb/init-functions - -if [ ! -r $osafdirfile ]; then - logger -t $osafprog "can't read $osafdirfile, exiting." - exit 6 -else - . $osafdirfile - . $pkgsysconfdir/nid.conf -fi - -if [ ! "$MDS_TRANSPORT" = "TIPC" ] ; then - osafprog="osafdtmd" - - #Read the pid of dtmd. - count=0 - while true - do - if [ $count -eq 15 ] ; then - logger -s -t $osafprog "dtmd failed to come up. " - $pkglibdir/opensaf_reboot 0 - exit 0; - fi - - pidval=`cat $pkgpiddir/$osafprog.pid` - if ! test -d /proc/$pidval ; then - #dtmd may not have been spawned yet, wait for it. - sleep 1 - count=$(($count + 1)) - else - #found the pid - break; - fi - done -fi - -#start monitoring dtmd pid and rotate MDS logs -echo "Running Permanent loop to clean MDS Logs..." -while true -do - MDS_LOG_FILE=$pkglogdir/mds.log - FILESIZE=`du -sk "$MDS_LOG_FILE" 2>/dev/null | cut -f1` - if [ 5000 -lt 0$FILESIZE ]; then - rm -f "$MDS_LOG_FILE.old" - mv -f "$MDS_LOG_FILE" "$MDS_LOG_FILE.old" - fi - - if [ ! "$MDS_TRANSPORT" = "TIPC" ] ; then - count=0 - while [ $count -le 15 ] - do - if ! test -d /proc/$pidval ; then - logger -s -t $osafprog "$osafprog Process down, Rebooting the node" - $pkglibdir/opensaf_reboot 0 - exit 0; - fi - #logger "osafdtmd PID : $pidval monitor count = $count" - sleep 1 - count=$(($count + 1)) - done - else - sleep 15 - fi -done diff --git a/osaf/services/infrastructure/dtms/scripts/osaf-transport.in b/osaf/services/infrastructure/dtms/scripts/osaf-transport.in --- a/osaf/services/infrastructure/dtms/scripts/osaf-transport.in +++ b/osaf/services/infrastructure/dtms/scripts/osaf-transport.in @@ -13,7 +13,9 @@ ### END INIT INFO osafdirfile=@sysconfdir@/@PACKAGE_NAME@/osafdir.conf - +osafprog="osaftransportd" +initscript=$(basename "$0") + # Source LSB functions library . /lib/lsb/init-functions @@ -29,12 +31,16 @@ NIDSERV=TRANSPORT MANAGE_TIPC=${OPENSAF_MANAGE_TIPC:="yes"} RETVAL=0 -if [ ! "$MDS_TRANSPORT" = "TIPC" ] ; then - osafprog="osafdtmd" -fi +binary=$pkglibdir/$osafprog +pidfile=$pkgpiddir/$osafprog.pid +lockfile=$lockdir/$initscript start() { [ -p $NIDFIFO ] || return 1 + if [ ! -x "$binary" ]; then + echo "$NID_MAGIC:$NIDSERV:$DAEMON_NOT_FND" > "$NIDFIFO" + exit 5 + fi if [ "$MDS_TRANSPORT" = "TIPC" ]; then if [ $MANAGE_TIPC = "yes" ]; then $pkglibdir/configure_tipc start $TIPC_ETH_IF $TIPC_NET_ID @@ -47,14 +53,14 @@ start() { lsmod | grep tipc RETVAL=$? if [ $RETVAL -ne 0 ]; then - logger -t osaf-transport -s "TIPC module not loaded to OpenSAF requirements, returning..." + logger -t $osafprog -s "TIPC module not loaded to OpenSAF requirements, returning..." echo "$NID_MAGIC:$NIDSERV:$DAEMON_START_FAILED" > $NIDFIFO return $RETVAL else ls $pkglocalstatedir/node_id RETVAL=$? if [ $RETVAL -ne 0 ]; then - logger -t osaf-transport -s "$pkglocalstatedir/node_id not available whic is OpenSAF requirements, returning..." + logger -t $osafprog -s "$pkglocalstatedir/node_id not available whic is OpenSAF requirements, returning..." echo "$NID_MAGIC:$NIDSERV:$DAEMON_START_FAILED" > $NIDFIFO return $RETVAL fi @@ -64,9 +70,11 @@ start() { RETVAL=0 echo "$NID_MAGIC:$NIDSERV:$DAEMON_STARTED" > $NIDFIFO - $pkgclcclidir/osaf-transport-monitor & + start_daemon -p "$pidfile" "$binary" $args RETVAL=$? - if [ $RETVAL -ne 0 ]; then + if [ "$RETVAL" -eq 0 ]; then + touch "$lockfile" + else echo "Unable to start running Permanent loop to clean MDS Logs..." fi @@ -76,22 +84,31 @@ start() { if [ $RETVAL -ne 0 ]; then echo "$NID_MAGIC:$NIDSERV:$DAEMON_START_FAILED" > $NIDFIFO fi - #Fot TCP osaf-transport-monitor start will be moved to osaf-dtm process to make this script restart on fault - $pkgclcclidir/osaf-transport-monitor & + #Fot TCP osaftransportd start will be moved to osaf-dtm process to make this script restart on fault + start_daemon -p "$pidfile" "$binary" $args RETVAL=$? - if [ $RETVAL -ne 0 ]; then + if [ "$RETVAL" -eq 0 ]; then + touch "$lockfile" + else echo "Unable to start running Permanent loop to clean MDS Logs..." fi fi - + return "$RETVAL" } stop() { + killproc -p "$pidfile" "$osafprog" + RETVAL=$? + if [ "$RETVAL" -eq 0 ] || [ "$RETVAL" -eq 7 ]; then + rm -f "$lockfile" + RETVAL=0 + fi if [ ! "$MDS_TRANSPORT" = "TIPC" ]; then - killall -s KILL osaf-transport-monitor >/dev/null 2>&1 $pkgclcclidir/osaf-dtm stop + if [ "$RETVAL" -eq 0 ]; then + RETVAL=$? + fi fi - RETVAL=$? return $RETVAL } diff --git a/osaf/services/infrastructure/dtms/transport/Makefile.am b/osaf/services/infrastructure/dtms/transport/Makefile.am new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/Makefile.am @@ -0,0 +1,41 @@ +# -*- OpenSAF -*- +# +# (C) Copyright 2016 The OpenSAF Foundation # # This program is +distributed in the hope that it will be useful, but # WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY # or +FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed # +under the GNU Lesser General Public License Version 2.1, February 1999. +# The complete license can be accessed from the following location: +# http://opensource.org/licenses/lgpl-license.php +# See the Copying file included with the OpenSAF distribution for full +# licensing terms. +# +# Author(s): Ericsson AB +# + +include $(top_srcdir)/Makefile.common + +MAINTAINERCLEANFILES = Makefile.in + +DEFAULT_INCLUDES = + +SUBDIRS = tests + +noinst_HEADERS = \ + transport_monitor.h + +osaf_execbindir = $(pkglibdir) +osaf_execbin_PROGRAMS = osaftransportd + +osaftransportd_CXXFLAGS =$(AM_CXXFLAGS) + +osaftransportd_CPPFLAGS = \ + $(AM_CPPFLAGS) + +osaftransportd_SOURCES = \ + transport_monitor.cc \ + main.cc + +osaftransportd_LDADD = \ + $(top_builddir)/osaf/libs/core/libopensaf_core.la diff --git a/osaf/services/infrastructure/dtms/transport/main.cc b/osaf/services/infrastructure/dtms/transport/main.cc new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/main.cc @@ -0,0 +1,52 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <unistd.h> +#include <cstdlib> +#include "osaf/libs/core/common/include/daemon.h" +#include "osaf/libs/core/include/ncssysf_def.h" +#include "osaf/services/infrastructure/dtms/transport/transport_monitor.h" + +constexpr static const int kDaemonStartWaitTimeInSeconds = 15; + +int main(int argc, char** argv) { + opensaf_reboot_prepare(); + daemonize(argc, argv); + int term_fd; + daemon_sigterm_install(&term_fd); + TransportMonitor monitor{term_fd}; + pid_t pid = pid_t{0}; + if (!monitor.use_tipc()) { + pid = monitor.WaitForDaemon("osafdtmd", +kDaemonStartWaitTimeInSeconds); + } + const char* msg; + if (pid != pid_t{-1}) { + monitor.RotateMdsLogs(pid); + msg = "osafdtmd Process down, Rebooting the node"; + } else { + msg = "osafdtmd failed to start"; + } + if (!monitor.Sleep(0)) { + opensaf_reboot(0, nullptr, msg); + } else { + daemon_exit(); + } + return EXIT_FAILURE; +} diff --git a/osaf/services/infrastructure/dtms/transport/tests/Makefile.am b/osaf/services/infrastructure/dtms/transport/tests/Makefile.am new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/Makefile.am @@ -0,0 +1,45 @@ +# -*- OpenSAF -*- +# +# (C) Copyright 2016 The OpenSAF Foundation # # This program is +distributed in the hope that it will be useful, but # WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY # or +FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed # +under the GNU Lesser General Public License Version 2.1, February 1999. +# The complete license can be accessed from the following location: +# http://opensource.org/licenses/lgpl-license.php +# See the Copying file included with the OpenSAF distribution for full +# licensing terms. +# +# Author(s): Ericsson AB +# + +include $(top_srcdir)/Makefile.common + +MAINTAINERCLEANFILES = Makefile.in + +DEFAULT_INCLUDES = + +TESTS = transport_test + +check_PROGRAMS = $(TESTS) + +transport_test_CXXFLAGS =$(AM_CXXFLAGS) + +transport_test_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(GTEST_DIR)/include + +transport_test_LDFLAGS = \ + -pthread -lrt \ + $(top_builddir)/osaf/libs/core/cplusplus/base/libbase_la-getenv.o \ + +$(top_builddir)/osaf/services/infrastructure/dtms/transport/osaftranspo +rtd-transport_monitor.o + +transport_test_SOURCES = \ + transport_monitor_test.cc \ + mock_logtrace.cc \ + mock_osaf_poll.cc + +transport_test_LDADD = \ + $(GTEST_DIR)/lib/libgtest.la \ + $(GTEST_DIR)/lib/libgtest_main.la diff --git a/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.cc b/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.cc new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.cc @@ -0,0 +1,34 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#include "osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.h" + +void _logtrace_log(const char *file, unsigned int line, int priority, + const char *format, ...) { + (void) file; + (void) line; + (void) priority; + (void) format; +} + +void _logtrace_trace(const char *file, unsigned int line, unsigned int category, + const char *format, ...) { + (void) file; + (void) line; + (void) category; + (void) format; +} diff --git a/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.h b/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.h new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/mock_logtrace.h @@ -0,0 +1,23 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_LOGTRACE_H_ +#define +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_LOGTRACE_H_ + +#include "osaf/libs/core/common/include/logtrace.h" + +#endif // +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_LOGTRACE_H_ diff --git a/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.cc b/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.cc new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.c +++ c @@ -0,0 +1,26 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#include "osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h" +#include <cstdint> + +MockOsafPoll mock_osaf_poll; + +int osaf_poll_one_fd(int fd, int64_t timeout) { + ++mock_osaf_poll.invocations; + return mock_osaf_poll.return_value; +} diff --git a/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h b/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h @@ -0,0 +1,38 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_OSAF_POLL_H_ +#define +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_OSAF_POLL_H_ + +#include "osaf/libs/core/common/include/osaf_poll.h" + +struct MockOsafPoll { + MockOsafPoll() : + return_value{0}, + invocations{0} { + } + void reset() { + return_value = 0; + invocations = 0; + } + int return_value; + int invocations; +}; + +extern MockOsafPoll mock_osaf_poll; + +#endif // +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TESTS_MOCK_OSAF_POLL_H_ diff --git a/osaf/services/infrastructure/dtms/transport/tests/transport_monitor_test.cc b/osaf/services/infrastructure/dtms/transport/tests/transport_monitor_test.cc new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/tests/transport_monito +++ r_test.cc @@ -0,0 +1,109 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <unistd.h> +#include <cstdlib> +#include <fstream> +#include <string> +#include "gtest/gtest.h" +#include "osaf/services/infrastructure/dtms/transport/tests/mock_osaf_poll.h" +#include "osaf/services/infrastructure/dtms/transport/transport_monitor.h" + +class TransportMonitorTest : public ::testing::Test { + protected: + TransportMonitorTest() : + tmpdir_{}, + monitor_{nullptr} { + } + + virtual ~TransportMonitorTest() { + } + + virtual void SetUp() { + char tmpdir[] = "/tmp/transport_monitor_test_XXXXXX"; + char* result = mkdtemp(tmpdir); + ASSERT_NE(result, nullptr); + tmpdir_ = result; + int retval = setenv("pkgpiddir", tmpdir_.c_str(), 1); + ASSERT_EQ(retval, 0); + retval = setenv("pkglogdir", tmpdir_.c_str(), 1); + ASSERT_EQ(retval, 0); + mock_osaf_poll.reset(); + monitor_ = new TransportMonitor(0); } + + virtual void TearDown() { + delete monitor_; + monitor_ = nullptr; + std::string cmd = std::string("rm -f ") + tmpdir_ + std::string("/*"); + int result = system(cmd.c_str()); + ASSERT_EQ(result, 0); + result = rmdir(tmpdir_.c_str()); + ASSERT_EQ(result, 0); + result = unsetenv("pkglogdir"); + ASSERT_EQ(result, 0); + result = unsetenv("pkgpiddir"); + ASSERT_EQ(result, 0); + } + + void CreatePidFile(const char* daemon_name, pid_t pid, bool newline) { + std::ofstream str(tmpdir_ + std::string("/") + std::string(daemon_name) + + std::string(".pid")); + ASSERT_TRUE(str.good()); + str << pid; + ASSERT_TRUE(str.good()); + if (newline) str << "\n"; + ASSERT_TRUE(str.good()); + str.close(); + ASSERT_TRUE(str.good()); + } + + std::string tmpdir_; + TransportMonitor* monitor_; +}; + +TEST_F(TransportMonitorTest, WaitForNonexistentDaemonName) { + pid_t pid = monitor_->WaitForDaemon("name_does_not_exist", 17); + EXPECT_EQ(pid, pid_t{-1}); + EXPECT_EQ(mock_osaf_poll.invocations, 17); } + +TEST_F(TransportMonitorTest, WaitForNonexistentDaemonPid) { + CreatePidFile("pid_does_not_exist", 1234567890, false); + pid_t pid = monitor_->WaitForDaemon("pid_does_not_exist", 1); + EXPECT_EQ(pid, pid_t{-1}); + EXPECT_EQ(mock_osaf_poll.invocations, 1); } + +TEST_F(TransportMonitorTest, WaitForExistingPid) { + pid_t mypid = getpid(); + CreatePidFile("existing", mypid, false); + pid_t pid = monitor_->WaitForDaemon("existing", 1); + EXPECT_EQ(pid, mypid); + EXPECT_EQ(mock_osaf_poll.invocations, 0); } + +TEST_F(TransportMonitorTest, WaitForExistingPidWithNewline) { + pid_t mypid = getpid(); + CreatePidFile("existing", mypid, true); + pid_t pid = monitor_->WaitForDaemon("existing", 1); + EXPECT_EQ(pid, mypid); + EXPECT_EQ(mock_osaf_poll.invocations, 0); } diff --git a/osaf/services/infrastructure/dtms/transport/transport_monitor.cc b/osaf/services/infrastructure/dtms/transport/transport_monitor.cc new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/transport_monitor.cc @@ -0,0 +1,95 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "osaf/services/infrastructure/dtms/transport/transport_monitor.h" +#include <sys/stat.h> +#include <cstdio> +#include <fstream> +#include "./configmake.h" +#include "osaf/libs/core/common/include/osaf_poll.h" +#include "osaf/libs/core/cplusplus/base/getenv.h" + +TransportMonitor::TransportMonitor(int term_fd) + : term_fd_{term_fd}, + pkgpiddir_{base::GetEnv<std::string>("pkgpiddir", PKGPIDDIR)}, + proc_path_{"/proc/"}, + mds_log_file_{base::GetEnv<std::string>("pkglogdir", PKGLOGDIR) + + "/mds.log"}, + old_mds_log_file_{mds_log_file_ + ".old"}, + use_tipc_{base::GetEnv<std::string>("MDS_TRANSPORT", "TCP") == +"TIPC"} { } + +TransportMonitor::~TransportMonitor() { } + +pid_t TransportMonitor::WaitForDaemon(const std::string& daemon_name, + int64_t seconds_to_wait) { + std::string pidfile = pkgpiddir_ + "/" + daemon_name + ".pid"; + pid_t pid = pid_t{-1}; + for (int64_t count = 0; count != seconds_to_wait; ++count) { + if (!(std::ifstream{pidfile} >> pid).fail() + && IsDir(proc_path_ + std::to_string(pid))) + break; + pid = pid_t{-1}; + if (Sleep(1)) + return pid_t{-1}; + } + return pid; +} + +bool TransportMonitor::Sleep(int64_t seconds_to_wait) { + return osaf_poll_one_fd(term_fd_, seconds_to_wait * 1000) != 0; } + +bool TransportMonitor::IsDir(const std::string& path) { + struct stat stat_buf; + int stat_result = stat(path.c_str(), &stat_buf); + return stat_result == 0 && S_ISDIR(stat_buf.st_mode) != 0; } + +void TransportMonitor::RotateMdsLogs(pid_t pid_to_watch) { + std::string pid_path{proc_path_ + std::to_string(pid_to_watch)}; + for (;;) { + if (FileSize(mds_log_file_) > kMaxFileSize) { + unlink(old_mds_log_file()); + rename(mds_log_file(), old_mds_log_file()); + } + if (pid_to_watch != pid_t{0}) { + for (int64_t i = 0; i != kLogRotationIntervalInSeconds; ++i) { + if (!IsDir(pid_path) || Sleep(1)) + return; + } + } else { + if (Sleep(kLogRotationIntervalInSeconds)) + return; + } + } +} + +uint64_t TransportMonitor::FileSize(const std::string& path) { + struct stat stat_buf; + uint64_t file_size; + if (stat(path.c_str(), &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) != 0) { + file_size = static_cast<uint64_t>(stat_buf.st_blocks) * 512; + } else { + file_size = 0; + } + return file_size; +} diff --git a/osaf/services/infrastructure/dtms/transport/transport_monitor.h b/osaf/services/infrastructure/dtms/transport/transport_monitor.h new file mode 100644 --- /dev/null +++ b/osaf/services/infrastructure/dtms/transport/transport_monitor.h @@ -0,0 +1,92 @@ +/* -*- OpenSAF -*- + * + * (C) Copyright 2016 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are +licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson AB + * + */ + +#ifndef +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TRANSPORT_MONITOR_H_ +#define +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TRANSPORT_MONITOR_H_ + +#include <unistd.h> +#include <cstdint> +#include <string> +#include "osaf/libs/core/cplusplus/base/macros.h" + +// This class is responsible for monitoring the osafdtmd process and +rotating // the MDS logs. +class TransportMonitor { + public: + // @a term_fd is a file descriptor that will become readable when the +program + // should exit because it has received the SIGTERM signal. + explicit TransportMonitor(int term_fd); + virtual ~TransportMonitor(); + + // Wait @a seconds_to_wait seconds for the OpenSAF daemon + @daemon_name to // start. Return the process id of the daemon + process, or pid_t{-1} if the // daemon didn't start within @a + seconds_to wait or if we have received the // SIGTERM signal and should exit. + pid_t WaitForDaemon(const std::string& daemon_name, int64_t + seconds_to_wait); + + // Run in a loop, rotating the MDS logs every + kLogRotationIntervalInSeconds // seconds if the MDS log file size is + larger than kMaxFileSize. If @a // pid_to_watch is non-zero, watch + the process with that process id. Return if // the process dies, or + if we have received the SIGTERM signal and should // exit. + void RotateMdsLogs(pid_t pid_to_watch); + + // Sleep for @a seconds_to_wait seconds, or until we have received + the SIGTERM // signal and should exit, whichever happens first. + Return true if the SIGTERM // signal has been received, and false otherwise. + bool Sleep(int64_t seconds_to_wait); + + // Return true if OpenSAF has been configured to use the TIPC + transport, and // false if the TCP transport has been configured. + bool use_tipc() const { + return use_tipc_; + } + + private: + constexpr static const uint64_t kMaxFileSize = 5000 * uint64_t{1024}; + constexpr static const int64_t kLogRotationIntervalInSeconds = 15; + + const char* pkgpiddir() const { + return pkgpiddir_.c_str(); + } + + const char* proc_path() const { + return proc_path_.c_str(); + } + + const char* mds_log_file() const { + return mds_log_file_.c_str(); + } + + const char* old_mds_log_file() const { + return old_mds_log_file_.c_str(); + } + + static bool IsDir(const std::string& path); static uint64_t + FileSize(const std::string& path); + + int term_fd_; + const std::string pkgpiddir_; + const std::string proc_path_; + const std::string mds_log_file_; + const std::string old_mds_log_file_; + const bool use_tipc_; + + DELETE_COPY_AND_MOVE_OPERATORS(TransportMonitor); +}; + +#endif // +OSAF_SERVICES_INFRASTRUCTURE_DTMS_TRANSPORT_TRANSPORT_MONITOR_H_ diff --git a/osaf/services/infrastructure/nid/scripts/opensafd.in b/osaf/services/infrastructure/nid/scripts/opensafd.in --- a/osaf/services/infrastructure/nid/scripts/opensafd.in +++ b/osaf/services/infrastructure/nid/scripts/opensafd.in @@ -113,11 +113,9 @@ enable_coredump() { final_clean() { # Loop throught all the OpenSAF LSB CLC-CLI scripts to clean staling pid/lock - killall -s KILL osaf-transport-monitor >/dev/null 2>&1 - for cmd in `ls $pkgclcclidir/osaf-*`; do # skip dtm here to allow shutdown of other services (e.g. amfd) - if [ "$cmd" != "$pkgclcclidir/osaf-dtm" ] && [ "$cmd" != "$pkgclcclidir/osaf-transport-monitor" ]; then + if [ "$cmd" != "$pkgclcclidir/osaf-dtm" ]; then $cmd stop >/dev/null 2>&1 fi done @@ -241,8 +239,6 @@ start() { stop() { logger -t $osafprog "Stopping OpenSAF Services" - killall -s KILL osaf-transport-monitor >/dev/null 2>&1 - amfpid=`pidofproc -p $amfnd_pid $amfnd_bin` echo -n "Stopping OpenSAF Services: " if [ -n "$amfpid" ]; then ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel