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));