You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2015/09/20 20:37:39 UTC
[5/5] mesos git commit: Synchronized global environment manipulation
in TestContainerizer.
Synchronized global environment manipulation in TestContainerizer.
This fixes non-deterministic behavior in the TestContainerizer. There
is still an open issue mentioned in the comments and documented in
MESOS-3475.
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a92ff3cd
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a92ff3cd
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a92ff3cd
Branch: refs/heads/master
Commit: a92ff3cd7388cfcf948e4ffa3dabcad98a29e3a8
Parents: 31defd4
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Sun Sep 20 14:04:42 2015 -0400
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Sun Sep 20 14:21:28 2015 -0400
----------------------------------------------------------------------
src/tests/containerizer.cpp | 105 +++++++++++++++++++++++----------------
1 file changed, 62 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a92ff3cd/src/tests/containerizer.cpp
----------------------------------------------------------------------
diff --git a/src/tests/containerizer.cpp b/src/tests/containerizer.cpp
index 5134e63..1f74315 100644
--- a/src/tests/containerizer.cpp
+++ b/src/tests/containerizer.cpp
@@ -17,6 +17,11 @@
*/
#include "tests/containerizer.hpp"
+
+#include <mutex>
+
+#include "stout/synchronized.hpp"
+
#include "tests/mesos.hpp"
using std::map;
@@ -99,56 +104,70 @@ Future<bool> TestContainerizer::_launch(
containers_[key] = containerId;
Executor* executor = executors[executorInfo.executor_id()];
- Owned<MesosExecutorDriver> driver(new MesosExecutorDriver(executor));
- drivers[containerId] = driver;
-
- // Prepare additional environment variables for the executor.
- // TODO(benh): Need to get flags passed into the TestContainerizer
- // in order to properly use here.
- slave::Flags flags;
- flags.recovery_timeout = Duration::zero();
-
- // We need to save the original set of environment variables so we
- // can reset the environment after calling 'driver->start()' below.
- hashmap<string, string> original = os::environment();
-
- const map<string, string> environment = executorEnvironment(
- executorInfo,
- directory,
- slaveId,
- slavePid,
- checkpoint,
- flags);
- foreachpair (const string& name, const string variable, environment) {
- os::setenv(name, variable);
- }
+ // We need to synchronize all reads and writes to the environment as this is
+ // global state.
+ // TODO(jmlvanre): Even this is not sufficient, as other aspects of the code
+ // may read an environment variable while we are manipulating it. The better
+ // solution is to pass the environment variables into the fork, or to set them
+ // on the command line. See MESOS-3475.
+ static std::mutex mutex;
+
+ synchronized(mutex) {
+ // Since the constructor for `MesosExecutorDriver` reads environment
+ // variables to load flags, even it needs to be within this synchronization
+ // section.
+ Owned<MesosExecutorDriver> driver(new MesosExecutorDriver(executor));
+ drivers[containerId] = driver;
+
+ // Prepare additional environment variables for the executor.
+ // TODO(benh): Need to get flags passed into the TestContainerizer
+ // in order to properly use here.
+ slave::Flags flags;
+ flags.recovery_timeout = Duration::zero();
+
+ // We need to save the original set of environment variables so we
+ // can reset the environment after calling 'driver->start()' below.
+ hashmap<string, string> original = os::environment();
+
+ const map<string, string> environment = executorEnvironment(
+ executorInfo,
+ directory,
+ slaveId,
+ slavePid,
+ checkpoint,
+ flags);
+
+ foreachpair (const string& name, const string variable, environment) {
+ os::setenv(name, variable);
+ }
- // TODO(benh): Can this be removed and done exlusively in the
- // 'executorEnvironment()' function? There are other places in the
- // code where we do this as well and it's likely we can do this once
- // in 'executorEnvironment()'.
- foreach (const Environment::Variable& variable,
- executorInfo.command().environment().variables()) {
- os::setenv(variable.name(), variable.value());
- }
+ // TODO(benh): Can this be removed and done exlusively in the
+ // 'executorEnvironment()' function? There are other places in the
+ // code where we do this as well and it's likely we can do this once
+ // in 'executorEnvironment()'.
+ foreach (const Environment::Variable& variable,
+ executorInfo.command().environment().variables()) {
+ os::setenv(variable.name(), variable.value());
+ }
- os::setenv("MESOS_LOCAL", "1");
+ os::setenv("MESOS_LOCAL", "1");
- driver->start();
+ driver->start();
- os::unsetenv("MESOS_LOCAL");
+ os::unsetenv("MESOS_LOCAL");
- // Unset the environment variables we set by resetting them to their
- // original values and also removing any that were not part of the
- // original environment.
- foreachpair (const string& name, const string& value, original) {
- os::setenv(name, value);
- }
+ // Unset the environment variables we set by resetting them to their
+ // original values and also removing any that were not part of the
+ // original environment.
+ foreachpair (const string& name, const string& value, original) {
+ os::setenv(name, value);
+ }
- foreachkey (const string& name, environment) {
- if (!original.contains(name)) {
- os::unsetenv(name);
+ foreachkey (const string& name, environment) {
+ if (!original.contains(name)) {
+ os::unsetenv(name);
+ }
}
}