You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2015/06/09 22:53:19 UTC

mesos git commit: Added HTB queueing discipline wrapper class.

Repository: mesos
Updated Branches:
  refs/heads/master 118c9d56b -> 8559d7b73


Added HTB queueing discipline wrapper class.

Review: https://reviews.apache.org/r/35225


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8559d7b7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8559d7b7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8559d7b7

Branch: refs/heads/master
Commit: 8559d7b7356ec91795e564767588c6f4519653a5
Parents: 118c9d5
Author: Paul Brett <pa...@twopensource.com>
Authored: Tue Jun 9 13:52:10 2015 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Tue Jun 9 13:53:05 2015 -0700

----------------------------------------------------------------------
 src/Makefile.am                    |   2 +
 src/linux/routing/queueing/htb.cpp | 126 ++++++++++++++++++++++++++++++++
 src/linux/routing/queueing/htb.hpp |  73 ++++++++++++++++++
 src/tests/routing_tests.cpp        |  87 +++++++++++++++++++++-
 4 files changed, 287 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8559d7b7/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 10b1902..9c6b52a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -538,6 +538,7 @@ if WITH_NETWORK_ISOLATOR
 	linux/routing/filter/ip.cpp					\
 	linux/routing/link/link.cpp					\
 	linux/routing/queueing/fq_codel.cpp				\
+	linux/routing/queueing/htb.cpp					\
 	linux/routing/queueing/ingress.cpp
 
   libmesos_no_3rdparty_la_SOURCES +=					\
@@ -558,6 +559,7 @@ if WITH_NETWORK_ISOLATOR
 	linux/routing/link/link.hpp					\
 	linux/routing/queueing/discipline.hpp				\
 	linux/routing/queueing/fq_codel.hpp				\
+	linux/routing/queueing/htb.hpp					\
 	linux/routing/queueing/ingress.hpp				\
 	linux/routing/queueing/internal.hpp				\
 	linux/routing/queueing/statistics.hpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/8559d7b7/src/linux/routing/queueing/htb.cpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/queueing/htb.cpp b/src/linux/routing/queueing/htb.cpp
new file mode 100644
index 0000000..d2f68f5
--- /dev/null
+++ b/src/linux/routing/queueing/htb.cpp
@@ -0,0 +1,126 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <netlink/errno.h>
+
+#include <netlink/route/qdisc.h>
+#include <netlink/route/tc.h>
+
+#include <stout/error.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/result.hpp>
+
+#include "linux/routing/handle.hpp"
+
+#include "linux/routing/queueing/htb.hpp"
+#include "linux/routing/queueing/internal.hpp"
+
+using std::string;
+
+namespace routing {
+namespace queueing {
+
+namespace htb {
+
+// TODO(cwang): The htb queueing discipline configuration is not
+// exposed to the user because we use all the default parameters
+// currently.
+struct Config {};
+
+} // namespace htb {
+
+/////////////////////////////////////////////////
+// Type specific {en}decoding functions.
+/////////////////////////////////////////////////
+
+namespace internal {
+
+// Encodes an htb queueing discipline configuration into the
+// libnl queueing discipline 'qdisc'. Each type of queueing discipline
+// needs to implement this function.
+template <>
+Try<Nothing> encode<htb::Config>(
+    const Netlink<struct rtnl_qdisc>& qdisc,
+    const htb::Config& config)
+{
+  return Nothing();
+}
+
+
+// Decodes the htb queue discipline configuration from the libnl
+// queueing discipline 'qdisc'. Each type of queueing discipline needs
+// to implement this function. Returns None if the libnl queueing
+// discipline is not an htb queueing discipline.
+template <>
+Result<htb::Config> decode<htb::Config>(
+    const Netlink<struct rtnl_qdisc>& qdisc)
+{
+  if (rtnl_tc_get_kind(TC_CAST(qdisc.get())) != htb::KIND) {
+    return None();
+  }
+
+  return htb::Config();
+}
+
+} // namespace internal {
+
+/////////////////////////////////////////////////
+// Public interfaces.
+/////////////////////////////////////////////////
+
+namespace htb {
+
+Try<bool> exists( const string& link, const Handle& parent)
+{
+  return internal::exists(link, parent, KIND);
+}
+
+
+Try<bool> create(
+    const string& link,
+    const Handle& parent,
+    const Option<Handle>& handle)
+{
+  return internal::create(
+      link,
+      Discipline<Config>(
+          KIND,
+          parent,
+          handle,
+          Config()));
+}
+
+
+Try<bool> remove(const string& link, const Handle& parent)
+{
+  return internal::remove(link, parent, KIND);
+}
+
+
+Result<hashmap<string, uint64_t>> statistics(
+    const string& link,
+    const Handle& parent)
+{
+  return internal::statistics(link, parent, KIND);
+}
+
+
+} // namespace htb {
+} // namespace queueing {
+} // namespace routing {

http://git-wip-us.apache.org/repos/asf/mesos/blob/8559d7b7/src/linux/routing/queueing/htb.hpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/queueing/htb.hpp b/src/linux/routing/queueing/htb.hpp
new file mode 100644
index 0000000..fdbf3b8
--- /dev/null
+++ b/src/linux/routing/queueing/htb.hpp
@@ -0,0 +1,73 @@
+ /**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LINUX_ROUTING_QUEUEING_HTB_HPP__
+#define __LINUX_ROUTING_QUEUEING_HTB_HPP__
+
+#include <stdint.h>
+
+#include <string>
+
+#include <stout/hashmap.hpp>
+#include <stout/try.hpp>
+
+#include "linux/routing/handle.hpp"
+
+namespace routing {
+namespace queueing {
+namespace htb {
+
+constexpr char KIND[] = "htb";
+
+// Returns true if there exists an htb queueing discipline on the
+// egress side of the link.
+Try<bool> exists(
+    const std::string& link,
+    const Handle& parent);
+
+
+// Creates a new htb queueing discipline on the egress side of
+// the link. Returns false if a queueing discipline already exists which
+// prevents the creation.
+Try<bool> create(
+    const std::string& link,
+    const Handle& parent,
+    const Option<Handle>& handle);
+
+
+// Removes the htb queueing discipline from the link. Returns
+// false if the htb queueing discipline is not found.
+Try<bool> remove(
+    const std::string& link,
+    const Handle& parent);
+
+
+// Returns the set of common Traffic Control statistics for the
+// htb queueing discipline on the link, None() if the link or
+// qdisc does not exist or an error if we cannot cannot determine the
+// result.
+Result<hashmap<std::string, uint64_t>> statistics(
+    const std::string& link,
+    const Handle& parent);
+
+
+} // namespace htb {
+} // namespace queueing {
+} // namespace routing {
+
+#endif // __LINUX_ROUTING_QUEUEING_HTB_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/8559d7b7/src/tests/routing_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/routing_tests.cpp b/src/tests/routing_tests.cpp
index 4be9967..463c2e5 100644
--- a/src/tests/routing_tests.cpp
+++ b/src/tests/routing_tests.cpp
@@ -51,6 +51,7 @@
 #include "linux/routing/link/link.hpp"
 
 #include "linux/routing/queueing/fq_codel.hpp"
+#include "linux/routing/queueing/htb.hpp"
 #include "linux/routing/queueing/ingress.hpp"
 #include "linux/routing/queueing/statistics.hpp"
 
@@ -480,7 +481,91 @@ TEST_F(RoutingVethTest, ROOT_IngressQdisc)
 }
 
 
-TEST_F(RoutingVethTest, ROOT_FqCodelQdisc)
+TEST_F(RoutingVethTest, ROOT_HTBQdisc)
+{
+  // Test for a qdisc on a nonexistent interface should fail.
+  EXPECT_SOME_FALSE(htb::exists("noSuchInterface", EGRESS_ROOT));
+
+  EXPECT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+  EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+  EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+  // This test uses a common handle throughout
+  const Handle handle = Handle(1, 0);
+
+  // Interface exists but does not have an htb qdisc.
+  EXPECT_SOME_FALSE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Interfaces without qdisc established no data.
+  EXPECT_NONE(htb::statistics(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_NONE(htb::statistics(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Try to create an htb qdisc on a nonexistent interface.
+  EXPECT_ERROR(htb::create("noSuchInterface", EGRESS_ROOT, handle));
+
+  // Create an htb qdisc on an existing interface.
+  EXPECT_SOME_TRUE(htb::create(TEST_VETH_LINK, EGRESS_ROOT, handle));
+
+  // Interface exists and has an htb qdisc.
+  EXPECT_SOME_TRUE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Interfaces which exist return at least the core statisitcs.
+  Result<hashmap<string, uint64_t>> stats =
+      htb::statistics(TEST_VETH_LINK, EGRESS_ROOT);
+  ASSERT_SOME(stats);
+  EXPECT_TRUE(stats.get().contains(statistics::PACKETS));
+  EXPECT_TRUE(stats.get().contains(statistics::BYTES));
+  EXPECT_TRUE(stats.get().contains(statistics::RATE_BPS));
+  EXPECT_TRUE(stats.get().contains(statistics::RATE_PPS));
+  EXPECT_TRUE(stats.get().contains(statistics::QLEN));
+  EXPECT_TRUE(stats.get().contains(statistics::BACKLOG));
+  EXPECT_TRUE(stats.get().contains(statistics::DROPS));
+  EXPECT_TRUE(stats.get().contains(statistics::REQUEUES));
+  EXPECT_TRUE(stats.get().contains(statistics::OVERLIMITS));
+
+  // Interface without htb qdisc returns no data.
+  EXPECT_NONE(htb::statistics(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Try to create a second htb qdisc on an existing interface.
+  EXPECT_SOME_FALSE(htb::create(TEST_VETH_LINK, EGRESS_ROOT, handle));
+  EXPECT_SOME_TRUE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Remove the htb qdisc.
+  EXPECT_SOME_TRUE(htb::remove(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Try to remove it from a nonexistent interface.
+  EXPECT_SOME_FALSE(htb::remove("noSuchInterface", EGRESS_ROOT));
+
+  // Remove the htb qdisc when it does not exist.
+  EXPECT_SOME_FALSE(htb::remove(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Try to create an htb qdisc on a nonexistent interface and
+  // default handle.
+  EXPECT_ERROR(htb::create("noSuchInterface", EGRESS_ROOT, None()));
+
+  // Create an htb qdisc on an existing interface.
+  EXPECT_SOME_TRUE(htb::create(TEST_VETH_LINK, EGRESS_ROOT, None()));
+
+  // Interface exists and has an htb qdisc.
+  EXPECT_SOME_TRUE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+
+  // Remove the htb qdisc.
+  EXPECT_SOME_TRUE(htb::remove(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_VETH_LINK, EGRESS_ROOT));
+  EXPECT_SOME_FALSE(htb::exists(TEST_PEER_LINK, EGRESS_ROOT));
+}
+
+
+TEST_F(RoutingVethTest, ROOT_FqCodeQdisc)
 {
   // Test for a qdisc on a nonexistent interface should fail.
   EXPECT_SOME_FALSE(fq_codel::exists("noSuchInterface", EGRESS_ROOT));