Adding Sanity checks in Get and Iterator->value for ttl

Summary: The 2 checks added will increase reliabilty and help in debugging

Test Plan: make ttl_test;./ttl_test

Reviewers: vamsi, dhruba, sheki, haobo

Reviewed By: vamsi

Differential Revision: https://reviews.facebook.net/D10713
main
Mayank Agarwal 12 years ago
parent ff1a0801fc
commit c605e12479
  1. 25
      utilities/ttl/db_ttl.cc
  2. 4
      utilities/ttl/db_ttl.h

@ -53,7 +53,7 @@ class TtlIterator : public Iterator {
} }
Slice value() const { Slice value() const {
assert(iter_->value().size() >= (unsigned)ts_len_); assert(DBWithTTL::SanityCheckTimestamp(iter_->value().ToString()).ok());
Slice trimmed_value = iter_->value(); Slice trimmed_value = iter_->value();
trimmed_value.size_ -= ts_len_; trimmed_value.size_ -= ts_len_;
return trimmed_value; return trimmed_value;
@ -130,6 +130,22 @@ Status DBWithTTL::AppendTS(const Slice& val, std::string& val_with_ts) {
return st; return st;
} }
// Returns corruption if the length of the string is lesser than timestamp, or
// timestamp refers to a time lesser than ttl-feature release time
Status DBWithTTL::SanityCheckTimestamp(const std::string& str) {
if (str.length() < (unsigned)kTSLength) {
return Status::Corruption("Error: value's length less than timestamp's\n");
}
// Checks that TS is not lesser than kMinTimestamp
// Gaurds against corruption & normal database opened incorrectly in ttl mode
int32_t timestamp_value =
DecodeFixed32(str.data() + str.size() - kTSLength);
if (timestamp_value < kMinTimestamp){
return Status::Corruption("Error: Timestamp < ttl feature release time!\n");
}
return Status::OK();
}
// Checks if the string is stale or not according to TTl provided // Checks if the string is stale or not according to TTl provided
bool DBWithTTL::IsStale(const Slice& value, int32_t ttl) { bool DBWithTTL::IsStale(const Slice& value, int32_t ttl) {
if (ttl <= 0) { // Data is fresh if TTL is non-positive if (ttl <= 0) { // Data is fresh if TTL is non-positive
@ -151,9 +167,6 @@ bool DBWithTTL::IsStale(const Slice& value, int32_t ttl) {
// Strips the TS from the end of the string // Strips the TS from the end of the string
Status DBWithTTL::StripTS(std::string* str) { Status DBWithTTL::StripTS(std::string* str) {
Status st; Status st;
if (str->length() < (unsigned)kTSLength) {
return Status::IOError("Error: value's length less than timestamp's\n");
}
// Erasing characters which hold the TS // Erasing characters which hold the TS
str->erase(str->length() - kTSLength, kTSLength); str->erase(str->length() - kTSLength, kTSLength);
return st; return st;
@ -178,6 +191,10 @@ Status DBWithTTL::Get(const ReadOptions& options,
if (!st.ok()) { if (!st.ok()) {
return st; return st;
} }
st = SanityCheckTimestamp(*value);
if (!st.ok()) {
return st;
}
return StripTS(value); return StripTS(value);
} }

@ -81,12 +81,16 @@ class DBWithTTL : public DB {
static Status AppendTS(const Slice& val, std::string& val_with_ts); static Status AppendTS(const Slice& val, std::string& val_with_ts);
static Status SanityCheckTimestamp(const std::string& str);
static Status StripTS(std::string* str); static Status StripTS(std::string* str);
static Status GetCurrentTime(int32_t& curtime); static Status GetCurrentTime(int32_t& curtime);
static const int32_t kTSLength = sizeof(int32_t); // size of timestamp static const int32_t kTSLength = sizeof(int32_t); // size of timestamp
static const int32_t kMinTimestamp = 1368146402; // 05/09/2013:5:40PM
private: private:
DB* db_; DB* db_;
int32_t ttl_; int32_t ttl_;

Loading…
Cancel
Save