This is an automated email from the ASF dual-hosted git repository.

amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 6c8cd24  Check version in the snap file on ATS upgrade
6c8cd24 is described below

commit 6c8cd246baa5a8d4c0957a19585d45833682a33e
Author: Xavier Chi <[email protected]>
AuthorDate: Tue Jul 17 10:25:42 2018 -0500

    Check version in the snap file on ATS upgrade
---
 lib/records/P_RecCore.cc  | 25 +++++++++++++++++++++++++
 lib/records/P_RecFile.h   |  3 +++
 lib/records/RecCore.cc    |  2 +-
 lib/records/RecFile.cc    | 36 ++++++++++++++++++++++++++++++++++++
 lib/records/RecMessage.cc |  6 +++---
 5 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/lib/records/P_RecCore.cc b/lib/records/P_RecCore.cc
index 4e07377..11d800c 100644
--- a/lib/records/P_RecCore.cc
+++ b/lib/records/P_RecCore.cc
@@ -34,6 +34,8 @@
 #include "P_RecMessage.h"
 #include "P_RecCore.h"
 
+#include <fstream>
+
 RecModeT g_mode_type = RECM_NULL;
 
 //-------------------------------------------------------------------------
@@ -491,6 +493,27 @@ RecSetRecordCounter(const char *name, RecCounter 
rec_counter, RecSourceT source,
   return RecSetRecord(RECT_NULL, name, RECD_COUNTER, &data, nullptr, source, 
lock, inc_version);
 }
 
+// check the version of the snap file to remove records.snap or not
+static void
+CheckSnapFileVersion(const char *path)
+{
+  std::ifstream f(path, std::ios::binary);
+  if (f.good()) {
+    // get version, compare and remove
+    char data[VERSION_HDR_SIZE];
+    if (!f.read(data, VERSION_HDR_SIZE)) {
+      return;
+    }
+    if (data[0] != 'V' || data[1] != PACKAGE_VERSION[0] || data[2] != 
PACKAGE_VERSION[2] || data[3] != PACKAGE_VERSION[4] ||
+        data[4] != '\0') {
+      // not the right version found
+      if (remove(path) != 0) {
+        ink_warning("unable to remove incompatible snap file '%s'", path);
+      }
+    }
+  }
+}
+
 //-------------------------------------------------------------------------
 // RecReadStatsFile
 //-------------------------------------------------------------------------
@@ -506,6 +529,8 @@ RecReadStatsFile()
   // lock our hash table
   ink_rwlock_wrlock(&g_records_rwlock);
 
+  CheckSnapFileVersion(snap_fpath);
+
   if ((m = RecMessageReadFromDisk(snap_fpath)) != nullptr) {
     if (RecMessageUnmarshalFirst(m, &itr, &r) != REC_ERR_FAIL) {
       do {
diff --git a/lib/records/P_RecFile.h b/lib/records/P_RecFile.h
index a47448d..93c0c40 100644
--- a/lib/records/P_RecFile.h
+++ b/lib/records/P_RecFile.h
@@ -30,6 +30,7 @@
 #define REC_HANDLE_INVALID -1
 typedef int RecHandle;
 
+static constexpr unsigned VERSION_HDR_SIZE = 5;
 //-------------------------------------------------------------------------
 // RecFile
 //-------------------------------------------------------------------------
@@ -38,7 +39,9 @@ RecHandle RecFileOpenR(const char *file);
 RecHandle RecFileOpenW(const char *file);
 int RecFileClose(RecHandle h_file);
 int RecFileRead(RecHandle h_file, char *buf, int size, int *bytes_read);
+int RecSnapFileRead(RecHandle h_file, char *buf, int size, int *bytes_read);
 int RecFileWrite(RecHandle h_file, char *buf, int size, int *bytes_written);
+int RecSnapFileWrite(RecHandle h_file, char *buf, int size, int 
*bytes_written);
 int RecFileGetSize(RecHandle h_file);
 int RecFileExists(const char *file);
 int RecFileSync(RecHandle h_file);
diff --git a/lib/records/RecCore.cc b/lib/records/RecCore.cc
index ddd281b..d6c4530 100644
--- a/lib/records/RecCore.cc
+++ b/lib/records/RecCore.cc
@@ -47,7 +47,7 @@ register_record(RecT rec_type, const char *name, RecDataT 
data_type, RecData dat
   RecRecord *r = nullptr;
 
   // Metrics are restored from persistence before they are registered. In this 
case, when the registration arrives, we
-  // might find that they yave changed. For example, a metric might change 
it's type due to a software upgrade. Records
+  // might find that they have changed. For example, a metric might change 
it's type due to a software upgrade. Records
   // must not flip between config and metrics, but changing within those 
classes is OK.
   if (ink_hash_table_lookup(g_records_ht, name, (void **)&r)) {
     if (REC_TYPE_IS_STAT(rec_type)) {
diff --git a/lib/records/RecFile.cc b/lib/records/RecFile.cc
index 466864b..99a5189 100644
--- a/lib/records/RecFile.cc
+++ b/lib/records/RecFile.cc
@@ -27,6 +27,8 @@
 #include "P_RecDefs.h"
 #include "P_RecUtils.h"
 
+#include <array>
+
 //-------------------------------------------------------------------------
 // RecFileOpenR
 //-------------------------------------------------------------------------
@@ -75,6 +77,20 @@ RecFileClose(RecHandle h_file)
 }
 
 //-------------------------------------------------------------------------
+// RecSnapFileRead
+//-------------------------------------------------------------------------
+
+int
+RecSnapFileRead(RecHandle h_file, char *buf, int size, int *bytes_read)
+{
+  if ((*bytes_read = ::pread(h_file, buf, size, VERSION_HDR_SIZE)) <= 0) {
+    *bytes_read = 0;
+    return REC_ERR_FAIL;
+  }
+  return REC_ERR_OKAY;
+}
+
+//-------------------------------------------------------------------------
 // RecFileRead
 //-------------------------------------------------------------------------
 
@@ -89,6 +105,26 @@ RecFileRead(RecHandle h_file, char *buf, int size, int 
*bytes_read)
 }
 
 //-------------------------------------------------------------------------
+// RecSnapFileWrite
+//-------------------------------------------------------------------------
+
+int
+RecSnapFileWrite(RecHandle h_file, char *buf, int size, int *bytes_written)
+{
+  // First write the version byes for snap file
+  std::array<char, VERSION_HDR_SIZE> VERSION_HDR{{'V', PACKAGE_VERSION[0], 
PACKAGE_VERSION[2], PACKAGE_VERSION[4], '\0'}};
+  if (::write(h_file, VERSION_HDR.data(), VERSION_HDR_SIZE) < 0) {
+    return REC_ERR_FAIL;
+  }
+
+  if ((*bytes_written = ::pwrite(h_file, buf, size, VERSION_HDR_SIZE)) < 0) {
+    *bytes_written = 0;
+    return REC_ERR_FAIL;
+  }
+  return REC_ERR_OKAY;
+}
+
+//-------------------------------------------------------------------------
 // RecFileWrite
 //-------------------------------------------------------------------------
 
diff --git a/lib/records/RecMessage.cc b/lib/records/RecMessage.cc
index bcb35cf..e863636 100644
--- a/lib/records/RecMessage.cc
+++ b/lib/records/RecMessage.cc
@@ -266,12 +266,12 @@ RecMessageReadFromDisk(const char *fpath)
   if ((h_file = RecFileOpenR(fpath)) == REC_HANDLE_INVALID) {
     goto Lerror;
   }
-  if (RecFileRead(h_file, (char *)(&msg_hdr), sizeof(RecMessageHdr), 
&bytes_read) == REC_ERR_FAIL) {
+  if (RecSnapFileRead(h_file, (char *)(&msg_hdr), sizeof(RecMessageHdr), 
&bytes_read) == REC_ERR_FAIL) {
     goto Lerror;
   }
   msg = (RecMessage *)ats_malloc((msg_hdr.o_end - msg_hdr.o_start) + 
sizeof(RecMessageHdr));
   memcpy(msg, &msg_hdr, sizeof(RecMessageHdr));
-  if (RecFileRead(h_file, (char *)(msg) + msg_hdr.o_start, msg_hdr.o_end - 
msg_hdr.o_start, &bytes_read) == REC_ERR_FAIL) {
+  if (RecSnapFileRead(h_file, (char *)(msg) + msg_hdr.o_start, msg_hdr.o_end - 
msg_hdr.o_start, &bytes_read) == REC_ERR_FAIL) {
     goto Lerror;
   }
 
@@ -307,7 +307,7 @@ RecMessageWriteToDisk(RecMessage *msg, const char *fpath)
 
   msg_size = sizeof(RecMessageHdr) + (msg->o_write - msg->o_start);
   if ((h_file = RecFileOpenW(fpath)) != REC_HANDLE_INVALID) {
-    if (RecFileWrite(h_file, (char *)msg, msg_size, &bytes_written) == 
REC_ERR_FAIL) {
+    if (RecSnapFileWrite(h_file, (char *)msg, msg_size, &bytes_written) == 
REC_ERR_FAIL) {
       RecFileClose(h_file);
       return REC_ERR_FAIL;
     }

Reply via email to