src/dtm/Makefile.am                        |   7 ++-
 src/dtm/transport/log_server.cc            |   6 +-
 src/dtm/transport/log_writer.cc            |  15 +----
 src/dtm/transport/log_writer.h             |   3 +-
 src/dtm/transport/tests/log_writer_test.cc |  75 ++++++++++++++++++++++++++++++
 5 files changed, 89 insertions(+), 17 deletions(-)


Fix a bug in the MDS log server that caused it to overwrite an existing MDS log
after a node reboot. An existing log file will now be appended.

diff --git a/src/dtm/Makefile.am b/src/dtm/Makefile.am
--- a/src/dtm/Makefile.am
+++ b/src/dtm/Makefile.am
@@ -1,6 +1,7 @@
 #      -*- OpenSAF  -*-
 #
 # (C) Copyright 2016 The OpenSAF Foundation
+# Copyright Ericsson AB 2017 - All Rights Reserved.
 #
 # This program is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -82,12 +83,14 @@ bin_transport_test_CPPFLAGS = \
 bin_transport_test_LDFLAGS = \
        $(AM_LDFLAGS) \
        src/base/lib_libopensaf_core_la-getenv.lo \
+       src/dtm/transport/bin_osaftransportd-log_writer.o \
        src/dtm/transport/bin_osaftransportd-transport_monitor.o
 
 bin_transport_test_SOURCES = \
-       src/dtm/transport/tests/transport_monitor_test.cc \
+       src/dtm/transport/tests/log_writer_test.cc \
        src/dtm/transport/tests/mock_logtrace.cc \
-       src/dtm/transport/tests/mock_osaf_poll.cc
+       src/dtm/transport/tests/mock_osaf_poll.cc \
+       src/dtm/transport/tests/transport_monitor_test.cc
 
 bin_transport_test_LDADD = \
        $(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/dtm/transport/log_server.cc b/src/dtm/transport/log_server.cc
--- a/src/dtm/transport/log_server.cc
+++ b/src/dtm/transport/log_server.cc
@@ -1,6 +1,7 @@
 /*      -*- OpenSAF  -*-
  *
  * (C) Copyright 2016 The OpenSAF Foundation
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -36,8 +37,9 @@ void LogServer::Run() {
     {term_fd_, POLLIN, 0},
     {log_socket_.fd(), POLLIN, 0}
   };
-  struct timespec last_flush = base::ReadMonotonicClock();
+  struct timespec last_flush{};
   do {
+    if (log_writer_.empty()) last_flush = base::ReadMonotonicClock();
     for (int i = 0; i < 256; ++i) {
       char* buffer = log_writer_.current_buffer_position();
       ssize_t result = log_socket_.Recv(buffer, LogWriter::kMaxMessageSize);
@@ -57,6 +59,6 @@ void LogServer::Run() {
     }
     struct timespec timeout = (last_flush + base::kFifteenSeconds) - current;
     pfd[1].fd = log_socket_.fd();
-    osaf_ppoll(pfd, 2, &timeout, nullptr);
+    osaf_ppoll(pfd, 2, log_writer_.empty() ? nullptr : &timeout, nullptr);
   } while ((pfd[0].revents & POLLIN) == 0);
 }
diff --git a/src/dtm/transport/log_writer.cc b/src/dtm/transport/log_writer.cc
--- a/src/dtm/transport/log_writer.cc
+++ b/src/dtm/transport/log_writer.cc
@@ -1,6 +1,7 @@
 /*      -*- OpenSAF  -*-
  *
  * (C) Copyright 2016 The OpenSAF Foundation
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -48,8 +49,9 @@ void LogWriter::Open() {
                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
     } while (fd == -1 && errno == EINTR);
     if (fd >= 0) {
+      off_t seek_result = lseek(fd, 0, SEEK_END);
+      if (seek_result >= 0) current_file_size_ = seek_result;
       fd_ = fd;
-      current_file_size_ = FileSize(fd);
     }
   }
 }
@@ -98,14 +100,3 @@ void LogWriter::Flush() {
   }
   current_file_size_ += bytes_written;
 }
-
-size_t LogWriter::FileSize(int fd) {
-  struct stat stat_buf;
-  size_t file_size;
-  if (fstat(fd, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) != 0) {
-    file_size = static_cast<size_t>(stat_buf.st_blocks) * 512;
-  } else {
-    file_size = 0;
-  }
-  return file_size;
-}
diff --git a/src/dtm/transport/log_writer.h b/src/dtm/transport/log_writer.h
--- a/src/dtm/transport/log_writer.h
+++ b/src/dtm/transport/log_writer.h
@@ -1,6 +1,7 @@
 /*      -*- OpenSAF  -*-
  *
  * (C) Copyright 2016 The OpenSAF Foundation
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -32,6 +33,7 @@ class LogWriter {
   virtual ~LogWriter();
 
   char* current_buffer_position() { return buffer_ + current_buffer_size_; }
+  bool empty() const { return current_buffer_size_ == 0; }
 
   // Write @a size bytes of log message data in the memory pointed to by @a
   // buffer to the MDS log file. After the log message has been written, the
@@ -42,7 +44,6 @@ class LogWriter {
  private:
   constexpr static const size_t kBufferSize = 128 * size_t{1024};
   constexpr static const size_t kMaxFileSize = 5000 * size_t{1024};
-  static size_t FileSize(int fd);
   void Open();
   void Close();
   void RotateLog();
diff --git a/src/dtm/transport/tests/log_writer_test.cc 
b/src/dtm/transport/tests/log_writer_test.cc
new file mode 100644
--- /dev/null
+++ b/src/dtm/transport/tests/log_writer_test.cc
@@ -0,0 +1,75 @@
+/*      -*- OpenSAF  -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <string>
+#include "dtm/transport/log_writer.h"
+#include "gtest/gtest.h"
+
+class LogWriterTest : public ::testing::Test {
+ protected:
+  LogWriterTest() :
+      tmpdir_{} {
+  }
+
+  virtual ~LogWriterTest() {
+  }
+
+  virtual void SetUp() {
+    char tmpdir[] = "/tmp/log_writer_test_XXXXXX";
+    char* result = mkdtemp(tmpdir);
+    ASSERT_NE(result, nullptr);
+    tmpdir_ = result;
+    int retval = setenv("pkglogdir", tmpdir_.c_str(), 1);
+    ASSERT_EQ(retval, 0);
+  }
+
+  virtual void TearDown() {
+    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);
+  }
+
+  std::string tmpdir_;
+};
+
+TEST_F(LogWriterTest, ExistingFileShouldBeAppended) {
+  const char first_line[] = "first line";
+  const char second_line[] = "second line";
+  std::ofstream ostr(tmpdir_ + std::string("/mds.log"));
+  ostr << first_line << std::endl;
+  ostr.close();
+  LogWriter* log_writer = new LogWriter();
+  memcpy(log_writer->current_buffer_position(), second_line,
+         sizeof(second_line) - 1);
+  log_writer->current_buffer_position()[sizeof(second_line) - 1] = '\n';
+  log_writer->Write(sizeof(second_line));
+  delete log_writer;
+  std::ifstream istr(tmpdir_ + std::string("/mds.log"));
+  std::string line1;
+  std::string line2;
+  std::getline(istr, line1);
+  EXPECT_FALSE(istr.fail());
+  std::getline(istr, line2);
+  EXPECT_FALSE(istr.fail());
+  EXPECT_EQ(line1, std::string(first_line));
+  EXPECT_EQ(line2, std::string(second_line));
+}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to