Removed CgroupsPerfEventIsolatorProcess.

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


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

Branch: refs/heads/master
Commit: edf824b4d95d44c33c7c381718594b01d0357712
Parents: 34bcae4
Author: haosdent huang <haosd...@gmail.com>
Authored: Mon Sep 12 16:34:51 2016 -0700
Committer: Jie Yu <yujie....@gmail.com>
Committed: Tue Sep 13 10:52:01 2016 -0700

----------------------------------------------------------------------
 src/CMakeLists.txt                              |   1 -
 src/Makefile.am                                 |   2 -
 src/slave/containerizer/mesos/containerizer.cpp |   1 -
 .../mesos/isolators/cgroups/perf_event.cpp      | 415 -------------------
 .../mesos/isolators/cgroups/perf_event.hpp      | 118 ------
 src/tests/containerizer/isolator_tests.cpp      | 232 -----------
 6 files changed, 769 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7caa466..42c52b6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -159,7 +159,6 @@ set(LINUX_SRC
   slave/containerizer/mesos/linux_launcher.cpp
   slave/containerizer/mesos/isolators/appc/runtime.cpp
   slave/containerizer/mesos/isolators/cgroups/cgroups.cpp
-  slave/containerizer/mesos/isolators/cgroups/perf_event.cpp
   slave/containerizer/mesos/isolators/cgroups/subsystem.cpp
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.cpp
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.cpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index d4b90f1..e789994 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1025,7 +1025,6 @@ MESOS_LINUX_FILES =                                       
                                \
   slave/containerizer/mesos/linux_launcher.cpp                                 
        \
   slave/containerizer/mesos/isolators/appc/runtime.cpp                         
        \
   slave/containerizer/mesos/isolators/cgroups/cgroups.cpp                      
        \
-  slave/containerizer/mesos/isolators/cgroups/perf_event.cpp                   
        \
   slave/containerizer/mesos/isolators/cgroups/subsystem.cpp                    
        \
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.cpp               
        \
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.cpp           
        \
@@ -1062,7 +1061,6 @@ MESOS_LINUX_FILES +=                                      
                                \
   slave/containerizer/mesos/isolators/appc/runtime.hpp                         
        \
   slave/containerizer/mesos/isolators/cgroups/cgroups.hpp                      
        \
   slave/containerizer/mesos/isolators/cgroups/constants.hpp                    
        \
-  slave/containerizer/mesos/isolators/cgroups/perf_event.hpp                   
        \
   slave/containerizer/mesos/isolators/cgroups/subsystem.hpp                    
        \
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpu.hpp               
        \
   slave/containerizer/mesos/isolators/cgroups/subsystems/cpuacct.hpp           
        \

http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/slave/containerizer/mesos/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/containerizer.cpp 
b/src/slave/containerizer/mesos/containerizer.cpp
index bbf5d53..dc18e4e 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -73,7 +73,6 @@
 
 #ifdef __linux__
 #include "slave/containerizer/mesos/isolators/cgroups/cgroups.hpp"
-#include "slave/containerizer/mesos/isolators/cgroups/perf_event.hpp"
 #endif // __linux__
 
 #ifdef __linux__

http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/slave/containerizer/mesos/isolators/cgroups/perf_event.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/perf_event.cpp 
b/src/slave/containerizer/mesos/isolators/cgroups/perf_event.cpp
deleted file mode 100644
index 31f3538..0000000
--- a/src/slave/containerizer/mesos/isolators/cgroups/perf_event.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-// 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 <stdint.h>
-
-#include <vector>
-
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/message.h>
-
-#include <process/collect.hpp>
-#include <process/defer.hpp>
-#include <process/delay.hpp>
-#include <process/io.hpp>
-#include <process/pid.hpp>
-#include <process/reap.hpp>
-#include <process/subprocess.hpp>
-
-#include <stout/bytes.hpp>
-#include <stout/check.hpp>
-#include <stout/error.hpp>
-#include <stout/foreach.hpp>
-#include <stout/hashset.hpp>
-#include <stout/lambda.hpp>
-#include <stout/os.hpp>
-#include <stout/path.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-
-#include "linux/cgroups.hpp"
-#include "linux/perf.hpp"
-
-#include "slave/containerizer/mesos/isolators/cgroups/perf_event.hpp"
-
-using mesos::slave::ContainerConfig;
-using mesos::slave::ContainerLaunchInfo;
-using mesos::slave::ContainerLimitation;
-using mesos::slave::ContainerState;
-using mesos::slave::Isolator;
-
-using std::list;
-using std::set;
-using std::string;
-using std::vector;
-
-using process::Clock;
-using process::Failure;
-using process::Future;
-using process::PID;
-using process::Time;
-
-namespace mesos {
-namespace internal {
-namespace slave {
-
-Try<Isolator*> CgroupsPerfEventIsolatorProcess::create(const Flags& flags)
-{
-  LOG(INFO) << "Creating PerfEvent isolator";
-
-  if (!perf::supported()) {
-    return Error("Perf is not supported");
-  }
-
-  if (flags.perf_duration > flags.perf_interval) {
-    return Error("Sampling perf for duration (" +
-                 stringify(flags.perf_duration) +
-                 ") > interval (" +
-                 stringify(flags.perf_interval) +
-                 ") is not supported.");
-  }
-
-  if (!flags.perf_events.isSome()) {
-    return Error("No perf events specified");
-  }
-
-  set<string> events;
-  foreach (const string& event,
-           strings::tokenize(flags.perf_events.get(), ",")) {
-    events.insert(event);
-  }
-
-  if (!perf::valid(events)) {
-    return Error("Failed to create PerfEvent isolator, invalid events: " +
-                 stringify(events));
-  }
-
-  Try<string> hierarchy = cgroups::prepare(
-      flags.cgroups_hierarchy,
-      "perf_event",
-      flags.cgroups_root);
-
-  if (hierarchy.isError()) {
-    return Error("Failed to create perf_event cgroup: " + hierarchy.error());
-  }
-
-  LOG(INFO) << "PerfEvent isolator will profile for " << flags.perf_duration
-            << " every " << flags.perf_interval
-            << " for events: " << stringify(events);
-
-  process::Owned<MesosIsolatorProcess> process(
-      new CgroupsPerfEventIsolatorProcess(flags, hierarchy.get(), events));
-
-  return new MesosIsolator(process);
-}
-
-
-CgroupsPerfEventIsolatorProcess::~CgroupsPerfEventIsolatorProcess() {}
-
-
-void CgroupsPerfEventIsolatorProcess::initialize()
-{
-  // Start sampling.
-  sample();
-}
-
-
-Future<Nothing> CgroupsPerfEventIsolatorProcess::recover(
-    const list<ContainerState>& states,
-    const hashset<ContainerID>& orphans)
-{
-  foreach (const ContainerState& state, states) {
-    const ContainerID& containerId = state.container_id();
-    const string cgroup = path::join(flags.cgroups_root, containerId.value());
-
-    Try<bool> exists = cgroups::exists(hierarchy, cgroup);
-    if (exists.isError()) {
-      foreachvalue (Info* info, infos) {
-        delete info;
-      }
-
-      infos.clear();
-      return Failure("Failed to check cgroup " + cgroup +
-                     " for container '" + stringify(containerId) + "'");
-    }
-
-    if (!exists.get()) {
-      // This may occur if the executor is exiting and the isolator has
-      // destroyed the cgroup but the slave dies before noticing this. This
-      // will be detected when the containerizer tries to monitor the
-      // executor's pid.
-      // NOTE: This could also occur if this isolator is now enabled for a
-      // container that was started without this isolator. For this
-      // particular isolator it is acceptable to continue running this
-      // container without a perf_event cgroup because we don't ever
-      // query it and the destroy will succeed immediately.
-      VLOG(1) << "Couldn't find perf event cgroup for container " << 
containerId
-              << ", perf statistics will not be available";
-      continue;
-    }
-
-    infos[containerId] = new Info(containerId, cgroup);
-  }
-
-  // Remove orphan cgroups.
-  Try<vector<string>> cgroups = cgroups::get(hierarchy, flags.cgroups_root);
-  if (cgroups.isError()) {
-    foreachvalue (Info* info, infos) {
-      delete info;
-    }
-    infos.clear();
-    return Failure(cgroups.error());
-  }
-
-  foreach (const string& cgroup, cgroups.get()) {
-    // Ignore the slave cgroup (see the --agent_subsystems flag).
-    // TODO(idownes): Remove this when the cgroups layout is updated,
-    // see MESOS-1185.
-    if (cgroup == path::join(flags.cgroups_root, "slave")) {
-      continue;
-    }
-
-    ContainerID containerId;
-    containerId.set_value(Path(cgroup).basename());
-
-    if (infos.contains(containerId)) {
-      continue;
-    }
-
-    // Known orphan cgroups will be destroyed by the containerizer
-    // using the normal cleanup path. See details in MESOS-2367.
-    if (orphans.contains(containerId)) {
-      infos[containerId] = new Info(containerId, cgroup);
-      continue;
-    }
-
-    LOG(INFO) << "Removing unknown orphaned cgroup '" << cgroup << "'";
-
-    // We don't wait on the destroy as we don't want to block recovery.
-    cgroups::destroy(hierarchy, cgroup, cgroups::DESTROY_TIMEOUT);
-  }
-
-  return Nothing();
-}
-
-
-Future<Option<ContainerLaunchInfo>> CgroupsPerfEventIsolatorProcess::prepare(
-    const ContainerID& containerId,
-    const ContainerConfig& containerConfig)
-{
-  if (infos.contains(containerId)) {
-    return Failure("Container has already been prepared");
-  }
-
-  LOG(INFO) << "Preparing perf event cgroup for " << containerId;
-
-  Info* info = new Info(
-      containerId,
-      path::join(flags.cgroups_root, containerId.value()));
-
-  infos[containerId] = CHECK_NOTNULL(info);
-
-  // Create a cgroup for this container.
-  Try<bool> exists = cgroups::exists(hierarchy, info->cgroup);
-
-  if (exists.isError()) {
-    return Failure("Failed to prepare isolator: " + exists.error());
-  }
-
-  if (exists.get()) {
-    return Failure("Failed to prepare isolator: cgroup already exists");
-  }
-
-  if (!exists.get()) {
-    Try<Nothing> create = cgroups::create(hierarchy, info->cgroup);
-    if (create.isError()) {
-      return Failure("Failed to prepare isolator: " + create.error());
-    }
-  }
-
-  // Chown the cgroup so the executor can create nested cgroups. Do
-  // not recurse so the control files are still owned by the slave
-  // user and thus cannot be changed by the executor.
-  if (containerConfig.has_user()) {
-    Try<Nothing> chown = os::chown(
-        containerConfig.user(),
-        path::join(hierarchy, info->cgroup),
-        false);
-    if (chown.isError()) {
-      return Failure("Failed to prepare isolator: " + chown.error());
-    }
-  }
-
-  return None();
-}
-
-
-Future<Nothing> CgroupsPerfEventIsolatorProcess::isolate(
-    const ContainerID& containerId,
-    pid_t pid)
-{
-  if (!infos.contains(containerId)) {
-    return Failure("Unknown container");
-  }
-
-  Info* info = CHECK_NOTNULL(infos[containerId]);
-
-  Try<Nothing> assign = cgroups::assign(hierarchy, info->cgroup, pid);
-  if (assign.isError()) {
-    return Failure("Failed to assign container '" +
-                   stringify(info->containerId) + "' to its own cgroup '" +
-                   path::join(hierarchy, info->cgroup) +
-                   "' : " + assign.error());
-  }
-
-  return Nothing();
-}
-
-
-Future<ResourceStatistics> CgroupsPerfEventIsolatorProcess::usage(
-    const ContainerID& containerId)
-{
-  if (!infos.contains(containerId)) {
-    // Return an empty ResourceStatistics, i.e., without
-    // PerfStatistics, if we don't know about this container.
-    return ResourceStatistics();
-  }
-
-  CHECK_NOTNULL(infos[containerId]);
-
-  ResourceStatistics statistics;
-  statistics.mutable_perf()->CopyFrom(infos[containerId]->statistics);
-
-  return statistics;
-}
-
-
-Future<Nothing> CgroupsPerfEventIsolatorProcess::cleanup(
-    const ContainerID& containerId)
-{
-  // Tolerate clean up attempts for unknown containers which may arise from
-  // repeated clean up attempts (during test cleanup).
-  if (!infos.contains(containerId)) {
-    VLOG(1) << "Ignoring cleanup request for unknown container: "
-            << containerId;
-    return Nothing();
-  }
-
-  Info* info = CHECK_NOTNULL(infos[containerId]);
-
-  info->destroying = true;
-
-  return cgroups::destroy(hierarchy, info->cgroup)
-    .then(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
-                &CgroupsPerfEventIsolatorProcess::_cleanup,
-                containerId));
-}
-
-
-Future<Nothing> CgroupsPerfEventIsolatorProcess::_cleanup(
-    const ContainerID& containerId)
-{
-  if (!infos.contains(containerId)) {
-    return Nothing();
-  }
-
-  delete infos[containerId];
-  infos.erase(containerId);
-
-  return Nothing();
-}
-
-
-Future<hashmap<string, PerfStatistics>> discardSample(
-    Future<hashmap<string, PerfStatistics>> future,
-    const Duration& duration,
-    const Duration& timeout)
-{
-  LOG(ERROR) << "Perf sample of " << stringify(duration)
-             << " failed to complete within " << stringify(timeout)
-             << "; sampling will be halted";
-
-  future.discard();
-
-  return future;
-}
-
-
-void CgroupsPerfEventIsolatorProcess::sample()
-{
-  // Collect a perf sample for all cgroups that are not being
-  // destroyed. Since destroyal is asynchronous, 'perf stat' may
-  // fail if the cgroup is destroyed before running perf.
-  set<string> cgroups;
-
-  foreachvalue (Info* info, infos) {
-    CHECK_NOTNULL(info);
-
-    if (!info->destroying) {
-      cgroups.insert(info->cgroup);
-    }
-  }
-
-  // The discard timeout includes an allowance of twice the
-  // reaper interval to ensure we see the perf process exit.
-  Duration timeout = flags.perf_duration + process::MAX_REAP_INTERVAL() * 2;
-
-  perf::sample(events, cgroups, flags.perf_duration)
-    .after(timeout,
-           lambda::bind(&discardSample,
-                        lambda::_1,
-                        flags.perf_duration,
-                        timeout))
-    .onAny(defer(PID<CgroupsPerfEventIsolatorProcess>(this),
-                 &CgroupsPerfEventIsolatorProcess::_sample,
-                 Clock::now() + flags.perf_interval,
-                 lambda::_1));
-}
-
-
-void CgroupsPerfEventIsolatorProcess::_sample(
-    const Time& next,
-    const Future<hashmap<string, PerfStatistics>>& statistics)
-{
-  if (!statistics.isReady()) {
-    // In case the failure is transient or this is due to a timeout,
-    // we continue sampling. Note that since sampling is done on an
-    // interval, it should be ok if this is a non-transient failure.
-    LOG(ERROR) << "Failed to get perf sample: "
-               << (statistics.isFailed()
-                   ? statistics.failure()
-                   : "discarded due to timeout");
-  } else {
-    // Store the latest statistics, note that cgroups added in the
-    // interim will be picked up by the next sample.
-    foreachvalue (Info* info, infos) {
-      CHECK_NOTNULL(info);
-
-      if (statistics->contains(info->cgroup)) {
-        info->statistics = statistics->get(info->cgroup).get();
-      }
-    }
-  }
-
-  // Schedule sample for the next time.
-  delay(next - Clock::now(),
-        PID<CgroupsPerfEventIsolatorProcess>(this),
-        &CgroupsPerfEventIsolatorProcess::sample);
-}
-
-} // namespace slave {
-} // namespace internal {
-} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/slave/containerizer/mesos/isolators/cgroups/perf_event.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/isolators/cgroups/perf_event.hpp 
b/src/slave/containerizer/mesos/isolators/cgroups/perf_event.hpp
deleted file mode 100644
index 4abde12..0000000
--- a/src/slave/containerizer/mesos/isolators/cgroups/perf_event.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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 __PERF_EVENT_ISOLATOR_HPP__
-#define __PERF_EVENT_ISOLATOR_HPP__
-
-#include <set>
-
-#include <process/id.hpp>
-#include <process/time.hpp>
-
-#include <stout/hashmap.hpp>
-#include <stout/nothing.hpp>
-
-#include "slave/flags.hpp"
-
-#include "slave/containerizer/mesos/isolator.hpp"
-
-namespace mesos {
-namespace internal {
-namespace slave {
-
-class CgroupsPerfEventIsolatorProcess : public MesosIsolatorProcess
-{
-public:
-  static Try<mesos::slave::Isolator*> create(const Flags& flags);
-
-  virtual ~CgroupsPerfEventIsolatorProcess();
-
-  virtual process::Future<Nothing> recover(
-      const std::list<mesos::slave::ContainerState>& states,
-      const hashset<ContainerID>& orphans);
-
-  virtual process::Future<Option<mesos::slave::ContainerLaunchInfo>> prepare(
-      const ContainerID& containerId,
-      const mesos::slave::ContainerConfig& containerConfig);
-
-  virtual process::Future<Nothing> isolate(
-      const ContainerID& containerId,
-      pid_t pid);
-
-  virtual process::Future<ResourceStatistics> usage(
-      const ContainerID& containerId);
-
-  virtual process::Future<Nothing> cleanup(
-      const ContainerID& containerId);
-
-protected:
-  virtual void initialize();
-
-private:
-  CgroupsPerfEventIsolatorProcess(
-      const Flags& _flags,
-      const std::string& _hierarchy,
-      const std::set<std::string>& _events)
-    : ProcessBase(process::ID::generate("cgroups-perf-event-isolator")),
-      flags(_flags),
-      hierarchy(_hierarchy),
-      events(_events) {}
-
-  void sample();
-
-  void _sample(
-      const process::Time& next,
-      const process::Future<hashmap<std::string, PerfStatistics>>& statistics);
-
-  virtual process::Future<Nothing> _cleanup(const ContainerID& containerId);
-
-  struct Info
-  {
-    Info(const ContainerID& _containerId, const std::string& _cgroup)
-      : containerId(_containerId), cgroup(_cgroup), destroying(false)
-    {
-      // Ensure the initial statistics include the required fields.
-      // Note the duration is set to zero to indicate no sampling has
-      // taken place. This empty sample will be returned from usage()
-      // until the first true sample is obtained.
-      statistics.set_timestamp(process::Clock::now().secs());
-      statistics.set_duration(Seconds(0).secs());
-    }
-
-    const ContainerID containerId;
-    const std::string cgroup;
-    PerfStatistics statistics;
-    // Mark a container when we start destruction so we stop sampling it.
-    bool destroying;
-  };
-
-  const Flags flags;
-
-  // The path to the cgroups subsystem hierarchy root.
-  const std::string hierarchy;
-
-  // Set of events to sample.
-  std::set<std::string> events;
-
-  // TODO(jieyu): Use Owned<Info>.
-  hashmap<ContainerID, Info*> infos;
-};
-
-} // namespace slave {
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __PERF_EVENT_ISOLATOR_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/edf824b4/src/tests/containerizer/isolator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer/isolator_tests.cpp 
b/src/tests/containerizer/isolator_tests.cpp
index 85a13d7..9bb1e69 100644
--- a/src/tests/containerizer/isolator_tests.cpp
+++ b/src/tests/containerizer/isolator_tests.cpp
@@ -52,7 +52,6 @@
 #include "slave/slave.hpp"
 
 #ifdef __linux__
-#include "slave/containerizer/mesos/isolators/cgroups/perf_event.hpp"
 #include "slave/containerizer/mesos/isolators/filesystem/shared.hpp"
 #endif // __linux__
 #include "slave/containerizer/mesos/isolators/posix.hpp"
@@ -74,7 +73,6 @@ using namespace process;
 
 using mesos::internal::master::Master;
 #ifdef __linux__
-using mesos::internal::slave::CgroupsPerfEventIsolatorProcess;
 using mesos::internal::slave::Fetcher;
 using mesos::internal::slave::LinuxLauncher;
 using mesos::internal::slave::SharedFilesystemIsolatorProcess;
@@ -101,85 +99,6 @@ namespace internal {
 namespace tests {
 
 #ifdef __linux__
-class PerfEventIsolatorTest : public MesosTest {};
-
-
-TEST_F(PerfEventIsolatorTest, ROOT_CGROUPS_PERF_Sample)
-{
-  slave::Flags flags;
-
-  flags.perf_events = "cycles,task-clock";
-  flags.perf_duration = Milliseconds(250);
-  flags.perf_interval = Milliseconds(500);
-
-  Try<Isolator*> _isolator = CgroupsPerfEventIsolatorProcess::create(flags);
-  ASSERT_SOME(_isolator);
-  Owned<Isolator> isolator(_isolator.get());
-
-  ExecutorInfo executorInfo;
-
-  ContainerID containerId;
-  containerId.set_value(UUID::random().toString());
-
-  // Use a relative temporary directory so it gets cleaned up
-  // automatically with the test.
-  Try<string> dir = os::mkdtemp(path::join(os::getcwd(), "XXXXXX"));
-  ASSERT_SOME(dir);
-
-  ContainerConfig containerConfig;
-  containerConfig.mutable_executor_info()->CopyFrom(executorInfo);
-  containerConfig.set_directory(dir.get());
-
-  AWAIT_READY(isolator->prepare(
-      containerId,
-      containerConfig));
-
-  // This first sample is likely to be empty because perf hasn't
-  // completed yet but we should still have the required fields.
-  Future<ResourceStatistics> statistics1 = isolator->usage(containerId);
-  AWAIT_READY(statistics1);
-  ASSERT_TRUE(statistics1.get().has_perf());
-  EXPECT_TRUE(statistics1.get().perf().has_timestamp());
-  EXPECT_TRUE(statistics1.get().perf().has_duration());
-
-  // Wait until we get the next sample. We use a generous timeout of
-  // two seconds because we currently have a one second reap interval;
-  // when running perf with perf_duration of 250ms we won't notice the
-  // exit for up to one second.
-  ResourceStatistics statistics2;
-  Duration waited = Duration::zero();
-  do {
-    Future<ResourceStatistics> statistics = isolator->usage(containerId);
-    AWAIT_READY(statistics);
-
-    statistics2 = statistics.get();
-
-    ASSERT_TRUE(statistics2.has_perf());
-
-    if (statistics1.get().perf().timestamp() !=
-        statistics2.perf().timestamp()) {
-      break;
-    }
-
-    os::sleep(Milliseconds(250));
-    waited += Milliseconds(250);
-  } while (waited < Seconds(2));
-
-  sleep(2);
-
-  EXPECT_NE(statistics1.get().perf().timestamp(),
-            statistics2.perf().timestamp());
-
-  EXPECT_TRUE(statistics2.perf().has_cycles());
-  EXPECT_LE(0u, statistics2.perf().cycles());
-
-  EXPECT_TRUE(statistics2.perf().has_task_clock());
-  EXPECT_LE(0.0, statistics2.perf().task_clock());
-
-  AWAIT_READY(isolator->cleanup(containerId));
-}
-
-
 class SharedFilesystemIsolatorTest : public MesosTest {};
 
 
@@ -444,157 +363,6 @@ TEST_F(NamespacesPidIsolatorTest, ROOT_PidNamespace)
 
   EXPECT_EQ("sh", strings::trim(init.get()));
 }
-
-
-// Username for the unprivileged user that will be created to test
-// unprivileged cgroup creation. It will be removed after the tests.
-// It is presumed this user does not normally exist.
-const string UNPRIVILEGED_USERNAME = "mesos.test.unprivileged.user";
-
-
-template <typename T>
-class UserCgroupIsolatorTest
-  : public ContainerizerTest<slave::MesosContainerizer>
-{
-public:
-  static void SetUpTestCase()
-  {
-    ContainerizerTest<slave::MesosContainerizer>::SetUpTestCase();
-
-    // Remove the user in case it wasn't cleaned up from a previous
-    // test.
-    os::system("userdel -r " + UNPRIVILEGED_USERNAME + " > /dev/null");
-
-    ASSERT_EQ(0, os::system("useradd " + UNPRIVILEGED_USERNAME));
-  }
-
-
-  static void TearDownTestCase()
-  {
-    ContainerizerTest<slave::MesosContainerizer>::TearDownTestCase();
-
-    ASSERT_EQ(0, os::system("userdel -r " + UNPRIVILEGED_USERNAME));
-  }
-};
-
-
-// Test all isolators that use cgroups.
-typedef ::testing::Types<CgroupsPerfEventIsolatorProcess> CgroupsIsolatorTypes;
-
-
-TYPED_TEST_CASE(UserCgroupIsolatorTest, CgroupsIsolatorTypes);
-
-
-TYPED_TEST(UserCgroupIsolatorTest, ROOT_CGROUPS_PERF_UserCgroup)
-{
-  slave::Flags flags = UserCgroupIsolatorTest<TypeParam>::CreateSlaveFlags();
-  flags.perf_events = "cpu-cycles"; // Needed for CgroupsPerfEventIsolator.
-
-  Try<Isolator*> _isolator = TypeParam::create(flags);
-  ASSERT_SOME(_isolator);
-  Owned<Isolator> isolator(_isolator.get());
-
-  ExecutorInfo executorInfo;
-  executorInfo.mutable_resources()->CopyFrom(
-      Resources::parse("mem:1024;cpus:1").get()); // For cpu/mem isolators.
-
-  ContainerID containerId;
-  containerId.set_value(UUID::random().toString());
-
-  ContainerConfig containerConfig;
-  containerConfig.mutable_executor_info()->CopyFrom(executorInfo);
-  containerConfig.set_directory(os::getcwd());
-  containerConfig.set_user(UNPRIVILEGED_USERNAME);
-
-  AWAIT_READY(isolator->prepare(
-      containerId,
-      containerConfig));
-
-  // Isolators don't provide a way to determine the cgroups they use
-  // so we'll inspect the cgroups for an isolated dummy process.
-  pid_t pid = fork();
-  if (pid == 0) {
-    // Child just sleeps.
-    ::sleep(100);
-
-    ABORT("Child process should not reach here");
-  }
-  ASSERT_GT(pid, 0);
-
-  AWAIT_READY(isolator->isolate(containerId, pid));
-
-  // Get the container's cgroups from /proc/$PID/cgroup. We're only
-  // interested in the cgroups that this isolator has created which we
-  // can do explicitly by selecting those that have the path that
-  // corresponds to the 'cgroups_root' slave flag. For example:
-  //
-  //   $ cat /proc/pid/cgroup
-  //   6:blkio:/
-  //   5:perf_event:/
-  //   4:memory:/mesos/b7410ed8-c85b-445e-b50e-3a1698d0e18c
-  //   3:freezer:/
-  //   2:cpuacct:/
-  //   1:cpu:/
-  //
-  // Our 'grep' will only select the 'memory' line and then 'awk' will
-  // output 'memory/mesos/b7410ed8-c85b-445e-b50e-3a1698d0e18c'.
-  Try<string> grepOut = os::shell(
-      "grep '" + path::join("/", flags.cgroups_root) + "' /proc/" +
-       stringify(pid) + "/cgroup | awk -F ':' '{print $2$3}'");
-
-  ASSERT_SOME(grepOut);
-
-  // Kill the dummy child process.
-  ::kill(pid, SIGKILL);
-  int exitStatus;
-  EXPECT_NE(-1, ::waitpid(pid, &exitStatus, 0));
-
-  vector<string> cgroups = strings::tokenize(grepOut.get(), "\n");
-  ASSERT_FALSE(cgroups.empty());
-
-  foreach (string cgroup, cgroups) {
-    if (!os::exists(path::join(flags.cgroups_hierarchy, cgroup)) &&
-        strings::startsWith(cgroup, "cpuacct,cpu")) {
-      // An existing bug in CentOS 7.x causes 'cpuacct,cpu' cgroup to
-      // be under 'cpu,cpuacct'. Actively detect this here to
-      // work around this problem.
-      vector<string> parts = strings::split(cgroup, "/");
-      parts[0] = "cpu,cpuacct";
-      cgroup = strings::join("/", parts);
-    }
-
-    // Check the user cannot manipulate the container's cgroup control
-    // files.
-    EXPECT_NE(0, os::system(
-          "su - " + UNPRIVILEGED_USERNAME +
-          " -c 'echo $$ >" +
-          path::join(flags.cgroups_hierarchy, cgroup, "cgroup.procs") +
-          "'"));
-
-    // Check the user can create a cgroup under the container's
-    // cgroup.
-    string userCgroup = path::join(cgroup, "user");
-
-    EXPECT_EQ(0, os::system(
-          "su - " +
-          UNPRIVILEGED_USERNAME +
-          " -c 'mkdir " +
-          path::join(flags.cgroups_hierarchy, userCgroup) +
-          "'"));
-
-    // Check the user can manipulate control files in the created
-    // cgroup.
-    EXPECT_EQ(0, os::system(
-          "su - " +
-          UNPRIVILEGED_USERNAME +
-          " -c 'echo $$ >" +
-          path::join(flags.cgroups_hierarchy, userCgroup, "cgroup.procs") +
-          "'"));
-  }
-
-  // Clean up the container. This will also remove the nested cgroups.
-  AWAIT_READY(isolator->cleanup(containerId));
-}
 #endif // __linux__
 
 } // namespace tests {

Reply via email to