You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by mp...@apache.org on 2016/08/25 23:03:04 UTC

kudu git commit: Rolling-upgrades compat for changing TSRegistrationPB

Repository: kudu
Updated Branches:
  refs/heads/master ebe4d78bf -> 43d2749dd


Rolling-upgrades compat for changing TSRegistrationPB

This should allow for adding fields to TSRegistrationPB.
Only the host/port is checked.

Change-Id: I794517d200b1c9ad74b3897b17aa808d68d7924b
Reviewed-on: http://gerrit.cloudera.org:8080/4062
Tested-by: Kudu Jenkins
Reviewed-by: Adar Dembo <ad...@cloudera.com>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/43d2749d
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/43d2749d
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/43d2749d

Branch: refs/heads/master
Commit: 43d2749ddb096d5534507d71314a558cbf420537
Parents: ebe4d78
Author: Mike Percy <mp...@apache.org>
Authored: Fri Aug 19 03:06:09 2016 -0600
Committer: Mike Percy <mp...@apache.org>
Committed: Thu Aug 25 23:02:50 2016 +0000

----------------------------------------------------------------------
 src/kudu/master/master-test.cc   | 15 +++++++++++++++
 src/kudu/master/ts_descriptor.cc | 26 +++++++++++++++++++++++++-
 src/kudu/util/net/net_util.cc    | 12 ++++++++++++
 src/kudu/util/net/net_util.h     | 18 ++++++++++++++++++
 4 files changed, 70 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/43d2749d/src/kudu/master/master-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/master/master-test.cc b/src/kudu/master/master-test.cc
index ccd75b1..e47ec07 100644
--- a/src/kudu/master/master-test.cc
+++ b/src/kudu/master/master-test.cc
@@ -25,6 +25,7 @@
 
 #include "kudu/common/partial_row.h"
 #include "kudu/common/row_operations.h"
+#include "kudu/generated/version_defines.h"
 #include "kudu/gutil/strings/join.h"
 #include "kudu/master/master.h"
 #include "kudu/master/master.proxy.h"
@@ -277,6 +278,20 @@ TEST_F(MasterTest, TestRegisterAndHeartbeat) {
     ASSERT_EQ(1, resp.servers(0).instance_id().instance_seqno());
   }
 
+  // Ensure that trying to re-register with a different version is OK.
+  {
+    TSHeartbeatRequestPB req;
+    TSHeartbeatResponsePB resp;
+    RpcController rpc;
+    req.mutable_common()->CopyFrom(common);
+    req.mutable_registration()->CopyFrom(fake_reg);
+    // This string should never match the actual VersionInfo string, although
+    // the numeric portion will match.
+    req.mutable_registration()->set_software_version(Substitute("kudu $0 (rev SOME_NON_GIT_HASH)",
+                                                                KUDU_VERSION_STRING));
+    ASSERT_OK(proxy_->TSHeartbeat(req, &resp, &rpc));
+  }
+
   // Ensure that trying to re-register with a different port fails.
   {
     TSHeartbeatRequestPB req;

http://git-wip-us.apache.org/repos/asf/kudu/blob/43d2749d/src/kudu/master/ts_descriptor.cc
----------------------------------------------------------------------
diff --git a/src/kudu/master/ts_descriptor.cc b/src/kudu/master/ts_descriptor.cc
index 35c8629..1f3ef11 100644
--- a/src/kudu/master/ts_descriptor.cc
+++ b/src/kudu/master/ts_descriptor.cc
@@ -19,6 +19,7 @@
 
 #include <math.h>
 #include <mutex>
+#include <unordered_set>
 #include <vector>
 
 #include "kudu/common/wire_protocol.h"
@@ -55,6 +56,27 @@ TSDescriptor::TSDescriptor(std::string perm_id)
 TSDescriptor::~TSDescriptor() {
 }
 
+// Compares two repeated HostPortPB fields. Returns true if equal, false otherwise.
+static bool HostPortPBsEqual(const google::protobuf::RepeatedPtrField<HostPortPB>& pb1,
+                             const google::protobuf::RepeatedPtrField<HostPortPB>& pb2) {
+  if (pb1.size() != pb2.size()) {
+    return false;
+  }
+
+  // Do a set-based equality search.
+  std::unordered_set<HostPort, HostPortHasher, HostPortEqualityPredicate> hostports1;
+  std::unordered_set<HostPort, HostPortHasher, HostPortEqualityPredicate> hostports2;
+  for (int i = 0; i < pb1.size(); i++) {
+    HostPort hp1;
+    HostPort hp2;
+    if (!HostPortFromPB(pb1.Get(i), &hp1).ok()) return false;
+    if (!HostPortFromPB(pb2.Get(i), &hp2).ok()) return false;
+    hostports1.insert(hp1);
+    hostports2.insert(hp2);
+  }
+  return hostports1 == hostports2;
+}
+
 Status TSDescriptor::Register(const NodeInstancePB& instance,
                               const TSRegistrationPB& registration) {
   std::lock_guard<simple_spinlock> l(lock_);
@@ -62,7 +84,9 @@ Status TSDescriptor::Register(const NodeInstancePB& instance,
 
   // TODO(KUDU-418): we don't currently support changing IPs or hosts since the
   // host/port is stored persistently in each tablet's metadata.
-  if (registration_ && registration_->ShortDebugString() != registration.ShortDebugString()) {
+  if (registration_ &&
+      (!HostPortPBsEqual(registration_->rpc_addresses(), registration.rpc_addresses()) ||
+       !HostPortPBsEqual(registration_->http_addresses(), registration.http_addresses()))) {
     string msg = strings::Substitute(
         "Tablet server $0 is attempting to re-register with a different host/port. "
         "This is not currently supported. Old: {$1} New: {$2}",

http://git-wip-us.apache.org/repos/asf/kudu/blob/43d2749d/src/kudu/util/net/net_util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/net/net_util.cc b/src/kudu/util/net/net_util.cc
index 6b1d4f6..0564398 100644
--- a/src/kudu/util/net/net_util.cc
+++ b/src/kudu/util/net/net_util.cc
@@ -21,6 +21,7 @@
 #include <netdb.h>
 
 #include <algorithm>
+#include <boost/functional/hash.hpp>
 #include <gflags/gflags.h>
 #include <unordered_set>
 #include <utility>
@@ -78,6 +79,17 @@ HostPort::HostPort(const Sockaddr& addr)
     port_(addr.port()) {
 }
 
+bool operator==(const HostPort& hp1, const HostPort& hp2) {
+  return hp1.port() == hp2.port() && hp1.host() == hp2.host();
+}
+
+size_t HostPort::HashCode() const {
+  size_t seed = 0;
+  boost::hash_combine(seed, host_);
+  boost::hash_combine(seed, port_);
+  return seed;
+}
+
 Status HostPort::ParseString(const string& str, uint16_t default_port) {
   std::pair<string, string> p = strings::Split(str, strings::delimiter::Limit(":", 1));
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/43d2749d/src/kudu/util/net/net_util.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/net/net_util.h b/src/kudu/util/net/net_util.h
index d0bb92e..3086f4a 100644
--- a/src/kudu/util/net/net_util.h
+++ b/src/kudu/util/net/net_util.h
@@ -52,6 +52,8 @@ class HostPort {
   uint16_t port() const { return port_; }
   void set_port(uint16_t port) { port_ = port; }
 
+  size_t HashCode() const;
+
   // Parse a comma separated list of "host:port" pairs into a vector
   // HostPort objects. If no port is specified for an entry in the
   // comma separated list, 'default_port' is used for that entry's
@@ -69,6 +71,22 @@ class HostPort {
   uint16_t port_;
 };
 
+bool operator==(const HostPort& hp1, const HostPort& hp2);
+
+// Hasher of HostPort objects for UnorderedAssociativeContainers.
+struct HostPortHasher {
+  size_t operator()(const HostPort& hp) const {
+    return hp.HashCode();
+  }
+};
+
+// Equality BinaryPredicate of HostPort objects for UnorderedAssociativeContainers.
+struct HostPortEqualityPredicate {
+  bool operator()(const HostPort& hp1, const HostPort& hp2) const {
+    return hp1 == hp2;
+  }
+};
+
 // Parse and resolve the given comma-separated list of addresses.
 //
 // The resulting addresses will be resolved, made unique, and added to